Partial POSIX Entry ()
As described in SUSv4 or POSIX.1-2008
http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html#tag_16_685_08
The write () call can return less than nbytes if write () is connected to a NONBLOCK pipe / FIFO . Thus, it is necessary to check the return value and write () the rest of the buffer in the loop shown below:
while (bytes_to_write > 0) {
select(...); // Or poll()
retv = write(...);
if (retv < 0)
... // Error
bytes_to_write -= retv;
}
The standard is silent about regular files, special files (eg devices), and sockets , especially for stream sockets (eg TCP and UNIX Domain sockets).
Then I have the following two questions:
- Is it possible to write partial () (or partial send ()) on regular files (or sockets with O_NONBLOCK unset )?
- How about writev () and sendmsg () for NONBLOCK sockets? This is very important because handling a partially written vector (struct iovec []) is a small problem.
Sorry for the broken english.
source to share
Ok. Since the standard does not provide any guarantee, we cannot count the full write()
s.
I tried to partially write v and got the answer:
http://developerweb.net/viewtopic.php?id=4154
Yes, I've seen this behavior too (albeit with sendmsg () and its iovecs) ... And, in fact, this is NOT IMPOSSIBLE / unexpected behavior ... Both read () / recv () and write () / send ( ) (and all permutations of I / O functions) can return short reads / writes and all socket code has to be prepared to handle this ... It doesn't matter if they block or non-block mode sockets, or ... Whatever controls is what happens when the buffer is completely empty (in case of input) or completely full (in case of output) ... But, when the send buffer is not completely full, any write to it (via a blocking or non-blocking socket) is greater than the remaining free space write as much as possible and then return a short count of letters ... And you are expected to call it again to send the remaining amount ... With the usual write () / send (),it's easy to do, but with writev () / sendmsg () iovecs it gets tricky to handle and a real pain ... But you still MUST do it
writev_all()
cannot be avoided.
Thank.
source to share
Can partial write () (or partial send ()) occur in regular files
Yes.
(or sockets with O_NONBLOCK disabled)?
Yes.
How about writev () and sendmsg () on NONBLOCK sockets?
Yes.
This is very important because the handling of a partially written vector (struct iovec []) is a little difficult.
Not really. You know how many bytes have been written, you just have to advance the pointers and downsize accordingly. If you have too many problems, use block mode.
source to share
Is partial
write()
(or partialsend()
) possible in regular files (orO_NONBLOCK
unset sockets )?
Maybe. Signals can interrupt any I / O operation, but the library will automatically restart based on SA_RESTART
:
This flag affects the behavior of intermittent functions; that is, those listed in error with
errno
set to [EINTR]. If set, and a function specified to be interrupted is interrupted by this signal, the function shall restart and not interrupt with [EINTR] unless otherwise specified. If a restartable function that uses a timeout is restarted, the duration of the timeout after the restart is set to an undefined value that does not exceed the original timeout value. If the flag is not set, intermittent functions interrupted by this signal failerrno
set to [EINTR].
This flag is set by default on Linux, so you don't need to worry if custom signal handling isn't working.
How about
writev()
, andsendmsg()
in theNONBLOCK
socket? This is very important, as dealing with a partially written vector (struct iovec []
) is a little frustrating.
More complex system calls are handled the same way. The user-space library code does the heavy lifting of restarting the interrupted call after the signal handler (if any) has returned.
source to share