如何管理stdin从孩子到父母?

时间:2016-11-23 15:29:45

标签: c pipe stdin

我尝试从父进程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:,但是当我尝试输入内容时,即使我按下返回键也没有任何内容。

你知道我怎么能让它发挥作用?

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

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

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

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

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

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

答案 1 :(得分:0)

您的代码有几个问题:

  • 混合整数(低级)文件描述符和(高级)FILE *常量。
  • 你反转stdin和stdout以及通过pipe
  • 获得的描述符的顺序
  • 当你打算重定向它时,你在stdout上写了一条消息(应该使用stderr)

这是一个固定版本(我用fgets更改你的获取,以及你的exec用execl来编译所有内容):

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;
}

child.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;
}

答案 2 :(得分:0)

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

再次感谢您的帮助!