diff -r 6e8f42fa4a86 Lib/ctypes/util.py --- a/Lib/ctypes/util.py Tue Oct 14 23:03:13 2014 +0200 +++ b/Lib/ctypes/util.py Wed Oct 15 00:31:27 2014 +0200 @@ -1,6 +1,8 @@ -import sys, os import contextlib +import os +import shutil import subprocess +import sys # find_library(name) returns the pathname of a library, or None. if os.name == "nt": @@ -88,28 +90,36 @@ elif os.name == "posix": import re, tempfile def _findLib_gcc(name): - expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) - fdout, ccout = tempfile.mkstemp() - os.close(fdout) - cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;' \ - 'LANG=C LC_ALL=C $CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name - try: - f = os.popen(cmd) + expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % name) + + if shutil.which('gcc'): + c_compiler = 'gcc' + elif shutil.which('cc'): + c_compiler = 'cc' + else: + raise OSError('gcc or cc command not found') + + with tempfile.NamedTemporaryFile() as temp: + args = [c_compiler, '-Wl,-t', '-l', name, '-o', temp.name] + + env = os.environ.copy() + env['LC_ALL'] = 'C' + env['LANG'] = 'C' + proc = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + env=env) + with proc: + trace = proc.stdout.read() + try: - trace = f.read() - finally: - rv = f.close() - finally: - try: - os.unlink(ccout) + temp.close() except FileNotFoundError: pass - if rv == 10: - raise OSError('gcc or cc command not found') res = re.search(expr, trace) if not res: return None - return res.group(0) + return os.fsdecode(res.group(0)) if sys.platform == "sunos5": @@ -129,19 +139,17 @@ elif os.name == "posix": # assuming GNU binutils / ELF if not f: return None - cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \ - "objdump -p -j .dynamic 2>/dev/null " + f - f = os.popen(cmd) - try: - dump = f.read() - finally: - rv = f.close() - if rv == 10: + if not shutil.which('objdump'): raise OSError('objdump command not found') - res = re.search(r'\sSONAME\s+([^\s]+)', dump) + proc = subprocess.Popen(['objdump', '-p', '-j', '.dynamic', f], + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL) + with proc: + dump = proc.stdout.read() + res = re.search(br'\sSONAME\s+([^\s]+)', dump) if not res: return None - return res.group(1) + return os.fsdecode(res.group(1)) if sys.platform.startswith(("freebsd", "openbsd", "dragonfly")):