Search code examples
clinuxpipeforkexecvp

how to use a file descriptor in a child process after execvp?


I am trying to open a child process using fork(), and then execvp()-ing into another program. I also want the parent process and the child process to communicate with each other using a pipe.

here is the parent process -

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


in the program 'proc2' I am trying to access the writerfd in the following way-

write(writerfd, msg, msg_len);

but instead, I get a compilation time error - "error: ‘writerfd’ undeclared (first use in this function);"

why is that? I read here on stack overflow that "Open file descriptors are preserved across a call to exec." link. should't I be able to reach writerfd if that is so?

how can I write to that file descriptor on the child process after using execvp? what is the correct way to do this and where can I read about the answer (I looked but I didn't find..)?

Thanks!


Solution

  • Open file descriptors are preserved when you call an exec function. What is not preserved are the names of any variables used to store them.

    You need to duplicate the file descriptor to a known file descriptor number that the other program can reference. Since the child process is writing, you should copy the child end of the pipe to file descriptor 1, which is 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);
    }
    

    Then proc2 can write to file descriptor 1:

    write(1, msg, msg_len);
    

    Or, if the message is a string, just use printf

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