2016-11-15 52 views
-1

對於一個類,我需要在C中創建我自己的shell。 我正在嘗試使用管道支持命令的管道。據我可以告訴管道的兩端關閉。儘管如此,我沒有得到任何結果,任何人都可以發現這裏有什麼問題嗎?在c中支撐殼體的管道

do_ *函數帶有一個小錯誤處理包裝函數。爲了完整起見,它們包含在頁面的底部。

該函數產生一個程序並確保孩子只能讀寫正確的管道。

int execute_piped_binairy (int input, int output, Pgm *program){ 
     pid_t pid = do_fork(); 

     if (pid == 0){ //I am the child 
     if (input != 0){//input is not standard input, overwrite stdin with given input 
      do_dub_and_close(input, 0); 
     } if (output != 1) { //output is not standard output, overwrite stdout with given output 
      do_dub_and_close(output, 1); 
     } 
     do_exec(program->pgmlist); 
     } else { 
     return pid; 
     } 
    } 

該函數產生k個孩子和k-1管道以執行k個命令。命令以相反的順序給出,這意味着第一個命令應該輸出到全局輸出。

int execute_binairy_list (int input, int output, int pgmCount, Pgm *program){ 

     int childPids[pgmCount]; 
     int childStatus[pgmCount]; 
     int childId; 
     int idx; 

     // For k programs we need k-1 pipes and need to spawn k children 
     for(idx = 0; idx<pgmCount-1; idx++){ 
     int file_descriptors[2]={0, 1}; 
     //create unnamed pipe 
     do_pipe(file_descriptors); 

     // pass stored input and created write file descriptor 
     childId = do_execute_piped_binairy (file_descriptors[0], output, program+idx); 
     childPids[idx]=childId; //keep child id to make parent wait for all children. 

     if(output!=1){ 
      do_close(output); 
     }; 
     do_close(file_descriptors[0]); // close read end of new pipe, child reads from this pipe. 
     output = file_descriptors [1]; //store write end of new pipe for next iteration 
     } 
     //we still need to spawn 1 child to execute the first command based on the global input 
     // pass stored input and created write file descriptor 
     childId = do_execute_piped_binairy (input, output, program+idx); 
     childPids[idx]=childId; //keep child id to make parent wait for all children. 
     if(output!=1){ 
      do_close(output); 
     }; 
     for(idx=0; idx<pgmCount; idx++){ 
     do_wait(childPids[idx], childStatus+idx); //wait for all children to return; 
     } 
     return 0; 
    } 

我測試了我的三個命令心願的代碼會導致這個順序: 命令1 - > PIPE1 - >命令2 - > pipe2 - >命令3 當有很多printfs輸出的運行,這是發生了什麼(更或更小的調度影響的順序排列):

created pipe: 3 4 //pipe 2 
    created child: 2452 //command 3 
    closed input: 3 //parent closes read end of pipe 2 
    created pipe: 3 5 //pipe 1 
    child: 2452 3 1 //command 3 reads from read end of pipe 2 and writes to 1 
    closed input: 3 2452 //command 3 closes read end of pipe 2 
    created child: 2453 //command 2 
    closed output: 4 //parent closes write end of pipe 2 
    closed input: 3 //parent closes read end of pipe 1 
    closed output: 5 //parent closes write end of pipe 1 
    child: 2453 3 4 //command 2 reads from read end of pipe 1 and writes to write end of pipe 2 
    closed input: 3 2453 //command 2 closes read end of pipe 1 
    closed output: 4 2453 //command 2 closes write end of pipe 2 
    child: 2454 0 5 //command 1 reads from 0 and writes to write end of pipe 1 
    closed output: 5 2454 //command 1 closes write end of pipe 1 

任何幫助感激

回答

0

了它自己。分叉時,孩子從父母那裏收到管道兩端的副本。由於孩子只關閉他們使用的末端,因此總是有一個管道的寫入端未關閉。這意味着永遠不會發送eof消息