1

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. 質問 1: dup()d fd が閉じられた原因は何ですか?
  2. 質問 2: マニュアルで FD_CLOEXEC を調べましたが、fcntl() で設定しないでください。fopen() は自動的に設定しますか? このフラグは fork だけでなく exec ファミリにも影響しますか?
  3. 質問 3: dup2 を dup に置き換えた後、結果は予想どおり 2 fds を示しています。マニュアルが言ったように:

    「dup2() は newfd を oldfd のコピーにし、必要に応じて newfd を最初に閉じます」。

    newfdがすでに開いている場合、dupの前にnewfdを閉じることを意味しますか?

4

1 に答える 1

3

あなたのコードにはバグがある (fdnew設定する前に の値を使用する) ため、その動作は予測できません。プログラムが何をしているのかを理解する前に、バグを修正してください。dup2また、成功したかどうかを確認するために、の戻り値を確認する必要があります。

于 2014-05-26T04:06:20.793 に答える