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

后端 未结 3 664
无人及你
无人及你 2021-02-09 21:55

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 e

相关标签:
3条回答
  • 2021-02-09 22:28

    Writes shouldn't have any reason to ever write a partial buffer afaik. Possible reasons I could think of for a partial write is if you run out of disk space, you're writing past the end of a block device, or if you're writing to a char device / some other sort of device.

    However, the plan to retry writes blindly is probably not such a good one - check errno to see whether you should be retrying first.

    0 讨论(0)
  • 2021-02-09 22:29

    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.

    0 讨论(0)
  • 2021-02-09 22:38

    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.

    0 讨论(0)
提交回复
热议问题