summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvery Pennarun <apenwarr@gmail.com>2011-03-21 03:12:32 -0700
committerAvery Pennarun <apenwarr@gmail.com>2011-03-21 03:15:11 -0700
commit94241b938bcf92a06d1b07184deca98349ab363f (patch)
tree04c6ecbacfc9ca8c535439f7fb3de80232676643
parent9031de1527a3ef377eedfd99a67496ec7ed5c102 (diff)
On FreeBSD, avoid a crash caused by buggy socket.connect() in python pre-2.5.
Bug reported by Ed Maste. The fix in later versions of python is documented here: http://mail.python.org/pipermail/python-bugs-list/2006-August/034667.html We're basically just doing the same thing when we see EINVAL. Note that this doesn't happen on Linux because connect() is more forgiving.
-rw-r--r--ssnet.py10
1 files changed, 10 insertions, 0 deletions
diff --git a/ssnet.py b/ssnet.py
index b4327d8..2abf5d0 100644
--- a/ssnet.py
+++ b/ssnet.py
@@ -130,6 +130,16 @@ class SockWrapper:
self.connect_to = None
except socket.error, e:
debug3('%r: connect result: %s\n' % (self, e))
+ if e.args[0] == errno.EINVAL:
+ # this is what happens when you call connect() on a socket
+ # that is now connected but returned EINPROGRESS last time,
+ # on BSD, on python pre-2.5.1. We need to use getsockopt()
+ # to get the "real" error. Later pythons do this
+ # automatically, so this code won't run.
+ realerr = self.rsock.getsockopt(socket.SOL_SOCKET,
+ socket.SO_ERROR)
+ e = socket.error(realerr, os.strerror(realerr))
+ debug3('%r: fixed connect result: %s\n' % (self, e))
if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]:
pass # not connected yet
elif e.args[0] == errno.EISCONN: