From f575c55f5ba16388ea33c970c7732135152e403b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 7 Dec 2019 11:04:00 -0800 Subject: [PATCH] Migrate the logic to make empty functions succeed into the performer This is a more natural place for this logic. --- src/exec.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/exec.cpp b/src/exec.cpp index fb914fdd1..257c0a27b 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -848,10 +848,20 @@ static proc_performer_t get_performer_for_process(process_t *p, const io_chain_t } auto argv = move_to_sharedptr(p->get_argv_array().to_list()); return [=](parser_t &parser, std::shared_ptr parent) { + const auto &ld = parser.libdata(); + auto saved_exec_count = ld.exec_count; const block_t *fb = function_prepare_environment(parser, *argv, *props); internal_exec_helper(parser, props->parsed_source, props->body_node, io_chain, parent); function_restore_environment(parser, fb); - int status = parser.get_last_status(); + + // If the function did not execute anything, treat it as success. + int status; + if (saved_exec_count == ld.exec_count) { + status = 0; + } else { + status = parser.get_last_status(); + } + // FIXME: setting the status this way is dangerous nonsense, we need to decode the // status properly if it was a signal. return proc_status_t::from_exit_code(status); @@ -1015,15 +1025,6 @@ static bool exec_process_in_job(parser_t &parser, process_t *p, std::shared_ptr< allow_buffering)) { return false; } - - // Functions are basically treated as named blocks, and this is the only place we can - // distinguish between them. A block by default does not touch $status, on the other - // hand, calling an empty function should clear $status. - if (parser.libdata().exec_count == cached_exec_count && - p->type == process_type_t::function) { - p->status = proc_status_t::from_exit_code(0); - } - break; }