Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the linux system call read(fd, buf, count) return less than count when fd is a regular file?

When we call read(fd, buf, count) on Linux, can the return value of the system (function) call be less than count other than the scenario where there were fewer bytes to the end-of-file?

I looked it up in the man page, it says

"On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal."

So here is my question: How can read() on a regular file be interrupted by a signal? By what possible signals?

like image 980
pthreadself Avatar asked Feb 13 '15 13:02

pthreadself


People also ask

What does the read () system call return on success?

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number.

How does the read syscall work?

The read system call interface is standardized by the POSIX specification. Data from a file is read by calling the read function: ssize_t read(int fd, void *buf, size_t count); The value returned is the number of bytes read (zero indicates end of file) and the file position is advanced by this number.

What is read return EOF?

Upon reading end-of-file, zero is returned. Otherwise, a -1 is returned and the global variable errno is set to indicate the error.

Is read system call blocking?

Because client socket is configured to be nonblocking, read is incapable of blocking.


1 Answers

Yes, read() can be interrupted by a signal. But not when the process is reading from a descriptor that belongs to file on file system.

When process calls read() on file it enters a so-called uninterruptible sleep. In this mode process will not handle any signals until system call is completed. Either because of some error or when requested data was read.

Note: when process is in an uninterruptible sleep you can't even terminate it with SIGKILL signal. Or in the other words kill $pid -9 will have no effect.

In this question there is an explanation of an uninterruptible sleep: What is an uninterruptable process?

Note further: there is and interesting real-life cases when hard drive experiences failure and all processes that either trying to write data to that disk (File System) or to read from it are stuck and cannot be killed by any means other than rebooting a system. This is also true for volumes mounted over a network, such as NFS.

Edit: as psmears has pointed out, read() can be interrupted if reading from file that is on the volume, mounted via NFS iff intr mount option was specified.

like image 166
GreenScape Avatar answered Oct 06 '22 01:10

GreenScape