管道问题(管道破裂)

Piping problems (Broken pipe)

提问人:Jonathan Chiou 提问时间:2/16/2014 最后编辑:Jonathan Chiou 更新时间:2/17/2014 访问量:759

问:

给定以下格式的命令:

cat < inputfile.txt | tee outputfile.txt

我正在尝试让输入文件.txt写入管道,然后从管道中读取输出文件.txt,并且我编写了以下功能来执行此操作:

void piperead(char** input, int* fd, int start) {

    dup2(fd[0], 0);
    close(fd[1]);
    execl("usr/bin/tee", "usr/bin/tee", input[start + 1], NULL);

}

void pipewrite(char** input, int* fd, int start, int end) {

    dup2(fd[1], 1);
    close(fd[0]);
    execl("usr/bin/cat", "usr/bin/tee", input[start + 2], NULL);

}

void dopiping(char** input, int start, int end) {

    int fd[2];
    if (pipe(fd) == -1) {
        cout << "Error: Pipe failed." << endl;
        exit(1);
    }
    int pid = fork();
    switch(pid = fork()) {        
        case 0:
            piperead(input, fd, start, end);
        default:
            pipewrite(input, fd, end + 1);        
        case -1:
            exit(1);
    }


}

我已将命令转换为c_strings数组(我们将其称为 cmdarray),然后调用 dopiping(cmdarray, 0, 3)。程序到达生产线的那一刻:

 dup2(fd[1], 1)

程序终止,因为程序收到了 SIGPIPE。为什么我的管道坏了,我该如何解决?

C++ UNIX 管道

评论

0赞 Some programmer dude 2/16/2014
你确定你是认真的而不是?"usr/bin/cat""/usr/bin/cat"
0赞 Some programmer dude 2/16/2014
此外,您的程序存在逻辑错误:调用成功后不会继续。你忘了吗?execfork
0赞 Jonathan Chiou 2/16/2014
是的,我的意思是做“/usr/......”。我是否使用 fork() 来避免逻辑错误?
0赞 Some programmer dude 2/16/2014
如果你阅读 execl(3) 的手册页,你会看到它 “用一个新的进程映像替换了当前的进程映像”, 并且该函数没有返回。你通常调用 fork(2) 来创建一个新的进程来执行调用,这样你的主进程就可以继续运行。exec
0赞 Jonathan Chiou 2/16/2014
好吧,我分叉了我的 dopiping() 函数,让孩子从管道中读取,让父母写入管道。我的管道仍然坏了,所以我无法判断它是否正常工作。

答:

1赞 Beano 2/17/2014 #1

所以从逻辑上看

  • SIGPIPE 被传送到一个进程,该进程对封闭的管道/套筒执行 write()。
  • 因此,您创建的管道的读取侧必须已关闭。
  • 执行fd[0]dup2()
  • 因此,子进程似乎正在退出。
  • 我猜要么是失败的 - 你应该尝试指定“/usr/bin/tee”(完整路径而不是相对路径)execl()
  • 或 your is failed - 需要确保指向表示有效文件路径的 null 终止字符串。teeinput[start+1]