mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									c3960c28b0
								
							
						
					
					
						commit
						e186e384f4
					
				
					 3 changed files with 71 additions and 11 deletions
				
			
		| 
						 | 
					@ -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):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -194,6 +194,25 @@ def test_mac_ver(self):
 | 
				
			||||||
            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()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue