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

时间:2022-06-30 09:25:52

I'm looking at the read syscall in Unix, which (at least in Linux) has this signature: [1]

我正在看Unix中的read syscall,它(至少在Linux中)有这个签名:[1]

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

Let's assume that the call succeeds (i.e. no negative return values) and that count > 0 (i.e. the buffer actually can store a nonzero amount of bytes). Under which circumstances would read() return 0? I can think of the following:

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

  • When fd refers to a regular file and the end of the file has been reached.
  • 当fd引用常规文件并且已到达文件末尾时。
  • When fd refers to the receiving end of a pipe, socket or FIFO, the sending end has been closed and the pipe's/socket's/FIFO's own buffer has been exhausted.
  • 当fd指向管道,套接字或FIFO的接收端时,发送端已关闭,管道/套接字/ FIFO自身的缓冲区已用完。
  • When fd refers to the slave side of a terminal device that is in ICANON and Ctrl-D has been sent into the master side while the line buffer was empty.
  • 当fd指的是ICANON中的终端设备的从属端,并且当行缓冲器为空时,Ctrl-D已被发送到主端。

I'm curious if there are any other situations that I'm not aware of, where read() would return with a result of 0. I'm especially interested (because of reasons) in situations like the last one in the list above, where read() returns 0 once, but subsequent calls to read() on the same FD could return a nonzero result. If an answer only applies to a certain flavor of Unix, I'm still interested in hearing it.

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

[1] I know this signature is for the libc wrapper, not the actual syscall, but that's not important right now.

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

2 个解决方案

#1


4  

  • If the Physical File System does not support simple reads from directories, read() will return 0 if it is used for a directory. Users should use Opendir() and readdir() instead.
  • 如果物理文件系统不支持从目录中进行简单读取,则read()将返回0(如果它用于目录)。用户应该使用Opendir()和readdir()。
  • If no process has the pipe open for writing, read() returns 0 to indicate the end of the file.
  • 如果没有进程打开管道进行写入,则read()返回0以指示文件的结尾。
  • If the connection is broken on a stream socket, but no data is available, then the read() function returns 0 bytes as EOF.
  • 如果连接在流套接字上断开,但没有数据可用,则read()函数返回0字节作为EOF。

#2


-3  

Normally a return value of 0 always means end-of-file. However, if you specify 0 as the number of bytes to read, it will always return 0 unless there's an error detected.

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

Terminal devices are a special case. If the terminal is in cooked mode, typing Control-d tells the device driver to return from any pending read() immediately with whatever is in the input editing buffer, rather than waiting for the user to enter a newline. If the buffer is empty, this results in a zero-length read. This is how typing the EOF character at the beginning of a line is automatically treated as EOF by applications.

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

#1


4  

  • If the Physical File System does not support simple reads from directories, read() will return 0 if it is used for a directory. Users should use Opendir() and readdir() instead.
  • 如果物理文件系统不支持从目录中进行简单读取,则read()将返回0(如果它用于目录)。用户应该使用Opendir()和readdir()。
  • If no process has the pipe open for writing, read() returns 0 to indicate the end of the file.
  • 如果没有进程打开管道进行写入,则read()返回0以指示文件的结尾。
  • If the connection is broken on a stream socket, but no data is available, then the read() function returns 0 bytes as EOF.
  • 如果连接在流套接字上断开,但没有数据可用,则read()函数返回0字节作为EOF。

#2


-3  

Normally a return value of 0 always means end-of-file. However, if you specify 0 as the number of bytes to read, it will always return 0 unless there's an error detected.

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

Terminal devices are a special case. If the terminal is in cooked mode, typing Control-d tells the device driver to return from any pending read() immediately with whatever is in the input editing buffer, rather than waiting for the user to enter a newline. If the buffer is empty, this results in a zero-length read. This is how typing the EOF character at the beginning of a line is automatically treated as EOF by applications.

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