Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can posix read() receive less than requested 4 bytes from a pipe?

Tags:

linux

posix

pipe

A program from the answer https://stackoverflow.com/a/1586277/6362199 uses the system call read() to receive exactly 4 bytes from a pipe. It assumes that the function read() returns -1, 0 or 4. Can the read() function return 1, 2 or 3 for example if it was interrupted by a signal?

In the man page read(2) there is:

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.

Does this mean that the read() function can be interrupted during receiving such a small amount of data as 4 bytes? Should the source code from this answer be corrected?

In the man page pipe(7) there is:

POSIX.1-2001 says that write(2)s of less than PIPE_BUF bytes must be atomic: the output data is written to the pipe as a contiguous sequence.

but there is nothing similar about read().

like image 652
pjkozlowski Avatar asked May 20 '16 20:05

pjkozlowski


People also ask

What does the read () function do?

The read() function reads data previously written to a file. If any portion of a regular file prior to the end-of-file has not been written, read() shall return bytes with value 0. For example, lseek() allows the file offset to be set beyond the end of existing data in the file.

What does the read function return?

Definition and Usage. The read() method returns the specified number of bytes from the file. Default is -1 which means the whole file.

Does read () Change file offset?

On files that support seeking (for example, a regular file), the read() shall start at a position in the file given by the file offset associated with fildes. The file offset shall be incremented by the number of bytes actually read.

Is read () a system call?

The "read()" system call reads data from a open file. Its syntax is exactly the same as that of the "write()" call: read( <file descriptor>, <buffer>, <buffer length> ); The "read()" function returns the number of bytes it actually returns.


1 Answers

If the write is atomic, that means that the entire content is already present in the buffer when the read happens so the only way to have an incomplete read is if the kernel thread decides to yield before it's finished - which wouldn't happen here.

In general you can rely on small write()s on pipes on the same system mapping to identical read()s. 4 bytes is unquestionably far smaller than any buffer would ever be, so it will definitely be atomic.

like image 74
Jim Driscoll Avatar answered Oct 07 '22 01:10

Jim Driscoll