2
fd = open("/dev/null", O_RDWR);
if (fd == -1) {
    ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                  "open(\"/dev/null\") failed");
    return NGX_ERROR;
}

if (dup2(fd, STDIN_FILENO) == -1) {
    ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
    return NGX_ERROR;
}

if (dup2(fd, STDOUT_FILENO) == -1) {
    ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
    return NGX_ERROR;
}


if (fd > STDERR_FILENO) {
    if (close(fd) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
        return NGX_ERROR;
    }
}

man私にそれを教えてくれますdup2() makes newfd be the copy of oldfd, closing newfd first if necessary.

int dup2(int oldfd, int newfd);

しかし、読み取り専用ではありませんSTDIN_FILENOSTDOUT_FILENO

Dump of assembler code for function dup2:
0x00000037aa4c6ac0 <dup2+0>:    mov    $0x21,%eax
0x00000037aa4c6ac5 <dup2+5>:    syscall 
0x00000037aa4c6ac7 <dup2+7>:    cmp    $0xfffffffffffff001,%rax
0x00000037aa4c6acd <dup2+13>:   jae    0x37aa4c6ad0 <dup2+16>
0x00000037aa4c6acf <dup2+15>:   retq   
0x00000037aa4c6ad0 <dup2+16>:   mov    0x28a4d1(%rip),%rcx        # 0x37aa750fa8 <free+3356736>
0x00000037aa4c6ad7 <dup2+23>:   xor    %edx,%edx
0x00000037aa4c6ad9 <dup2+25>:   sub    %rax,%rdx
0x00000037aa4c6adc <dup2+28>:   mov    %edx,%fs:(%rcx)
0x00000037aa4c6adf <dup2+31>:   or     $0xffffffffffffffff,%rax
0x00000037aa4c6ae3 <dup2+35>:   jmp    0x37aa4c6acf <dup2+15>

それともdup2まったく変わらなかっnewfdたのですか?

4

3 に答える 3

4

定数自体 (POSIX ではSTDIN_FILENOis0およびSTDOUT_FILENOis 1) は実際には読み取り専用ですが、それらが特徴付けるファイル記述子は閉じられ、代わりに他の何かが開かれる場合があります。それらは単なる通常のファイル記述子です (通常は、execve()システム コールで開いたままになるようにフラグが設定されています)。

変更されているのは、OS カーネル内に存在するプロセスのファイル記述子のテーブルです。そのsyscall指示を見ますか?これは非常に重要です。これは、プロセスから OS へのトラップです。

于 2011-06-01T07:59:57.153 に答える
3

これはデーモン化の最後の部分であり、後で使用されることはないため、stdoutstdinへのリダイレクトが含まれます。/dev/null

デーモンは通常、標準出力ではなく、ログ ファイルに書き込みます。

この記事を引用:

実行中のデーモンは、起動元の端末から読み書きするべきではありません。これを確実にする最も簡単で効果的な方法は、stdin、stdout、および stderr に対応するファイル記述子を閉じることです。次に、これらを /dev/null に、または必要に応じて他の場所に再度開く必要があります。それらを閉じたままにしない理由は 2 つあります。

  • これらのファイル記述子を参照するコードが失敗するのを防ぐため、および
  • 記述子が他の目的で再利用されるのを防ぐため。
于 2011-06-01T07:57:53.673 に答える
0

標準入力と標準出力を閉じると、完全に正常に機能します。ただし、これを行うと、それらから読み取ることができなくなり、dup() された記述子を使用する必要があります。

于 2011-06-01T07:59:16.097 に答える