]> granicus.if.org Git - python/commitdiff
Merged revisions 83085 via svnmerge from
authorRonald Oussoren <ronaldoussoren@mac.com>
Fri, 23 Jul 2010 12:45:53 +0000 (12:45 +0000)
committerRonald Oussoren <ronaldoussoren@mac.com>
Fri, 23 Jul 2010 12:45:53 +0000 (12:45 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/release27-maint

................
  r83085 | ronald.oussoren | 2010-07-23 13:41:00 +0100 (Fri, 23 Jul 2010) | 12 lines

  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.
  ........
................

Lib/platform.py
Lib/test/test_platform.py
Misc/NEWS

index fa13b5fe7807a07aaba865842ae160d83afe6e92..aba2c3308d750168a405ec23d434c7716097870d 100755 (executable)
@@ -717,28 +717,20 @@ 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
         import MacOS
     except ImportError:
-        return release,versioninfo,machine
+        return None
     # Get the infos
     sysv,sysa = _mac_ver_lookup(('sysv','sysa'))
     # Decode the infos
@@ -762,6 +754,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):
index 2177123dae05e055050a91e2adbfb918d5d33772..98d691196a186e94c3e2d0c82e61f4532217bd49 100644 (file)
@@ -120,6 +120,25 @@ class PlatformTest(unittest.TestCase):
             else:
                 self.assertEquals(res[2], 'PowerPC')
 
+
+    if sys.platform == 'darwin':
+        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()
 
index fa9d522b618c9839f44a8a6c424daba60212d2bd..23a52d0ea04f909f2dcd8fc6f9db7d6344f0f4ba 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -81,6 +81,8 @@ C-API
 Library
 -------
 
+- Issue #7895: platform.mac_ver() no longer crashes after calling os.fork()
+
 - Issue #5395: array.fromfile() would raise a spurious EOFError when an
   I/O error occurred.  Now an IOError is raised instead.  Patch by chuck
   (Jan Hosang).