diff options
author | Ron Yorston <rmy@pobox.com> | 2016-11-10 10:52:50 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-11-10 10:52:50 +0000 |
commit | 550b6b0421d3f74c2c6ff3f8d9dfbc9e7ac22c3a (patch) | |
tree | 9c48aa74b3a7ca2d58a740af4eca3bbf7d8e7096 /shell/ash.c | |
parent | 87ff6cda847a11db5994205cb068d8deb8c4fdd1 (diff) | |
parent | 87e039d0160be16a9a242f74af2e90cdb9f97e12 (diff) | |
download | busybox-w32-550b6b0421d3f74c2c6ff3f8d9dfbc9e7ac22c3a.tar.gz busybox-w32-550b6b0421d3f74c2c6ff3f8d9dfbc9e7ac22c3a.tar.bz2 busybox-w32-550b6b0421d3f74c2c6ff3f8d9dfbc9e7ac22c3a.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/shell/ash.c b/shell/ash.c index 29eb44263..d0ccfe982 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #define DEBUG_TIME 0 | 46 | #define DEBUG_TIME 0 |
47 | #define DEBUG_PID 1 | 47 | #define DEBUG_PID 1 |
48 | #define DEBUG_SIG 1 | 48 | #define DEBUG_SIG 1 |
49 | #define DEBUG_INTONOFF 0 | ||
49 | 50 | ||
50 | #define PROFILE 0 | 51 | #define PROFILE 0 |
51 | 52 | ||
@@ -512,10 +513,18 @@ static void exitshell(void) NORETURN; | |||
512 | * much more efficient and portable. (But hacking the kernel is so much | 513 | * much more efficient and portable. (But hacking the kernel is so much |
513 | * more fun than worrying about efficiency and portability. :-)) | 514 | * more fun than worrying about efficiency and portability. :-)) |
514 | */ | 515 | */ |
515 | #define INT_OFF do { \ | 516 | #if DEBUG_INTONOFF |
517 | # define INT_OFF do { \ | ||
518 | TRACE(("%s:%d INT_OFF(%d)\n", __func__, __LINE__, suppress_int)); \ | ||
516 | suppress_int++; \ | 519 | suppress_int++; \ |
517 | barrier(); \ | 520 | barrier(); \ |
518 | } while (0) | 521 | } while (0) |
522 | #else | ||
523 | # define INT_OFF do { \ | ||
524 | suppress_int++; \ | ||
525 | barrier(); \ | ||
526 | } while (0) | ||
527 | #endif | ||
519 | 528 | ||
520 | /* | 529 | /* |
521 | * Called to raise an exception. Since C doesn't include exceptions, we | 530 | * Called to raise an exception. Since C doesn't include exceptions, we |
@@ -583,7 +592,14 @@ int_on(void) | |||
583 | raise_interrupt(); | 592 | raise_interrupt(); |
584 | } | 593 | } |
585 | } | 594 | } |
586 | #define INT_ON int_on() | 595 | #if DEBUG_INTONOFF |
596 | # define INT_ON do { \ | ||
597 | TRACE(("%s:%d INT_ON(%d)\n", __func__, __LINE__, suppress_int-1)); \ | ||
598 | int_on(); \ | ||
599 | } while (0) | ||
600 | #else | ||
601 | # define INT_ON int_on() | ||
602 | #endif | ||
587 | static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void | 603 | static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void |
588 | force_int_on(void) | 604 | force_int_on(void) |
589 | { | 605 | { |
@@ -4225,6 +4241,8 @@ wait_block_or_sig(int *status) | |||
4225 | int pid; | 4241 | int pid; |
4226 | 4242 | ||
4227 | do { | 4243 | do { |
4244 | sigset_t mask; | ||
4245 | |||
4228 | /* Poll all children for changes in their state */ | 4246 | /* Poll all children for changes in their state */ |
4229 | got_sigchld = 0; | 4247 | got_sigchld = 0; |
4230 | /* if job control is active, accept stopped processes too */ | 4248 | /* if job control is active, accept stopped processes too */ |
@@ -4233,14 +4251,13 @@ wait_block_or_sig(int *status) | |||
4233 | break; /* Error (e.g. EINTR, ECHILD) or pid */ | 4251 | break; /* Error (e.g. EINTR, ECHILD) or pid */ |
4234 | 4252 | ||
4235 | /* Children exist, but none are ready. Sleep until interesting signal */ | 4253 | /* Children exist, but none are ready. Sleep until interesting signal */ |
4236 | #if 0 /* dash does this */ | 4254 | #if 1 |
4237 | sigset_t mask; | ||
4238 | sigfillset(&mask); | 4255 | sigfillset(&mask); |
4239 | sigprocmask(SIG_SETMASK, &mask, &mask); | 4256 | sigprocmask(SIG_SETMASK, &mask, &mask); |
4240 | while (!got_sigchld && !pending_sig) | 4257 | while (!got_sigchld && !pending_sig) |
4241 | sigsuspend(&mask); | 4258 | sigsuspend(&mask); |
4242 | sigprocmask(SIG_SETMASK, &mask, NULL); | 4259 | sigprocmask(SIG_SETMASK, &mask, NULL); |
4243 | #else | 4260 | #else /* unsafe: a signal can set pending_sig after check, but before pause() */ |
4244 | while (!got_sigchld && !pending_sig) | 4261 | while (!got_sigchld && !pending_sig) |
4245 | pause(); | 4262 | pause(); |
4246 | #endif | 4263 | #endif |
@@ -4280,9 +4297,9 @@ dowait(int block, struct job *job) | |||
4280 | * either enter a sleeping waitpid() (BUG), or need to busy-loop. | 4297 | * either enter a sleeping waitpid() (BUG), or need to busy-loop. |
4281 | * | 4298 | * |
4282 | * Because of this, we run inside INT_OFF, but use a special routine | 4299 | * Because of this, we run inside INT_OFF, but use a special routine |
4283 | * which combines waitpid() and pause(). | 4300 | * which combines waitpid() and sigsuspend(). |
4284 | * This is the reason why we need to have a handler for SIGCHLD: | 4301 | * This is the reason why we need to have a handler for SIGCHLD: |
4285 | * SIG_DFL handler does not wake pause(). | 4302 | * SIG_DFL handler does not wake sigsuspend(). |
4286 | */ | 4303 | */ |
4287 | INT_OFF; | 4304 | INT_OFF; |
4288 | if (block == DOWAIT_BLOCK_OR_SIG) { | 4305 | if (block == DOWAIT_BLOCK_OR_SIG) { |
@@ -9542,7 +9559,7 @@ mklocal(char *name) | |||
9542 | /* else: | 9559 | /* else: |
9543 | * it's a duplicate "local VAR" declaration, do nothing | 9560 | * it's a duplicate "local VAR" declaration, do nothing |
9544 | */ | 9561 | */ |
9545 | return; | 9562 | goto ret; |
9546 | } | 9563 | } |
9547 | lvp = lvp->next; | 9564 | lvp = lvp->next; |
9548 | } | 9565 | } |
@@ -9581,6 +9598,7 @@ mklocal(char *name) | |||
9581 | lvp->vp = vp; | 9598 | lvp->vp = vp; |
9582 | lvp->next = localvars; | 9599 | lvp->next = localvars; |
9583 | localvars = lvp; | 9600 | localvars = lvp; |
9601 | ret: | ||
9584 | INT_ON; | 9602 | INT_ON; |
9585 | } | 9603 | } |
9586 | 9604 | ||