重定向子进程的标准输入和stdout来管 [英] Redirect child process's stdin and stdout to pipes

查看:134
本文介绍了重定向子进程的标准输入和stdout来管的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


编辑:
解决的办法是

  INT C1 = dup2(管[0] [1],STDOUT_FILENO);
 INT C2 = dup2(管道[1] [0],STDIN_FILENO);
 setvbuf用来(标准输出,NULL,_IONBF,0);

有setvbuf用来设置标准输出成为非缓冲。虽然我是打印换行符如果目标不是一个实际的屏幕,我想,它成为缓冲。



编辑:
当我把 fflush(标准输出):订单后4 LINE 1和 fflush(FOUT)后按预期工作。但是,它并没有在 fflush(标准输出)工作第1行的问题是,我不能够把后的 fflush在我计划程序运行。


我想从我的过程开始另一个程序。我没有访问它的code,但我知道它使用标准输入和stdout用户交互。我试图通过创建2管,叉ING和调整孩子的标准输入/输出到合适的管端来启动该程序。这些点是,家长应该能够通过文件描述符孩子沟通,而其标准输入/输出应完好无损。该系统调用POPEN只开放单向管道。下面code几乎工作。

有标记为LINE 1..4 4行

1号线儿童发送给管,
LINE 2孩子从管接收,
LINE 3父送管道,
4号线从管父接收,

这仅仅是一个玩具的例子,以确保一切工作。问题是这是所有4行LINE1..4都注释掉了输出我在终端上看到的是

  PARENT1:-1
FD:1 0 4 5 0 1
DEBUG1:0
DEBUG2:0

而如果LINE 1和LINE 3都注释掉只有我看到连续的数据流。同样的情况,如果如果只有2号线4号线是注释。不过,我想一个完整的双向通信。还添加评论SLEEP不改变行为。

这可能是什么问题在这里。我不知道为什么没有双向POPEN。

  INT PID;
INT管[2] [2];管(管子[0]);
管(管子[1]);PID =叉();如果(PID == 0)
  {
  // usleep(1000000);
  附近(管[0] [0]);
  附近(管[1] [1]);  INT C1 = dup2(管道[0] [1],STDOUT_FILENO);
  INT C2 = dup2(管道[1] [0],STDIN_FILENO);
  // INT C2 = dup2(STDIN_FILENO,管道[1] [0]);  fprintf中(标准错误,FD:%D%D%D \\ n,C1,C2,管道[0] [1],管道[1] [0],STDIN_FILENO,STDOUT_FILENO);  // FILE * FOUT = fdopen(管道[0] [1],W);
  // FILE *翅片= fdopen(管道[1] [0],R);
  而(1)
    {
    静态INT C1 = 0;
    fprintf中(标准错误,DEBUG1数:%d \\ n,C1);
    的printf(%d个\\ N,C1); // LINE 1
    fprintf中(标准错误,DEBUG2数:%d \\ n,C1);
    scanf函数(%d个,&安培; C1); // LINE 2
    fprintf中(标准错误,DEBUG3数:%d \\ n,C1);
    C1 ++;
    }
  // FCLOSE(FOUT);
  // FCLOSE(翅);
  返回0;
  }附近(管[0] [1]);
附近(管[1] [0]);炭缓冲器[100];
FILE *翅片= fdopen(管道[0] [0],R);
FILE * FOUT = fdopen(管道[1] [1],W);
而(1)
  {
  INT C1 = -1;
  的printf(PARENT1数:%d \\ n,C1);
  的fscanf(翅,%D,&安培; C1); // LINE 3
  的printf(RECV数:%d \\ n,C1);  fprintf中(FOUT,%d个\\ N,C1 + 1); // 4号线
  的printf(PARENT3数:%d \\ n,C1 + 1);
  }
FCLOSE(翅);
FCLOSE(FOUT);


解决方案

您code相当长,所以我不知道我有明白一切,但你为什么不使用的选择
你想对孩子的输出重定向在tird过程中或在你的父进程使用它?

以下为例是猫子进程。

 的#include<&unistd.h中GT;
#包括LT&;&stdlib.h中GT;诠释的main()
{
  将为pid_t PID;
  INT P [2];
  管(P);
  PID =叉();
  如果(PID == 0)
    {
      dup2(第[1],1); //输出重定向(STDOUT到管)
      关闭(P [0]);
      execlp(猫,猫,NULL);
      出口(EXIT_FAILURE);
    }
  其他
    {
      关闭(第[1]);
      FD_SET RFDS;
      炭缓冲液[10] = {0};       而(1)
        {
          FD_ZERO(安培; RFDS);
          FD_SET(P [0],&放大器; RFDS);
          选择(P [0] + 1,&安培; RFDS,NULL,NULL,NULL); //等待页上的变化[0]
          如果(FD_ISSET(P [0],&放大器; RFDS))
            {
              INT RET = 0;
              而((保留=读(P [0],缓冲液,10))大于0)//在管读
                {
                  写(1,缓冲,RET); //显示结果
                  memset的(缓冲液,0,10);
                }
            }
        }
    }
}


