Search code examples
cio

Can non-buffered write return 0?


According to the documentation, write returns either the number of bytes written or -1 in case of an error. It's not clear whether the number of bytes written can be 0 when nbyte is positive. The documentation does state that the returned value of bytes can be smaller than nbyte, but it's unclear whether it can be 0:

If a write() requests that more bytes be written than there is room for ... only as many bytes as there is room for shall be written. For example, suppose there is space for 20 bytes more in a file before reaching a limit. A write of 512 bytes will return 20.

The question is: if there is no room at all, will write return 0 or an error?

This matters for the code that calls write in a loop until either all bytes were written or an error returned.


Solution

  • The question is: if there is no room at all, will write return 0 or an error?

    Reviewing the text in the ERRORS section of the documentation you link to, there are two errors that match the description of “a write() requests that more bytes be written than there is room for”. Both are in the subsection starting:

    The write() and [for XSI] *pwrite() functions shall fail [emphasis added] if:

    One of them is:

    [ENOSPC] There was no free space remaining on the device containing the file.

    In the case where write writes 20 bytes of 512, there was free space remaining on the device, so no error occurred yet. The free space was used up, and 20 was returned.

    In the case where write writes 0 bytes of 512, there was no free space remaining on the device, so the documentation requires an error.

    The other is:

    [EFBIG] An attempt was made to write a file that exceeds the implementation-defined maximum file size or [for XSI] the process' file size limit, and there was no room for any bytes to be written.”

    This case is clearer: If there was no room for any bytes to be written, then write shall fail.

    Note also that the ERRORS section has another subsection saying “The write() function may fail if,” so it is clear the “shall fail” is a deliberate requirement.

    The above applies to the specific situation asked about in the question, when the issue is a write cannot make progress because there is no room, and for implementations complying to the linked version of the Unix specification. However, you may wish to be aware that, beyond those constraints, write may return zero. The documentation says in its RATIONALE section:

    Where this volume of IEEE Std 1003.1-2001 requires -1 to be returned and errno set to [EAGAIN], most historical implementations return zero (with the O_NDELAY flag set, which is the historical predecessor of O_NONBLOCK, but is not itself in this volume of IEEE Std 1003.1-2001).