Skip to content

Commit

Permalink
bpo-26544: Fixed implementation of platform.libc_ver(). (pythonGH-7684)
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka committed Jul 9, 2018
1 parent f85af03 commit 2a9b8ba
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Doc/library/platform.rst
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ Mac OS Platform
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
to the Python interpreter) is linked. Returns a tuple of strings ``(lib,
Expand Down
24 changes: 13 additions & 11 deletions Lib/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@
b'|'
br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)

def libc_ver(executable=sys.executable, lib='', version='',

chunksize=16384):
def libc_ver(executable=sys.executable, lib='', version='', chunksize=16384):

""" Tries to determine the libc version that the file executable
(which defaults to the Python interpreter) is linked against.
Expand All @@ -157,6 +155,7 @@ def libc_ver(executable=sys.executable, lib='', version='',
The file is read and scanned in chunks of chunksize bytes.
"""
from distutils.version import LooseVersion as V
if hasattr(os.path, 'realpath'):
# Python 2.2 introduced os.path.realpath(); it is used
# here to work around problems with Cygwin not being
Expand All @@ -165,17 +164,19 @@ def libc_ver(executable=sys.executable, lib='', version='',
with open(executable, 'rb') as f:
binary = f.read(chunksize)
pos = 0
while 1:
while pos < len(binary):
if b'libc' in binary or b'GLIBC' in binary:
m = _libc_search.search(binary, pos)
else:
m = None
if not m:
binary = f.read(chunksize)
if not binary:
if not m or m.end() == len(binary):
chunk = f.read(chunksize)
if chunk:
binary = binary[max(pos, len(binary) - 1000):] + chunk
pos = 0
continue
if not m:
break
pos = 0
continue
libcinit, glibc, glibcversion, so, threads, soversion = [
s.decode('latin1') if s is not None else s
for s in m.groups()]
Expand All @@ -185,12 +186,12 @@ def libc_ver(executable=sys.executable, lib='', version='',
if lib != 'glibc':
lib = 'glibc'
version = glibcversion
elif glibcversion > version:
elif V(glibcversion) > V(version):
version = glibcversion
elif so:
if lib != 'glibc':
lib = 'libc'
if soversion and soversion > version:
if soversion and (not version or V(soversion) > V(version)):
version = soversion
if threads and version[-len(threads):] != threads:
version = version + threads
Expand Down Expand Up @@ -253,6 +254,7 @@ def popen(cmd, mode='r', bufsize=-1):
warnings.warn('use os.popen instead', DeprecationWarning, stacklevel=2)
return os.popen(cmd, mode, bufsize)


def _norm_version(version, build=''):

""" Normalize the version and build strings and return a single
Expand Down
8 changes: 7 additions & 1 deletion Lib/test/test_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ def test_mac_ver_with_fork(self):
self.assertEqual(sts, 0)

def test_libc_ver(self):
import os
if os.path.isdir(sys.executable) and \
os.path.exists(sys.executable+'.exe'):
# Cygwin horror
Expand All @@ -269,6 +268,13 @@ def test_libc_ver(self):
executable = sys.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):
mswindows = (sys.platform == "win32")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed implementation of :func:`platform.libc_ver`. It almost always returned
version '2.9' for glibc.

0 comments on commit 2a9b8ba

Please sign in to comment.