2015-05-09 8 views
0

我不敢发邮件给distutils邮件列表,因为我很确定我在做一个愚蠢的误解。distutils中的_spawn_posix总会产生错误吗?

下面是函数_spawn_posix在2.7.9版本distutils

def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): 
    log.info(' '.join(cmd)) 
    if dry_run: 
     return 
    executable = cmd[0] 
    exec_fn = search_path and os.execvp or os.execv 
    env = None 
    if sys.platform == 'darwin': 
     global _cfg_target, _cfg_target_split 
     if _cfg_target is None: 
      _cfg_target = sysconfig.get_config_var(
            'MACOSX_DEPLOYMENT_TARGET') or '' 
      if _cfg_target: 
       _cfg_target_split = [int(x) for x in _cfg_target.split('.')] 
     if _cfg_target: 
      # ensure that the deployment target of build process is not less 
      # than that used when the interpreter was built. This ensures 
      # extension modules are built with correct compatibility values 
      cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) 
      if _cfg_target_split > [int(x) for x in cur_target.split('.')]: 
       my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' 
          'now "%s" but "%s" during configure' 
           % (cur_target, _cfg_target)) 
       raise DistutilsPlatformError(my_msg) 
      env = dict(os.environ, 
         MACOSX_DEPLOYMENT_TARGET=cur_target) 
      exec_fn = search_path and os.execvpe or os.execve 
    pid = os.fork() 

    if pid == 0: # in the child 
     try: 
      if env is None: 
       exec_fn(executable, cmd) 
      else: 
       exec_fn(executable, cmd, env) 
     except OSError, e: 
      if not DEBUG: 
       cmd = executable 
      sys.stderr.write("unable to execute %r: %s\n" % 
          (cmd, e.strerror)) 
      os._exit(1) 

     if not DEBUG: 
      cmd = executable 
     sys.stderr.write("unable to execute %r for unknown reasons" % cmd) 
     os._exit(1) 
    else: # in the parent 
     # Loop until the child either exits or is terminated by a signal 
     # (ie. keep waiting if it's merely stopped) 
     while 1: 
      try: 
       pid, status = os.waitpid(pid, 0) 
      except OSError, exc: 
       import errno 
       if exc.errno == errno.EINTR: 
        continue 
       if not DEBUG: 
        cmd = executable 
       raise DistutilsExecError, \ 
         "command %r failed: %s" % (cmd, exc[-1]) 
      if os.WIFSIGNALED(status): 
       if not DEBUG: 
        cmd = executable 
       raise DistutilsExecError, \ 
         "command %r terminated by signal %d" % \ 
         (cmd, os.WTERMSIG(status)) 

      elif os.WIFEXITED(status): 
       exit_status = os.WEXITSTATUS(status) 
       if exit_status == 0: 
        return # hey, it succeeded! 
       else: 
        if not DEBUG: 
         cmd = executable 
        raise DistutilsExecError, \ 
          "command %r failed with exit status %d" % \ 
          (cmd, exit_status) 

      elif os.WIFSTOPPED(status): 
       continue 

      else: 
       if not DEBUG: 
        cmd = executable 
       raise DistutilsExecError, \ 
         "unknown error executing %r: termination status %d" % \ 
         (cmd, status) 

显然还有很多在那里。没有人想读这个。所有你需要做的是以下几点:

  • 找到线exec_fn(executable, cmd)。这是整个功能设置执行的路线。它叫os.execvp
  • 请注意,exec_fn仅在pid == 0时才会调用。
  • 注意,当pid == 0,下面的代码被称为:

    try: 
         if env is None: 
          exec_fn(executable, cmd) 
         else: 
          exec_fn(executable, cmd, env) 
        except OSError, e: 
         if not DEBUG: 
          cmd = executable 
         sys.stderr.write("unable to execute %r: %s\n" % 
             (cmd, e.strerror)) 
         os._exit(1) 
    
        if not DEBUG: 
         cmd = executable 
        sys.stderr.write("unable to execute %r for unknown reasons" % cmd) 
        os._exit(1) 
    
  • 注意这里,如果一个OSErrortry块升起,我们退出到系统1(失败)状态。

  • 注意,即使OSError提出,我们仍然退出对系统的1(失败)状态。
  • 在这两种情况下,一直等待孩子完成的父进程会产生一个DistutilsExecError

有人能指出我的错误吗?或者我是否正在使用版本distutils以及一个已经修复的疯狂错误?

回答

0

啊哈,OK,该docs说一下os.execvp和其他os.exec功能

这些功能全部执行新的程序,取代当前进程;他们不回来。 在Unix上,新的可执行文件被加载到当前进程中,并且将具有与调用者相同的进程ID。错误将被报告为OSError异常。

因此,一旦拨打exec_fn,如果成功,则不会执行下面的行。它们已被新的os.execvp过程取代。