2015-05-09 21 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過程取代。