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 つのプロセス (以下のコード) に fork() しますが、開いている /workspace/source/throw.cpp は 1 つだけです。
#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: dup()d fd が閉じられた原因は何ですか?
- 質問 2: マニュアルで FD_CLOEXEC を調べましたが、fcntl() で設定しないでください。fopen() は自動的に設定しますか? このフラグは fork だけでなく exec ファミリにも影響しますか?
質問 3: dup2 を dup に置き換えた後、結果は予想どおり 2 fds を示しています。マニュアルが言ったように:
「dup2() は newfd を oldfd のコピーにし、必要に応じて newfd を最初に閉じます」。
newfdがすでに開いている場合、dupの前にnewfdを閉じることを意味しますか?