Commit c33ebf92 authored by Jason Madden's avatar Jason Madden Committed by GitHub

Merge pull request #949 from gevent/issue944-cloexec

Python 2 sockets don't pass type/protocol to getaddrinfo in connect.
parents ca9c3b8c 18ddc987
...@@ -9,6 +9,10 @@ ...@@ -9,6 +9,10 @@
- Testing on Python 3.5 now uses Python 3.5.3 due to SSL changes. See - Testing on Python 3.5 now uses Python 3.5.3 due to SSL changes. See
:issue:`943`. :issue:`943`.
- Python 2 sockets are compatible with the ``SOCK_CLOEXEC`` flag found
on Linux. They no longer pass the socket type or protocol to
``getaddrinfo`` when ``connect`` is called. Reported in :issue:`944`
by Bernie Hackett.
1.2.1 (2017-01-12) 1.2.1 (2017-01-12)
================== ==================
......
...@@ -218,7 +218,7 @@ class socket(object): ...@@ -218,7 +218,7 @@ class socket(object):
return self._sock.connect(address) return self._sock.connect(address)
sock = self._sock sock = self._sock
if isinstance(address, tuple): if isinstance(address, tuple):
r = getaddrinfo(address[0], address[1], sock.family, sock.type, sock.proto) r = getaddrinfo(address[0], address[1], sock.family)
address = r[0][-1] address = r[0][-1]
if self.timeout is not None: if self.timeout is not None:
timer = Timeout.start_new(self.timeout, timeout('timed out')) timer = Timeout.start_new(self.timeout, timeout('timed out'))
......
...@@ -5,6 +5,7 @@ import array ...@@ -5,6 +5,7 @@ import array
import socket import socket
import traceback import traceback
import time import time
import unittest
import greentest import greentest
from functools import wraps from functools import wraps
import _six as six import _six as six
...@@ -212,7 +213,7 @@ class TestTCP(greentest.TestCase): ...@@ -212,7 +213,7 @@ class TestTCP(greentest.TestCase):
def test_makefile(self): def test_makefile(self):
def accept_once(): def accept_once():
conn, addr = self.listener.accept() conn, _ = self.listener.accept()
fd = conn.makefile(mode='wb') fd = conn.makefile(mode='wb')
fd.write(b'hello\n') fd.write(b'hello\n')
fd.close() fd.close()
...@@ -230,7 +231,7 @@ class TestTCP(greentest.TestCase): ...@@ -230,7 +231,7 @@ class TestTCP(greentest.TestCase):
def test_makefile_timeout(self): def test_makefile_timeout(self):
def accept_once(): def accept_once():
conn, addr = self.listener.accept() conn, _ = self.listener.accept()
try: try:
time.sleep(0.3) time.sleep(0.3)
finally: finally:
...@@ -285,6 +286,32 @@ class TestTCP(greentest.TestCase): ...@@ -285,6 +286,32 @@ class TestTCP(greentest.TestCase):
s.connect_ex(('localhost', 65539)) s.connect_ex(('localhost', 65539))
s.close() s.close()
@unittest.skipUnless(hasattr(socket, 'SOCK_CLOEXEC'),
"Requires SOCK_CLOEXEC")
def test_connect_with_type_flags_ignored(self):
# Issue 944
# If we have SOCK_CLOEXEC or similar, we shouldn't be passing
# them through to the getaddrinfo call that connect() makes
SOCK_CLOEXEC = socket.SOCK_CLOEXEC
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM | SOCK_CLOEXEC)
def accept_once():
conn, _ = self.listener.accept()
fd = conn.makefile(mode='wb')
fd.write(b'hello\n')
fd.close()
conn.close()
acceptor = Thread(target=accept_once)
s.connect(('127.0.0.1', self.port))
fd = s.makefile(mode='rb')
self.assertEqual(fd.readline(), b'hello\n')
fd.close()
s.close()
acceptor.join()
def get_port(): def get_port():
tempsock = socket.socket() tempsock = socket.socket()
tempsock.bind(('', 0)) tempsock.bind(('', 0))
......
...@@ -70,6 +70,9 @@ class TestSSL(test__socket.TestTCP): ...@@ -70,6 +70,9 @@ class TestSSL(test__socket.TestTCP):
# Override; doesn't work with SSL sockets. # Override; doesn't work with SSL sockets.
pass pass
def test_connect_with_type_flags_ignored(self):
# Override; doesn't work with SSL sockets.
pass
def ssl_listener(address, private_key, certificate): def ssl_listener(address, private_key, certificate):
raw_listener = socket.socket() raw_listener = socket.socket()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment