This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: socket.accept() with a timout socket creates bogus socket
Type: behavior Stage:
Components: IO Versions: Python 3.1, Python 3.2, Python 3.3, Python 3.4, Python 2.7, Python 2.6, Python 2.5
process
Status: closed Resolution: duplicate
Dependencies: Superseder: On Mac / BSD sockets returned by accept inherit the parent's FD flags
View: 7995
Assigned To: Nosy List: kristjan.jonsson, pitrou
Priority: normal Keywords:

Created on 2011-03-30 12:17 by kristjan.jonsson, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
bug.py kristjan.jonsson, 2011-03-30 12:17 demonstrates a socket incongruency.
Messages (4)
msg132581 - (view) Author: Kristján Valur Jónsson (kristjan.jonsson) * (Python committer) Date: 2011-03-30 12:17
I found this defect at PyCon 2011 after spending a lot of type fidgeting with ssl.  The test_ssl.py unittest was using timeout on accept sockets and it was working fine there, but not with the code I was working out.  Turns out that _ssl.py resets the timeout state of sockets, but not regular sockets.

In short:  If you have a socket with settimeout(1), then accept a connection on it, the new socket will have gettimeout()==None, but its state will still (internally) be non-blocking.  The attached script demonstrates the issue.

This is an issue with all versions of python from 2.5 upwards.

There are basically two things we can do to fis this:
1) retain gettimeout()=None but internally make sure we set the resulting socket to blocking mode
2) have the accepted socket inherit the timeout properties of the parent socket properly, and so inherit its timeout value too.

Number 2 is more in line with expected BSD socket behaviour that sockets at least inherit the non-blocking attribute of their parent socket.
msg132582 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-03-30 12:25
> In short:  If you have a socket with settimeout(1), then accept a
> connection on it, the new socket will have gettimeout()==None, but its 
> state will still (internally) be non-blocking.  The attached script
> demonstrates the issue.

This should have been fixed in ed0259230611. Can you confirm?
msg132583 - (view) Author: Kristján Valur Jónsson (kristjan.jonsson) * (Python committer) Date: 2011-03-30 13:05
I cannot see from the link to which branch that was committed, or what revision.  But I assume it is the default branch.  I can confirm that this appears to be fixed.

The corresponding defect has a long (and bothersome) discussion.  I am, however, surprised that this was not considered a "bug" and backported.

The "bug" is pretty clear:  socket.gettimeout() returns None, and yet socket.recv() returns in EWOULDBLOCK.  This is clearly against spec, since the gettimeout() == None means that the socket is supposed to be blocking.

I can agree with the fix (my number 1 suggestion) but I would have liked to see it done in socketmodule.c where the timeout semantics are all defined, rather than as a cludgy special case in socket.py
msg132584 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-03-30 13:08
> The corresponding defect has a long (and bothersome) discussion.  I am, 
> however, surprised that this was not considered a "bug" and backported.

I think Martin's argument was that it could break compatibility.

> I can agree with the fix (my number 1 suggestion) but I would have
> liked to see it done in socketmodule.c where the timeout semantics are 
> all defined, rather than as a cludgy special case in socket.py

There's definitely a reason for doing it in socket.py rather than socketmodule.c, although I don't remember which one.
History
Date User Action Args
2022-04-11 14:57:15adminsetgithub: 55930
2011-03-30 14:00:36kristjan.jonssonsetstatus: open -> closed
resolution: duplicate
superseder: On Mac / BSD sockets returned by accept inherit the parent's FD flags
2011-03-30 13:08:49pitrousetmessages: + msg132584
2011-03-30 13:05:48kristjan.jonssonsetmessages: + msg132583
2011-03-30 12:25:33pitrousetnosy: + pitrou
messages: + msg132582
2011-03-30 12:17:47kristjan.jonssonsettype: behavior
2011-03-30 12:17:21kristjan.jonssoncreate