From 94241b938bcf92a06d1b07184deca98349ab363f Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Mon, 21 Mar 2011 03:12:32 -0700 Subject: [PATCH] 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. --- ssnet.py | 10 ++++++++++ 1 file changed, 10 insertions(+) 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: