【发布时间】:2021-09-21 12:35:33
【问题描述】:
我有一些代码练习分叉进程(在命令行中模拟 (|))。但是,每次的输出都不相同。比如./pipe ls cat wc的输入,应该和ls | cat | wc一样。但是,有时我的代码会输出
Child with PID 12126 exited with status 0x0.
Child with PID 12127 exited with status 0x0.
7 7 52
Child with PID 12128 exited with status 0x0.
但有时它也会输出:
Makefile
pipe
#pipe.c#
pipe.c
pipe.o
README.md
test
Child with PID 12138 exited with status 0x0.
Child with PID 12139 exited with status 0x0.
0 0 0
Child with PID 12140 exited with status 0x0.
第一个输出是正确的(与ls | cat | wc 相比)。我发现通过第二个输出,ls 和cat 程序的管道输出没有被wc 处理。我想知道我的程序出了什么问题,因为似乎我正确设置了管道 - 第一个程序将从标准输入获取输入并输出到管道的写入端,最后一个程序将从读取端获取输入管道并输出到标准输出。任何意见表示赞赏。
代码(./pipe):
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd[2];
if (pipe(fd) == -1) {
int err = errno;
perror("pipe");
return err;
}
pid_t pid[argc-1];
int n = argc;
if(argc <= 1){
return EINVAL;
}
for (int i = 1; i < argc; i++){
if ((pid[i] = fork()) == -1){
int err = errno;
perror("fork");
return err;
}else if(pid[i] == 0){
//open(fd[1]);
if(i == 1){
dup2(fd[1],STDOUT_FILENO);
if (execlp(argv[i], argv[i], NULL) == -1) {
printf("failed to search for the provided executed program. \n");
return errno;
}
}else if(i == argc-1){
dup2(fd[0],STDIN_FILENO);
if (execlp(argv[i], argv[i], NULL) == -1) {
printf("failed to search for the provided executed program. \n");
return errno;
}
}else{
dup2(fd[0],STDIN_FILENO);
dup2(fd[1],STDOUT_FILENO);
if (execlp(argv[i], argv[i], NULL) == -1) {
printf("failed to search for the provided executed program. \n");
return errno;
}
}
}
close(fd[1]);
}
int wstatus;
pid_t pids;
while (n > 1) {
pids = wait(&wstatus);
printf("Child with PID %ld exited with status 0x%x.\n", (long)pids, wstatus);
--n;
}
}
【问题讨论】: