Perform extended validation on the executable path, argv, and envp. Mostly to make Python happy, but also to prevent common pitfalls.
(self, cwd, executable, argv, env)
| 548 | |
| 549 | |
| 550 | def _validate(self, cwd, executable, argv, env): |
| 551 | """ |
| 552 | Perform extended validation on the executable path, argv, and envp. |
| 553 | |
| 554 | Mostly to make Python happy, but also to prevent common pitfalls. |
| 555 | """ |
| 556 | |
| 557 | orig_cwd = cwd |
| 558 | cwd = cwd or os.path.curdir |
| 559 | |
| 560 | argv, env = normalize_argv_env(argv, env, self, 4) |
| 561 | if env: |
| 562 | if sys.platform == 'win32': |
| 563 | # Windows requires that all environment variables be strings |
| 564 | env = {_decode(k): _decode(v) for k, v in env} |
| 565 | else: |
| 566 | env = {bytes(k): bytes(v) for k, v in env} |
| 567 | if argv: |
| 568 | argv = list(map(bytes, argv)) |
| 569 | |
| 570 | # |
| 571 | # Validate executable |
| 572 | # |
| 573 | # - Must be an absolute or relative path to the target executable |
| 574 | # - If not, attempt to resolve the name in $PATH |
| 575 | # |
| 576 | if not executable: |
| 577 | if not argv: |
| 578 | self.error("Must specify argv or executable") |
| 579 | executable = argv[0] |
| 580 | |
| 581 | if not isinstance(executable, str): |
| 582 | executable = executable.decode('utf-8') |
| 583 | |
| 584 | path = env and env.get(b'PATH') |
| 585 | if path: |
| 586 | path = path.decode() |
| 587 | else: |
| 588 | path = os.environ.get('PATH') |
| 589 | # Do not change absolute paths to binaries |
| 590 | if executable.startswith(os.path.sep): |
| 591 | pass |
| 592 | |
| 593 | # If there's no path component, it's in $PATH or relative to the |
| 594 | # target directory. |
| 595 | # |
| 596 | # For example, 'sh' |
| 597 | elif os.path.sep not in executable and which(executable, path=path): |
| 598 | executable = which(executable, path=path) |
| 599 | |
| 600 | # Either there is a path component, or the binary is not in $PATH |
| 601 | # For example, 'foo/bar' or 'bar' with cwd=='foo' |
| 602 | elif os.path.sep not in executable: |
| 603 | tmp = executable |
| 604 | executable = os.path.join(cwd, executable) |
| 605 | self.warn_once("Could not find executable %r in $PATH, using %r instead" % (tmp, executable)) |
| 606 | |
| 607 | # There is a path component and user specified a working directory, |