使用Pipes和exec()来控制另一个控制台应用程序

时间:2016-06-23 21:13:09

标签: c pipe fork ipc file-descriptor

我正在尝试教自己一些重定向。我有以下问题:

我有一个简单的程序,要求用户输入一个整数,然后输出一些其他整数,它会无限期地执行,直到用户输入0,然后关闭。

我正在尝试为该程序编写一个包装器,将来它可能是另一个控制台应用程序的GUI包装器。 目标是与该计划进行沟通。

我的第一个想法是使用管道,分叉进程,将管道设置为子进程的stdin和stdout,然后exec()控制台应用程序。

现在,我的代码到目前为止无法正常运行,因为控制台应用程序确实已执行但是它像往常一样运行,在控制台中,输出不会到达我想要的位置。

main()
{
  int master_to_slave[2];
  int slave_to_master[2];

  pipe(master_to_slave);
  pipe(slave_to_master);

  int pid;

  if((pid=fork())==0){
     close(master_to_slave[1]);
     close(slave_to_master[0]);
     dup2(0, master_to_slave[0]);
     dup2(1, slave_to_master[1]);
     char *args[] = { NULL };
     execv("/home/ebach/Documents/HIWI/random.exe",args);
  }
  else if(pid<0){
    //ALARM ALARM
  }
  else{
     close(master_to_slave[0]);
     close(slave_to_master[1]);

    while(1){
      char buff[16];
      int rd = read(slave_to_master[0], &buff, sizeof(buff));
      if(rd > 0){
      buff[rd-1] = '\0';
      printf("Redirected: ");
      for(int i = 0; i < rd; i++){
    printf("T%c", buff[i]);
      }
      printf("\n");
      }
    }
    wait(NULL);
  }
}

到目前为止,它只是应该重定向控制台应用程序的输出。 (你可以看到它应该只添加'重定向:'

无论如何,我不像你所看到的那样完全精通c,所以我找不到错误。

我错误地连接了管道吗?

我遇到的另一个解决方案是使用forkpty()和exec()来使用伪终端,我应该走那条路吗?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您已向后使用@a1。根据{{​​3}}:dup2 int dup2(int fildes, int fildes2);会导致dup2引用与filedes2相同的打开文件。

答案 1 :(得分:2)

@hacatu似乎在他的回答中找出了你的主要问题。此外,

  • 当我对hacatu的回答发表评论时,一旦孩子dup2()的管道端到其中一个标准流上,就应该关闭那个管道端。例如,
    dup2(slave_to_master[1], 1);
    close(slave_to_master[1]);
  • 提交给execv()execvp()的参数向量,以及提交给execl()execlp()execle()的参数列表直接映射到目标程序的argv向量。因此,传统上存在至少一个元素,命名正在执行的程序。有些程序依赖于此。例如:
    char *args[] = { "random.exe", NULL };
    execv("/home/ebach/Documents/HIWI/random.exe", args);

在这种情况下,您可能会发现execl()更方便一点:

    execl("/home/ebach/Documents/HIWI/random.exe", "random.exe", NULL);