STDIN_FILENO和STDOUT_FILENO是否仅在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,\"dup2(STDIN) failed\");
    return NGX_ERROR;
}

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


if (fd > STDERR_FILENO) {
    if (close(fd) == -1) {
        ngx_log_error(NGX_LOG_EMERG,\"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
?     

解决方法

        常量本身(在POSIX上,
STDIN_FILENO
0
STDOUT_FILENO
1
)确实是只读的,但它们所表征的文件描述符可能已关闭,而其他位置已打开。它们只是普通的文件描述符(通常设置一个标志,以便它们在
execve()
系统调用中保持打开状态)。 变化的是位于OS内核内部的进程的文件描述符表。看到那个“ 14”指令?这真的很重要;这是您进入操作系统的过程的陷阱。     ,        这是守护进程的最后一部分,涉及到将
stdout
stdin
重定向到
/dev/null
,因为以后将不再使用它们。 守护程序通常写入日志文件,而不是标准输出。 引用本文:   守护程序一旦运行,就不应从其启动的终端中读取或写入。确保这一点的最简单,最有效的方法是关闭与stdin,stdout和stderr对应的文件描述符。然后应重新打开这些文件,或者将其打开到/ dev / null,或者如果需要,可以将其重新打开。没有关闭它们有两个原因:         为了防止引用这些文件描述符的代码失败,并且   以防止描述符再用于其他目的。        ,        关闭stdin和stdout可以很好地工作。尽管执行此操作时无法再从它们中读取内容,而必须使用dup()\ d描述符。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...