我正在准备周二的操作系统考试。为了准备,我正在尝试通过C程序模拟命令行管道。
这个程序很简单。我创建了一个管道,然后fork一个子进程。
子进程将标准输出重定向到管道的写端口,关闭管道的文件描述符,然后执行一个命令(在这种情况下是
父进程等待子进程退出,将标准输入重定向到管道的读端口,关闭管道的文件描述符,然后执行一个命令(在这种情况下是
当我通过命令行使用
当我运行自己编写的程序时,没有收到任何错误消息,但也没有产生任何输出。
我能想到唯一可能导致程序无法正常工作的事情是子进程中重定向标准输出会影响父进程命令的输出,但我几乎可以肯定不应该是这种情况。
以下是代码:
这个程序很简单。我创建了一个管道,然后fork一个子进程。
子进程将标准输出重定向到管道的写端口,关闭管道的文件描述符,然后执行一个命令(在这种情况下是
ls
)。父进程等待子进程退出,将标准输入重定向到管道的读端口,关闭管道的文件描述符,然后执行一个命令(在这种情况下是
grep 'school'
)。当我通过命令行使用
ls | grep 'school'
命令执行时,有一行打印到标准输出,这是有道理的,因为我运行程序的目录中有一个名为“school”的目录。当我运行自己编写的程序时,没有收到任何错误消息,但也没有产生任何输出。
我能想到唯一可能导致程序无法正常工作的事情是子进程中重定向标准输出会影响父进程命令的输出,但我几乎可以肯定不应该是这种情况。
以下是代码:
#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;
}
}