aboutsummaryrefslogtreecommitdiffhomepage
path: root/exec.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-03-25 16:06:12 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-03-25 16:06:12 -0700
commitb04e874e432fddb603aa023f39433a4be0387d89 (patch)
tree236aa67b79e6934a227672ebe6e94b1082f63d11 /exec.cpp
parentd146f578a49ad4164662a6b1bb9db474c3a1b269 (diff)
Teach fish how to push and pop blocks even in the face of no_exec. All tests finally pass.
Diffstat (limited to 'exec.cpp')
-rw-r--r--exec.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/exec.cpp b/exec.cpp
index 7a8d92a6..633a16e4 100644
--- a/exec.cpp
+++ b/exec.cpp
@@ -538,6 +538,37 @@ static bool can_use_posix_spawn_for_job(const job_t *job, const process_t *proce
return result;
}
+/* What exec does if no_exec is set. This only has to handle block pushing and popping. See #624. */
+static void exec_no_exec(parser_t &parser, const job_t *job)
+{
+ /* Hack hack hack. If this is an 'end' job, then trigger a pop. If this is a job that would create a block, trigger a push. See #624 */
+ const process_t *p = job->first_process;
+ if (p && p->type == INTERNAL_BUILTIN)
+ {
+ const wchar_t *builtin_name_cstr = p->argv0();
+ if (builtin_name_cstr != NULL)
+ {
+ const wcstring builtin_name = builtin_name_cstr;
+ if (contains(builtin_name, L"for", L"function", L"begin", L"switch"))
+ {
+ // The above builtins are the ones that produce an unbalanced block from within their function implementation
+ // This list should be maintained somewhere else
+ parser.push_block(new fake_block_t());
+ }
+ else if (builtin_name == L"end")
+ {
+ if (parser.current_block == NULL || parser.current_block->type() == TOP)
+ {
+ fprintf(stderr, "Warning: not popping the root block\n");
+ }
+ else
+ {
+ parser.pop_block();
+ }
+ }
+ }
+ }
+}
void exec(parser_t &parser, job_t *j)
{
@@ -559,8 +590,10 @@ void exec(parser_t &parser, job_t *j)
CHECK(j,);
CHECK_BLOCK();
- if (no_exec)
+ if (no_exec) {
+ exec_no_exec(parser, j);
return;
+ }
sigemptyset(&chldset);
sigaddset(&chldset, SIGCHLD);
@@ -1269,7 +1302,6 @@ void exec(parser_t &parser, job_t *j)
p->pid = pid;
set_child_group(j, p, 0);
-
}
break;