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

Ste*_*sky 18 unix linux system-calls

我在看readUnix 中的系统调用,至少在Linux中有这个签名:[1]

ssize_t read(int fd, void* buf, size_t count);
Run Code Online (Sandbox Code Playgroud)

假设调用成功(即没有负返回值)和count > 0(即缓冲区实际上可以存储非零字节量).在哪种情况下会read()返回0?我能想到以下几点:

  • fd引用常规文件并且已到达文件末尾时.
  • fd指向管道,套接字或FIFO的接收端时,发送端已关闭,管道/套接字/ FIFO自身的缓冲区已用尽.
  • fd指的是在终端设备的从站侧ICANONCtrl-D已发送到主侧,而行缓存器是空的.

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

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

Vis*_*uVS 7

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


Bar*_*mar 0

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

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