Bug report
Bug description:
The 5 and 6-argument variants of gethostbyname_r() and gethostbyaddr_r() use h_errnop output parameter for errors, but CPython implementation discards its value. gethost_common() subsequently reads global h_errno when the lookup fails, but h_errno should not be set by gethostbyname_r implementation as they should use that output parameter instead.
On Solaris (which uses 5 argument variant), this can result in the following error:
>>> socket.gethostbyaddr('1.2.3.4')
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
socket.gethostbyaddr('1.2.3.4')
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
socket.herror: [Errno 0] Resolver Error 0 (no error)where the error is set from incorrect (unset) h_errno.
I couldn't reproduce this on either MacOS (which, AFAICT, doesn't use the reentrant variant and sets h_errno) nor Linux (which is surprising to me? I guess that the glibc implementation sets h_errno as well although the documentation states that the passed in int *h_errnop should be checked instead), but I still believe this is the correct way of handling this.
CPython versions tested on:
3.13, CPython main branch
Operating systems tested on:
Other
Linked PRs
- gh-155336: Preserve resolver errors from gethostby*_r() #155337
- [3.15] gh-155336: Preserve resolver errors from gethostby*_r() (GH-155337) #155469
- [3.14] gh-155336: Preserve resolver errors from gethostby*_r() (GH-155337) #155470
- [3.13] gh-155336: Preserve resolver errors from gethostby*_r() (GH-155337) #155473