Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does the write() system call write all of the requested buffer versus just doing a partial write?

Tags:

linux

unix

If I am counting on my write() system call to write say e.g., 100 bytes, I always put that write() call in a loop that checks to see if the length that gets returned is what I expected to send and, if not, it bumps the buffer pointer and decreases the length by the amount that was written.

So once again I just did this, but now that there's StackOverflow, I can ask you all if people know when my writes will write ALL that I ask for versus give me back a partial write?

Additional comments: X-Istence's reply reminded me that I should have noted that the file descriptor was blocking (i.e., not non-blocking). I think he is suggesting that the only way a write() on a blocking file descriptor will not write all the specified data is when the write() is interrupted by a signal. This seems to make at least intuitive sense to me...

like image 218
Chris Markle Avatar asked Mar 29 '09 06:03

Chris Markle


2 Answers

write may return partial write especially using operations on sockets or if internal buffers full. So good way is to do following:

while(size > 0 && (res=write(fd,buff,size))!=size) {
    if(res<0 && errno==EINTR) 
       continue;
    if(res < 0) {
        // real error processing
        break;
    }
    size-=res;
    buf+=res;
}

Never relay on what usually happens...

Note: in case of full disk you would get ENOSPC not partial write.

like image 108
Artyom Avatar answered Sep 28 '22 08:09

Artyom


You need to check errno to see if your call got interrupted, or why write() returned early, and why it only wrote a certain number of bytes.

From man 2 write

When using non-blocking I/O on objects such as sockets that are subject to flow control, write() and writev() may write fewer bytes than requested; the return value must be noted, and the remainder of the operation should be retried when possible.

Basically, unless you are writing to a non-blocking socket, the only other time this will happen is if you get interrupted by a signal.

[EINTR] A signal interrupted the write before it could be completed.

See the Errors section in the man page for more information on what can be returned, and when it will be returned. From there you need to figure out if the error is severe enough to log an error and quit, or if you can continue the operation at hand!

This is all discussed in the book: Advanced Unix Programming by Marc J. Rochkind, I have written countless programs with the help of this book, and would suggest it while programming for a UNIX like OS.

like image 20
X-Istence Avatar answered Sep 28 '22 09:09

X-Istence