2013-06-04 69 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; 
}