首页 > 解决方案 > execvp后如何在子进程中使用文件描述符?

问题描述

我正在尝试使用 fork() 打开一个子进程,然后在另一个程序中执行 execvp()。我还希望父进程和子进程使用管道相互通信。

这是父进程-

int pipefds[2];
pipe(pipefds); // In original code I check for errors...
int readerfd = pipefds[0];
int writerfd = pipefds[1];

if(pid == 0){
    // Child
    close(readerfd);
        execvp("./proc2",NULL);
}


在程序'proc2'中,我试图通过以下方式访问writerfd -

write(writerfd, msg, msg_len);

但相反,我得到一个编译时错误 - “错误:'writerfd'未声明(在此函数中首次使用);”

这是为什么?我在这里读到堆栈溢出“打开的文件描述符在对 exec 的调用中被保留。” 链接。如果是这样,我不应该能够联系到 writerfd 吗?

使用 execvp 后,如何在子进程上写入该文件描述符?执行此操作的正确方法是什么,我在哪里可以阅读答案(我看过但没有找到..)?

谢谢!

标签: clinuxpipeforkexecvp

解决方案


exec调用函数时会保留打开的文件描述符。没有保留的是用于存储它们的任何变量的名称。

您需要将文件描述符复制到其他程序可以引用的已知文件描述符编号。由于子进程正在写入,您应该将管道的子端复制到文件描述符1,即stdout:

int pipefds[2];
pipe(pipefds);
int readerfd = pipefds[0];
int writerfd = pipefds[1];

if(pid == 0){
    // Child
        close(readerfd);
        dup2(writerfd, 1);
        execvp("./proc2",NULL);
}

然后 proc2 可以写入文件描述符 1:

write(1, msg, msg_len);

或者,如果消息是字符串,只需使用printf

printf("%s", msg);
fflush(stdout);

推荐阅读