在什么情况下,read()系统调用返回0



我正在查看Unix中的read系统调用,它(至少在Linux中(具有以下签名:[1]

ssize_t read(int fd, void* buf, size_t count);

让我们假设调用成功(即没有负返回值(,并且count > 0(即缓冲区实际上可以存储非零值的字节(。在什么情况下read()会返回0?我可以想到以下内容:

  • fd引用一个常规文件并且已经到达该文件的末尾时
  • fd指的是管道、套接字或FIFO的接收端时,发送端已关闭,管道/套接字的/FIFO自身的缓冲区已耗尽
  • fd指的是处于ICANON中的终端设备的从端,并且在线路缓冲器为空时Ctrl-D已被发送到主端

我很好奇是否还有其他我不知道的情况,read()会返回结果为0。我对上面列表中的最后一种情况特别感兴趣(因为原因(,其中read()返回0一次,但随后对同一FD上的read()的调用可能返回非零结果。如果一个答案只适用于Unix的某种风格,我仍然有兴趣听到它

[1] 我知道这个签名是针对libc包装器的,而不是实际的系统调用,但现在这并不重要。

  • 如果物理文件系统不支持从目录中进行简单读取,则read((用于目录时将返回0
  • 如果没有进程打开管道进行写入,则read((返回0以指示文件的结尾
  • 如果流套接字上的连接断开,但没有可用的数据,那么read((函数将返回0字节作为EOF

通常0的返回值总是表示文件结束。但是,如果将0指定为要读取的字节数,则它将始终返回0,除非检测到错误。

终端设备是一种特殊情况。如果终端处于熟模式,键入Control-d告诉设备驱动程序立即从任何挂起的read()返回输入编辑缓冲区中的任何内容,而不是等待用户输入新行。如果缓冲区为空,则会导致读取长度为零。这就是在一行的开头键入EOF字符被应用程序自动视为EOF的方式。

最新更新