2012-10-21 84 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);這是第二個孩子做的事 –