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;
}
- Question1: What caused the dup()d fd being closed?
- 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?
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?