为什么我的管道不能互相通信?

时间:2016-11-20 07:48:22

标签: c pipe

我正在尝试用c编写一个简单的shell。现在我正试图让管道工作。我有一个结构<body> <ul> <li id="first"><a href="#home">Home</a></li> <li id="second"><a href="#news">News</a></li> <li id="third"><a href="#contact">Contact</a></li> <li id="forth"><a href="#about">About</a></li> </ul> <p id="home"> home section </p> <p id="news"> news section </p> <p id="contact"> contact section </p> <p id="about"> about section </p> </body> <style> p{ display: none; } :target { display:block; border: 2px solid #D4D4D4; background-color: #e5eecc; } </style> <script type="text/javascript"> $(document).ready(function(){ if(localStorage.getItem("active_state") == null ){ activeStateId = "first"; } else{ activeStateId = localStorage.getItem("active_state") } $('#'+activeStateId).addClass('active'); $('li').click(function(){ $('.active').removeClass('active'); $(this).addClass('active'); localStorage.setItem("active_state", $(this).attr('id')); }); }); </script> ,我在这个函数中提供它,它包含一个存储管道文件描述符c的地方,还包含有关每个命令的结束标记的信息{{1} }(这可以是|||&amp;&amp;&amp; etc)。 pipfd只是跟踪最后一个命令,因此我可以看到之前的命令是否有管道标记。

完成此功能后,我将子pid(返回值)提供给c->type,等待我使用CommandPrev

调用的命令

当我运行诸如waitpid之类的命令时,我得到execvp作为输出完全符合我的预期,一切都很好。我的问题是当我尝试运行任何实际使用管道前半部分输入的命令时,一切都会卡住。如果我运行类似echo foo | echo bar的东西,我就没有输出,它只会永远挂起。

我可以看到这个函数完成这些命令,因为我在返回时打印。发生的事情是,我用execvp调用的命令永远不会发生,所以我的waitpid会永远等待。

我认为我的管道两端之间的连接断了。要么事情永远不会被写入,要么它们永远不会被阅读,或者管道的接收端永远不会意识到写作方面已经完成并且只是永远等待。我立刻打电话给所有管道,所以我倾向于怀疑它是最后一个...但我真的不确定如何测试这三种情况中的任何一种。

这是我的代码:

bar

谢谢!

1 个答案:

答案 0 :(得分:0)

正如另一位评论者所说,你看起来像是在试图关闭阵列。 这样的事情会更好:

// writing side of the pipe
if (c->type == TOKEN_PIPE){
    close(c->pipefd[READ_SIDE]);
    dup2(c->pipefd[WRITE_SIDE], STDOUT_FILENO);
    close(c->pipefd[WRITE_SIDE]);
}
// receiving side of the pipe
if (commandPrev->type == TOKEN_PIPE){
    close(commandPrev->pipefd[WRITE_SIDE]);
    dup2(commandPrev->pipefd[READ_SIDE], STDIN_FILENO);
    close(commandPrev->pipefd[READ_SIDE]);
}

或者,您可以在父级中的waitpid调用之后关闭管道的活动侧。像这样:

waitpid(child, &status, 0);

if (commandPrev->type == TOKEN_PIPE){
    close(commandPrev->pipefd[READ_SIDE]);
}
if (c->type == TOKEN_PIPE){
    close(c->pipefd[WRITE_SIDE]);
}