1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 08:28:11 +00:00

Shell: Don't reset 'last_return_code' before running commands

Some variables depend on its value to function correctly.
Fixes the following issue:
    $ false; echo $?
    1
    $ false
    $ echo $?
    128
This commit is contained in:
Ali Mohammad Pur 2022-01-05 08:00:06 +03:30 committed by Andreas Kling
parent 689fe7ddff
commit 310a18da1e
4 changed files with 20 additions and 18 deletions

View file

@ -3564,7 +3564,7 @@ Vector<String> SpecialVariableValue::resolve_as_list(RefPtr<Shell> shell)
switch (m_name) {
case '?':
return { resolve_slices(shell, String::number(shell->last_return_code), m_slices) };
return { resolve_slices(shell, String::number(shell->last_return_code.value_or(0)), m_slices) };
case '$':
return { resolve_slices(shell, String::number(getpid()), m_slices) };
case '*':

View file

@ -1059,7 +1059,7 @@ int Shell::builtin_not(int argc, const char** argv)
}
// In case it was a function.
if (!found_a_job)
exit_code = last_return_code;
exit_code = last_return_code.value_or(0);
return exit_code == 0 ? 1 : 0;
}

View file

@ -469,7 +469,7 @@ bool Shell::invoke_function(const AST::Command& command, int& retval)
(void)function.body->run(*this);
retval = last_return_code;
retval = last_return_code.value_or(0);
return true;
}
@ -536,8 +536,8 @@ int Shell::run_command(StringView cmd, Optional<SourcePosition> source_position_
take_error();
// If we end up executing nothing, let's return a failing exit code.
last_return_code = 128;
if (!last_return_code.has_value())
last_return_code = 0;
ScopedValueRollback source_position_rollback { m_source_position };
if (source_position_override.has_value())
@ -581,7 +581,7 @@ int Shell::run_command(StringView cmd, Optional<SourcePosition> source_position_
return 1;
}
return last_return_code;
return last_return_code.value_or(0);
}
ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
@ -595,7 +595,7 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
if (command.argv.is_empty() && !command.should_immediately_execute_next) {
m_global_redirections.extend(command.redirections);
for (auto& next_in_chain : command.next_chain)
run_tail(command, next_in_chain, last_return_code);
run_tail(command, next_in_chain, last_return_code.value_or(0));
return nullptr;
}
@ -668,9 +668,10 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
for (auto& redirection : command.redirections)
TRY(resolve_redirection(redirection));
if (command.should_wait && run_builtin(command, rewirings, last_return_code)) {
if (int local_return_code = 0; command.should_wait && run_builtin(command, rewirings, local_return_code)) {
last_return_code = local_return_code;
for (auto& next_in_chain : command.next_chain)
run_tail(command, next_in_chain, last_return_code);
run_tail(command, next_in_chain, *last_return_code);
return nullptr;
}
@ -681,9 +682,10 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
for (auto& rewiring : rewirings)
TRY(Core::System::dup2(rewiring.old_fd, rewiring.new_fd));
if (invoke_function(command, last_return_code)) {
if (int local_return_code = 0; invoke_function(command, local_return_code)) {
last_return_code = local_return_code;
for (auto& next_in_chain : command.next_chain)
run_tail(command, next_in_chain, last_return_code);
run_tail(command, next_in_chain, *last_return_code);
return nullptr;
}
}
@ -695,7 +697,7 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
&& command.next_chain.first().node->should_override_execution_in_current_process()) {
for (auto& next_in_chain : command.next_chain)
run_tail(command, next_in_chain, last_return_code);
run_tail(command, next_in_chain, last_return_code.value_or(0));
return nullptr;
}
@ -752,14 +754,14 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
for (auto& next_in_chain : command.next_chain)
run_tail(command, next_in_chain, 0);
_exit(last_return_code);
_exit(last_return_code.value_or(0));
}
if (run_builtin(command, {}, last_return_code))
_exit(last_return_code);
if (int local_return_code = 0; run_builtin(command, {}, local_return_code))
_exit(local_return_code);
if (invoke_function(command, last_return_code))
_exit(last_return_code);
if (int local_return_code = 0; invoke_function(command, local_return_code))
_exit(local_return_code);
// We no longer need the jobs here.
jobs.clear();

View file

@ -212,7 +212,7 @@ public:
char hostname[HostNameSize];
uid_t uid;
int last_return_code { 0 };
Optional<int> last_return_code;
Vector<String> directory_stack;
CircularQueue<String, 8> cd_history; // FIXME: have a configurable cd history length
HashMap<u64, NonnullRefPtr<Job>> jobs;