C:重定向标准输入,标准输出到管道

问题描述:

我正在正确理解管道和FD的过程中,我试图编程以下东西: 该程序基本上压缩像gzip这样的选项使用-cf。 的基本思路是:C:重定向标准输入,标准输出到管道

我在父进程中创建两个管道,然后我分叉两次,这样我就会有两个孩子。在第一个孩子中,我将第一个管道的读取端重定向到stdin,第二个管道的写入结束到stdout。然后,我用-cf选项执行gzip,以便它写入标准输出(现在是pipe2的写入结束)

在第二个孩子中,我从pipe2读取并直接输出或将其保存到文件。 但问题是没有数据到达第二个孩子,我不确定为什么。这里是代码:

int main(int argc, char **argv) { 
    char *file; 
    int out = 0; 
    if(argc == 2) { 
     file = argv[1]; 
     out = 1; 
    } else if (argc > 2) { 
     exit(EXIT_FAILURE);   
    } 

    int c1pipe[2]; 
    int c2pipe[2]; 
    pipe(c1pipe); 
    pipe(c2pipe); 

    int f;  
    for(int i = 0; i < 2; i++) { 
     switch(f = fork()) { 
      case 0: //child 
       if(i == 0) { //first loop iteration, child 1 
        close(c1pipe[1]); 
        dup2(c1pipe[0], fileno(stdin)); 
        close(c1pipe[0]); 
        close(c2pipe[0]); 
        dup2(c2pipe[1], fileno(stdout)); 
        close(c2pipe[1]); 
        execlp("gzip", "gzip", "-cf", (char *) NULL); 
       } else if (i == 1) { //second loop iteration, child2 
        close(c1pipe[0]); 
        close(c1pipe[1]); 
        close(c2pipe[1]); 
        FILE *read = fdopen(c2pipe[0], "r");  
        char buffer[1024]; 

        if(out == 0) { //output to stdout 
         while(fgets(buffer, 1024, read) != NULL) { 
          fprintf(stdout, "%s", buffer); 
          fflush(stdout); 
         } 
        } else { //write to specified file 
         FILE *writeto = fopen(file, "w"); 
         while(fread(buffer, sizeof(char), strlen(buffer)+1, read) > 0) { 
          fwrite(buffer, sizeof(char), strlen(buffer)+1, writeto); 
          fflush(writeto); 
         } 
         fclose(writeto); 
        } 

        close(c2pipe[0]); 
        fclose(read); 
       }   
      break; 
      case -1: //err 
       //not implemented 
      break; 
      default: //parent 
       if(i == 0) { 
        close(c2pipe[0]); 
        close(c2pipe[1]); 
        close(c1pipe[0]); 
        FILE *writer; 
        writer = fdopen(c1pipe[1], "w"); 
        char buffer[1024]; 
        while(fgets(buffer, sizeof buffer, stdin) != NULL) { 
         fwrite(buffer, sizeof (char), strlen(buffer)+1, writer); 
        } 
        close(c1pipe[1]); 
        fclose(writer); 
       } 
      break; 
     } 
    } 

    return 0; 
} 

请原谅缺少的错误处理,因为我想创建一个快速和肮脏的版本。

任何帮助表示赞赏。

在父过程中,你正在关闭c2pipe的两端你已付出了第二个孩子之前。

你可能已经,如果你已经把任何错误在任何读/写呼叫处理在想通了这一点。事实上,如果你检查的DUP2调用一个错误,然后看着错误号,你很可能会发现,这是EBADF(坏的文件描述符)。

另一个问题是,你的父进程退出就知道这两个子进程结束之前。这意味着子进程将收到一个信号,并将自己终止。父母需要拨打wait()的其中一个变种以确保两个孩子都已离开。

+0

谢谢,这是有道理的。我曾尝试将闭合c2pipe移动到父级循环的第二个迭代中,但它没有帮助。事实上,第一个孩子似乎根本没有收到任何数据,我也无法弄清楚为什么。 我想我会尝试加入一些错误处理这一点,也许它会明确的事情了。 – skulpt

+0

@skulpt我发现了另一个问题。我已经更新了答案。 – JeremyP

+0

谢谢,这似乎是。现在我实际上得到了一个输出。我不知道父母发送信号给子女终止 - 我知道孤儿程序存在,我只是假定他们在这种情况下将成为孤儿,没有终止。 非常感谢您清除这个问题。 – skulpt