在subprocess中redirect标准输出对父进程是否也这样做?

我正在周二学习OS考试。 为了准备,我试图通过C程序模拟命令行pipe道。

该程序非常简单。 我做了一个pipe道,然后fork一个subprocess。

subprocess将标准输出redirect到pipe道的写入端,closurespipe道的文件描述符,然后执行一个命令(本例中为ls )。

父进程等待subprocess退出,将标准inputredirect到pipe道的读端,closurespipe道的文件描述符,然后执行命令(本例中为grep 'school' )。

当我通过命令行使用ls | grep 'school'执行命令时 ls | grep 'school'有一条线,说“学校”打印到标准输出,这是有道理的,因为目录中有一个目录,我正在运行程序中的名称。

当我运行我制作的程序时,我没有收到任何错误消息,但是它不会产生任何输出。

我唯一能想到的就是阻止这个工作,就是在subprocess中redirect标准输出会以某种方式影响父进程命令的输出,但是我几乎肯定不应该是这样。

这里是代码:

 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> int main() { int fds[2]; int pipe_val, close_val, write_val, dup_val, status; pid_t pid; char *error; pipe_val = pipe(fds); if (pipe_val) { fprintf(stderr, "Failed to prepare pipe.\n"); return -1; } pid = fork(); if (pid == -1) { fprintf(stderr, "Failed to fork a child process.\n"); return -1; } else if (pid == 0) { dup_val = dup2(fds[1], STDOUT_FILENO); if (dup_val) { error = strerror(errno); fprintf(stderr, "Failed to redirect standard output in child process because %s\n", error); exit(1); } close_val = close(fds[0]); if (close_val) { fprintf(stderr, "Failed to close read-end of pipe in child process.\n"); exit(1); } close_val = close(fds[1]); if (close_val) { fprintf(stderr, "Failed to close write-end of pipe in child process.\n"); exit(1); } execl("/bin/ls", "ls", NULL); fprintf(stderr, "Failed to execute command in child process.\n"); exit(1); } else { wait(&status); dup_val = dup2(fds[0], STDIN_FILENO); if (dup_val) { error = strerror(errno); fprintf(stderr, "Failed to redirect standard input in parent process because %s.\n", error); return -1; } close_val = close(fds[0]); if (close_val) { fprintf(stderr, "Failed to close read-end of the pipe in the parent process.\n"); return -1; } close_val = close(fds[1]); if (close_val) { fprintf(stderr, "Failed to close write-end of the pipe in the parent process.\n"); return -1; } execl("/bin/grep", "grep", "school", NULL); fprintf(stderr, "Failed to execute the command in the parent process.\n"); return -1; } } 

你的第一个问题是,你没有包含你所使用的函数的所有必要的头文件。 strerror需要<string.h>wait需要<sys/wait.h>

如果你用gcc编译,总是使用gcc -Wall并读取警告。 在这种情况下,它会抱怨strerror的隐含声明。

由于strerror没有声明,编译器假定它返回一个int ,这是错误的。 如果您在64位Linux x86上运行该程序,则int大小strerror返回的指针大小不同 。 当你以%s格式将strerror的结果传递给fprintf时,这将成为一个致命的问题,因为指针被错误地解释为int,然后转换回指针,最终导致伪造值。 fprintf错误,你永远不会看到你的错误信息。

包括正确的标题,你会看到一个错误信息,这将导致你需要解决的下一个问题。