Fix zombie job on failed redirection in exec_job

Closes #5346.
This commit is contained in:
Mahmoud Al-Qudsi 2018-11-18 17:14:08 -06:00
parent a8ce7bad7b
commit d0085cae3c
3 changed files with 14 additions and 13 deletions

View file

@ -990,16 +990,16 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, std::shared_ptr<
return true;
}
void exec_job(parser_t &parser, shared_ptr<job_t> j) {
bool exec_job(parser_t &parser, shared_ptr<job_t> j) {
assert(j && "null job_t passed to exec_job!");
// Set to true if something goes wrong while exec:ing the job, in which case the cleanup code
// will kick in.
// Set to true if something goes wrong while executing the job, in which case the cleanup
// code will kick in.
bool exec_error = false;
// If fish was invoked with -n or --no-execute, then no_exec will be set and we do nothing.
if (no_exec) {
return;
return true;
}
const std::shared_ptr<job_t> parent_job = j->get_parent();
@ -1059,7 +1059,7 @@ void exec_job(parser_t &parser, shared_ptr<job_t> j) {
// 3. The pipe that the next process should read from (courtesy of us)
//
autoclose_fd_t pipe_next_read;
for (std::unique_ptr<process_t> &unique_p : j->processes) {
for (const auto &unique_p : j->processes) {
autoclose_fd_t current_read = std::move(pipe_next_read);
if (!exec_process_in_job(parser, unique_p.get(), j, std::move(current_read),
&pipe_next_read, all_ios, stdout_read_limit)) {
@ -1077,13 +1077,12 @@ void exec_job(parser_t &parser, shared_ptr<job_t> j) {
env_set_one(L"last_pid", ENV_GLOBAL, to_string(j->pgid));
}
if (!exec_error) {
j->continue_job(false);
} else {
// Mark the errored job as not in the foreground. I can't fully justify whether this is the
// right place, but it prevents sanity_lose from complaining.
j->set_flag(job_flag_t::FOREGROUND, false);
if (exec_error) {
return false;
}
j->continue_job(false);
return true;
}
static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst, bool apply_exit_status,

View file

@ -14,7 +14,7 @@
/// Execute the processes specified by \p j in the parser \p.
class job_t;
class parser_t;
void exec_job(parser_t &parser, std::shared_ptr<job_t> j);
bool exec_job(parser_t &parser, std::shared_ptr<job_t> j);
/// Evaluate the expression cmd in a subshell, add the outputs into the list l. On return, the
/// status flag as returned bu \c proc_gfet_last_status will not be changed.

View file

@ -1232,7 +1232,9 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t<g::job> jo
}
// Actually execute the job.
exec_job(*this->parser, job);
if (!exec_job(*this->parser, job)) {
parser->job_remove(job.get());
}
// Only external commands require a new fishd barrier.
if (job_contained_external_command) {