diff --git a/src/exec.cpp b/src/exec.cpp index ee1873fec..55e65c622 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -150,6 +150,7 @@ bool is_thompson_shell_script(const char *path) { // This function never returns, so we take certain liberties with constness. auto envv = const_cast(cenvv); auto argv = const_cast(cargv); + auto cmd2 = const_cast(actual_cmd); execve(actual_cmd, argv, envv); err = errno; @@ -169,6 +170,9 @@ bool is_thompson_shell_script(const char *path) { char interp[] = _PATH_BSHELL; argv2[0] = interp; std::copy_n(argv, 1 + nargs, &argv2[1]); // +1 to copy terminating nullptr + // The command to call should use the full path, + // not what we would pass as argv0. + argv2[1] = cmd2; execve(_PATH_BSHELL, argv2, envv); } } diff --git a/src/postfork.cpp b/src/postfork.cpp index ef6858e1e..d74693342 100644 --- a/src/postfork.cpp +++ b/src/postfork.cpp @@ -350,7 +350,11 @@ maybe_t posix_spawner_t::spawn(const char *cmd, char *const argv[], char std::vector argv2; char interp[] = _PATH_BSHELL; argv2.push_back(interp); - for (size_t i = 0; argv[i] != nullptr; i++) { + // The command to call should use the full path, + // not what we would pass as argv0. + std::string cmd2 = cmd; + argv2.push_back(&cmd2[0]); + for (size_t i = 1; argv[i] != nullptr; i++) { argv2.push_back(argv[i]); } argv2.push_back(nullptr); diff --git a/tests/checks/noshebang.fish b/tests/checks/noshebang.fish index 7826fb947..aa166d68f 100644 --- a/tests/checks/noshebang.fish +++ b/tests/checks/noshebang.fish @@ -80,3 +80,13 @@ runfile #CHECK: 126 #CHECKERR: exec: {{.*}} + +echo 'echo foo' >./- +sleep 0.1 +chmod +x ./- +set PATH ./ $PATH +sleep 0.1 +- +#CHECK: foo +echo $status +#CHECK: 0