【问题标题】:Sharing file descriptors between a parent and child after the child performs an exec call (UNIX/C)在子执行 exec 调用后在父子之间共享文件描述符 (UNIX/C)
【发布时间】:2011-09-07 07:24:19
【问题描述】:

我的操作系统课上有一个作业。我应该写三个程序,一个程序从文件读取并写入管道,一个程序从管道读取并写入文件,第三个程序是创建管道并执行两个分叉的父程序以生成子进程,这些子进程立即执行 exec() 调用。我目前使用管道所做的是将 exec() 调用中的文件描述符作为 argv[] 的一部分传递,它可以工作,但似乎是错误的解决方案。

我想知道是否有更好的方法来做到这一点。通过参数传递文件描述符似乎很尴尬。

【问题讨论】:

  • 是否已从该问题中删除了代码 sn-ps?
  • 这个问题应该结束了:答案显然是基于一些不再可用的代码。

标签: unix exec fork parent-child pipe


【解决方案1】:

fork 后的子进程继承父进程打开的文件描述符。见man 2 fork

好的。我对您的第一个建议是使用标志 -Wall -Wextra -pedantic 进行编译以获取所有警告。现在我对您的代码进行了更改:

/*removed char pipe_readend[12];*/
char * arg[2] = {"test2", NULL}; /*first argument of program should be always it's name*/
char message[3] = {'h', 'i', '\0'}; /*c-string should be always terminated by '\0'*/
/*...*/
 case 0:
        /* child actions */
            close(pfd[1]); /* close write end */
            close(STDIN_FILENO); /*close standard input descriptor*/
            dup(pfd[0]); /*now standard input will be pfd[0]*/
            execve("test2", arg, NULL); /* start new process */
            break;

和 test2.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (void){
    char msg[3];
    read(STDIN_FILENO, msg, 3); /*read from standard input*/
    printf("test2: %s\n", msg);
    return 0;
}

总结一下:在 fork 之后,您将关闭标准输入描述符并复制 pfd[0],这将成为新的标准输入。然后调用 execve(),它使用 pfd[0] 作为标准输入。在man 2 的函数fork, execve, pipe 中查看更多信息。

【讨论】:

  • 这并没有真正的帮助。在 exec 调用之后,我不知道文件描述符是什么。假设管道使用 fd 3 和 4,在 fork 之后和 exec 调用之前,我在变量 pfd[0] 和 pfd[1] 中有这些文件描述符,但是在 exec 调用之后,我不再知道这些值了。我知道文件描述符是继承的,并且我可以在 exec() 调用之后盲目地在 read()/write() 调用中使用值 3 和 4,并且它们仍然可以工作,但这似乎是不好的做法。有没有比我正在做的更好的方法来处理这个问题?在 argv[] 中传递文件描述符?
  • pastebin.com/iwzFWSNU - 这是我对父母和孩子所做的精简版。在参数中传递文件描述符。效果很好,只是看起来不太常见。
猜你喜欢
  • 2014-02-26
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 2011-01-19
  • 2012-12-03
  • 1970-01-01
  • 2011-10-02
  • 2011-10-26
相关资源
最近更新 更多