我正在尝试在C中实现多个管道。我在这个网站上找到了一个教程,我的函数是基于这个示例的。以下是我的函数:
void executePipes(cmdLine* command, char* userInput) {
int numPipes = 2 * countPipes(userInput);
int status;
int i = 0, j = 0;
int pipefds[numPipes];
for(i = 0; i < (numPipes); i += 2)
pipe(pipefds + i);
while(command != NULL) {
if(fork() == 0){
if(j != 0){
dup2(pipefds[j - 2], 0);
}
if(command->next != NULL){
dup2(pipefds[j + 1], 1);
}
for(i = 0; i < (numPipes); i++){
close(pipefds[i]);
}
if( execvp(*command->arguments, command->arguments) < 0 ){
perror(*command->arguments);
exit(EXIT_FAILURE);
}
}
else{
if(command != NULL)
command = command->next;
j += 2;
for(i = 0; i < (numPipes ); i++){
close(pipefds[i]);
}
while(waitpid(0,0,0) < 0);
}
}
}
执行后,当我输入像ls | grep bin
这样的命令时,终端挂起并没有输出任何结果。我确定已关闭所有管道,但它仍然挂起。我认为问题出在waitpid
上,于是我删除了waitpid
,但执行后仍无结果。我哪里做错了吗?谢谢。void runPipedCommands(cmdLine* command, char* userInput) {
int numPipes = countPipes(userInput);
int status;
int i = 0, j = 0;
pid_t pid;
int pipefds[2*numPipes];
for(i = 0; i < 2*(numPipes); i++){
if(pipe(pipefds + i*2) < 0) {
perror("pipe");
exit(EXIT_FAILURE);
}
}
while(command) {
pid = fork();
if(pid == 0) {
//if not first command
if(j != 0){
if(dup2(pipefds[(j-1) * 2], 0) < 0){
perror(" dup2");///j-2 0 j+1 1
exit(EXIT_FAILURE);
//printf("j != 0 dup(pipefd[%d], 0])\n", j-2);
}
//if not last command
if(command->next){
if(dup2(pipefds[j * 2 + 1], 1) < 0){
perror("dup2");
exit(EXIT_FAILURE);
}
}
for(i = 0; i < 2*numPipes; i++){
close(pipefds[i]);
}
if( execvp(*command->arguments, command->arguments) < 0 ){
perror(*command->arguments);
exit(EXIT_FAILURE);
}
} else if(pid < 0){
perror("error");
exit(EXIT_FAILURE);
}
command = command->next;
j++;
}
for(i = 0; i < 2 * numPipes; i++){
close(pipefds[i]);
puts("closed pipe in parent");
}
while(waitpid(0,0,0) <= 0);
}
}