Merged revisions 83075 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r83075 | ronald.oussoren | 2010-07-23 12:54:59 +0100 (Fri, 23 Jul 2010) | 5 lines

  Fix for issue 7895. Avoid crashing the interpreter
  when calling platform.mac_ver after calling os.fork by
  reading from a system configuration file instead of
  using OSX APIs.
........
This commit is contained in:
Ronald Oussoren 2010-07-23 12:36:59 +00:00
parent b0a3074d92
commit 7180d48781
3 changed files with 71 additions and 11 deletions

View File

@ -696,27 +696,19 @@ def _bcd2str(bcd):
return hex(bcd)[2:]
def mac_ver(release='',versioninfo=('','',''),machine=''):
""" Get MacOS version information and return it as tuple (release,
versioninfo, machine) with versioninfo being a tuple (version,
dev_stage, non_release_version).
Entries which cannot be determined are set to the paramter values
which default to ''. All tuple entries are strings.
def _mac_ver_gestalt():
"""
Thanks to Mark R. Levinson for mailing documentation links and
code examples for this function. Documentation for the
gestalt() API is available online at:
http://www.rgaros.nl/gestalt/
"""
# Check whether the version info module is available
try:
import _gestalt
except ImportError:
return release,versioninfo,machine
return None
# Get the infos
sysv, sysa = _mac_ver_lookup(('sysv','sysa'))
# Decode the infos
@ -740,6 +732,53 @@ def mac_ver(release='',versioninfo=('','',''),machine=''):
machine = {0x1: '68k',
0x2: 'PowerPC',
0xa: 'i386'}.get(sysa,'')
return release,versioninfo,machine
def _mac_ver_xml():
fn = '/System/Library/CoreServices/SystemVersion.plist'
if not os.path.exists(fn):
return None
try:
import plistlib
except ImportError:
return None
pl = plistlib.readPlist(fn)
release = pl['ProductVersion']
versioninfo=('', '', '')
machine = os.uname()[4]
if machine == 'ppc':
# for compatibility with the gestalt based code
machine = 'PowerPC'
return release,versioninfo,machine
def mac_ver(release='',versioninfo=('','',''),machine=''):
""" Get MacOS version information and return it as tuple (release,
versioninfo, machine) with versioninfo being a tuple (version,
dev_stage, non_release_version).
Entries which cannot be determined are set to the paramter values
which default to ''. All tuple entries are strings.
"""
# First try reading the information from an XML file which should
# always be present
info = _mac_ver_xml()
if info is not None:
return info
# If that doesn't work for some reason fall back to reading the
# information using gestalt calls.
info = _mac_ver_gestalt()
if info is not None:
return info
# If that also doesn't work return the default values
return release,versioninfo,machine
def _java_getprop(name,default):

View File

@ -167,6 +167,25 @@ class PlatformTest(unittest.TestCase):
else:
self.assertEquals(res[2], 'PowerPC')
@unittest.skipUnless(sys.platform == 'darwin', "OSX only test")
def test_mac_ver_with_fork(self):
# Issue7895: platform.mac_ver() crashes when using fork without exec
#
# This test checks that the fix for that issue works.
#
pid = os.fork()
if pid == 0:
# child
info = platform.mac_ver()
os._exit(0)
else:
# parent
cpid, sts = os.waitpid(pid, 0)
self.assertEquals(cpid, pid)
self.assertEquals(sts, 0)
def test_dist(self):
res = platform.dist()

View File

@ -78,6 +78,8 @@ C-API
Library
-------
- Issue #7895: platform.mac_ver() no longer crashes after calling os.fork()
- Issue #9323: Fixed a bug in trace.py that resulted in loosing the
name of the script being traced. Patch by Eli Bendersky.