2011-09-29 49 views
0

我知道這個問題被問了很多,但我仍然非常困惑如何去解決我的問題。我試圖編寫處理命令行輸入的代碼來處理多個管道的可能性。但是,我不成功,我的代碼雖然執行無法正常工作。這個錯誤一旦我分叉了孩子,我就無法到達第一個命令執行後管道的下一個命令。如何移動到管道中的下一個命令而不抓取錯誤的文件描述符?這是一段代碼;在c中的linux的迭代管道實現c

 a = 0; 
     while (a < cmdnum) 
     { 
     pid[a] = fork(); 
     if(pid[a] == 0) 
     { 
     if(a == 0) 
     { 

      close(1); 
      dup(p1_to_pn[a][1]); 
      for(k = 0; k < nump; k++) 
      { 
       close(p1_to_pn[k][0]); 
       close(p1_to_pn[k][1]); 
      } 

      args = tokenize(cmd[a]); 
      execv(args[0], args); 
     } 
     else if (a == (cmdnum-1)) 
     { 

      close(0); 
      dup(p1_to_pn[a][0]); 
      for(k = 0; k < nump; k++) 
      { 
       close(p1_to_pn[k][0]); 
       close(p1_to_pn[k][1]); 
      } 
      args = tokenize(cmd[a]); 

      i = execv(args[0], args); 
     } 
     else 
     { 

      close(0); 
      dup(p1_to_pn[a][0]); 
      close(1); 
      dup(p1_to_pn[a][1]); 
      for(k = 0; k < nump; k ++) 
      { 
       close(p1_to_pn[k][0]); 
       close(p1_to_pn[k][1]); 
      } 
      args = tokenize(cmd[a]); 

      execv(args[0], args); 
     } 
    } 
    a++; 
} 
+0

只是爲了澄清,你在寫一個shell(或者像shell一樣的東西)嗎? –

+0

一種外殼,是 – GFXGunblade

回答

1

你的錯誤認爲你需要移動到「下一個」命令。開始他們。

這裏的基本思路,對於像A | B | C

父進程讀取命令行管道。對於每一個新的命令,它都會分叉一個新的進程,並最終執行它。父進程已經有了fd 0,1,2 open(STDIN,STDOUT和STDERR)。當你點擊管道時,使用pipe(2)和dup(2)系統調用來創建一個新的fd;分叉下一個過程。

所有的fd操作都發生在父進程中。

+0

啊哇,不敢相信我錯過了。謝謝 – GFXGunblade

+0

哦,我可以。在系統編程課程中,我花了大半夜的時間在研究生課程中找出答案。 –

+0

我不是很瞭解管道功能的一件事情是,當你調用管道(2)時,它不會創建兩個新的文件描述符?你會如何得到,比如說從第二個命令中讀取輸出的雙管道調用作爲第三個輸入?第三個命令的輸入文件描述符不會指向不同的地方嗎? – GFXGunblade