[英]Explaining read, write system calls behavior with STDOUT_FILENO, STDIN_FILENO, and \n
[英]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_FILENO
和STDOUT_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
?
這是守護進程的最后一部分,涉及將stdout
和stdin
重定向到/dev/null
,因為以后不會使用它們。
守護進程通常寫入日志文件,而不是標准 output。
引用這篇文章:
一旦它運行,一個守護進程就不應讀取或寫入啟動它的終端。 確保這一點最簡單和最有效的方法是關閉與 stdin、stdout 和 stderr 對應的文件描述符。 然后應該將它們重新打開到 /dev/null,或者如果喜歡到其他位置。 不關閉它們有兩個原因:
- 防止引用這些文件描述符的代碼失敗,並且
- 以防止描述符被重用於其他目的。
常量本身(在 POSIX 上, STDIN_FILENO
是0
並且STDOUT_FILENO
是1
)確實是只讀的,但是它們表征的文件描述符可能是關閉的,並且在它們的位置打開了其他東西; 它們只是普通的文件描述符(通常帶有一個標志集,以便它們在execve()
系統調用時保持打開狀態)。
正在改變的是駐留在操作系統 kernel 內的進程的文件描述符表。 看到那個syscall
指令了嗎? 這在這里非常重要; 這就是你的進程進入操作系統的陷阱。
關閉標准輸入和標准輸出工作得很好。 雖然當你這樣做時,你不能再從它們中讀取數據並且必須使用 dup()'d 描述符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.