From 6225bb45dc36f32c068ec55ac95edf47a056ee3a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Fri, 14 Feb 2025 14:08:33 -0600 Subject: [PATCH] Preserve original exitval after trap handler. --- tests/sh.test | 3 +++ toys/pending/sh.c | 14 +++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/sh.test b/tests/sh.test index 27555c7a..9b817900 100644 --- a/tests/sh.test +++ b/tests/sh.test @@ -733,6 +733,9 @@ testing "\$'' suppresses variable expansion" \ testing 'if; is a syntax error but if $EMPTY; is not' \ 'if $NONE; then echo hello; fi' 'hello\n' '' '' +testing 'trap1' $'trap \'echo T=$?;false\' USR1;kill -s usr1 $$;echo A=$?' \ + 'T=0\nA=0\n' '' '' + # TODO finish variable list from shell init # $# $? $- $! $0 # $$ diff --git a/toys/pending/sh.c b/toys/pending/sh.c index 22ebebd3..be064b1c 100644 --- a/toys/pending/sh.c +++ b/toys/pending/sh.c @@ -1412,8 +1412,9 @@ static void end_fcall(void) sigset_t set; sigemptyset(&set); - sigaddset(&set, TT.ff->signal); + sigaddset(&set, TT.ff->signal>>8); sigprocmask(SIG_UNBLOCK, &set, 0); + toys.exitval = TT.ff->signal&255; } free(dlist_pop(&TT.ff)); @@ -2804,10 +2805,12 @@ static void signify(int sig, char *throw) if (throw && !*throw) throw = 0, ign = SIG_IGN; // If we're replacing a running trap handler, garbe collect in fcall pop. - for (ff = TT.ff; ff && ff!=TT.ff->prev; ff = ff->next) if (ff->signal==sig) { - push_arg(&ff->delete, TT.traps[sig]); - TT.traps[sig] = 0; - break; + for (ff = TT.ff; ff && ff!=TT.ff->prev; ff = ff->next) { + if (ff->signal>>8==sig) { + push_arg(&ff->delete, TT.traps[sig]); + TT.traps[sig] = 0; + break; + } } free(TT.traps[sig]); TT.traps[sig] = throw; @@ -3772,6 +3775,7 @@ static void run_lines(void) dl = dlist_pop(&TT.nextsig); sigprocmask(SIG_SETMASK, &set, 0); ss = TT.traps[call_function()->signal = (long)dl->data]; + TT.ff->signal = (TT.ff->signal<<8)|(toys.exitval&255); free(dl); TT.ff->source = fmemopen(ss, strlen(ss), "r"); } -- 2.39.5