【问题标题】:How do I redirect data from a pipe to another in c?如何在c中将数据从管道重定向到另一个管道?
【发布时间】:2015-05-09 17:53:04
【问题描述】:

我正在尝试使用两个单独的管道从一个进程写入另一个进程。方式如下:

  1. child1 写入父级(使用 pipe1)
  2. 父级写入子级 2(使用 pipe2)

我向父级写入没有问题,但是当我尝试将数据中继到 child2 时,文件描述符似乎为 NULL,我不知道为什么。为清楚起见,我试图让我遇到问题的领域更加大胆。我还删除了很多错误处理。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main (void)
  {
      pid_t pid;
      pid_t pid1;
      int mypipe[2];
      int mypipe1[2];
      int file;
      char buf[100];
      FILE *stream;
      FILE *stream2;
      FILE *rm;
      ssize_t numbersread;

          if (pipe (mypipe))
            {
              fprintf (stderr, "Pipe failed.\n");
              return EXIT_FAILURE;
            }
          if (pipe (mypipe1))
            {
              fprintf (stderr, "Pipe2 failed.\n");
              return EXIT_FAILURE;
            }

          /* CREATE THE FIRST CHILD HERE. */
          pid = fork ();

          if (pid == (pid_t) 0)
            {
                rm = fopen("Readme.txt","r");

                //10 BYTES AT A TIME
                close(mypipe[0]);
                for(k=0;k<=10;k++)
                {
                  transmitor(mypipe[1],rm); // GO READ FILE AND THEN WRITE ON PIPE
                }
                fclose(rm);

                return EXIT_SUCCESS;
            }


          // BACK TO THE PARENT PROCESS
          else
            {
            /*OBJECTIVES:
                1. READ THE FILE FROM THE PIPE
                2. WRITE THE FILE ONTO A SECOND PIPE
                3.SEND IT TO THE RECEIVER
            */

             FILE *file1;
             ssize_t numbersread1;
             file1 = fdopen(mypipe[0],"r");

             close (mypipe[1]);
             close(mypipe1[0]);
             stream2 = fdopen(mypipe1[1],"w");
             while(!feof(file1)){
              numbersread1 = fread(buf, 1, (sizeof buf),file1);
              printf("%zd\n", numbersread1);
              **fwrite(buf,1,numbersread1,stream2);**
              buf[numbersread1] = 0;
             }
             printf("%s\n","finished parent");
             fclose(file1);// FINISHED READING
             fclose(stream2);

           ** /* CREATE THE SECOND CHILD HERE #2. */
            /*OBJECTIVES:
               1. READ DATA FROM PIPE
               2. WRITE DATA TO FILE*/

             pid1 = fork ();
             sleep(2);
             if (pid1 == (pid_t) 0)
                {
                  /* This is the child process.
                     Close read end first. */
                     FILE *stream3;
                     stream3 = fdopen(mypipe1[0],"r");
                     close (mypipe1[1]);
                    if(stream3==NULL)
                     {
                      printf("%s","NULL Stream3 Variable");
                     }
                    else
                     {
                      while (!feof(stream3)) {
                      printf("\r\nIN WHILE\r\n");
                      numbersread = fread(buf, 1, (sizeof buf),stream3);
                      printf("%zd\n", numbersread);
                      buf[numbersread] = 0;
                    }
                     fclose(stream3);
                    }**

                    printf("%s","FINISHED RECEIVER");

                    return EXIT_SUCCESS;
                }


             return EXIT_SUCCESS;
            }// THIS CLOSES THE FIRST ENTRANCE TO THE PARENT PROCESS WHERE WE ARE WRITING TO THE FIRST RECEIVER



        }// THIS IS THE END OF THE MAIN FUNCTION

【问题讨论】:

  • 还有更多代码吗?这段代码不可能单独工作。它从不调用pipe() 来创建管道。使用int mypipe[2]; 创建变量只会创建一个包含两个整数的数组的变量。要获得管道,您必须将该数组传递给pipe()
  • 我最初删除了这部分: if (pipe (mypipe)) { fprintf (stderr, "Pipe failed.\n");返回 EXIT_FAILURE; } if (pipe (mypipe1)) { fprintf (stderr, "Pipe2 failed.\n");返回 EXIT_FAILURE; }
  • 看起来不错。你不应该删除它。
  • 查看linux.die.net/man/2/pipe上的示例如何正确使用pipe,然后检查linux.die.net/man/3/popen是否不是更好的选择。
  • 我想你会发现删除管道代码并重新编译程序会破坏所有的通信,因为它是创建管道的原因。 Johannes 似乎对 stream3 有一个答案。

标签: c linux pipe


【解决方案1】:

您以后使用close(2) 文件描述符,例如您的代码中的这段代码:

file1 = fdopen(mypipe[0],"r");

close (mypipe[1]);
close(mypipe1[0]);

你关闭mypipe1[0]。再往下走:

FILE *stream3;
stream3 = fdopen(mypipe1[0],"r");
close (mypipe1[1]);

因此stream3 将是NULL

我还强烈建议将变量命名为它们的作用。例如,mypipe 可以是 c1_to_parentmypipe1 可以是 parent_to_c2。这将使您的代码更具可读性。

【讨论】:

  • 你是对的,这就是问题所在。谢谢一百万!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 2020-05-03
  • 1970-01-01
  • 2020-12-10
  • 2010-11-20
相关资源
最近更新 更多