diff --git a/src/exec.cpp b/src/exec.cpp index 90bcd15d6..ddf612d9d 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -993,21 +993,21 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, std::shared_ptr< // This should show the output as it comes, not buffer until the end. // Any such process (only one per job) will be called the "deferred" process. static process_t *get_deferred_process(const shared_ptr &j) { - // By enumerating in reverse order, we can avoid walking the entire list - for (auto i = j->processes.rbegin(); i != j->processes.rend(); ++i) { - const auto &p = *i; + process_t *last_internal = nullptr; + for (const auto &p : j->processes) { if (p->type == process_type_t::exec) { // No tail reordering for execs. return nullptr; } else if (p->type != process_type_t::external) { - if (p->is_last_in_job) { - return nullptr; - } - debug(1, "Deferring execution of %ls", p->argv0()); - return p.get(); + last_internal = p.get(); } } - return nullptr; + if (last_internal && !last_internal->is_last_in_job) { + // This is the last internal process, and it pipes to an external process. + return last_internal; + } else { + return nullptr; + } } bool exec_job(parser_t &parser, shared_ptr j) { @@ -1086,16 +1086,16 @@ bool exec_job(parser_t &parser, shared_ptr j) { } pipe_next_read = std::move(pipes->read); proc_pipes.write = std::move(pipes->write); - - // The deferred process can never be the last in the job - if (p.get() == deferred_process) { - deferred_pipes = std::move(proc_pipes); - } } - if (!exec_process_in_job(parser, p.get(), j, std::move(proc_pipes), all_ios, deferred_pipes, - stdout_read_limit)) { - exec_error = true; - break; + + if (p.get() == deferred_process) { + deferred_pipes = std::move(proc_pipes); + } else { + if (!exec_process_in_job(parser, p.get(), j, std::move(proc_pipes), all_ios, + deferred_pipes, stdout_read_limit)) { + exec_error = true; + break; + } } } pipe_next_read.close();