mirror of
https://github.com/python/cpython.git
synced 2025-11-25 04:34:37 +00:00
bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684)
This commit is contained in:
parent
f85af035c5
commit
2a9b8babf0
4 changed files with 23 additions and 13 deletions
|
|
@ -243,7 +243,7 @@ Mac OS Platform
|
||||||
Unix Platforms
|
Unix Platforms
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
.. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=2048)
|
.. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=16384)
|
||||||
|
|
||||||
Tries to determine the libc version against which the file executable (defaults
|
Tries to determine the libc version against which the file executable (defaults
|
||||||
to the Python interpreter) is linked. Returns a tuple of strings ``(lib,
|
to the Python interpreter) is linked. Returns a tuple of strings ``(lib,
|
||||||
|
|
|
||||||
|
|
@ -140,9 +140,7 @@ _libc_search = re.compile(b'(__libc_init)'
|
||||||
b'|'
|
b'|'
|
||||||
br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)
|
br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)
|
||||||
|
|
||||||
def libc_ver(executable=sys.executable, lib='', version='',
|
def libc_ver(executable=sys.executable, lib='', version='', chunksize=16384):
|
||||||
|
|
||||||
chunksize=16384):
|
|
||||||
|
|
||||||
""" Tries to determine the libc version that the file executable
|
""" Tries to determine the libc version that the file executable
|
||||||
(which defaults to the Python interpreter) is linked against.
|
(which defaults to the Python interpreter) is linked against.
|
||||||
|
|
@ -157,6 +155,7 @@ def libc_ver(executable=sys.executable, lib='', version='',
|
||||||
The file is read and scanned in chunks of chunksize bytes.
|
The file is read and scanned in chunks of chunksize bytes.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from distutils.version import LooseVersion as V
|
||||||
if hasattr(os.path, 'realpath'):
|
if hasattr(os.path, 'realpath'):
|
||||||
# Python 2.2 introduced os.path.realpath(); it is used
|
# Python 2.2 introduced os.path.realpath(); it is used
|
||||||
# here to work around problems with Cygwin not being
|
# here to work around problems with Cygwin not being
|
||||||
|
|
@ -165,17 +164,19 @@ def libc_ver(executable=sys.executable, lib='', version='',
|
||||||
with open(executable, 'rb') as f:
|
with open(executable, 'rb') as f:
|
||||||
binary = f.read(chunksize)
|
binary = f.read(chunksize)
|
||||||
pos = 0
|
pos = 0
|
||||||
while 1:
|
while pos < len(binary):
|
||||||
if b'libc' in binary or b'GLIBC' in binary:
|
if b'libc' in binary or b'GLIBC' in binary:
|
||||||
m = _libc_search.search(binary, pos)
|
m = _libc_search.search(binary, pos)
|
||||||
else:
|
else:
|
||||||
m = None
|
m = None
|
||||||
if not m:
|
if not m or m.end() == len(binary):
|
||||||
binary = f.read(chunksize)
|
chunk = f.read(chunksize)
|
||||||
if not binary:
|
if chunk:
|
||||||
|
binary = binary[max(pos, len(binary) - 1000):] + chunk
|
||||||
|
pos = 0
|
||||||
|
continue
|
||||||
|
if not m:
|
||||||
break
|
break
|
||||||
pos = 0
|
|
||||||
continue
|
|
||||||
libcinit, glibc, glibcversion, so, threads, soversion = [
|
libcinit, glibc, glibcversion, so, threads, soversion = [
|
||||||
s.decode('latin1') if s is not None else s
|
s.decode('latin1') if s is not None else s
|
||||||
for s in m.groups()]
|
for s in m.groups()]
|
||||||
|
|
@ -185,12 +186,12 @@ def libc_ver(executable=sys.executable, lib='', version='',
|
||||||
if lib != 'glibc':
|
if lib != 'glibc':
|
||||||
lib = 'glibc'
|
lib = 'glibc'
|
||||||
version = glibcversion
|
version = glibcversion
|
||||||
elif glibcversion > version:
|
elif V(glibcversion) > V(version):
|
||||||
version = glibcversion
|
version = glibcversion
|
||||||
elif so:
|
elif so:
|
||||||
if lib != 'glibc':
|
if lib != 'glibc':
|
||||||
lib = 'libc'
|
lib = 'libc'
|
||||||
if soversion and soversion > version:
|
if soversion and (not version or V(soversion) > V(version)):
|
||||||
version = soversion
|
version = soversion
|
||||||
if threads and version[-len(threads):] != threads:
|
if threads and version[-len(threads):] != threads:
|
||||||
version = version + threads
|
version = version + threads
|
||||||
|
|
@ -253,6 +254,7 @@ def popen(cmd, mode='r', bufsize=-1):
|
||||||
warnings.warn('use os.popen instead', DeprecationWarning, stacklevel=2)
|
warnings.warn('use os.popen instead', DeprecationWarning, stacklevel=2)
|
||||||
return os.popen(cmd, mode, bufsize)
|
return os.popen(cmd, mode, bufsize)
|
||||||
|
|
||||||
|
|
||||||
def _norm_version(version, build=''):
|
def _norm_version(version, build=''):
|
||||||
|
|
||||||
""" Normalize the version and build strings and return a single
|
""" Normalize the version and build strings and return a single
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,6 @@ class PlatformTest(unittest.TestCase):
|
||||||
self.assertEqual(sts, 0)
|
self.assertEqual(sts, 0)
|
||||||
|
|
||||||
def test_libc_ver(self):
|
def test_libc_ver(self):
|
||||||
import os
|
|
||||||
if os.path.isdir(sys.executable) and \
|
if os.path.isdir(sys.executable) and \
|
||||||
os.path.exists(sys.executable+'.exe'):
|
os.path.exists(sys.executable+'.exe'):
|
||||||
# Cygwin horror
|
# Cygwin horror
|
||||||
|
|
@ -269,6 +268,13 @@ class PlatformTest(unittest.TestCase):
|
||||||
executable = sys.executable
|
executable = sys.executable
|
||||||
res = platform.libc_ver(executable)
|
res = platform.libc_ver(executable)
|
||||||
|
|
||||||
|
self.addCleanup(support.unlink, support.TESTFN)
|
||||||
|
with open(support.TESTFN, 'wb') as f:
|
||||||
|
f.write(b'x'*(16384-10))
|
||||||
|
f.write(b'GLIBC_1.23.4\0GLIBC_1.9\0GLIBC_1.21\0')
|
||||||
|
self.assertEqual(platform.libc_ver(support.TESTFN),
|
||||||
|
('glibc', '1.23.4'))
|
||||||
|
|
||||||
def test_popen(self):
|
def test_popen(self):
|
||||||
mswindows = (sys.platform == "win32")
|
mswindows = (sys.platform == "win32")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fixed implementation of :func:`platform.libc_ver`. It almost always returned
|
||||||
|
version '2.9' for glibc.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue