Author: Armin Rigo <[email protected]>
Branch: py3.5-noninherit
Changeset: r86576:e7787d31798f
Date: 2016-08-26 19:01 +0200
http://bitbucket.org/pypy/pypy/changeset/e7787d31798f/
Log: socket.accept()
diff --git a/pypy/module/_socket/interp_socket.py
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -228,7 +228,7 @@
For IP sockets, the address info is a pair (hostaddr, port).
"""
try:
- fd, addr = self.sock.accept()
+ fd, addr = self.sock.accept(inheritable=False)
return space.newtuple([space.wrap(fd),
addr_as_object(addr, fd, space)])
except SocketError as e:
diff --git a/pypy/module/_socket/test/test_sock_app.py
b/pypy/module/_socket/test/test_sock_app.py
--- a/pypy/module/_socket/test/test_sock_app.py
+++ b/pypy/module/_socket/test/test_sock_app.py
@@ -846,6 +846,16 @@
assert cli.family == socket.AF_INET
+ def test_accept_non_inheritable(self):
+ import _socket, posix
+ cli = _socket.socket()
+ cli.connect(self.serv.getsockname())
+ fileno, addr = self.serv._accept()
+ assert posix.get_inheritable(fileno) is False
+ posix.close(fileno)
+ cli.close()
+
+
class AppTestErrno:
spaceconfig = {'usemodules': ['_socket']}
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -320,6 +320,8 @@
[('p_proto', rffi.INT),
])
+CConfig.HAVE_ACCEPT4 = platform.Has('accept4')
+
if _POSIX:
CConfig.nfds_t = platform.SimpleType('nfds_t')
CConfig.pollfd = platform.Struct('struct pollfd',
@@ -542,6 +544,11 @@
socketaccept = external('accept', [socketfd_type, sockaddr_ptr,
socklen_t_ptr], socketfd_type,
save_err=SAVE_ERR)
+if cConfig.HAVE_ACCEPT4:
+ socketaccept4 = external('accept4', [socketfd_type, sockaddr_ptr,
+ socklen_t_ptr, rffi.INT],
+ socketfd_type,
+ save_err=SAVE_ERR)
socketbind = external('bind', [socketfd_type, sockaddr_ptr, socklen_t],
rffi.INT, save_err=SAVE_ERR)
socketlisten = external('listen', [socketfd_type, rffi.INT], rffi.INT,
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1172,8 +1172,7 @@
try:
if HAVE_PIPE2 and _pipe2_syscall.attempt_syscall():
res = c_pipe2(filedes, flags)
- _pipe2_syscall.update()
- if res < 0 and get_saved_errno() == errno.ENOSYS:
+ if _pipe2_syscall.fallback(res):
res = c_pipe(filedes)
else:
res = c_pipe(filedes) # 'flags' ignored
@@ -2269,6 +2268,9 @@
# 'fd' is inheritable; we must manually turn it off
set_inheritable(fd, False)
+ def _cleanup_(self):
+ self.cached_inheritable = -1
+
class ENoSysCache(object):
"""Cache whether a system call returns ENOSYS or not."""
_immutable_fields_ = ['cached_nosys?']
@@ -2277,8 +2279,14 @@
def attempt_syscall(self):
return self.cached_nosys != 1
- def update(self):
- if self.cached_nosys == -1:
- self.cached_nosys = (get_saved_errno() == errno.ENOSYS)
+ def fallback(self, res):
+ nosys = self.cached_nosys
+ if nosys == -1:
+ nosys = (res < 0 and get_saved_errno() == errno.ENOSYS)
+ self.cached_nosys = nosys
+ return nosys
+
+ def _cleanup_(self):
+ self.cached_nosys = -1
_pipe2_syscall = ENoSysCache()
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -646,20 +646,33 @@
return addr, addr.addr_p, addrlen_p
@jit.dont_look_inside
- def accept(self):
+ def accept(self, inheritable=True):
"""Wait for an incoming connection.
Return (new socket fd, client address)."""
if self._select(False) == 1:
raise SocketTimeout
address, addr_p, addrlen_p = self._addrbuf()
try:
- newfd = _c.socketaccept(self.fd, addr_p, addrlen_p)
+ remove_inheritable = not inheritable
+ if (not inheritable and SOCK_CLOEXEC is not None
+ and hasattr(_c, 'socketaccept4') and
+ _accept4_syscall.attempt_syscall()):
+ newfd = _c.socketaccept4(self.fd, addr_p, addrlen_p,
+ SOCK_CLOEXEC)
+ if _accept4_syscall.fallback(newfd):
+ newfd = _c.socketaccept(self.fd, addr_p, addrlen_p)
+ else:
+ remove_inheritable = False
+ else:
+ newfd = _c.socketaccept(self.fd, addr_p, addrlen_p)
addrlen = addrlen_p[0]
finally:
lltype.free(addrlen_p, flavor='raw')
address.unlock()
if _c.invalid_socket(newfd):
raise self.error_handler()
+ if remove_inheritable:
+ sock_set_inheritable(newfd, False)
address.addrlen = rffi.cast(lltype.Signed, addrlen)
return (newfd, address)
@@ -1452,3 +1465,5 @@
if timeout < 0.0:
timeout = -1.0
defaults.timeout = timeout
+
+_accept4_syscall = rposix.ENoSysCache()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit