Under what conditions could write(sock, buf, n), with n>0, return zero
for a TCP socket? According to POSIX? In Linux?
The return values I'm comfortable with are:
n - all got written
1..n-1 - partial write
-1 - fatal error, EINTR or EWOULDBLOCK
That doesn't seem to leave room for a distinct meaning of 0.
This supposedly happened to the guy who asked me, on Linux. I'm not
sure if the socket was set blocking or nonblocking.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
The nonstandard O_NDELAY can (could?) cause this on some platforms,
though I don't believe Linux is one of them.
Zero means the connection is closed and no bytes were sent.
DS
That situation yields a return of -1 with errno=EPIPE (and raises
SIGPIPE, though that might be ignored); or EBADF if you've closed at
this end.
0 means nothing is written (socket send buffer is full, that it could
not accommodate even a single byte) and you have to call write again
at a later point in time. This is similar to partial write. Strictly
cannot be called partial, because nothing was actually written :)
So if write returns 0, your action will be
Return value of zero means nothing was written to the socket (socket
send buffer is full, that it could not accommodate even a single
byte). This is not a serious error, just that you should attempt again
to write to the socket at a later point in time. In a sense, this is
similar to partial write 1..n-1 bytes, but may be we cannot call this
a partial write, since nothing was actually written. May be we should
call it incomplete write in general instead of partial write if we
want to be picky on the terms :)
I believe the man page states this quite clearly
"On success, the number of bytes written is returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately."
How can this happen?
If the socket is in blocking mode and the buffer is full, the write
should block until it's able to write at least one byte, then return
1..n.
If the socket is in non-blocking mode and the buffer is full, it should
return -1 with errno = EWOULDBLOCK.
What other cases are there?
--
Barry Margolin
Arlington, MA
> That situation yields a return of -1 with errno=EPIPE (and raises
> SIGPIPE, though that might be ignored); or EBADF if you've closed at
> this end.
>
> --http://www.greenend.org.uk/rjk/
Okay, here's a good non-answer for you: If 'write' returns zero, it
means no bytes were sent even though no error occurred.
DS
>> That situation yields a return of -1 with errno=EPIPE (and raises
>> SIGPIPE, though that might be ignored); or EBADF if you've closed at
>> this end.
>
> Okay, here's a good non-answer for you: If 'write' returns zero, it
> means no bytes were sent even though no error occurred.
That would be an answer to "what would it mean". The question was "how
could it happen".
In fact the "this supposedly happened" makes me suspect that the OP's
interlocutor is just mistaken, and it didn't happen. But evidence to
the contrary would certainly be interesting.
Right, that's the Linux write(2) man page. But it covers more uses
than TCP sockets, and like Barry Magolin below, I have a hard time
seeing what socket cases aren't already covered by the two classics:
block or say EWOULDBLOCK.
> How can this happen?
>
> If the socket is in blocking mode and the buffer is full, the write
> should block until it's able to write at least one byte, then return
> 1..n.
>
> If the socket is in non-blocking mode and the buffer is full, it should
> return -1 with errno = EWOULDBLOCK.
>
> What other cases are there?
write(sock, buf, 0) is one trivial such case, but that's not what I'm
after, I think,
Well, the "supposedly" here mostly means I haven't investigated it
myself. But yes, it's possible that the cause is mistakenly passing a
zero size to write(), or send(), or whatever that code uses.
Also, the guy who asked me had googled around and the message he got
from the few hits (in non-authorative sources) was something like "new
code must cope with a 0 return".
I was hoping that e.g. someone would pop out and say "yes, Linux does
it like that nowadays in <these> situations", like e.g. Mr Schwartz
did in the past when I asked about select() and blocking UDP sockets.
As far as I can see, that hasn't happened yet.