我正在完成一项家庭作业,我们应该通过一系列管道过滤输入。我已经让程序在cat
管道文件到第一个过滤器而没有问题,但是当我尝试添加第3个分支时,我遇到程序刚挂起并需要中断退出的问题
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int pfd[2];
if(pipe(pfd) == -1) {
perror("could not create pipes");
exit(EXIT_FAILURE);
}
switch( fork() ) {
case -1:
perror("fork 1");
exit(EXIT_FAILURE);
case 0:
/* child:
* r = false
* w = true
*/
if( close(pfd[0]) == -1 ) {
perror("close 1");
exit(EXIT_FAILURE);
}
if( pfd[1] != STDOUT_FILENO ) {
if( dup2(pfd[1], STDOUT_FILENO) == -1 ) {
perror("dup2 1");
exit(EXIT_FAILURE);
}
if( close(pfd[1]) == -1 ) {
perror("close 2");
exit(EXIT_FAILURE);
}
}
execlp("cat", "cat", argv[1], (char *) NULL);
perror("cat failed");
exit(EXIT_FAILURE);
default:
/* parent */
break;
}
switch( fork() ) {
case -1:
perror("fork 2");
exit(EXIT_FAILURE);
case 0:
/* child:
* r = true
* w = true
*/
if( pfd[0] != STDIN_FILENO ) {
if( dup2(pfd[0], STDIN_FILENO) == -1 ) {
perror("dup2 2");
exit(EXIT_FAILURE);
}
if( close(pfd[0]) == -1 ) {
perror("close 4");
exit(EXIT_FAILURE);
}
}
if( pfd[1] != STDOUT_FILENO ) {
if( dup2(pfd[1], STDOUT_FILENO) == -1 ) {
perror("dup2 3");
exit(EXIT_FAILURE);
}
if( close(pfd[1]) == -1 ) {
perror("close 5");
exit(EXIT_FAILURE);
}
}
execlp("sed", "sed", "s/[^a-zA-Z]/ /g", (char *) NULL);
perror("sed failed");
exit(EXIT_FAILURE);
default:
/* parent */
break;
}
switch( fork() ) {
case -1:
perror("fork 3");
exit(EXIT_FAILURE);
case 0:
/* child:
* r = true
* w = false
*/
if( close(pfd[1]) == -1 ) {
perror("close 5");
exit(EXIT_FAILURE);
}
if( pfd[0] != STDIN_FILENO ) {
if( dup2(pfd[0], STDIN_FILENO) == -1 ) {
perror("dup2 4");
exit(EXIT_FAILURE);
}
if( close(pfd[0]) == -1 ) {
perror("close 6");
exit(EXIT_FAILURE);
}
}
execlp("tr", "tr", "[A-Z]", "[a-z]", (char *) NULL);
perror("tr failed");
exit(EXIT_FAILURE);
default:
/* parent */
break;
}
if( close(pfd[0]) == -1 ) {
perror("close 7");
exit(EXIT_FAILURE);
}
if( close(pfd[1]) == -1 ) {
perror("close 8");
exit(EXIT_FAILURE);
}
if( wait(NULL) == -1 ) {
perror("wait 1");
exit(EXIT_FAILURE);
}
if( wait(NULL) == -1 ) {
perror("wait 2");
exit(EXIT_FAILURE);
}
if( wait(NULL) == -1 ) {
perror("wait 3");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
我已经根据Michael Kerrisk的 Linux编程接口中的示例来创建此代码(第44.4节)。
答案 0 :(得分:1)
您写道,您需要&#34;通过一系列管道过滤输入&#34;。但是我看到你只创建了一个管道(一个管道()调用创建一个管道并返回两个文件描述符 - 两个管道末端)。如果您有3个孩子 - 您需要至少2个管道以正确的顺序连接。
stdin -> child1 -> PIPE1 -> child2 -> PIPE2 -> child3 -> stdout
这Q&A应该会有所帮助。