2012-10-21 46 views
1

我必须在UNIX中模拟C程序中的shell行为,记住一件重要的事情:父进程接收所有命令并将它们发送给子进程。然后小孩执行收到的命令,然后将输出发送给父亲。 这个想法是,我收到父母和我的主要子fork()的命令,以便他自己的孩子可以execvp命令并将输出发送到fifo管道。问题是我不能打破while循环(打印出正确的输出):打破从fifo频道读取的while循环

mkfifo("output",S_IFIFO|0644); 
while(read(fifod2,&c,1)) 
     printf("%c",c); 

我意识到FIFO的大小是可变的,但结束时,第二个孩子必须发送一个EOF,这样当读取达到它,返回0.但这似乎并没有发生。 如果需要,请向我咨询更多代码部分。 谢谢

+0

'read()'可能失败,状态-1指示错误。这并没有打破循环。在这种情况下,你应该测试'while(read(fifod,&c,1)== 1)',尽管你应该使用批量输入:while((nbytes = read(fifod,buffer,sizeof(buffer) )> 0)'一次处理尽可能多的数据,这不会等待FIFO填满;如果可用,它将返回'短读'(少于指定的最大字节数)。它会降低系统的负载 - 单字节I/O是可行的,但效率不高(尽管这两者都不是非常低效)。 –

+0

另外,请注意'mkfifo()'创建一个特殊类型的文件;它不会打开正如bdonlan所说,如果在任何进程中在FIFO上有一个可写的文件描述符被打开,那么在FIFO上没有得到EOF的问题就会发生。要非常小心FIFO的实际打开位置,以及它是打开的 –

回答

0

由于父母以O_RDWR开放了fifo的结尾,因此在任何时候都有一个带有可写入文件描述符的进程。 EOF只发生在fifo没有可写的fds时,因此父进程保持这样一个可写的fd打开,所以它永远不会得到EOF。

尝试在父项中使用O_RDONLY打开。

+0

主要的子代码:int fifod2 = open(“output”,O_RDWR);辅助子代码是相同的...父母不知道管道。 –

+0

@IonutGo​​ldan,那还不够。要确定是否实际上是这种情况,我需要看到第一次调用的整个代码路径,通过fork打开到上面打印的这个循环。如果您不知道发生了什么问题,请不要删除该程序的99%,因为完全有可能您将删除该进程中的错误。 – bdonlan

+0

dup2(fifod2,1); execvp(* argum,argum);这是第二个孩子做的事 –