【问题标题】:how to use a file descriptor in a child process after execvp?execvp后如何在子进程中使用文件描述符?
【发布时间】:2019-04-03 18:37:29
【问题描述】:

我正在尝试使用 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);

但是,我得到一个编译时错误 - "error: 'writerfd' undeclared (第一次在这个函数中使用);"

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

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

谢谢!

【问题讨论】:

  • I read here on stack overflow that "Open file descriptors are preserved across a call to exec." 没错,但这并不意味着您的变量writerfp 会神奇地出现在一个完全不相关的程序中。最简单的方法是将句柄复制到标准输出。

标签: c linux pipe fork execvp


【解决方案1】:

当您调用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);

【讨论】:

  • 知道了,谢谢!我还将在手册页中阅读有关 dup 的信息。再次感谢:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 1970-01-01
  • 2018-11-29
  • 2013-02-22
  • 1970-01-01
相关资源
最近更新 更多