As is described in SUSv4 or POSIX.1-2008
http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html#tag_16_685_08
The write() call may return a value less than nbytes if write()ing to a NONBLOCK pipe/FIFO.
Thus, it's necessary to check the return value and write() the rest of the buffer in a loop demonstrated below:
while (bytes_to_write > 0) {
select(...); // Or poll()
retv = write(...);
if (retv < 0)
... // Error
bytes_to_write -= retv;
}
The standard says nothing about regular files, special files (aka. devices) and sockets, especially stream-based sockets (TCP sockets and UNIX Domain ones, for example).
Then, I have the following two questions:
Sorry for broken English.
Ok. Since the standard does't provide any guarantee, we can't assume full write()s.
I Googled partial writev and got an answer:
http://developerweb.net/viewtopic.php?id=4154
Yes, I've seen that behavior before as well (though, with sendmsg() and its iovecs)... And, actually, no it's NOT incorrect/unexpected behavior... Both read()/recv() and write()/send() (and all permutations of the I/O funcs) can return short reads/writes, and all sockets code needs to be prepared to deal with that... It doesn't matter if they're blocking or non-blocking mode sockets, either... All that controls is what happens when the buffer is totally empty (in the case of input) or totally full (in the case of output)... But, when the send buffer isn't quite full, any write to it (via a blocking or non-blocking socket) of more than the amount of free space left will write as much as it can, and then return the short write count... And, you are expected to handle calling it again, to send the remaining amount... With normal write()/send(), it's easy to do, but with writev()/sendmsg() iovecs, it does become tricky to handle, and a real pain... But, you still MUST do it
writev_all() can't be avoided.
Thanks.
Will partial write() (or partial send()) possibly occur on regular files
Yes.
(or sockets with O_NONBLOCK unset) ?
Yes.
How about writev() and sendmsg() on NONBLOCK sockets?
Yes.
This is very important, since dealing with partially written vector (struct iovec []) is a bit of trouble.
Not really. You know how many bytes were written, you just have to advance the pointers and decrement the sizes accordingly. If it's too much trouble for you, use blocking mode.
Will partial
write()(or partialsend()) possibly occur on regular files (or sockets withO_NONBLOCKunset) ?
Possibly. Signals can interrupt any I/O operation, but the library will restart automatically depending on the SA_RESTART flag:
This flag affects the behavior of interruptible functions; that is, those specified to fail with
errnoset to [EINTR]. If set, and a function specified as interruptible is interrupted by this signal, the function shall restart and shall not fail with [EINTR] unless otherwise specified. If an interruptible function which uses a timeout is restarted, the duration of the timeout following the restart is set to an unspecified value that does not exceed the original timeout value. If the flag is not set, interruptible functions interrupted by this signal shall fail witherrnoset to [EINTR].
This flag is set by default on Linux, so you don't need to worry unless custom signal handling is in effect.
How about
writev()andsendmsg()onNONBLOCKsockets? This is very important, since dealing with partially written vector (struct iovec []) is a bit of trouble.
More complex system calls are handled the same. The user-space library code does the heavy lifting of restarting the interrupted call, after the signal handler (if any) has returned.