mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-22 06:10:57 +08:00
Move executable-check to C++
This was already apparently supposed to work, but didn't because we just overrode errno again. This now means that, if a correctly named candidate exists, we don't start the command-not-found handler. See #8804
This commit is contained in:
parent
90d52ee669
commit
f13979bfbb
|
@ -13,12 +13,6 @@ or set -g __fish_added_user_paths
|
|||
#
|
||||
function __fish_default_command_not_found_handler
|
||||
printf (_ "fish: Unknown command: %s\n") (string escape -- $argv[1]) >&2
|
||||
for file in $PATH/$argv[1]
|
||||
if test -e $file -a ! -x $file
|
||||
printf (_ "fish: %s exists but isn't executable\n") (string escape -- $file) >&2
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -13,12 +13,6 @@ end
|
|||
|
||||
function __fish_default_command_not_found_handler
|
||||
printf (_ "fish: Unknown command: %s\n") (string escape -- $argv[1]) >&2
|
||||
for file in $PATH/$argv[1]
|
||||
if test -e $file -a ! -x $file
|
||||
printf (_ "fish: %s exists but isn't executable\n") (string escape -- $file) >&2
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# If an old handler already exists, defer to that.
|
||||
|
|
|
@ -731,8 +731,12 @@ end_execution_reason_t parse_execution_context_t::handle_command_not_found(
|
|||
|
||||
const wchar_t *const cmd = cmd_str.c_str();
|
||||
if (err_code != ENOENT) {
|
||||
// TODO: We currently handle all errors here the same,
|
||||
// but this mainly applies to EACCES. We could also feasibly get:
|
||||
// ELOOP
|
||||
// ENAMETOOLONG
|
||||
return this->report_error(STATUS_NOT_EXECUTABLE, statement,
|
||||
_(L"The file '%ls' is not executable by this user"), cmd);
|
||||
_(L"Unknown command. '%ls' exists but is not an executable file."), cmd);
|
||||
}
|
||||
|
||||
// Handle unrecognized commands with standard command not found handler that can make better
|
||||
|
@ -872,7 +876,7 @@ end_execution_reason_t parse_execution_context_t::populate_plain_process(
|
|||
if (!has_command && !use_implicit_cd) {
|
||||
// No command. If we're --no-execute return okay - it might be a function.
|
||||
if (no_exec()) return end_execution_reason_t::ok;
|
||||
return this->handle_command_not_found(cmd, statement, no_cmd_err_code);
|
||||
return this->handle_command_not_found(path_to_external_command.empty() ? cmd : path_to_external_command, statement, no_cmd_err_code);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,15 @@ static bool path_get_path_core(const wcstring &cmd, wcstring *out_path,
|
|||
return true;
|
||||
}
|
||||
err = EACCES;
|
||||
if (out_path) *out_path = std::move(next_path);
|
||||
} else if (errno != ENOENT && err == ENOENT) {
|
||||
// Keep the first *interesting* error and path around.
|
||||
// ENOENT isn't interesting because not having a file is the normal case.
|
||||
auto tmperr = errno;
|
||||
// Ignore if the parent directory is already inaccessible.
|
||||
if (access(wcs2string(wdirname(next_path)).c_str(), X_OK) != 0) continue;
|
||||
err = tmperr;
|
||||
if (out_path) *out_path = std::move(next_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,7 @@ echo $status
|
|||
set -g PATH .
|
||||
echo banana > foobar
|
||||
foobar --banana
|
||||
# CHECKERR: fish: Unknown command: foobar
|
||||
# CHECKERR: fish: ./foobar exists but isn't executable
|
||||
# CHECKERR: checks/command-not-found.fish (line 37):
|
||||
# CHECKERR: checks/command-not-found.fish (line {{\d+}}): Unknown command. './foobar' exists but is not an executable file.
|
||||
# CHECKERR: foobar --banana
|
||||
# CHECKERR: ^
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user