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 11:54:59 +00:00
parent c3960c28b0
commit e186e384f4
3 changed files with 71 additions and 11 deletions

View File

@ -724,27 +724,19 @@ def _bcd2str(bcd):
return hex(bcd)[2:] return hex(bcd)[2:]
def mac_ver(release='',versioninfo=('','',''),machine=''): def _mac_ver_gestalt():
"""
""" 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.
Thanks to Mark R. Levinson for mailing documentation links and Thanks to Mark R. Levinson for mailing documentation links and
code examples for this function. Documentation for the code examples for this function. Documentation for the
gestalt() API is available online at: gestalt() API is available online at:
http://www.rgaros.nl/gestalt/ http://www.rgaros.nl/gestalt/
""" """
# Check whether the version info module is available # Check whether the version info module is available
try: try:
import _gestalt import _gestalt
except ImportError: except ImportError:
return release,versioninfo,machine return None
# Get the infos # Get the infos
sysv, sysa = _mac_ver_lookup(('sysv','sysa')) sysv, sysa = _mac_ver_lookup(('sysv','sysa'))
# Decode the infos # Decode the infos
@ -768,6 +760,53 @@ def mac_ver(release='',versioninfo=('','',''),machine=''):
machine = {0x1: '68k', machine = {0x1: '68k',
0x2: 'PowerPC', 0x2: 'PowerPC',
0xa: 'i386'}.get(sysa,'') 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 return release,versioninfo,machine
def _java_getprop(name,default): def _java_getprop(name,default):

View File

@ -194,6 +194,25 @@ class PlatformTest(unittest.TestCase):
else: else:
self.assertEquals(res[2], 'PowerPC') 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): def test_dist(self):
res = platform.dist() res = platform.dist()

View File

@ -473,6 +473,8 @@ C-API
Library 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 - Issue #9323: Fixed a bug in trace.py that resulted in loosing the
name of the script being traced. Patch by Eli Bendersky. name of the script being traced. Patch by Eli Bendersky.