aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-11-28 15:17:45 +0800
committermaximilian attems <max@stro.at>2011-06-03 18:44:13 +0200
commit69fa392db095e9b0663150b45f4a869ae4d3a8d1 (patch)
tree8bac530da3fc987ff110d1a16e857143d2f39e6a
parent2c5cce537ca6492aaa27d7ffd38b0285ee54aaca (diff)
downloadklibc-69fa392db095e9b0663150b45f4a869ae4d3a8d1.tar.gz
[klibc] [EVAL] Fixed trap/return regression due to SKIPEVAL removal
On Wed, Aug 11, 2010 at 08:06:16AM +0000, Guido Berhoerster wrote: > > with the latest git version of dash trap actions are not > evaluated in the context of a function. > > The following script demonstrates the bug: > ----8<---- > read_timeout () { > saved_traps="$(trap)" > trap 'printf "timed out\n"; eval "${saved_traps}"; return' TERM > ( sleep $1; kill -TERM $$ ) >/dev/null 2>&1 & > timer_pid=$! > read $2 > kill $timer_pid 2>/dev/null > } > > read_timeout 5 value > printf "read \"%s\"\n" "${value:=default}" > > ---->8---- > The return statement in the trap inside the read_timeout function > does not return from the function but rather exits the script. > > With dash 0.5.5.1 it works as expected. This bug was caused by the SKIPEVAL removal. When the SKIPEVAL hack was added to improve set -e support in traps, dotrap was changed to return whether set -e was detected. After the removal of SKIPEVAL, set -e is now handled through exraise. However, dotrap still returned a value which is now incorrectly used to trigger an exraise. This patch removes the vestigial link between dotrap and exraise. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: maximilian attems <max@stro.at>
-rw-r--r--usr/dash/eval.c12
-rw-r--r--usr/dash/trap.c7
-rw-r--r--usr/dash/trap.h2
3 files changed, 12 insertions, 9 deletions
diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index cb331ebeda86e..ae4719a986c5a 100644
--- a/usr/dash/eval.c
+++ b/usr/dash/eval.c
@@ -304,10 +304,16 @@ setstatus:
break;
}
out:
- if ((checkexit & exitstatus) ||
- (pendingsigs && dotrap()) ||
- (flags & EV_EXIT))
+ if (checkexit & exitstatus)
+ goto exexit;
+
+ if (pendingsigs)
+ dotrap();
+
+ if (flags & EV_EXIT) {
+exexit:
exraise(EXEXIT);
+ }
}
diff --git a/usr/dash/trap.c b/usr/dash/trap.c
index 67fda1ddfd58b..0014a1399f48b 100644
--- a/usr/dash/trap.c
+++ b/usr/dash/trap.c
@@ -308,8 +308,7 @@ onsig(int signo)
* handlers while we are executing a trap handler.
*/
-int
-dotrap(void)
+void dotrap(void)
{
char *p;
char *q;
@@ -331,10 +330,8 @@ dotrap(void)
evalstring(p, 0);
exitstatus = savestatus;
if (evalskip)
- return evalskip;
+ break;
}
-
- return 0;
}
diff --git a/usr/dash/trap.h b/usr/dash/trap.h
index f98520fa40aeb..6590be1273e7b 100644
--- a/usr/dash/trap.h
+++ b/usr/dash/trap.h
@@ -46,7 +46,7 @@ void clear_traps(void);
void setsignal(int);
void ignoresig(int);
void onsig(int);
-int dotrap(void);
+void dotrap(void);
void setinteractive(int);
void exitshell(void) __attribute__((__noreturn__));
int decode_signal(const char *, int);