簡體   English   中英

STDIN_FILENO 和 STDOUT_FILENO 在 c 中是只讀的嗎?

[英]Are STDIN_FILENO and STDOUT_FILENO read only in c?

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

這是守護進程的最后一部分,涉及將stdoutstdin重定向到/dev/null ,因為以后不會使用它們。

守護進程通常寫入日志文件,而不是標准 output。

引用這篇文章

一旦它運行,一個守護進程就不應讀取或寫入啟動它的終端。 確保這一點最簡單和最有效的方法是關閉與 stdin、stdout 和 stderr 對應的文件描述符。 然后應該將它們重新打開到 /dev/null,或者如果喜歡到其他位置。 不關閉它們有兩個原因:

  • 防止引用這些文件描述符的代碼失敗,並且
  • 以防止描述符被重用於其他目的。

常量本身(在 POSIX 上, STDIN_FILENO0並且STDOUT_FILENO1 )確實是只讀的,但是它們表征的文件描述符可能是關閉的,並且在它們的位置打開了其他東西; 它們只是普通的文件描述符(通常帶有一個標志集,以便它們在execve()系統調用時保持打開狀態)。

正在改變的是駐留在操作系統 kernel 內的進程的文件描述符表。 看到那個syscall指令了嗎? 這在這里非常重要; 這就是你的進程進入操作系統的陷阱。

關閉標准輸入和標准輸出工作得很好。 雖然當你這樣做時,你不能再從它們中讀取數據並且必須使用 dup()'d 描述符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM