2016-11-23 54 views
0

我正在尝试从父进程的子进程exec()。在这个子进程中,我要求用户输入一条消息,以便它可以通过父进程打印出来,但我找不到方法来执行它...如何将标准输入从孩子管到父母?

到目前为止,我的代码是:

parent.c

int main(int argc, char **argv) { 
    int fd[2]; 
    char line[80]; 

    pipe(fd); 

    pid_t pid = (pid_t)fork(); 

    if(pid > 0) { 
     waitpid(pid, NULL, 0); 
     close(fd[0]); 
     int size = read(fd[1], line, 79); 
     close(fd[1]); 
     line[size] = '\0'; 
     printf("[parent] Received \"%s\", size = %d\n", line, size); 
    } 
    else { 
     close(fd[1]); 
     close(stdin); 
     dup2(fd[0], stdin); 
     close(fd[0]); 
     exec("./child", 0, NULL); 
    } 

    return 0; 
} 

child.c

int main(int argc, char **argv) { 
    char line[80]; 

    printf("[child] Enter message: "); 
    gets(line, 80); 
    printf("[child] line = %s\n", line); 

    return 0; 
} 

当我启动父进程,它会显示[child] Enter message:,但是当我尝试输入内容时,即使按下回车键也不会显示任何内容。

你知道我该如何使它工作?

谢谢你的帮助。

+2

在家长中,不要等到孩子读完管道之前完成。它可能在这种情况下工作,因为你可能没有足够的写入来填充管道缓冲区,但是如果它被填充,那么作者将会阻塞,并且你有一个死锁。 –

+1

另外,你有什么版本的'gets'函数需要缓冲区大小?你在使用'gets_s'的一些变体吗? –

+0

您的父母计划还存在其他一些问题。例如,它不应该干净地编译。 –

回答

0

我找到了解决方法。我的实际目标是在父母和孩子之间传递信息。我的错误是在上stdin。通过这样做,当程序提出问题时,我无法输入任何内容。所以我传递了argv中的文件描述符的值,我的问题就解决了。

再次感谢您的帮助!

1

除了我评论中提到的问题,您遇到的问题是死锁。你明白了,因为父进程等待子进程退出。但是子进程正在等待从未到达的输入。

这是因为在子进程中你说输入应该来自管道

此外,在父进程中,您尝试从管道的写入端读取读取

最后,只要子进程正在读取用户输入,您的程序将永远不会工作,因为所有用户输入都将转到父进程进程。

为了使其工作,您需要重新考虑您的设计,并使处理从用户读取输入,并写入管道。并且子进程应该从管道读取并打印到(非管道式)标准输出。或者关闭父级中的(正常的,非管道式)标准输入以及写入管道的子级(作为标准输出)。

+0

谢谢你的回答。不幸的是,我不能重新考虑设计,因为我被要求按照我的解释去做。但也许我的做法不好,我不得不重新考虑这一点。我会及时通知你的! – Dayrona

0

你的代码中有几个问题:

  • 你混的整数(低电平)文件描述符,和(高电平)FILE *常量。
  • 您倒置stdin和stdout以及通过pipe
  • 你写在stdout的消息所获得的描述符的顺序时,打算重定向它(应该使用标准错误)

这里是一个固定的版本(我改变了你得到的与fgets,以及与EXECL你EXEC拥有一切编译):

parent.c:

int main(int argc, char **argv) { 
    int fd[2]; 
    char line[80]; 

    pipe(fd); 

    pid_t pid = (pid_t)fork(); 

    if(pid > 0) { 
     waitpid(pid, NULL, 0); 
     close(fd[1]); 
     int size = read(fd[0], line, 79); 
     close(fd[0]); 
     line[size] = '\0'; 
     printf("[parent] Received \"%s\", size = %d\n", line, size); 
    } 
    else { 
     close(fd[0]); 
     close(1); 
     dup2(fd[1], 1); 
     close(fd[1]); 
     execl("./child", NULL); 
    } 

    return 0; 
} 

孩子。c

int main(int argc, char **argv) { 
    char line[80]; 

    fprintf(stderr, "[child] Enter message: "); 
    fgets(line, 80, stdin); 
    printf("[child] line = %s\n", line); 

    return 0; 
} 
相关问题