From d4c5f7dd2f3a49cb014d4658440012926095166b Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 11 Dec 2010 23:35:36 -0800 Subject: [PATCH] Fixes #69, thanks to the solid test case and patch. Added a unit test that verifies correctness. Thank you! --- eventlet/greenio.py | 8 ++++++++ tests/greenio_test.py | 11 ++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/eventlet/greenio.py b/eventlet/greenio.py index 742fa82..1e526ca 100644 --- a/eventlet/greenio.py +++ b/eventlet/greenio.py @@ -37,6 +37,10 @@ def socket_connect(descriptor, address): raise socket.error(err, errno.errorcode[err]) return descriptor +def socket_checkerr(descriptor): + err = descriptor.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err not in CONNECT_SUCCESS: + raise socket.error(err, errno.errorcode[err]) def socket_accept(descriptor): """ @@ -162,6 +166,7 @@ class GreenSocket(object): if self.gettimeout() is None: while not socket_connect(fd, address): trampoline(fd, write=True) + socket_checkerr(fd) else: end = time.time() + self.gettimeout() while True: @@ -171,6 +176,7 @@ class GreenSocket(object): raise socket.timeout("timed out") trampoline(fd, write=True, timeout=end-time.time(), timeout_exc=socket.timeout("timed out")) + socket_checkerr(fd) def connect_ex(self, address): if self.act_non_blocking: @@ -180,6 +186,7 @@ class GreenSocket(object): while not socket_connect(fd, address): try: trampoline(fd, write=True) + socket_checkerr(fd) except socket.error, ex: return get_errno(ex) else: @@ -192,6 +199,7 @@ class GreenSocket(object): raise socket.timeout(errno.EAGAIN) trampoline(fd, write=True, timeout=end-time.time(), timeout_exc=socket.timeout(errno.EAGAIN)) + socket_checkerr(fd) except socket.error, ex: return get_errno(ex) diff --git a/tests/greenio_test.py b/tests/greenio_test.py index 5a90c8c..a4b4b8b 100644 --- a/tests/greenio_test.py +++ b/tests/greenio_test.py @@ -1,5 +1,5 @@ import socket as _orig_sock -from tests import LimitedTestCase, skip_with_pyevent, main, skipped, s2b, skip_if +from tests import LimitedTestCase, skip_with_pyevent, main, skipped, s2b, skip_if, skip_on_windows from eventlet import event from eventlet import greenio from eventlet import debug @@ -490,7 +490,7 @@ class TestGreenSocket(LimitedTestCase): try: sock.sendall('hello world') except socket.error, e: - if e.errno == errno.EPIPE: + if get_errno(e)== errno.EPIPE: return raise @@ -507,7 +507,7 @@ class TestGreenSocket(LimitedTestCase): except socket.error, e: # we get an EBADF because client is closed in the same process # (but a different greenthread) - if e.errno != errno.EBADF: + if get_errno(e) != errno.EBADF: raise def closer(): @@ -518,8 +518,13 @@ class TestGreenSocket(LimitedTestCase): reader.wait() sender.wait() + def test_invalid_connection(self): + # find an unused port by creating a socket then closing it + port = eventlet.listen(('127.0.0.1', 0)).getsockname()[1] + self.assertRaises(socket.error, eventlet.connect, ('127.0.0.1', port)) class TestGreenPipe(LimitedTestCase): + @skip_on_windows def setUp(self): super(self.__class__, self).setUp() self.tempdir = tempfile.mkdtemp('_green_pipe_test')