2013-06-04 98 views
0

我正在嘗試爲殼體制作管道系統,但它不能按預期工作。C殼的管道系統

void pipes (char *listaCommand[], int end, char **argv) 
{ 
    int cont = end; 
    for (cont;listaCommand[cont]; cont++) 
    { 
     if (listaCommand[cont] != NULL) 
     { 
      if (!strcmp(listaCommand[cont],"|")){ 
       int pid2, status; 
       int pipefd[2], ret; 

       listaCommand[cont] = NULL; 

       ret = pipe (pipefd); 
       if (ret < 0) fatal(); 

       /* Now fork. */ 

       pid2 = fork(); 
       if (pid2 <0) fatal(); 

       if (pid2 > 0) 
       { 
        printf ("P: waiting for child\n"); 
        wait (&status);  
        close(STDIN_FILENO); 
        dup(pipefd[0]); 
        close(pipefd[0]); 
        close(pipefd[1]); 
        /*execvp (auxCommand[0], auxCommand);*/ 
        pipes(listaCommand, cont+1, argv); 
        /*break;*/ 
       } 
       else 
       { 
        close (STDOUT_FILENO); 
        dup (pipefd[1]); 
        close (pipefd[1]); 
        close (pipefd[0]); 

       } 

      } 
     } 
    } 
    if (end >= 3) 
    { 
     printf("%s \n", listaCommand[end-1]); 
    } 
    execvp (listaCommand[end], listaCommand); 
    printf ("%s: command not found.\n", listaCommand[end]); /* Exec failed. */ 
    exit(EXIT_FAILURE); 
} 

如果我使用像ls |排序,它的工作原理,但如果ls有任何參數,它不起作用,因爲某些原因,listaCommand [cont]其中==「|」不是NULL,所以我只得到 ls:option - 'a'無效。

listaCommand have 
[0] = "ls" 
[1] = "-al" 
[2] = "|" 
[3] = "sort" 
+2

這裏有什麼問題? –

+0

爲什麼listaCommand [cont]在哪裏等於「|」對於執行「ls」命令的進程是不是NULL,即使我在創建新進程之前爲它賦予NULL值?這兩個過程應該具有相同的價值。 – Dante003

回答

1

你並不需要通過end的說法,而不是遞增指向您的命令陣列。您將初始數組傳遞給execvp調用,因此它會嘗試多次執行ls。此外,在將listaCommand[cont]設置爲NULL之後,您需要一個break語句,因爲迭代cont增加後。此外,我認爲您需要保護execvp調用,以便在處理完成後父級不調用它。

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#define fatal() exit(1) 
void pipes (char *listaCommand[], char **argv) 
{ 
    printf("pipes %s\n", listaCommand[0]); 
    int cont = 0; 
    for (;listaCommand[cont]; cont++) { 
     if (listaCommand[cont][0] == '|'){ 
      int pid2, status; 
      int pipefd[2], ret; 

      listaCommand[cont] = NULL; 

      ret = pipe (pipefd); 
      if (ret < 0) fatal(); 

      /* Now fork. */ 

      pid2 = fork(); 
      if (pid2 <0) fatal(); 

      if (pid2 > 0) 
      { 
       printf ("P: waiting for child\n"); 
       wait (&status);  
       close(STDIN_FILENO); 
       dup(pipefd[0]); 
       close(pipefd[0]); 
       close(pipefd[1]); 
       /*execvp (auxCommand[0], auxCommand);*/ 
       pipes(listaCommand + cont + 1, argv); 
       /*break;*/ 
      } 
      else 
      { 
       close (STDOUT_FILENO); 
       dup (pipefd[1]); 
       close (pipefd[1]); 
       close (pipefd[0]); 
       break; 
      } 

     } 
    } 
    if (listaCommand[0]) { 
     execvp (listaCommand[0], listaCommand); 
     printf ("%s: command not found.\n", listaCommand[0]); /* Exec failed. */ 
     exit(EXIT_FAILURE); 
    } 
} 

int main() { 
    char *args[] = { "ls", "-al", "|", "sort", "|" , "tr", "[a-z]", "[A-Z]", 0 }; 
    pipes(args, 0); 
    return 0; 
}