title: Does _spawn_posix in distutils always raise an error?
body: <p>I'm afraid to send this to the <code>distutils</code> mailing list, because I'm pretty sure I'm making a dumb misinterpretation.</p>
  
  <p>Here is the function <code>_spawn_posix</code> in <code>distutils</code> version 2.7.9:</p>
  
  <pre><code>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 &gt; [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)
  </code></pre>
  
  <p>Obviously there's a lot there.  No one wants to read that.  All you need to do is the following:</p>
  
  <ul>
  <li>Find the line <code>exec_fn(executable, cmd)</code>.  That's the line this whole function is setup to execute.  It calls <code>os.execvp</code>.</li>
  <li>Notice that <code>exec_fn</code> is only called when <code>pid == 0</code>.</li>
  <li><p>Notice that when <code>pid == 0</code>, the following code is called:</p>
  
  <pre><code>    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)
  </code></pre></li>
  <li><p>Notice here that if an <code>OSError</code> is raised in the <code>try</code> block, we exit to the system with a status of 1 (failure).</p></li>
  <li>Notice that even if an <code>OSError</code> is <em>not</em> raised, we <em>still</em> exit to the system with a status of 1 (failure).</li>
  <li>In both cases, the parent process, which has been waiting for the child to finish, raises a <code>DistutilsExecError</code>.</li>
  </ul>
  
  <p>Can someone point out my error?  Or do I happen to be using the version of <code>distutils</code> with a crazy bug that has since been fixed?</p>