c-使用dup2和管道重定向stdin



我有一个程序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("%dn", WEXITSTATUS(status));

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

}



return 0;
}

您将错误的数据输送到子进程。

我假设var_avar_b是您要发送到程序A的字符串。它们都是字符数组的类型,在C中,这与指向字符的指针是相同的(实际上指针和数组之间有一点区别,但这与这个问题无关)。所以它们实际上只是指向每个参数的第一个字节的指针。然而,sendarray是字符指针的数组,这与指向字符指针的指针是相同的。请记住这一点。

当调用write()时,第二个参数告诉它数据在内存中的位置。通过传递sendarray,write认为这个sendarray指向了要写入的数据,尽管它实际上指向了另一个指针。因此,var_avar_b的指针值(这就是sendarray所指向的)被写入管道。

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

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

因此,把所有这些放在一起,你的写作语句应该是这样的:

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

当然,如果我所做的任何假设都是错误的,那么您必须适当地采用此代码。

最新更新