Skip to content

Commit 2f13f99

Browse files
committed
Handle dlopen(NULL) failure in glibc fallback
1 parent 612515d commit 2f13f99

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

src/pip/_internal/utils/glibc.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,20 @@ def glibc_version_string_ctypes() -> Optional[str]:
4040
# manpage says, "If filename is NULL, then the returned handle is for the
4141
# main program". This way we can let the linker do the work to figure out
4242
# which libc our process is actually using.
43-
process_namespace = ctypes.CDLL(None)
43+
#
44+
# We must also handle the special case where the executable is not a
45+
# dynamically linked executable. This can occur when using musl libc,
46+
# for example. In this situation, dlopen() will error, leading to an
47+
# OSError. Interestingly, at least in the case of musl, there is no
48+
# errno set on the OSError. The single string argument used to construct
49+
# OSError comes from libc itself and is therefore not portable to
50+
# hard code here. In any case, failure to call dlopen() means we
51+
# can proceed, so we bail on our attempt.
52+
try:
53+
process_namespace = ctypes.CDLL(None)
54+
except OSError:
55+
return None
56+
4457
try:
4558
gnu_get_libc_version = process_namespace.gnu_get_libc_version
4659
except AttributeError:
@@ -50,7 +63,7 @@ def glibc_version_string_ctypes() -> Optional[str]:
5063

5164
# Call gnu_get_libc_version, which returns a string like "2.5"
5265
gnu_get_libc_version.restype = ctypes.c_char_p
53-
version_str = gnu_get_libc_version()
66+
version_str: str = gnu_get_libc_version()
5467
# py2 / py3 compatibility:
5568
if not isinstance(version_str, str):
5669
version_str = version_str.decode("ascii")

0 commit comments

Comments
 (0)