在子进行exec调用后,在父和子之间共享文件描述符(UNIX / C)

时间:2011-09-07 07:24:19

标签: unix exec fork parent-child pipe

我在OS类中有一个作业。我应该编写三个程序,一个程序从文件读取并写入管道,一个程序从管道读取并写入文件,第三个程序是创建管道的父程序,并执行两个分支以便产生子进程,立即执行exec()调用。我目前正在做的是使用管道,是作为argv []的一部分在exec()调用中传递文件描述符,它可以工作,但它似乎是错误的解决方案。

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

1 个答案:

答案 0 :(得分:3)

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

总而言之:在分叉之后你正在关闭标准输入描述符并重复pfd [0],这将成为新的标准输入。然后调用execve(),它使用pfd [0]作为标准输入。请参阅man 2函数fork, execve, pipe中的详细信息。