Set argv[0] of a subprocess to the command as inserted by the user

Currently Xonsh passes a resolved path of an executable as argv[0]
argument. This changes the argv[0] to containd the command as
inserted by the user. The new behavior is consistent with bash and
other shells. Some programs behave differently in dependence of the
argv[0] value.
See #3617 for details.
This commit is contained in:
David Strobach 2020-06-18 14:59:15 +02:00
parent ebca1e464f
commit 8a021b3727

View file

@ -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]))