All*_*nHu 9 sockets linux kernel
程序开始时,默认情况下是否需要stdin,stdout和stderr的文件描述符0,1和2?API调用(例如open(...),socket(...))是否会返回0,1和2,因为这些值已经被采用了?是否存在open(...)或socket(...)返回0,1或2的情况.0,1和2与stdin,stdout和stderr无关.
Bas*_*tch 14
在文件描述符级别,stdin被定义为文件描述符0,stdout被定义为文件描述符1 ; 和stderr被定义为文件描述符2.看到这个.
即使您的程序 - 或shell-更改(例如,使用dup2(2)重定向)什么是文件描述符0,它始终保持stdin(因为根据定义STDIN_FILENO为0).
因此,stdin当然可以是管道或套接字或文件(不是终端).如果它是tty,你可以使用isatty(3)进行测试,和/或使用fstat(2)来获取状态信息.
如果该文件描述符是空闲的(例如因为它之前已经接近(2) -d ),则像open(2)或pipe(2)或socket(2)这样的系统调用可以给出例如STDIN_FILENO(即0 ).但是当发生这种情况时,它仍然是stdin的定义.
当然,在stdio(3)中,FILE流stdin有点复杂.你的程序可以fclose(3),freopen(3),fdopen(3) ......
当神奇地从第一个进程开始时,内核可能会将stdin,stdout和stderr文件描述符设置到控制台/sbin/init.
尽管已经存在一些答案,但我发现它们的信息不足以解释完整的故事。
由于我继续进行了更多研究,因此我正在添加我的发现。
每当进程启动时,正在运行的进程的条目就会添加到/proc/<pid>目录中。这是保存与流程相关的所有数据的地方。此外,在进程启动时,内核会向进程分配 3 个文件描述符,用于与 3 个数据流(称为stdin、stdout和 )进行通信stderr。
Linux 内核使用一种算法来始终创建具有尽可能低的整数值的 FD,以便这些数据流映射到数字0、1和2。
因为这些只是对流的引用,所以我们可以关闭流。close(<fd>)在我们的例子中,我们可以轻松地调用close(1)来关闭文件描述符。
在这样做时ls -l /proc/<pid>/fd/,我们只看到那里列出了 2 个 FD0和2。
如果我们现在进行调用,open()内核将创建一个新的 FD 来映射此新文件引用,并且由于内核使用最低整数优先算法,因此它将获取整数值1。
所以现在,创建的新 FD 指向我们打开的文件(使用open()系统调用)。
现在发生的任何数据传输都不是通过之前链接的默认数据流,而是通过我们打开的新文件。
所以是的,我们可以将 FD 或 映射0到任何文件,但不是必需1的,或者2stdinstdoutstderr
| 归档时间: |
|
| 查看次数: |
29223 次 |
| 最近记录: |