我应该创建两个程序(main 和 aux),其中 main fork 一个子程序来执行 aux。父进程从用户处获取输入,直到空行“\n”,并且子进程执行 aux,这应该将输入打印回来。我可以使用注释代码而不是 execlp() 让它在 main 中工作,但无法让 execlp(aux) 正常工作。如有任何帮助,我们将不胜感激。
“main.c”
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int fd[2], i;
char line[100], buffer[100];
pipe(fd);
pid_t pid = fork();
if (pid < 0) {
printf("Fork Failed\n");
exit(-1);
}
else if (pid > 0) {
close(fd[0]);
while(fgets(line, sizeof(line), stdin) && line[0] != '\n') {
write(fd[1], line, sizeof(line));
}
close(fd[1]);
}
else {
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
//while(read(fd[0], buffer, sizeof(buffer)))
// printf("> %s", buffer);
execlp("./aux", "aux", (char *)0);
}
return 0;
}
“aux.c”
#include <stdio.h>
#include <stdlib.h>
int main() {
char data[100];
while(fgets(data, sizeof(data), stdin))
printf(">%s\n", data);
return 0;
}
示例输入/输出
this
>this
is a test
>
> test
only prints larger text with random \n
>
>ts larger text with random \n
最佳答案
您调用write(2)是错误的(你总是写
100字节,即使是较短的行
-s):
write(fd[1], line, sizeof(line)); // WRONG
可能应该使用 strlen(3)
size_t ll = strlen(line);
ssize_t wc = write(fd[1], line, ll);
if (wc != ll)
fprintf(stderr, "write was wrong (only %d, wanted %d) - %s\n",
(int) wc, (int) ll, strerror(errno));
由于您只想写入 line
缓冲区的填充字节,因此每次并不总是 100 个字节(其中一些未初始化)。
在您的情况下,sizeof(data)
是 100,因为您声明了 char data[100];
请仔细阅读每个使用函数的文档(以及 ALP 或其他有关 Unix/POSIX/Linux 编程的书籍)。 strerror(3)的文档和 errno(3)告诉您需要添加:
#include <string.h>
#include <errno.h>
实际上,如果你想用read(2)和 write(2)直接(没有 stdio(3) )你应该更喜欢使用更大的缓冲区(例如,每个至少 4Kbytes 以提高效率),并且你需要管理部分 read
-s 和 write
-s 和自己做缓冲。
顺便说一句,编译时包含所有警告和调试信息:gcc -Wall -Wextra -g
并学习 use the gdb
debugger和 strace(1) (和valgrind)。一般来说,是scared的undefined behavior (然而,乍一看,你的程序似乎没有UB)。
关于C - 将输入从一个程序传送到另一个程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47150237/