Author pitrou
Recipients BreamoreBoy, exarkun, lekma, nvetoshkin, pitrou, r.david.murray
Date 2010-10-12.19:29:46
SpamBayes Score 7.93809e-15
Marked as misclassified No
Message-id <1286911788.34.0.383080444965.issue7523@psf.upfronthosting.co.za>
In-reply-to
Content
The accept() issue is the following: the socket created by accept() (in Lib/socket.py) will formally inherit its parent's `type` attribute (including any SOCK_NONBLOCK and SOCK_CLOEXEC flags).

However, the underlying Linux socket is created by the accept() system call, which doesn't inherit flags as mentioned in the aforementioned man page. Therefore, the Python socket gives the wrong information about the socket's real flags.

This can be witnessed quickly:

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM | socket.SOCK_CLOEXEC)
>>> s.bind(("", 0))
>>> s.getsockname()
('0.0.0.0', 34634)
>>> s.listen(5)
>>> c, a = s.accept()
   # Here, just start a "telnet" or "nc" session from another term
>>> import fcntl
>>> fcntl.fcntl(s, fcntl.F_GETFD)
1
>>> fcntl.fcntl(c, fcntl.F_GETFD)
0
>>> fcntl.fcntl(c, fcntl.F_GETFD) & fcntl.FD_CLOEXEC
0
>>> c.type & socket.SOCK_CLOEXEC
524288


The quick solution would be to mask out these flags when creating the Python socket in accept(). A better solution might be to inherit these flags by using the accept4() system call when possible (this is useful especially for SOCK_CLOEXEC, of course).


Apart from that, the patch looks ok, but it would be nice to test that at least the underlying socket is really in non-blocking mode, like is done in NonBlockingTCPTests.testSetBlocking.
History
Date User Action Args
2010-10-12 19:29:48pitrousetrecipients: + pitrou, exarkun, r.david.murray, lekma, nvetoshkin, BreamoreBoy
2010-10-12 19:29:48pitrousetmessageid: <1286911788.34.0.383080444965.issue7523@psf.upfronthosting.co.za>
2010-10-12 19:29:47pitroulinkissue7523 messages
2010-10-12 19:29:46pitroucreate