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

时间:2018-07-18 21:42:21

标签: linux unix system-calls

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

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

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

  • fd引用常规文件并且到达文件末尾时。
  • fd指向管道,套接字或FIFO的接收端时,发送端已关闭,并且管道/套接字/ FIFO自己的缓冲区已用尽。
  • fdICANON中的终端设备的从属端,并且在行缓冲区为空时Ctrl-D已发送到主控端。

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

[1]我知道此签名是针对libc包装程序的,而不是针对实际的syscall的,但是现在这并不重要。

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:-3)

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

终端设备是一种特殊情况。如果终端处于烹调模式,则键入 Control-d 告诉设备驱动程序立即使用输入编辑缓冲区中的任何内容从任何暂挂的read()返回,而不是等待用户执行输入换行符。如果缓冲区为空,则读取长度为零。这样,应用程序会自动将在行首键入EOF字符视为EOF。