0

distutilsこれをメーリングリストに送るのは怖いです。

バージョン 2.7.9の関数_spawn_posixは次のとおりです。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)
    
  • ここで、ブロックでanOSErrorが発生した場合、ステータス 1 (失敗) でシステムを終了することに注意してください。try

  • OSErroranが発生しなく、ステータス 1 (失敗) でシステムを終了することに注意してください。
  • どちらの場合も、子プロセスの終了を待っていた親プロセスはDistutilsExecError.

誰かが私のエラーを指摘できますか? distutilsそれとも、バグが修正されたのバージョンを使用しているのでしょうか?

4

1 に答える 1

0

ああ、OK、ドキュメントos.execvpはと他のos.exec機能について言っています

これらの関数はすべて新しいプログラムを実行し、現在のプロセスを置き換えます。彼らは戻りません。Unix では、新しい実行可能ファイルが現在のプロセスにロードされ、呼び出し元と同じプロセス ID を持ちます。エラーは OSError 例外として報告されます。

したがって、呼び出しがexec_fn成功すると、その後の行は実行されません。os.execvpそれらは新しいプロセスに置き換えられました。

于 2015-05-09T07:52:55.290 に答える