[Patches] [ python-Patches-474307 ] Fix send() to send all data

noreply@sourceforge.net noreply@sourceforge.net
Tue, 23 Oct 2001 18:20:48 -0700


Patches item #474307, was opened at 2001-10-23 18:20
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=474307&group_id=5470

Category: Modules
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Guido van Rossum (gvanrossum)
Assigned to: Nobody/Anonymous (nobody)
Summary: Fix send() to send all data

Initial Comment:
This patch attempts to fix the problem that 
*occasionally*, *rarely*, only on *some* operating 
systems, the send() call doesn't send all bytes but 
returns a short count.  While this is totally OK 
according to the spec, it's so rare that most code 
(including almost all of the standard library) assumes 
that send() sends all bytes and doesn't bother to 
check the return value.  Such code can occasionally 
misbehave, e.g. on FreeBSD which apparently returns 
"short counts" more frequently than other platforms.

This has been reported before, e.g. SF bug #211710.

The fix adds a loop to the send() and sendto() calls 
that repeats the call until all bytes are sent or an 
error is encountered.  However, the code doesn't loop 
if the socket is in "non-blocking" mode, as set by the 
setblocking() method.  It also doesn't loop if an 
explicit 'flags' argument is passed, except if flags 
is -1.

Remaining problems:

- If the blocking mode of the socket is set through 
other means than the setblocking() method (e.g. 
through a setsockopt() call, or an fcntl() or ioctl() 
call on the fileno(), or if fromfd() is passed a 
non-blocking socket), the blocking flag may be wrong.
There doesn't seem to be a portable way to get the 
blocking flag, and I don't want to get it before each 
send() call.  The caller should aways use 
setblocking() to change the blocking flag.

- What should be returned if some bytes are written, 
and then an error is returned by the next send() call? 
I raise an exception in that case.

- This may cause blocking in a carefully constructed 
application that uses blocking sockets but always 
calls select() to check that a socket is writable 
before calling send().  Such an application (maybe 
asyncore does this?) can be fixed by passing an 
explicit flags argument of zero to send().

For all these reasons, it's a tough call to decide to 
apply this, and I am submitting this patch for review.

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=474307&group_id=5470