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.

+3


source to share


3 answers


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.

+3


source


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.

-1


source


Is partial write()

(or partial send()

) possible in regular files (or O_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 fail errno

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()

, and sendmsg()

in the NONBLOCK

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.

-1


source







All Articles