summaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2016-11-10 10:52:50 +0000
committerRon Yorston <rmy@pobox.com>2016-11-10 10:52:50 +0000
commit550b6b0421d3f74c2c6ff3f8d9dfbc9e7ac22c3a (patch)
tree9c48aa74b3a7ca2d58a740af4eca3bbf7d8e7096 /shell/ash.c
parent87ff6cda847a11db5994205cb068d8deb8c4fdd1 (diff)
parent87e039d0160be16a9a242f74af2e90cdb9f97e12 (diff)
downloadbusybox-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.c34
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
587static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void 603static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void
588force_int_on(void) 604force_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