fix gunicorn when used with musl libc

find_library('c') doesn't work in Alpine Linux. This happen because musl has a simpler implementation of libc.

This patch fix it by extending ctypes.util.find_library to search the libs using LD_LIBRARY_PATH.

Patch is based on e3f67780aa

See also https://bugs.python.org/issue21622

fix #2160
This commit is contained in:
benoitc 2019-11-20 00:19:07 +01:00
parent c5be1bae5c
commit b8860ef615
2 changed files with 31 additions and 1 deletions

View File

@ -12,7 +12,7 @@ import socket
import sys
import platform
from ctypes.util import find_library
from .util import find_library
__all__ = ('fromfd',)

View File

@ -3,6 +3,7 @@
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
import ast
import ctypes.util
import email.utils
import errno
import fcntl
@ -635,3 +636,32 @@ def bytes_to_str(b):
def unquote_to_wsgi_str(string):
return urllib.parse.unquote_to_bytes(string).decode('latin-1')
def _findWalk_ldpath(name):
def _is_elf(filepath):
try:
with open(filepath, 'rb') as fh:
return fh.read(4) == b'\x7fELF'
except:
return False
from glob import glob
if os.path.isabs(name):
return name
# search LD_LIBRARY_PATH list
paths = os.environ.get('LD_LIBRARY_PATH', '').split(':')
if paths:
for d in paths:
f = os.path.join(d, name)
if _is_elf(f):
return os.path.basename(f)
prefix = os.path.join(d, 'lib'+name)
for suffix in ['.so', '.so.*']:
for f in glob('{0}{1}'.format(prefix, suffix)):
if _is_elf(f):
return os.path.basename(f)
def find_library(name):
return ctypes.util.find_library(name) or _findWalk_ldpath(name)