使用dup2和pipe重定向stdin

时间:2017-11-03 17:52:15

标签: c pipe exec dup2

我有一个程序A,它从stdin获取两个参数,并根据参数以唯一代码退出。我正在编写一个程序B,它使用fork和exec调用程序A,让程序B打印出代码程序A退出。出于某种原因,程序A似乎没有在fork的子进程中获取我传递给它的数据。我不确定我是否将正确的数据传递给子进程。

有人可以帮帮我吗?谢谢!

这是我的代码:

int program_B(void) {
char var_a[256];
char var_b[256];
int fd[2];

 // Read from stdin 
char *sendarray[2];
sendarray[0] = var_a;
sendarray[1] = var_b;


if(fgets(var_a, MAXLINE, stdin) == NULL) {
    perror("fgets");
    exit(1);
}

if(fgets(var_b, MAXLINE, stdin) == NULL) {
    perror("fgets");
    exit(1);
}

if (pipe(fd) == -1) {
  perror("pipe");
  exit(1);
}

int pid = fork();

// Child process -- error seems to be here. 
if (pid == 0) {

    close(fd[1]);

    dup2(fd[0], fileno(stdin));

    close(fd[0]);

    execl("program_A", NULL);

    perror("exec"); 
    exit(1);

} else {

    close(fd[0]);
    write(fd[1], sendarray, 2*sizeof(char*));
    close (fd[1]);

    int status; 

      if (wait(&status) != -1) {

        if (WIFEXITED(status)) {


            printf("%d\n", WEXITSTATUS(status));


        } else {
          perror("wait");
          exit(1);
        }
      }


}







return 0;
}

1 个答案:

答案 0 :(得分:1)

您正在将错误的数据传递给子进程。

我假设var_avar_b是要发送给程序A的字符串。它们都是字符数组,在C中是< strong>同样的事情作为指向char的指针(实际上指针和数组之间存在细微的差别,但这与此问题无关)。所以它们实际上只是指向每个参数的第一个字节的指针。 sendarray,但是 char-pointers数组相同的东西指向char-pointer的指针。记住这一点。

当调用write()时,第二个参数告诉它数据在内存中的位置。通过传递sendarray,write认为这个sendarray指向您想要写入的数据,尽管它实际指向另一个指针。那么会发生的是var_avar_b(指向sendarray的指针)的指针值被写入管道。

因此,您必须将var_avar_b传递给write(),因为它们是您要发送的实际数据的指针。此外,您还必须知道此数据的长度(多少字节)。如果var_avar_b指向以空字符结尾的字符串,则可以使用strlen()来确定其长度。

最后一件事:我不知道你的程序A如何从连续的字节流中获得2个参数,如stdin,但假设它逐行读取它,你显然必须发送一个新的程序B中的行字符。

因此,将所有写入语句放在一起应该如下所示:

write(fd[1], var_a, strlen(var_a));
write(fd[1], "\n", 1);
write(fd[1], var_b, strlen(var_b));

当然,如果我做出的任何假设都是错误的,你必须适当地采用这个代码。