From 3963d943f8a9b4ef89f000b5e1424e63dba920f5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 26 Apr 2010 14:21:27 +0200 Subject: ash: refresh stack pointers after makestrspace in rmescapes Without this, rmescapes sometimes returns random garbage while performing parameter expansions such as ${foo#bar}, in the event that the allocation of r happens to need to reallocate the stack and hence invalidate str and p. I'd love to provide a test case but unfortunately it's dependent on exact stack layout, so I don't have anything simpler than the situation described in https://bugs.launchpad.net/ubuntu/+source/partman-base/+bug/527401/comments/23 which involved a sequence of foo="${foo#*, }" expansions on a long string inside our RAID configuration tool. The same fix has been in dash since 2007-09-26, contributed by Roy Marples . I actually came up with it independently almost to the character, but then synced it up with the variable naming used in dash when I noticed that change afterwards. Signed-off-by: Colin Watson Signed-off-by: Denys Vlasenko --- shell/ash.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 9d55f892e..ec5e0b8c7 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -5425,7 +5425,11 @@ rmescapes(char *str, int flag) size_t fulllen = len + strlen(p) + 1; if (flag & RMESCAPE_GROW) { + int strloc = str - (char *)stackblock(); r = makestrspace(fulllen, expdest); + /* p and str may be invalidated by makestrspace */ + str = (char *)stackblock() + strloc; + p = str + len; } else if (flag & RMESCAPE_HEAP) { r = ckmalloc(fulllen); } else { -- cgit v1.2.3-55-g6feb From 5055a9f98999d3a6c2f4d043a85f6c2d6fb7eaf2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 14 May 2010 04:08:20 +0200 Subject: cttyhack: don't do anything if ctty is already available function old new delta cttyhack_main 244 269 +25 Signed-off-by: Denys Vlasenko --- shell/cttyhack.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'shell') diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 572a3af03..bde2acdc9 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c @@ -53,23 +53,32 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) } strcpy(console, "/dev/tty"); - if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { - /* this is a serial console */ - sprintf(console + 8, "S%d", u.sr.line); - } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { - /* this is linux virtual tty */ - sprintf(console + 8, "S%d" + 1, u.vt.v_active); - } - - if (console[8]) { - fd = xopen(console, O_RDWR); - //bb_error_msg("switching to '%s'", console); - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - while (fd > 2) close(fd--); - /* Some other session may have it as ctty. Steal it from them */ - ioctl(0, TIOCSCTTY, 1); + fd = open(console, O_RDWR); + if (fd >= 0) { + /* We already have ctty, nothing to do */ + close(fd); + } else { + /* We don't have ctty (or don't have "/dev/tty" node...) */ + if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { + /* this is a serial console */ + sprintf(console + 8, "S%d", u.sr.line); + } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { + /* this is linux virtual tty */ + sprintf(console + 8, "S%d" + 1, u.vt.v_active); + } + if (console[8]) { + fd = xopen(console, O_RDWR); + //bb_error_msg("switching to '%s'", console); + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + while (fd > 2) + close(fd--); + /* Some other session may have it as ctty, + * steal it from them: + */ + ioctl(0, TIOCSCTTY, 1); + } } BB_EXECVP(argv[0], argv); -- cgit v1.2.3-55-g6feb From b367bb2a620d3c349b0a61b949a6ebca32bf5395 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 15 May 2010 20:43:07 +0200 Subject: cttyhack: document the need to setsid function old new delta packed_usage 26988 27057 +69 Signed-off-by: Denys Vlasenko --- include/usage.h | 12 ++++++++++-- shell/Config.in | 15 +++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'shell') diff --git a/include/usage.h b/include/usage.h index 9d9ad008b..be52f187f 100644 --- a/include/usage.h +++ b/include/usage.h @@ -649,8 +649,16 @@ "\n -S SALT" \ ) \ -#define cttyhack_trivial_usage NOUSAGE_STR -#define cttyhack_full_usage "" +#define cttyhack_trivial_usage \ + "PROG ARGS" +#define cttyhack_full_usage "\n\n" \ + "Give PROG a controlling tty if possible." \ + "\nExample for /etc/inittab (for busybox init):" \ + "\n ::respawn:/bin/cttyhack /bin/sh" \ + "\nGiving controlling tty to shell running with PID 1:" \ + "\n $ exec cttyhack sh" \ + "\nStarting an interative shell from boot shell script:" \ + "\n setsid cttyhack sh" \ #define cut_trivial_usage \ "[OPTIONS] [FILE]..." diff --git a/shell/Config.in b/shell/Config.in index 3b1650615..36a931715 100644 --- a/shell/Config.in +++ b/shell/Config.in @@ -354,9 +354,20 @@ config CTTYHACK It analyzes stdin with various ioctls, trying to determine whether it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line). If it detects one, it closes stdin/out/err and reopens that device. - Then it executes given program. Usage example for /etc/inittab - (for busybox init): + Then it executes given program. Opening the device will make + that device a controlling tty. This may require cttyhack + to be a session leader. + + Example for /etc/inittab (for busybox init): ::respawn:/bin/cttyhack /bin/sh + Giving controlling tty to shell running with PID 1: + + $ exec cttyhack sh + + Starting an interative shell from boot shell script: + + setsid cttyhack sh + endmenu -- cgit v1.2.3-55-g6feb From 8806d64acd621cb5fd65b6a512cb6dc99079ca4d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 16 May 2010 02:36:18 +0200 Subject: hush: mention PPID, RANDOM support Signed-off-by: Denys Vlasenko --- shell/hush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 9b15efb30..07cacbfc9 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -57,7 +57,7 @@ * * TODOs: * grep for "TODO" and fix (some of them are easy) - * special variables (done: PWD) + * special variables (done: PWD, PPID, RANDOM) * follow IFS rules more precisely, including update semantics * export builtin should be special, its arguments are assignments * and therefore expansion of them should be "one-word" expansion: -- cgit v1.2.3-55-g6feb From 27ff681cfa573ce2a63b35c48047f1d7adcb1f02 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 02:56:18 +0200 Subject: ash: add two testcases for (not yet fixed) ash bugs Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/source2.right | 1 + shell/ash_test/ash-misc/source2.tests | 4 ++++ shell/ash_test/ash-signals/signal5.right | 12 ++++++++++++ shell/ash_test/ash-signals/signal5.tests | 14 ++++++++++++++ 4 files changed, 31 insertions(+) create mode 100644 shell/ash_test/ash-misc/source2.right create mode 100755 shell/ash_test/ash-misc/source2.tests create mode 100644 shell/ash_test/ash-signals/signal5.right create mode 100755 shell/ash_test/ash-signals/signal5.tests (limited to 'shell') diff --git a/shell/ash_test/ash-misc/source2.right b/shell/ash_test/ash-misc/source2.right new file mode 100644 index 000000000..ce7171c87 --- /dev/null +++ b/shell/ash_test/ash-misc/source2.right @@ -0,0 +1 @@ +Done: 0 diff --git a/shell/ash_test/ash-misc/source2.tests b/shell/ash_test/ash-misc/source2.tests new file mode 100755 index 000000000..ab63247ef --- /dev/null +++ b/shell/ash_test/ash-misc/source2.tests @@ -0,0 +1,4 @@ +# Not fixed yet +false +. /dev/null +echo Done: $? diff --git a/shell/ash_test/ash-signals/signal5.right b/shell/ash_test/ash-signals/signal5.right new file mode 100644 index 000000000..35fcbd63d --- /dev/null +++ b/shell/ash_test/ash-signals/signal5.right @@ -0,0 +1,12 @@ +Waiting +sleeping for 1 sec +sleeping for 2 sec +1 sec passed, sending USR1 to parent +USR1 received +Wait exit code: 138 +Waiting +2 sec passed, sending USR1 to parent +USR1 received +Wait exit code: 138 +Waiting +Wait returned 0 diff --git a/shell/ash_test/ash-signals/signal5.tests b/shell/ash_test/ash-signals/signal5.tests new file mode 100755 index 000000000..b75b14917 --- /dev/null +++ b/shell/ash_test/ash-signals/signal5.tests @@ -0,0 +1,14 @@ +# Not fixed yet +trap "echo USR1 received" USR1 +stub() { + echo "sleeping for $1 sec" + sleep $1 + echo "$1 sec passed, sending USR1 to parent" + kill -USR1 $$ +} +stub 2 & +stub 1 & +until { echo "Waiting"; wait; } do + echo "Wait exit code: $?" +done +echo "Wait returned 0" -- cgit v1.2.3-55-g6feb From 7c1ed9fbdedb6cd038df11322a82ac7aea412524 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 04:42:40 +0200 Subject: ash: fix signal5.tests Signed-off-by: Denys Vlasenko --- shell/ash.c | 17 ++++++++++++----- shell/ash_test/ash-signals/signal5.tests | 1 - 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index ec5e0b8c7..ef22da1b6 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -3874,9 +3874,9 @@ dowait(int wait_flags, struct job *job) } static int -blocking_wait_with_raise_on_sig(struct job *job) +blocking_wait_with_raise_on_sig(void) { - pid_t pid = dowait(DOWAIT_BLOCK, job); + pid_t pid = dowait(DOWAIT_BLOCK, NULL); if (pid <= 0 && pending_sig) raise_exception(EXSIG); return pid; @@ -4069,14 +4069,21 @@ waitcmd(int argc UNUSED_PARAM, char **argv) jp->waited = 1; jp = jp->prev_job; } + blocking_wait_with_raise_on_sig(); /* man bash: * "When bash is waiting for an asynchronous command via * the wait builtin, the reception of a signal for which a trap * has been set will cause the wait builtin to return immediately * with an exit status greater than 128, immediately after which * the trap is executed." - * Do we do it that way? */ - blocking_wait_with_raise_on_sig(NULL); + * + * blocking_wait_with_raise_on_sig raises signal handlers + * if it gets no pid (pid < 0). However, + * if child sends us a signal *and immediately exits*, + * blocking_wait_with_raise_on_sig gets pid > 0 + * and does not handle pending_sig. Check this case: */ + if (pending_sig) + raise_exception(EXSIG); } } @@ -4096,7 +4103,7 @@ waitcmd(int argc UNUSED_PARAM, char **argv) job = getjob(*argv, 0); /* loop until process terminated or stopped */ while (job->state == JOBRUNNING) - blocking_wait_with_raise_on_sig(NULL); + blocking_wait_with_raise_on_sig(); job->waited = 1; retval = getstatus(job); repeat: ; diff --git a/shell/ash_test/ash-signals/signal5.tests b/shell/ash_test/ash-signals/signal5.tests index b75b14917..5003180f7 100755 --- a/shell/ash_test/ash-signals/signal5.tests +++ b/shell/ash_test/ash-signals/signal5.tests @@ -1,4 +1,3 @@ -# Not fixed yet trap "echo USR1 received" USR1 stub() { echo "sleeping for $1 sec" -- cgit v1.2.3-55-g6feb From 0f01b00d742f92061cbbd9e95d1cd0368c4d2a4c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 04:57:55 +0200 Subject: add two more tests which currently fail Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-signals/signal6.right | 2 ++ shell/ash_test/ash-signals/signal6.tests | 3 +++ shell/hush_test/hush-bugs/parse_err.right | 2 ++ shell/hush_test/hush-bugs/parse_err.tests | 3 +++ 4 files changed, 10 insertions(+) create mode 100644 shell/ash_test/ash-signals/signal6.right create mode 100755 shell/ash_test/ash-signals/signal6.tests create mode 100644 shell/hush_test/hush-bugs/parse_err.right create mode 100755 shell/hush_test/hush-bugs/parse_err.tests (limited to 'shell') diff --git a/shell/ash_test/ash-signals/signal6.right b/shell/ash_test/ash-signals/signal6.right new file mode 100644 index 000000000..df4d9306a --- /dev/null +++ b/shell/ash_test/ash-signals/signal6.right @@ -0,0 +1,2 @@ +got TERM +Done: 0 diff --git a/shell/ash_test/ash-signals/signal6.tests b/shell/ash_test/ash-signals/signal6.tests new file mode 100755 index 000000000..ffeded2a5 --- /dev/null +++ b/shell/ash_test/ash-signals/signal6.tests @@ -0,0 +1,3 @@ +# Bug: TERM does not trigger in the child +{ trap "echo got TERM" TERM; sleep 3; }& sleep 1; kill $!; wait +echo Done: $? diff --git a/shell/hush_test/hush-bugs/parse_err.right b/shell/hush_test/hush-bugs/parse_err.right new file mode 100644 index 000000000..df4d9306a --- /dev/null +++ b/shell/hush_test/hush-bugs/parse_err.right @@ -0,0 +1,2 @@ +got TERM +Done: 0 diff --git a/shell/hush_test/hush-bugs/parse_err.tests b/shell/hush_test/hush-bugs/parse_err.tests new file mode 100755 index 000000000..dd7d9ad64 --- /dev/null +++ b/shell/hush_test/hush-bugs/parse_err.tests @@ -0,0 +1,3 @@ +# Bug happens only if there is no space in "}&" +{ trap "echo got TERM" TERM; sleep 3; }& sleep 1; kill $!; wait +echo Done: $? -- cgit v1.2.3-55-g6feb From 3227d3f982e809fd02b37d6274f1c7da0a307cea Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 09:49:47 +0200 Subject: hush: fix hush-bugs/parse_err.tests function old new delta parse_stream 2325 2339 +14 builtin_umask 121 123 +2 builtin_type 116 114 -2 Signed-off-by: Denys Vlasenko --- shell/hush.c | 13 +++++++++---- shell/hush_test/hush-bugs/parse_err.right | 2 -- shell/hush_test/hush-bugs/parse_err.tests | 3 --- shell/hush_test/hush-parsing/group2.right | 2 ++ shell/hush_test/hush-parsing/group2.tests | 3 +++ 5 files changed, 14 insertions(+), 9 deletions(-) delete mode 100644 shell/hush_test/hush-bugs/parse_err.right delete mode 100755 shell/hush_test/hush-bugs/parse_err.tests create mode 100644 shell/hush_test/hush-parsing/group2.right create mode 100755 shell/hush_test/hush-parsing/group2.tests (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 07cacbfc9..1bc0c611d 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6232,10 +6232,15 @@ static struct pipe *parse_stream(char **pstring, is_special = "{}<>;&|()#'" /* special outside of "str" */ "\\$\"" IF_HUSH_TICK("`"); /* always special */ /* Are { and } special here? */ - if (ctx.command->argv /* word [word]{... */ - || dest.length /* word{... */ - || dest.o_quoted /* ""{... */ - || (next != ';' && next != ')' && !strchr(G.ifs, next)) /* {word */ + if (ctx.command->argv /* word [word]{... - non-special */ + || dest.length /* word{... - non-special */ + || dest.o_quoted /* ""{... - non-special */ + || (next != ';' /* }; - special */ + && next != ')' /* }) - special */ + && next != '&' /* }& and }&& ... - special */ + && next != '|' /* }|| ... - special */ + && !strchr(G.ifs, next) /* {word - non-special */ + ) ) { /* They are not special, skip "{}" */ is_special += 2; diff --git a/shell/hush_test/hush-bugs/parse_err.right b/shell/hush_test/hush-bugs/parse_err.right deleted file mode 100644 index df4d9306a..000000000 --- a/shell/hush_test/hush-bugs/parse_err.right +++ /dev/null @@ -1,2 +0,0 @@ -got TERM -Done: 0 diff --git a/shell/hush_test/hush-bugs/parse_err.tests b/shell/hush_test/hush-bugs/parse_err.tests deleted file mode 100755 index dd7d9ad64..000000000 --- a/shell/hush_test/hush-bugs/parse_err.tests +++ /dev/null @@ -1,3 +0,0 @@ -# Bug happens only if there is no space in "}&" -{ trap "echo got TERM" TERM; sleep 3; }& sleep 1; kill $!; wait -echo Done: $? diff --git a/shell/hush_test/hush-parsing/group2.right b/shell/hush_test/hush-parsing/group2.right new file mode 100644 index 000000000..df4d9306a --- /dev/null +++ b/shell/hush_test/hush-parsing/group2.right @@ -0,0 +1,2 @@ +got TERM +Done: 0 diff --git a/shell/hush_test/hush-parsing/group2.tests b/shell/hush_test/hush-parsing/group2.tests new file mode 100755 index 000000000..d99178585 --- /dev/null +++ b/shell/hush_test/hush-parsing/group2.tests @@ -0,0 +1,3 @@ +# Bug was in handling of "}&" without space +{ trap "echo got TERM" TERM; sleep 2; }& sleep 1; kill $!; wait +echo Done: $? -- cgit v1.2.3-55-g6feb From ef215558fa261d0aeb653ea49efebcf2811d59a3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 09:55:13 +0200 Subject: typo fix Signed-off-by: Denys Vlasenko --- include/usage.h | 2 +- shell/Config.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/include/usage.h b/include/usage.h index be52f187f..3fce939bb 100644 --- a/include/usage.h +++ b/include/usage.h @@ -657,7 +657,7 @@ "\n ::respawn:/bin/cttyhack /bin/sh" \ "\nGiving controlling tty to shell running with PID 1:" \ "\n $ exec cttyhack sh" \ - "\nStarting an interative shell from boot shell script:" \ + "\nStarting interactive shell from boot shell script:" \ "\n setsid cttyhack sh" \ #define cut_trivial_usage \ diff --git a/shell/Config.in b/shell/Config.in index 36a931715..cf599dff4 100644 --- a/shell/Config.in +++ b/shell/Config.in @@ -366,7 +366,7 @@ config CTTYHACK $ exec cttyhack sh - Starting an interative shell from boot shell script: + Starting an interactive shell from boot shell script: setsid cttyhack sh -- cgit v1.2.3-55-g6feb From 82dd14a510caf192c90e764f36bf424d647b5376 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 10:10:01 +0200 Subject: ash: use CONFIG_FEATURE_EDITING_MAX_LEN Signed-off-by: Denys Vlasenko --- init/bootchartd.c | 2 +- shell/ash.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'shell') diff --git a/init/bootchartd.c b/init/bootchartd.c index 9faf14d36..d1f9ed30e 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c @@ -57,7 +57,7 @@ /* Globals */ struct globals { - char jiffy_line[sizeof(bb_common_bufsiz1)]; + char jiffy_line[COMMON_BUFSIZE]; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) #define INIT_G() do { } while (0) diff --git a/shell/ash.c b/shell/ash.c index ef22da1b6..75bfbf115 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2589,9 +2589,7 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) /* ============ ... */ -#define IBUFSIZ COMMON_BUFSIZE -/* buffer for top level input file */ -#define basebuf bb_common_bufsiz1 +#define IBUFSIZ (ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 1024) /* Syntax classes */ #define CWORD 0 /* character is nothing special */ @@ -9447,12 +9445,12 @@ preadfd(void) #if ENABLE_FEATURE_EDITING retry: if (!iflag || g_parsefile->fd != STDIN_FILENO) - nr = nonblock_safe_read(g_parsefile->fd, buf, BUFSIZ - 1); + nr = nonblock_safe_read(g_parsefile->fd, buf, IBUFSIZ - 1); else { #if ENABLE_FEATURE_TAB_COMPLETION line_input_state->path_lookup = pathval(); #endif - nr = read_line_input(cmdedit_prompt, buf, BUFSIZ, line_input_state); + nr = read_line_input(cmdedit_prompt, buf, IBUFSIZ, line_input_state); if (nr == 0) { /* Ctrl+C pressed */ if (trap[SIGINT]) { @@ -9469,7 +9467,7 @@ preadfd(void) } } #else - nr = nonblock_safe_read(g_parsefile->fd, buf, BUFSIZ - 1); + nr = nonblock_safe_read(g_parsefile->fd, buf, IBUFSIZ - 1); #endif #if 0 @@ -12728,7 +12726,8 @@ static void init(void) { /* from input.c: */ - basepf.next_to_pgetc = basepf.buf = basebuf; + /* we will never free this */ + basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ); /* from trap.c: */ signal(SIGCHLD, SIG_DFL); -- cgit v1.2.3-55-g6feb From 786cce1871ade4240c629187d6609de155fe3536 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 10:14:20 +0200 Subject: fix false positive in signal5.tests Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-signals/signal5.right | 8 ++++---- shell/ash_test/ash-signals/signal5.tests | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'shell') diff --git a/shell/ash_test/ash-signals/signal5.right b/shell/ash_test/ash-signals/signal5.right index 35fcbd63d..162f56bbc 100644 --- a/shell/ash_test/ash-signals/signal5.right +++ b/shell/ash_test/ash-signals/signal5.right @@ -1,11 +1,11 @@ -Waiting -sleeping for 1 sec +sleeping for 3 sec sleeping for 2 sec -1 sec passed, sending USR1 to parent +Waiting +2 sec passed, sending USR1 to parent USR1 received Wait exit code: 138 Waiting -2 sec passed, sending USR1 to parent +3 sec passed, sending USR1 to parent USR1 received Wait exit code: 138 Waiting diff --git a/shell/ash_test/ash-signals/signal5.tests b/shell/ash_test/ash-signals/signal5.tests index 5003180f7..371120e95 100755 --- a/shell/ash_test/ash-signals/signal5.tests +++ b/shell/ash_test/ash-signals/signal5.tests @@ -5,8 +5,9 @@ stub() { echo "$1 sec passed, sending USR1 to parent" kill -USR1 $$ } +stub 3 & stub 2 & -stub 1 & +sleep 1 until { echo "Waiting"; wait; } do echo "Wait exit code: $?" done -- cgit v1.2.3-55-g6feb From cd10dc40e4057d081caf7676a4fed31977f2d94d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 17:10:46 +0200 Subject: ash: fix ". empty_file" exitcode. +5 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 8 +++++--- shell/ash_test/ash-misc/source2.tests | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 75bfbf115..ef5b2d4c1 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12031,13 +12031,16 @@ dotcmd(int argc, char **argv) { struct strlist *sp; volatile struct shparam saveparam; - int status = 0; for (sp = cmdenviron; sp; sp = sp->next) setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED); + /* "false; . empty_file; echo $?" should print 0, not 1: */ + exitstatus = 0; + if (argv[1]) { /* That's what SVR2 does */ char *fullname = find_dot_file(argv[1]); + argv += 2; argc -= 2; if (argc) { /* argc > 0, argv[0] != NULL */ @@ -12056,9 +12059,8 @@ dotcmd(int argc, char **argv) freeparam(&shellparam); shellparam = saveparam; }; - status = exitstatus; } - return status; + return exitstatus; } static int FAST_FUNC diff --git a/shell/ash_test/ash-misc/source2.tests b/shell/ash_test/ash-misc/source2.tests index ab63247ef..1870cdf7e 100755 --- a/shell/ash_test/ash-misc/source2.tests +++ b/shell/ash_test/ash-misc/source2.tests @@ -1,4 +1,3 @@ -# Not fixed yet false . /dev/null echo Done: $? -- cgit v1.2.3-55-g6feb From 82731b4b7a5634bdee52d98b1a7686e18a861ebc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 17:49:52 +0200 Subject: ash,hush: make "source" a synonym for . if bash compat is on Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 ++ shell/hush.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index ef5b2d4c1..ea813e02f 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -8944,7 +8944,9 @@ static const struct builtincmd builtintab[] = { { BUILTIN_SPEC_REG "return" , returncmd }, { BUILTIN_SPEC_REG "set" , setcmd }, { BUILTIN_SPEC_REG "shift" , shiftcmd }, +#if ENABLE_ASH_BASH_COMPAT { BUILTIN_SPEC_REG "source" , dotcmd }, +#endif #if ENABLE_ASH_BUILTIN_TEST { BUILTIN_REGULAR "test" , testcmd }, #endif diff --git a/shell/hush.c b/shell/hush.c index 1bc0c611d..a88fa055b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -673,6 +673,9 @@ static const struct built_in_command bltins1[] = { #endif BLTIN("set" , builtin_set , "Set/unset positional parameters"), BLTIN("shift" , builtin_shift , "Shift positional parameters"), +#if ENABLE_HUSH_BASH_COMPAT + BLTIN("source" , builtin_source , "Run commands in a file"), +#endif BLTIN("trap" , builtin_trap , "Trap signals"), BLTIN("type" , builtin_type , "Show command type"), BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"), -- cgit v1.2.3-55-g6feb From adc0e20892d55b8c762c6d259d3c87a100aec14d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 18:56:58 +0200 Subject: hush: update bash compat todo comment Signed-off-by: Denys Vlasenko --- shell/hush.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index a88fa055b..e6c083f55 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -39,21 +39,24 @@ * * POSIX syntax not implemented: * aliases - * <(list) and >(list) Process Substitution * Tilde Expansion * - * Bash stuff (optionally enabled): - * &> and >& redirection of stdout+stderr - * Brace Expansion - * reserved words: [[ ]] function select - * substrings ${var:1:5} + * Bash compat TODO: + * redirection of stdout+stderr: &> and >& + * brace expansion: one/{two,three,four} + * reserved words: function select + * advanced test: [[ ]] + * substrings: ${var:1:5} + * process substitution: <(list) and >(list) + * =~: regex operator * let EXPR [EXPR...] * Each EXPR is an arithmetic expression (ARITHMETIC EVALUATION) * If the last arg evaluates to 0, let returns 1; 0 otherwise. * NB: let `echo 'a=a + 1'` - error (IOW: multi-word expansion is used) * ((EXPR)) * The EXPR is evaluated according to ARITHMETIC EVALUATION. - * This is exactly equivalent to let "expression". + * This is exactly equivalent to let "EXPR". + * $[EXPR]: synonym for $((EXPR)) * * TODOs: * grep for "TODO" and fix (some of them are easy) -- cgit v1.2.3-55-g6feb From 0e81e488fdec7d6b1d96439407b8a50737d35929 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 17 May 2010 23:51:00 +0200 Subject: shell/README: describe special builtins Signed-off-by: Denys Vlasenko --- shell/README | 190 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 82 insertions(+), 108 deletions(-) (limited to 'shell') diff --git a/shell/README b/shell/README index 59efe499f..550c712d3 100644 --- a/shell/README +++ b/shell/README @@ -1,108 +1,82 @@ -Various bits of what is known about busybox shells, in no particular order. - -2008-02-14 -ash: does not restore tty pgrp if killed by HUP. Symptom: Midnight Commander -is backgrounded if you started ash under it, and then killed it with HUP. - -2007-11-23 -hush: fixed bogus glob handling; fixed exec <"$1"; added test and echo builtins - -2007-06-13 -hush: exec <"$1" doesn't do parameter subst - -2007-05-24 -hush: environment-related memory leak plugged, with net code size -decrease. - -2007-05-24 -hush: '( echo ${name )' will show syntax error message, but prompt -doesn't return (need to press ). Pressing Ctrl-C, , -'( echo ${name )' again, Ctrl-C segfaults. - -2007-05-21 -hush: environment cannot be handled by libc routines as they are leaky -(by API design and thus unfixable): hush will leak memory in this script, -bash does not: -pid=$$ -while true; do - unset t; - t=111111111111111111111111111111111111111111111111111111111111111111111111 - export t - ps -o vsz,pid,comm | grep " $pid " -done -The fix is to not use setenv/putenv/unsetenv but manipulate env ourself. TODO. -hush: meanwhile, first three command subst bugs mentioned below are fixed. :) - -2007-05-06 -hush: more bugs spotted. Comparison with bash: -bash-3.2# echo "TEST`date;echo;echo`BEST" -TESTSun May 6 09:21:05 CEST 2007BEST [we dont strip eols] -bash-3.2# echo "TEST`echo '$(echo ZZ)'`BEST" -TEST$(echo ZZ)BEST [we execute inner echo] -bash-3.2# echo "TEST`echo "'"`BEST" -TEST'BEST [we totally mess up this one] -bash-3.2# echo `sleep 5` -[Ctrl-C should work, Ctrl-Z should do nothing][we totally mess up this one] -bash-3.2# if true; then -> [Ctrl-C] -bash-3.2# [we re-issue "> "] -bash-3.2# if echo `sleep 5`; then -> true; fi [we execute sleep before "> "] - -2007-05-04 -hush: made ctrl-Z/C work correctly for "while true; do true; done" -(namely, it backgrounds/interrupts entire "while") - -2007-05-03 -hush: new bug spotted: Ctrl-C on "while true; do true; done" doesn't -work right: -# while true; do true; done -[1] 0 true <-- pressing Ctrl-C several times... -[2] 0 true -[3] 0 true -Segmentation fault - -2007-05-03 -hush: update on "sleep 1 | exit 3; echo $?" bug. -parse_stream_outer() repeatedly calls parse_stream(). -parse_stream() is now fixed to stop on ';' in this example, -fixing it (parse_stream_outer() will call parse_stream() 1st time, -execute the parse tree, call parse_stream() 2nd time and execute the tree). -But it's not the end of story. -In more complex situations we _must_ parse way farther before executing. -Example #2: "{ sleep 1 | exit 3; echo $?; ...few_lines... } >file". -Because of redirection, we cannot execute 1st pipe before we parse it all. -We probably need to learn to store $var expressions in parse tree. -Debug printing of parse tree would be nice too. - -2007-04-28 -hush: Ctrl-C and Ctrl-Z for single NOFORK commands are working. -Memory and other resource leaks (opendir) are not addressed -(testcase is "rm -i" interrupted by ctrl-c). - -2007-04-21 -hush: "sleep 5 | sleep 6" + Ctrl-Z + fg seems to work. -"rm -i" + Ctrl-C, "sleep 5" + Ctrl-Z still doesn't work -for SH_STANDALONE case :( - -2007-04-21 -hush: fixed non-backgrounding of "sleep 1 &" and totally broken -"sleep 1 | sleep 2 &". Noticed a bug where successive jobs -get numbers 1,2,3 even when job #1 has exited before job# 2 is started. -(bash reuses #1 in this case) - -2007-04-21 -hush: "sleep 1 | exit 3; echo $?" prints 0 because $? is substituted -_before_ pipe gets executed!! run_list_real() already has "pipe;echo" -parsed and handed to it for execution, so it sees "pipe"; "echo 0". - -2007-04-21 -hush: removed setsid() and made job control sort-of-sometimes-work. -Ctrl-C in "rm -i" works now except for SH_STANDALONE case. -"sleep 1 | exit 3" + "echo $?" works, "sleep 1 | exit 3; echo $?" -shows exitcode 0 (should be 3). "sleep 1 | sleep 2 &" fails horribly. - -2007-04-14 -lash, hush: both do setsid() and as a result don't have ctty! -Ctrl-C doesn't work for any child (try rm -i), etc... -lash: bare ">file" doesn't create a file (hush works) +http://www.opengroup.org/onlinepubs/9699919799/ +Open Group Base Specifications Issue 7 + + +http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html +Shell & Utilities + +It says that any of the standard utilities may be implemented +as a regular shell built-in. It gives a list of utilities which +are usually implemented that way (and some of them can only +be implemented as built-ins, like "alias"): + +alias +bg +cd +command +false +fc +fg +getopts +jobs +kill +newgrp +pwd +read +true +umask +unalias +wait + + +http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html +Shell Command Language + +It says that shell must implement special built-ins. Special built-ins +differ from regular ones by the fact that variable assignments +done on special builtin is *PRESERVED*. That is, + +VAR=VAL special_builtin; echo $VAR + +should print VAL. + +(Another distinction is that an error in special built-in should +abort the shell, but this is not such a critical difference, +and moreover, at least bash's "set" does not follow this rule, +which is even codified in autoconf now...). + +List of special builtins: + +. file +: [argument...] +break [n] +continue [n] +eval [argument...] +exec [command [argument...]] +exit [n] +export name[=word]... +export -p +readonly name[=word]... +readonly -p +return [n] +set [-abCefhmnuvx] [-o option] [argument...] +set [+abCefhmnuvx] [+o option] [argument...] +set -- [argument...] +set -o +set +o +shift [n] +times +trap n [condition...] +trap [action condition...] +unset [-fv] name... + +In practice, no one uses this obscure feature - none of these builtins +gives any special reasons to play such dirty tricks. + +However. This section says that *function invocation* should act +similar to special built-in. That is, variable assignments +done on function invocation should be preserved after function invocation. + +This is significant: it is not unthinkable to want to run a function +with some variables set to special values. But because of the above, +it does not work: variable will "leak" out of the function. -- cgit v1.2.3-55-g6feb From e66cf821cf1e4bd8c1ef28445c0559269f69bab9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 18 May 2010 09:12:53 +0200 Subject: ash,hush: make bare "." set exitcode to 2 function old new delta dotcmd 300 305 +5 builtin_source 176 171 -5 Signed-off-by: Denys Vlasenko --- shell/ash.c | 45 +++++++++++++++++++++++++-------------------- shell/hush.c | 23 ++++++++++++++--------- 2 files changed, 39 insertions(+), 29 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index ea813e02f..641a14035 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12031,37 +12031,42 @@ find_dot_file(char *name) static int FAST_FUNC dotcmd(int argc, char **argv) { + char *fullname; struct strlist *sp; volatile struct shparam saveparam; for (sp = cmdenviron; sp; sp = sp->next) setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED); + if (!argv[1]) { + /* bash says: "bash: .: filename argument required" */ + return 2; /* bash compat */ + } + /* "false; . empty_file; echo $?" should print 0, not 1: */ exitstatus = 0; - if (argv[1]) { /* That's what SVR2 does */ - char *fullname = find_dot_file(argv[1]); + fullname = find_dot_file(argv[1]); - argv += 2; - argc -= 2; - if (argc) { /* argc > 0, argv[0] != NULL */ - saveparam = shellparam; - shellparam.malloced = 0; - shellparam.nparam = argc; - shellparam.p = argv; - }; - - setinputfile(fullname, INPUT_PUSH_FILE); - commandname = fullname; - cmdloop(0); - popfile(); + argv += 2; + argc -= 2; + if (argc) { /* argc > 0, argv[0] != NULL */ + saveparam = shellparam; + shellparam.malloced = 0; + shellparam.nparam = argc; + shellparam.p = argv; + }; + + setinputfile(fullname, INPUT_PUSH_FILE); + commandname = fullname; + cmdloop(0); + popfile(); + + if (argc) { + freeparam(&shellparam); + shellparam = saveparam; + }; - if (argc) { - freeparam(&shellparam); - shellparam = saveparam; - }; - } return exitstatus; } diff --git a/shell/hush.c b/shell/hush.c index e6c083f55..8baccf246 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -7870,21 +7870,26 @@ static int FAST_FUNC builtin_shift(char **argv) static int FAST_FUNC builtin_source(char **argv) { - char *arg_path; + char *arg_path, *filename; FILE *input; save_arg_t sv; #if ENABLE_HUSH_FUNCTIONS smallint sv_flg; #endif - if (*++argv == NULL) - return EXIT_FAILURE; - - if (strchr(*argv, '/') == NULL && (arg_path = find_in_path(*argv)) != NULL) { - input = fopen_for_read(arg_path); - free(arg_path); - } else - input = fopen_or_warn(*argv, "r"); + arg_path = NULL; + filename = *++argv; + if (!filename) { + /* bash says: "bash: .: filename argument required" */ + return 2; /* bash compat */ + } + if (!strchr(filename, '/')) { + arg_path = find_in_path(filename); + if (arg_path) + filename = arg_path; + } + input = fopen_or_warn(filename, "r"); + free(arg_path); if (!input) { /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ return EXIT_FAILURE; -- cgit v1.2.3-55-g6feb From 5e2d572381dd0c354a4463382fe1297c709a8464 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 18 May 2010 14:11:21 +0200 Subject: ash: fix testsuite false positives Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-redir/redir3.tests | 2 +- shell/ash_test/ash-redir/redir7.tests | 2 +- shell/ash_test/ash-redir/redir8.tests | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'shell') diff --git a/shell/ash_test/ash-redir/redir3.tests b/shell/ash_test/ash-redir/redir3.tests index f50a7674c..e37d5e45a 100755 --- a/shell/ash_test/ash-redir/redir3.tests +++ b/shell/ash_test/ash-redir/redir3.tests @@ -1,4 +1,4 @@ -# redirects to closed descriptors should not leave these descriptors" +# redirects to closed descriptors should not leave these descriptors # open afterwards echo TEST 9>/dev/null echo MUST ERROR OUT >&9 diff --git a/shell/ash_test/ash-redir/redir7.tests b/shell/ash_test/ash-redir/redir7.tests index 17d1040e0..ca3979a81 100755 --- a/shell/ash_test/ash-redir/redir7.tests +++ b/shell/ash_test/ash-redir/redir7.tests @@ -7,6 +7,6 @@ echo -e 'echo Ok >uni\x81code' >>unicode.sh echo -e 'cat uni\x81code' >>unicode.sh echo -e 'cat uni?code' >>unicode.sh -. unicode.sh +. ./unicode.sh rm uni*code* echo Done diff --git a/shell/ash_test/ash-redir/redir8.tests b/shell/ash_test/ash-redir/redir8.tests index 32ab607b8..8cb42c0d3 100755 --- a/shell/ash_test/ash-redir/redir8.tests +++ b/shell/ash_test/ash-redir/redir8.tests @@ -10,6 +10,6 @@ echo -e 'v=uni\x81code' >>unicode.sh echo -e 'echo Ok >"$v"' >>unicode.sh echo -e 'cat uni\x81code' >>unicode.sh echo -e 'cat uni?code' >>unicode.sh -. unicode.sh +. ./unicode.sh rm uni*code* echo Done -- cgit v1.2.3-55-g6feb From 51b4a9e2f192c03039f339401026752f6340df25 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 18 May 2010 14:35:20 +0200 Subject: ash: fix var_leak testcase Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-vars/var_leak.right | 3 ++- shell/ash_test/ash-vars/var_leak.tests | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'shell') diff --git a/shell/ash_test/ash-vars/var_leak.right b/shell/ash_test/ash-vars/var_leak.right index 45c5458dd..be78112c8 100644 --- a/shell/ash_test/ash-vars/var_leak.right +++ b/shell/ash_test/ash-vars/var_leak.right @@ -1,2 +1,3 @@ should be empty: '' -should be empty: '' +should be not empty: 'val2' +should be not empty: 'val3' diff --git a/shell/ash_test/ash-vars/var_leak.tests b/shell/ash_test/ash-vars/var_leak.tests index 1b1123fb7..032059295 100755 --- a/shell/ash_test/ash-vars/var_leak.tests +++ b/shell/ash_test/ash-vars/var_leak.tests @@ -1,9 +1,18 @@ -# This currently fails with CONFIG_FEATURE_SH_NOFORK=y +# true is a regular builtin, varibale should not leak out of it +# this currently fails with CONFIG_FEATURE_SH_NOFORK=y VAR='' -VAR=qwe true +VAR=val1 true echo "should be empty: '$VAR'" -# This fails (always) +# ash follows the "special builtin leaks variables" rule here: +# exec is a special builtin. (bash does not do it) VAR='' -VAR=qwe exec 2>&1 -echo "should be empty: '$VAR'" +VAR=val2 exec 2>&1 +echo "should be not empty: '$VAR'" + +# ash follows the "function call is a special builtin" rule here +# (bash does not do it) +f() { true; } +VAR='' +VAR=val3 f +echo "should be not empty: '$VAR'" -- cgit v1.2.3-55-g6feb From 238bf187ba5708bc04065b761ffc98c877043fe4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 18 May 2010 15:49:07 +0200 Subject: ash: fix bug which causes signal6.tests to fail function old new delta trapcmd 271 277 +6 localcmd 277 275 -2 Signed-off-by: Denys Vlasenko --- networking/route.c | 2 +- shell/ash.c | 22 +++++++++++++++------- shell/ash_test/ash-signals/signal6.tests | 1 - 3 files changed, 16 insertions(+), 9 deletions(-) (limited to 'shell') diff --git a/networking/route.c b/networking/route.c index 241be8e09..a3199621a 100644 --- a/networking/route.c +++ b/networking/route.c @@ -178,7 +178,7 @@ static NOINLINE void INET_setroute(int action, char **args) int prefix_len; prefix_len = xatoul_range(prefix+1, 0, 32); - mask_in_addr(rt) = htonl( ~ (0xffffffffUL >> prefix_len)); + mask_in_addr(rt) = htonl( ~(0xffffffffUL >> prefix_len)); *prefix = '\0'; #if HAVE_NEW_ADDRT rt.rt_genmask.sa_family = AF_INET; diff --git a/shell/ash.c b/shell/ash.c index 641a14035..4f2fa756b 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -208,6 +208,7 @@ struct globals_misc { /* indicates specified signal received */ uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */ + uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */ char *trap[NSIG]; char **trap_ptr; /* used only by "trap hack" */ @@ -236,6 +237,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc; #define optlist (G_misc.optlist ) #define sigmode (G_misc.sigmode ) #define gotsig (G_misc.gotsig ) +#define may_have_traps (G_misc.may_have_traps ) #define trap (G_misc.trap ) #define trap_ptr (G_misc.trap_ptr ) #define random_gen (G_misc.random_gen ) @@ -333,7 +335,7 @@ raise_interrupt(void) /* Signal is not automatically unmasked after it is raised, * do it ourself - unmask all signals */ sigprocmask_allsigs(SIG_UNBLOCK); - /* pending_sig = 0; - now done in onsig() */ + /* pending_sig = 0; - now done in signal_handler() */ ex_type = EXSIG; if (gotsig[SIGINT - 1] && !trap[SIGINT]) { @@ -3268,10 +3270,10 @@ ignoresig(int signo) } /* - * Signal handler. Only one usage site - in setsignal() + * Only one usage site - in setsignal() */ static void -onsig(int signo) +signal_handler(int signo) { gotsig[signo - 1] = 1; @@ -3366,7 +3368,7 @@ setsignal(int signo) act.sa_handler = SIG_DFL; switch (new_act) { case S_CATCH: - act.sa_handler = onsig; + act.sa_handler = signal_handler; act.sa_flags = 0; /* matters only if !DFL and !IGN */ sigfillset(&act.sa_mask); /* ditto */ break; @@ -8443,15 +8445,16 @@ evalsubshell(union node *n, int flags) int status; expredir(n->nredir.redirect); - if (!backgnd && flags & EV_EXIT && !trap[0]) + if (!backgnd && (flags & EV_EXIT) && !may_have_traps) goto nofork; INT_OFF; jp = makejob(/*n,*/ 1); if (forkshell(jp, n, backgnd) == 0) { + /* child */ INT_ON; flags |= EV_EXIT; if (backgnd) - flags &=~ EV_TESTED; + flags &= ~EV_TESTED; nofork: redirect(n->nredir.redirect, 0); evaltreenr(n->nredir.n, flags); @@ -9193,16 +9196,19 @@ evalcommand(union node *cmd, int flags) } #endif /* Fork off a child process if necessary. */ - if (!(flags & EV_EXIT) || trap[0]) { + if (!(flags & EV_EXIT) || may_have_traps) { INT_OFF; jp = makejob(/*cmd,*/ 1); if (forkshell(jp, cmd, FORK_FG) != 0) { + /* parent */ exitstatus = waitforjob(jp); INT_ON; TRACE(("forked child exited with %d\n", exitstatus)); break; } + /* child */ FORCE_INT_ON; + /* fall through to exec'ing exeternal program */ } listsetvar(varlist.list, VEXPORT|VSTACK); shellexec(argv, path, cmdentry.u.index); @@ -12349,6 +12355,8 @@ trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) action = ckstrdup(action); } free(trap[signo]); + if (action) + may_have_traps = 1; trap[signo] = action; if (signo != 0) setsignal(signo); diff --git a/shell/ash_test/ash-signals/signal6.tests b/shell/ash_test/ash-signals/signal6.tests index ffeded2a5..3ce151060 100755 --- a/shell/ash_test/ash-signals/signal6.tests +++ b/shell/ash_test/ash-signals/signal6.tests @@ -1,3 +1,2 @@ -# Bug: TERM does not trigger in the child { trap "echo got TERM" TERM; sleep 3; }& sleep 1; kill $!; wait echo Done: $? -- cgit v1.2.3-55-g6feb From c7f95d23f6bc7e17a3b79decf83eb362b389e53a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 18 May 2010 15:52:23 +0200 Subject: typo fix Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 4f2fa756b..d082333ba 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9208,7 +9208,7 @@ evalcommand(union node *cmd, int flags) } /* child */ FORCE_INT_ON; - /* fall through to exec'ing exeternal program */ + /* fall through to exec'ing external program */ } listsetvar(varlist.list, VEXPORT|VSTACK); shellexec(argv, path, cmdentry.u.index); -- cgit v1.2.3-55-g6feb