Skip to content

Commit 65fcaa3

Browse files
authored
gh-84808: socket.connect_ex: Handle negative errno (GH-122304)
POSIX allows errno to be negative. Even though all currently supported platforms have non-negative errno, relying on a quirk like that would make Python less portable.
1 parent d8f3c1e commit 65fcaa3

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix error handling in :py:class:`~socket.socket` method
2+
:py:func:`~socket.socket.connect_ex` on platforms where
3+
:c:data:`errno` can be negative.

Modules/socketmodule.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3421,6 +3421,18 @@ sock_connect_impl(PySocketSockObject *s, void* Py_UNUSED(data))
34213421
return 1;
34223422
}
34233423

3424+
/* Common functionality for socket.connect and socket.connect_ex.
3425+
*
3426+
* If *raise* is set:
3427+
* - On success, return 0.
3428+
* - On any failure, return -1 with an exception set.
3429+
* If *raise* is zero:
3430+
* - On success, return 0.
3431+
* - On connect() failure, return errno (without an exception set)
3432+
* - On other error, return -1 with an exception set.
3433+
*
3434+
* Note that -1 is a valid errno value on some systems.
3435+
*/
34243436
static int
34253437
internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
34263438
int raise)
@@ -3505,8 +3517,10 @@ sock_connect(PySocketSockObject *s, PyObject *addro)
35053517
}
35063518

35073519
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 1);
3508-
if (res < 0)
3520+
if (res < 0) {
3521+
assert(PyErr_Occurred());
35093522
return NULL;
3523+
}
35103524

35113525
Py_RETURN_NONE;
35123526
}
@@ -3536,8 +3550,9 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro)
35363550
}
35373551

35383552
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 0);
3539-
if (res < 0)
3553+
if (res == -1 && PyErr_Occurred()) {
35403554
return NULL;
3555+
}
35413556

35423557
return PyLong_FromLong((long) res);
35433558
}

0 commit comments

Comments
 (0)