mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 00:14:41 +01:00
Merge pull request #3627 from laloch/argv0
Set argv[0] of a subprocess to the command as inserted by the user
This commit is contained in:
commit
c40c9de9ad
4 changed files with 68 additions and 5 deletions
26
news/argv0.rst
Normal file
26
news/argv0.rst
Normal file
|
@ -0,0 +1,26 @@
|
|||
**Added:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Changed:**
|
||||
|
||||
* Xonsh now launches subprocesses with their ``argv[0]`` argument containing
|
||||
the command exactly as inserted by the user instead of setting it to the
|
||||
resolved path of the executable. This is for consistency with bash and other
|
||||
shells.
|
||||
|
||||
**Deprecated:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Removed:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Security:**
|
||||
|
||||
* <news item>
|
25
tests/bin/checkargv0.xsh
Executable file
25
tests/bin/checkargv0.xsh
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env xonsh
|
||||
res = True
|
||||
script = """import os
|
||||
path = "/proc/{}/cmdline".format(os.getpid())
|
||||
with open(path, "r") as f:
|
||||
lines = f.read().split("\x00")
|
||||
print(lines[0])"""
|
||||
|
||||
def check(python):
|
||||
argv0 = $(@(python) -c @(script)).rstrip()
|
||||
|
||||
if argv0 == python:
|
||||
return True
|
||||
|
||||
print("Unexpected argv[0]: {} != {}".format(argv0, python))
|
||||
return False
|
||||
|
||||
|
||||
python = "python"
|
||||
res &= check(python)
|
||||
|
||||
python = $(which -s python)
|
||||
res &= check(python)
|
||||
if res:
|
||||
print("OK")
|
|
@ -10,7 +10,9 @@ import xonsh
|
|||
from xonsh.lib.os import indir
|
||||
|
||||
from tools import (
|
||||
skip_if_on_msys,
|
||||
skip_if_on_windows,
|
||||
skip_if_on_darwin,
|
||||
ON_WINDOWS,
|
||||
ON_DARWIN,
|
||||
ON_TRAVIS,
|
||||
|
@ -681,3 +683,10 @@ aliases['echo'] = _echo
|
|||
def test_single_command_return_code(cmd, exp_rtn):
|
||||
_, _, rtn = run_xonsh(cmd, single_command=True)
|
||||
assert rtn == exp_rtn
|
||||
|
||||
|
||||
@skip_if_on_msys
|
||||
@skip_if_on_windows
|
||||
@skip_if_on_darwin
|
||||
def test_argv0():
|
||||
check_run_xonsh("checkargv0.xsh", None, "OK\n")
|
||||
|
|
|
@ -206,8 +206,9 @@ def _un_shebang(x):
|
|||
|
||||
def get_script_subproc_command(fname, args):
|
||||
"""Given the name of a script outside the path, returns a list representing
|
||||
an appropriate subprocess command to execute the script. Raises
|
||||
PermissionError if the script is not executable.
|
||||
an appropriate subprocess command to execute the script or None if
|
||||
the argument is not readable or not a script. Raises PermissionError
|
||||
if the script is not executable.
|
||||
"""
|
||||
# make sure file is executable
|
||||
if not os.access(fname, os.X_OK):
|
||||
|
@ -217,10 +218,10 @@ def get_script_subproc_command(fname, args):
|
|||
# execute permissions but not read/write permissions. This enables
|
||||
# things with the SUID set to be run. Needs to come before _is_binary()
|
||||
# is called, because that function tries to read the file.
|
||||
return [fname] + args
|
||||
return None
|
||||
elif _is_binary(fname):
|
||||
# if the file is a binary, we should call it directly
|
||||
return [fname] + args
|
||||
return None
|
||||
if ON_WINDOWS:
|
||||
# Windows can execute various filetypes directly
|
||||
# as given in PATHEXT
|
||||
|
@ -730,7 +731,9 @@ class SubprocSpec:
|
|||
if self.binary_loc is None:
|
||||
return
|
||||
try:
|
||||
self.cmd = get_script_subproc_command(self.binary_loc, self.cmd[1:])
|
||||
scriptcmd = get_script_subproc_command(self.binary_loc, self.cmd[1:])
|
||||
if scriptcmd is not None:
|
||||
self.cmd = scriptcmd
|
||||
except PermissionError:
|
||||
e = "xonsh: subprocess mode: permission denied: {0}"
|
||||
raise XonshError(e.format(self.cmd[0]))
|
||||
|
|
Loading…
Add table
Reference in a new issue