我正在尝试使用dup2()
,fork()
和pipe()
创建递归管道函数。但是,当我的数组类似{"ls", "grep shell"}
(其中shell是我的shell的名称)时,它会陷入无尽的循环,显示ls的结果并说“写错误:错误的文件描述符”。我确定某种方式我无法正确终止递归,并且我怀疑问题在于尝试复制fd[1]
或fd[0]
,但是在调试了几个小时之后,我仍然找不到出来。任何帮助表示赞赏!
void recursive_piping(char *recursive_pipe_args[MAX_ARGS]) {
int i = 0;
int fd[2];
char *first_arg[2] = {"", NULL};
char *rest_of_args[81];
// if its of size 1, base case
if (recursive_pipe_args[1] == NULL) {
if (execvp(recursive_pipe_args[0], recursive_pipe_args) == -1) {
printf("\nExecute didn't work");
fflush(stdout);
}
return;
}
// recursive case, split args into the first on and the rest of them
first_arg[0] = recursive_pipe_args[0];
for (i = 0; i < (num_pipes); i++) {
rest_of_args[i] = malloc(81);
strcpy(rest_of_args[i], recursive_pipe_args[i+1]);
}
if (pipe(fd) < 0) {
printf("\npipe Failure");
}
// parent section, reads file descriptor fd[0]
if (fork()) {
close(fd[0]);
dup2(fd[1], 0);
recursive_piping(rest_of_args);
// return;
}
close(fd[1]);
dup2(fd[0], 1);
execvp(first_arg[0], first_arg);
}
答案 0 :(得分:0)
我通过以下更改为您的功能做了准备:
recursive_pipe_args
的第一个元素添加NULL
进行检查,在这种情况下,它发出诊断信息而不执行任何操作。recursive_pipe_args
数组中初始非NULL元素的数量,并以该容量动态分配rest_of_args
(因此,空间少了一个参数加上NULL
标记) 。recursive_pipe_args
的尾部复制到rest_of_args
中,因此可以肯定地复制了NULL
哨兵。fork()
中的错误。fd[1]
)的写端复制到标准输出(文件描述符1
)上,将读取端复制到标准输入({{ 1}}和fd[0]
),并在每个过程中关闭在该过程中未使用的管道末端。0
。生成的程序对我来说是预期的工作:它将指定命令管道的结果发射到其标准输出。但是请注意,您的设计固有地限于不带任何参数的命令,这在很大程度上限制了其实用性。我的测试用例是perror()
。
实现这些更改的代码留作练习。