From: Barry Margolin on
In article
<6850c1a4-f0a7-4b9f-96cf-66a2396c07a0(a)11g2000prw.googlegroups.com>,
David Schwartz <davids(a)webmaster.com> wrote:

> On Jun 11, 2:39�am, Urs Thuermann <u...(a)isnogud.escape.de> wrote:
>
> > I am surprised that sometimes the write system call on the socket
> > returns with less than 256 bytes written.
> ...
> > Therefore, I expected the write(2) system call to return immediately
> > with 256 if the send buffer has enough space, or to block until 256
> > bytes can be written to the send buffer and then also return with 256.
>
> What happens when you immediately follow up with a 'write' call for
> the remaining bytes? Does it succeed? If so, the solution is pretty
> obvious (though it's not clear why you should need it), just call
> 'write' again. You should be doing that anyway.
>
> DS

Can the partial write happen if the system call is interrupted after
some of the bytes have been written to the network, but before there's
enough buffer space for everything? Or would that have to return -1,
with errno set to EINTR? If that's the case, how does the application
know where to resume? Or is the kernel not allowed to start writing to
the network until it's able to buffer the entire request? And if that's
the case, what happens if you try to write something so big that there
will never be enough buffer space (e.g. you mmap() a big file and then
wrtei() the whole thing, or use the sendfile() system call that some
systems have)?

--
Barry Margolin, barmar(a)alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: David Schwartz on
On Jun 11, 7:51 pm, Barry Margolin <bar...(a)alum.mit.edu> wrote:

> Can the partial write happen if the system call is interrupted after
> some of the bytes have been written to the network, but before there's
> enough buffer space for everything? Or would that have to return -1,
> with errno set to EINTR?

That may not return -1 with errno set to EINTR.

> If that's the case, how does the application
> know where to resume?

Exactly.

> Or is the kernel not allowed to start writing to
> the network until it's able to buffer the entire request?  And if that's
> the case, what happens if you try to write something so big that there
> will never be enough buffer space (e.g. you mmap() a big file and then
> wrtei() the whole thing, or use the sendfile() system call that some
> systems have)?

Exactly.

If the 'write' is interrupted for some reason (by a signal or if the
other end shuts down the connection) after some, but not all, bytes
have been (or may have been) sent, 'write' must return the number of
bytes sent. You can figure out the reason for the partial send by
attempting another 'write'.

DS
From: Scott Lurndal on
David Schwartz <davids(a)webmaster.com> writes:
>On Jun 11, 7:51=A0pm, Barry Margolin <bar...(a)alum.mit.edu> wrote:
>
>> Can the partial write happen if the system call is interrupted after
>> some of the bytes have been written to the network, but before there's
>> enough buffer space for everything?=A0Or would that have to return -1,
>> with errno set to EINTR?
>
>That may not return -1 with errno set to EINTR.

Indeed. By definition, if the system call returns EINTR, then
no bytes will have been transferred.

scott

From: Urs Thuermann on
David Schwartz <davids(a)webmaster.com> writes:

> What happens when you immediately follow up with a 'write' call for
> the remaining bytes? Does it succeed? If so, the solution is pretty
> obvious (though it's not clear why you should need it), just call
> 'write' again. You should be doing that anyway.

Oops, sorry for this unnecessary thread. In debugging I got things
wrong. By not trying to write again the remaining bytes I didn't see
the write error return which now has helped me to find a bug in the
client code.

Instead of trying to write again I exited the loop and closed the
socket, because I didn't expect that behavior of write in the correct
case.

My first observation was that the client got an EOF, i.e. read
returned with 0 and then exited. I thought this was because of the
server closing the socket after incomplete write and I wondered why
write(2) behaves this way. Now I found a bug in the client that
caused the read system call to be called with a byte count of 0 which
then of cause returned 0 which I interpreted as EOF. The client
closed the socket and only then the server returned with the
incomplete write. Repeating the write then gives the error "Broken
pipe" or "Connection reset by peer". So everything behaves as
expected.

urs