Add $fish_kill_signal to track the signal that terminated a command.

Set to `0` if the command exited normally.
This commit is contained in:
Soumya 2020-03-31 11:27:17 -07:00 committed by Johannes Altmanninger
parent 67eaefeb82
commit 61a9cdaa74
6 changed files with 32 additions and 1 deletions

View file

@ -3,6 +3,7 @@
## Notable improvements and fixes ## Notable improvements and fixes
- `fish --no-execute` will no longer complain about unknown commands or non-matching wildcards, as these could be defined differently at runtime (especially for functions). #977 - `fish --no-execute` will no longer complain about unknown commands or non-matching wildcards, as these could be defined differently at runtime (especially for functions). #977
- `jobs --quiet PID` will no longer print 'no suitable job' if the job for PID does not exist (e.g. because it has finished). #6809 - `jobs --quiet PID` will no longer print 'no suitable job' if the job for PID does not exist (e.g. because it has finished). #6809
- A variable `fish_kill_signal` will be set to the signal that terminated the last command, or `0` if the command exited normally.
### Syntax changes and new commands ### Syntax changes and new commands

View file

@ -1059,6 +1059,8 @@ The user can change the settings of ``fish`` by changing the values of certain v
- ``pipestatus``, a list of exit statuses of all processes that made up the last executed pipe. - ``pipestatus``, a list of exit statuses of all processes that made up the last executed pipe.
- ``fish_kill_signal``, the signal that terminated the previous command, or `0` if the command exited normally.
- ``USER``, the current username. This variable can be changed by the user. - ``USER``, the current username. This variable can be changed by the user.
- ``CMD_DURATION``, the runtime of the last command in milliseconds. - ``CMD_DURATION``, the runtime of the last command in milliseconds.

View file

@ -93,6 +93,7 @@ static const electric_var_t electric_variables[] = {
{L"_", electric_var_t::freadonly}, {L"_", electric_var_t::freadonly},
{L"fish_private_mode", electric_var_t::freadonly}, {L"fish_private_mode", electric_var_t::freadonly},
{L"umask", electric_var_t::fcomputed}, {L"umask", electric_var_t::fcomputed},
{L"fish_kill_signal", electric_var_t::freadonly | electric_var_t::fcomputed},
}; };
const electric_var_t *electric_var_t::for_name(const wcstring &name) { const electric_var_t *electric_var_t::for_name(const wcstring &name) {
@ -685,6 +686,9 @@ maybe_t<env_var_t> env_scoped_impl_t::try_get_computed(const wcstring &key) cons
} else if (key == L"status") { } else if (key == L"status") {
const auto &js = perproc_data().statuses; const auto &js = perproc_data().statuses;
return env_var_t(L"status", to_string(js.status)); return env_var_t(L"status", to_string(js.status));
} else if (key == L"fish_kill_signal") {
const auto &js = perproc_data().statuses;
return env_var_t(L"fish_kill_signal", to_string(js.kill_signal));
} else if (key == L"umask") { } else if (key == L"umask") {
// note umask() is an absurd API: you call it to set the value and it returns the old // note umask() is an absurd API: you call it to set the value and it returns the old
// value. Thus we have to call it twice, to reset the value. The env_lock protects // value. Thus we have to call it twice, to reset the value. The env_lock protects

View file

@ -63,6 +63,10 @@ struct statuses_t {
/// Status of the last job to exit. /// Status of the last job to exit.
int status{0}; int status{0};
/// Signal from the most recent process in the last job that was terminated by a signal.
/// 0 if all processes exited normally.
int kill_signal{0};
/// Pipestatus value. /// Pipestatus value.
std::vector<int> pipestatus{}; std::vector<int> pipestatus{};

View file

@ -187,7 +187,11 @@ statuses_t job_t::get_statuses() const {
statuses_t st{}; statuses_t st{};
st.pipestatus.reserve(processes.size()); st.pipestatus.reserve(processes.size());
for (const auto &p : processes) { for (const auto &p : processes) {
st.pipestatus.push_back(p->status.status_value()); auto status = p->status;
if (status.signal_exited()) {
st.kill_signal = status.signal_code();
}
st.pipestatus.push_back(status.status_value());
} }
int laststatus = st.pipestatus.back(); int laststatus = st.pipestatus.back();
st.status = flags().negate ? !laststatus : laststatus; st.status = flags().negate ? !laststatus : laststatus;

View file

@ -12,6 +12,22 @@ send_line read
expect -re "\\r\\n?read> $" expect -re "\\r\\n?read> $"
exec -- kill -INT $pid exec -- kill -INT $pid
expect "fish_postexec spotted" expect "fish_postexec spotted"
expect_prompt
# Verify that the fish_kill_signal is set.
send_line "functions -e postexec; function postexec --on-event fish_postexec; echo fish_kill_signal \$fish_kill_signal; end"
expect_prompt
send_line "sleep 5"
sleep 0.100
exec -- pkill -INT sleep -P $pid
expect "fish_kill_signal 2"
expect_prompt
send_line "sleep 5"
sleep 0.100
exec -- pkill -TERM sleep -P $pid
expect "fish_kill_signal 15"
expect_prompt
# Verify that sending SIGHUP to the shell, such as will happen when the tty is # Verify that sending SIGHUP to the shell, such as will happen when the tty is
# closed by the terminal, terminates the shell and the foreground command and # closed by the terminal, terminates the shell and the foreground command and