EDIT: The solution is

 int c1=dup2(pipes[0][1],STDOUT_FILENO);
 int c2=dup2(pipes[1][0],STDIN_FILENO);


 setvbuf(stdout,NULL,_IONBF,0);

It is SETVBUF to set stdout to be non-buffered. Even though I was printing the newline character if the destination is not an actual screen, I guess, it becomes buffered.



EDIT: When I put fflush(stdout) after LINE 1 and fflush(fout) after LINE 4 it works as expected. However, it does not work without the fflush(stdout) after LINE 1. The problem is that I would not be able to put fflush in the program which I am planning to run.


I am trying to start another program from my process. I don't have access to its code but I know it uses stdin and stdout for user interaction. I am trying to start that program by creating 2 pipes, fork-ing and redirecting the child's stdin/stdout to the proper pipe ends. The points is that the parent should be able communicate with the child via file descriptors, while its stdin/stdout should be intact. The POPEN syscall only opens unidirectional pipe. The following code almost works.

There are 4 lines marked as LINE 1..4.

LINE 1 is child sending to pipe, LINE 2 is child receiving from pipe, LINE 3 is parent sending to pipe, LINE 4 is parent receiving from pipe,

This is just a toy example to make sure things work. The issue is that is all 4 lines LINE1..4 are uncommented the output I see on the terminal is

PARENT1: -1
FD: 1 0    4 5    0 1
DEBUG1: 0
DEBUG2: 0

While if LINE 1 and LINE 3 are uncommented only I see a continuous stream of data. Same happens if if only LINE 2 and LINE 4 are uncommented. However, I want a full bidirectional communication. Also adding the commented SLEEP does not change the behavior.

What could be the issue here. I wonder why is there no bidirectional POPEN.

int pid;
int pipes[2][2];

pipe(pipes[0]);
pipe(pipes[1]);

pid=fork();

if(pid==0)
  {
  //usleep(1000000);
  close(pipes[0][0]);
  close(pipes[1][1]);

  int c1=dup2(pipes[0][1],STDOUT_FILENO);
  int c2=dup2(pipes[1][0],STDIN_FILENO);
  //int c2=dup2(STDIN_FILENO,pipes[1][0]);

  fprintf(stderr,"FD: %d %d    %d %d    %d %d\n",c1,c2,pipes[0][1],pipes[1][0],STDIN_FILENO,STDOUT_FILENO);

  //FILE*fout=fdopen(pipes[0][1],"w");
  //FILE*fin =fdopen(pipes[1][0],"r");
  while(1)
    {
    static int c1=0;
    fprintf(stderr,"DEBUG1: %d\n",c1);
    printf("%d\n",c1);                      // LINE 1
    fprintf(stderr,"DEBUG2: %d\n",c1);
    scanf("%d",&c1);                        // LINE 2
    fprintf(stderr,"DEBUG3: %d\n",c1);
    c1++;
    }
  //fclose(fout);
  //fclose(fin);
  return 0;
  }

close(pipes[0][1]);
close(pipes[1][0]);

char buffer[100];
FILE*fin=fdopen(pipes[0][0],"r");
FILE*fout=fdopen(pipes[1][1],"w");
while(1)
  {
  int c1=-1;
  printf("PARENT1: %d\n",c1);
  fscanf(fin,"%d",&c1);                         // LINE 3
  printf("Recv: %d\n",c1);

  fprintf(fout,"%d\n",c1+1);                    // LINE 4
  printf("PARENT3: %d\n",c1+1);
  }
fclose(fin);
fclose(fout);

解决方案

Your code is quite long so I'm not sure that I have understand everything but why you don't use select ? Do you want to redirect the output of the child in a tird process or use it in your parent process ?

The following exemple is with cat in the child process.

#include <unistd.h>
#include <stdlib.h>

int     main()
{
  pid_t pid;
  int   p[2];


  pipe(p);
  pid = fork();
  if (pid == 0)
    {
      dup2(p[1], 1); // redirect the output (STDOUT to the pipe)
      close(p[0]);
      execlp("cat", "cat", NULL);
      exit(EXIT_FAILURE);
    }
  else
    {
      close(p[1]);
      fd_set rfds;
      char      buffer[10] = {0};

       while (1)
        {
          FD_ZERO(&rfds);
          FD_SET(p[0], &rfds); 
          select(p[0] + 1, &rfds, NULL, NULL, NULL); //wait for changes on p[0]
          if(FD_ISSET(p[0], &rfds))
            {
              int       ret = 0;
              while ((ret = read(p[0], buffer, 10)) > 0) //read on the pipe
                {
                  write(1, buffer, ret); //display the result
                  memset(buffer, 0, 10);
                }
            }
        }
    }
}

这篇关于重定向子进程的标准输入和stdout来管的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