https://github.com/python/cpython/commit/5181a6eca5de011cba15f8fc8fbffbeb3eec6db6
commit: 5181a6eca5de011cba15f8fc8fbffbeb3eec6db6
branch: main
author: Jakub KulĂk <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-10T07:34:51Z
summary:
gh-155336: Preserve resolver errors from gethostby*_r() (GH-155337)
files:
A Misc/NEWS.d/next/Library/2026-08-10-09-00-18.gh-issue-155336.vrTXoU.rst
M Modules/socketmodule.c
diff --git
a/Misc/NEWS.d/next/Library/2026-08-10-09-00-18.gh-issue-155336.vrTXoU.rst
b/Misc/NEWS.d/next/Library/2026-08-10-09-00-18.gh-issue-155336.vrTXoU.rst
new file mode 100644
index 00000000000000..87f8a7f4a21e66
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-08-10-09-00-18.gh-issue-155336.vrTXoU.rst
@@ -0,0 +1,2 @@
+Fix error handling in :func:`socket.gethostbyaddr` and
+:func:`socket.gethostbyname_ex` when hostname resolution fails.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 73ae1c942daba4..f9c77c631b5d2a 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -6041,7 +6041,7 @@ sock_decode_hostname(const char *name)
static PyObject *
gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr,
- size_t alen, int af)
+ size_t alen, int af, int h_error)
{
char **pch;
PyObject *rtn_tuple = (PyObject *)NULL;
@@ -6052,7 +6052,7 @@ gethost_common(socket_state *state, struct hostent *h,
struct sockaddr *addr,
if (h == NULL) {
/* Let's get real error message to return */
- set_herror(state, h_errno);
+ set_herror(state, h_error);
return NULL;
}
@@ -6188,6 +6188,7 @@ static PyObject *
socket_gethostbyname_ex(PyObject *self, PyObject *args)
{
char *name;
+ int h_error;
struct hostent *h;
sock_addr_t addr;
struct sockaddr *sa;
@@ -6199,7 +6200,6 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
#else
char buf[16384];
int buf_len = (sizeof buf) - 1;
- int errnop;
#endif
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
int result;
@@ -6218,14 +6218,14 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_GETHOSTBYNAME_R
#if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
- gethostbyname_r(name, &hp_allocated, buf, buf_len,
- &h, &errnop);
+ gethostbyname_r(name, &hp_allocated, buf, buf_len, &h, &h_error);
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
- h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop);
+ h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &h_error);
#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
memset((void *) &data, '\0', sizeof(data));
result = gethostbyname_r(name, &hp_allocated, &data);
h = (result != 0) ? NULL : &hp_allocated;
+ h_error = h_errno;
#endif
#else /* not HAVE_GETHOSTBYNAME_R */
#ifdef USE_GETHOSTBYNAME_LOCK
@@ -6235,6 +6235,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
h = gethostbyname(name);
_Py_COMP_DIAG_POP
+ h_error = h_errno;
#endif /* HAVE_GETHOSTBYNAME_R */
Py_END_ALLOW_THREADS
/* Some C libraries would require addr.__ss_family instead of
@@ -6243,7 +6244,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args)
access sa_family. */
sa = SAS2SA(&addr);
ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr),
- sa->sa_family);
+ sa->sa_family, h_error);
#ifdef USE_GETHOSTBYNAME_LOCK
PyMutex_Unlock(&netdb_lock);
#endif
@@ -6282,7 +6283,6 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
to maintain this alignment. */
_Py_ALIGNED_DEF(8, char) buf[16384];
int buf_len = (sizeof buf) - 1;
- int errnop;
#endif
#ifdef HAVE_GETHOSTBYNAME_R_3_ARG
int result;
@@ -6291,6 +6291,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
const char *ap;
int al;
int af;
+ int h_error;
if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num))
return NULL;
@@ -6323,16 +6324,14 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_GETHOSTBYNAME_R
#if defined(HAVE_GETHOSTBYNAME_R_6_ARG)
- gethostbyaddr_r(ap, al, af,
- &hp_allocated, buf, buf_len,
- &h, &errnop);
+ gethostbyaddr_r(ap, al, af, &hp_allocated, buf, buf_len, &h, &h_error);
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
- h = gethostbyaddr_r(ap, al, af,
- &hp_allocated, buf, buf_len, &errnop);
+ h = gethostbyaddr_r(ap, al, af, &hp_allocated, buf, buf_len, &h_error);
#else /* HAVE_GETHOSTBYNAME_R_3_ARG */
memset((void *) &data, '\0', sizeof(data));
result = gethostbyaddr_r(ap, al, af, &hp_allocated, &data);
h = (result != 0) ? NULL : &hp_allocated;
+ h_error = h_errno;
#endif
#else /* not HAVE_GETHOSTBYNAME_R */
#ifdef USE_GETHOSTBYNAME_LOCK
@@ -6342,9 +6341,10 @@ socket_gethostbyaddr(PyObject *self, PyObject *args)
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
h = gethostbyaddr(ap, al, af);
_Py_COMP_DIAG_POP
+ h_error = h_errno;
#endif /* HAVE_GETHOSTBYNAME_R */
Py_END_ALLOW_THREADS
- ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr), af);
+ ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr), af, h_error);
#ifdef USE_GETHOSTBYNAME_LOCK
PyMutex_Unlock(&netdb_lock);
#endif
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]