Почему fork() закрывает один из файловых дескрипторов с помощью dup2()

Я написал код, чтобы получить представление о 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);
    }
}

lsof показывает 2 открытых файловых дескриптора (/workspace/source/throw.cpp — это переданные аргументы)

/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

НО, пока я разветвляю() его на 2 процесса (код, как показано ниже), открыт только один /workspace/source/throw.cpp.

#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. Вопрос 1: Что вызвало закрытие dup()d fd?
  2. Вопрос 2: Я просмотрел FD_CLOEXEC в ручном режиме, но не устанавливал его с помощью fcntl(). fopen() устанавливает его автоматически? и влияет ли этот флаг не только на fork, но и на семейства exec?
  3. #P4# <блочная цитата> #P5# #P6#

person user1744585    schedule 26.05.2014    source источник


Ответы (1)


В вашем коде есть ошибка (используется значение fdnew перед его установкой), поэтому его поведение будет непредсказуемым. Исправьте ошибку, прежде чем пытаться понять, что делает программа. Кроме того, вы должны проверить возвращаемое значение dup2, чтобы увидеть, удалось ли это.

person David Schwartz    schedule 26.05.2014
comment
Ты прав. Я не понимаю правильно dup, fdnew и fdold должны быть допустимыми файловыми дескрипторами. - person user1744585; 26.05.2014