user1744585
user1744585

Reputation: 147

Why fork() close one of the file descriptor by dup2()

I wrote code to get sense of dup2().

int main(int argc, char* argv[]) {
    FILE *fp = fopen(argv[1],"r");
    int fdold,fdnew;
    fdold = fileno(fp);
    fdnew = dup2(fdold,fdnew);
    while (1) {
        sleep(1000);
    }
}

the lsof shows 2 opened file descriptors (/workspace/source/throw.cpp is the arguements passed in)

/workspace/source/thread$ lsof -p 20779
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
dup2    20779  wto  cwd    DIR    8,1     4096 946031 /workspace/source
dup2    20779  wto  rtd    DIR    8,1     4096      2 /
dup2    20779  wto  txt    REG    8,1     8672 950259 /workspace/source/dup2
dup2    20779  wto  mem    REG    8,1  1852120 135869 /lib/x86_64-linux-gnu/libc-2.17.so
dup2    20779  wto  mem    REG    8,1   149312 135845 /lib/x86_64-linux-gnu/ld-2.17.so
dup2    20779  wto    0u   CHR  136,4      0t0      7 /dev/pts/4
dup2    20779  wto    1u   CHR  136,4      0t0      7 /dev/pts/4
dup2    20779  wto    2u   CHR  136,4      0t0      7 /dev/pts/4
dup2    20779  wto    3r   REG    8,1      653 951057 /workspace/source/throw.cpp
dup2    20779  wto *767r   REG    8,1      653 951057 /workspace/source/throw.cpp

BUT, while I fork() it to 2 processes(code as below), there's only one /workspace/source/throw.cpp opened.

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

int main(int argc, char* argv[]) {
    FILE *fp = fopen(argv[1],"r");
    int fdold,fdnew;
    fdold = fileno(fp);
    //fcntl(F_DUPFD_CLOEXEC,fdold);
    fdnew = dup2(fdold,fdnew);
    pid_t pid;
    if ((pid = fork()) < 0) {
        exit(-1);
    } else if (pid > 0) {
        waitpid(pid, WNOHANG, NULL);
        printf("parent exit\n");    
    } else {
        while (1) {
            sleep(1000);
        }
    }
    return 0;
}
  1. Question1: What caused the dup()d fd being closed?
  2. Question2: I looked into FD_CLOEXEC in manual, but don't set it by fcntl(). Does fopen() set it automatically? and does this flag impact on not only fork but exec families?
  3. Question3: After I replaced dup2 by dup, the result shows 2 fds as my expectation. as manual said:

    "dup2() makes newfd be the copy of oldfd, closing newfd first if necessary".

    Does it mean close newfd before dup, if the newfd is opened already?

Upvotes: 1

Views: 579

Answers (1)

David Schwartz
David Schwartz

Reputation: 182753

Your code has a bug (uses the value of fdnew before setting it), so its behavior will be unpredictable. Fix the bug before you try to understand what the program is doing. Also, you should check the return value of dup2 to see if it succeeded.

Upvotes: 3

Related Questions