2009-12-24 72 views
1

我正在寫一個實現管道的小程序,就像他們在shell中工作一樣。 即:fork()和pipe()的小問題

ls -hal | sort | grep p | wc 

它做工精細,用個小問題,在一行上,當CMD_NO = N,I biggerthan CMD_NO比較沒有工作,但我=(CMD_NO-1)呢!我試圖找出爲什麼在這種特殊情況下(該行在代碼中被視爲TROUBLED LINE),這些語句並不等同。非常感謝。

#include <sys/types.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 
#include <errno.h> 

#define READ_END 0 
#define WRITE_END 1 
#define CMDS_NO 5 

int main (int argc, char **argv) 
{ 
    pid_t pid; 
    int new_fds[2]; 
    int old_fds[2]; 

    char *array[CMDS_NO]; 
    char *param[CMDS_NO]; 

    array[0]="ls"; 
    array[1]="sort"; 
    array[2]="grep"; 
    array[3]="grep"; 
    array[4]="wc"; 

    param[0]="-hal"; 
    param[1]=NULL; 
    param[2]="p"; 
    param[3]="out"; 
    param[4]=NULL; 


    for (int i=0; i<CMDS_NO; i++) { 

     if (i<CMDS_NO) //if there is a next command 
      pipe(new_fds); 

     pid=fork(); 

     if (pid==0) { //if child 
      if (i!=0) { //if there is ap revoius commmand 
       dup2(old_fds[0], 0); 
       close(old_fds[0]); 
       close(old_fds[1]); 
      } 

      if (i!=(CMDS_NO-1)) { //TROUBLED LINE i<CMDS_NO does not work, 
            //if there is a next command 
       close(new_fds[0]); 
       dup2(new_fds[1],1); 
       close(new_fds[1]); 
      } 
      execlp(array[i], array[i], param[i], NULL); 

      } else { 
       if (i!=0) { //if there is a previous command 
        close(old_fds[0]); 
        close(old_fds[1]); 
       } 

       if (i<CMDS_NO) { //if there is a next command 
        old_fds[0] = new_fds[0]; 
        old_fds[1] = new_fds[1]; 
       } 
      } 
    } 
    if (CMDS_NO>1) { 
     close(old_fds[0]); 
     close(old_fds[1]); 
    }  

    while (1) { //wait for child processes to end 
     wait(NULL); 
     if(errno== ECHILD) { 
      printf("all children ended\n"); 
      break; 
     } 
    } 

return 0; 
} 
+0

多想想你要的時候'i'是'0','CMDS_NO-1',和值之間發生什麼。請注意,無論何時你在循環中都會有'i dave4420 2009-12-24 15:19:04

回答

1

條件i<CMDS_NO將永遠是正確的,因爲i從0到CMDS_NO-1。我想你的意思是把你的病情寫成i<CMDS_NO-1。當然,i!=CMDS_NO-1同樣有效。

請注意,這會影響您在其他地方使用if (i<CMDS_NO);這些也應該是if (i<CMDS_NO-1)

1

這很正常。

for (int i=0; i<CMDS_NO; i++) {

這意味着 「循環只要i小於CMDS_NO」。只要i == CMDS_NO循環將停止;所以,在循環內部,最高的i將達到CMDS_NO - 1

PS:CMDS_NO是一個非常可憐的變量名,叫它MAX_COMMANDS例如