所以我正处于一个使用C创建基本UNIX shell的项目的最后。我已经完成了很多不同的程序,但现在我想征服管道。我特别想创建一个可以处理任意数量管道的程序。
出于某种原因,我的代码达到某一行(标记为: // DIES HERE )然后停止,我无法弄清楚原因。
这是我到目前为止的代码:
//the contents of args[0] is {"ls","-l","-o"}
//the contents of args[1] is {"wc","-l"}
int pipefd[2];
pipe(&pipefd[0]); // Error check!
fflush(stdout);
for (i = 0; i < commands; i++){
int pid = fork();
if (pid == 0){
int command_no = i;
int prev_pipe = ((command_no - 1) % 2) * 2;
int current_pipe = (command_no % 2) * 2;
printf("\ncmd %d: prev pipe %d, curr pipe %d\n\n", i, prev_pipe, current_pipe);
fflush(stdout);
// If current command is the first command, close the
// read end, else read from the last command's pipe
if (command_no == 0){
close(pipefd[0]);
}
else{
dup2(pipefd[prev_pipe], 0);
close(pipefd[current_pipe]);
}
// If current command is the last command, close the
// write end, else write to the pipe
if (command_no == commands - 1){
close(pipefd[current_pipe + 1]);
}
else{
dup2(pipefd[current_pipe + 1], 1); //DIES HERE
}
// printf("Here?\n\n");
execvp(*args[i], args[i]);
fprintf(stderr, "Failed to exec: %s (%d: %s)\n", arrayOfCommands[i], errno, strerror(errno));
_exit(1);
}
}
任何帮助表示赞赏! :)
答案 0 :(得分:1)
我看到的主要问题是pipe()
不在循环中。在每对进程之间需要一个新的pipe()
。对你的问题的评论也提出了一些好处。
我在很多年前在大学写过一个shell,这里是我代码中类似的循环。我相信我现在会以不同的方式做到这一点,但它可能会对你有用:
for (i = 0; i < iNumPipes; ++i) {
if (i == iNumPipes - 1) {
/* this is the last command
*/
p[1] = fdOutput;
p[0] = -1;
} else if (-1 == pipe(p)) {
perror("pipe");
exit(1);
}
switch (iPid = fork()) {
case -1:
perror("fork");
exit(1);
case 0:
close(0);
dup2(fdInput, 0);
close(fdInput);
close(1);
dup2(p[1], 1);
close(p[1]);
if (-1 != fdErr) {
close(2);
dup2(fdErr, 2);
close(fdErr);
}
pc = SearchPath(pppcAvs[i][0]);
execve(pc, pppcAvs[i], ppcEnv);
perror(pc);
_exit(-1);
default:
close(fdInput);
close(p[1]);
fdInput = p[0];
}
}