2014-10-06 24 views
1

我正在使用管道,執行fork & exec來實現用戶shell。問題在於它在某些情況下不起作用。例如,如果我有ls |,它會起作用頭,但不會爲ls |工作貓。它會顯示貓的輸出,但是會在沒有返回提示的情況下掛起。在某些情況下執行管道中的第二個/最後一個命令後,進程掛起

參考代碼我有輸入存儲在c-> args [0]中,爲此我撥出一個子&執行它。

據我所知,第二個exec仍在等待EOF,但在此之前關閉文件描述符並沒有幫助。

通過類似的問題,我也嘗試在等待之前關閉父進程中的文件描述符,但在做完之後,即使ls |頭不起作用。 我已經發布了下面的相關功能。

void executeProcess(Cmd c,int noofcmds) 
{ 
// printf("Will be entering fork procedure \n"); 
    int cmdNo; 
    pipe(fd); 
    for (cmdNo = 0;cmdNo < noofcmds; cmdNo ++) 
    { 

    int processid = fork(); 
    pid_t childpid; 
// printf("Process id %d\n",processid); 
    if (processid == 0) 
     { 
// if (noofcmds != 1) 
//  { 
    if (cmdNo == 0) 
    { 
     printf("Inside first child \n"); 
     close(fd[0]); 
     dup2(fd[1], 1); 
//  close(fd[0]); 
    } else if (cmdNo == noofcmds-1) 
    { 
     close(fd[1]); 
     dup2(fd[0], 0); 
//   close(fd[0]); 

    } 
// close(fd[1]); 
// close(fd[0]); 
     if (execvp(c->args[0],c->args) < 1) 
    { printf("Error\n"); 
    } 
     } else 
     { 
// printf("Waiting in parent\n"); 
// close(fd[0]); 
// close(fd[1]); 

    int status; 
    int returnedpid; 
    wait(&status); 
     printf("Returned after waiting\n"); 
// close(fd[0]); 
// close(fd[1]); 
     } 
    c = c->next; 
// close(fd[0]); 
// close(fd[1]); 
    } // end of for 
} 

回答

1

看看事件的序列,ls | cat這就是現在發生的情況:在父母創建

1)管。
2)ls孩子產生了
3)母公司等待ls完成
4)cat孩子產生了
5)母公司等待cat完成

正如你注意到,在5)父母仍然有管打開,所以cat永遠不會結束。

當您在代碼的父部分中關閉它時,它會在3)之前關閉。所以在cat開始的時候,管道不再存在 - >從cat沒有輸出。

你需要的是像4後關閉):

... 
else // in parent 
{ 
    // printf("Waiting in parent\n"); 

    if (cmdNo == 1) // second child is spawned, can close the pipe now. 
    { 
     close(fd[0]); 
     close(fd[1]); 
    } 

    int status; 
    wait(&status); 
    printf("Returned after waiting\n"); 
} 

代碼將需要更多的工作在一個管道,處理2級以上的命令,但你的想法...

提示:找到一個自動縮進代碼的編輯器,它會讓你的生活變得更加輕鬆!

+0

非常感謝,作爲一種魅力!是的,我首先想確保它可以用於2個命令,現在我將嘗試其餘部分。 – user3730977 2014-10-06 17:53:06

+0

感謝上帝賜予你。我已經在互聯網上尋找這個答案。你救了我! – 2017-09-09 00:53:22

相關問題