aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-02-23 21:09:35 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-02-23 21:09:35 +0000
commit11d0c5d3f69fc689695067cf1512aa652f806bb3 (patch)
tree82d3cd99bd7939dbdb708b9866ca5f6092692767 /shell
parent96dd882fef3ec81174c00f2ec05267cbe67a144c (diff)
downloadbusybox-w32-11d0c5d3f69fc689695067cf1512aa652f806bb3.tar.gz
busybox-w32-11d0c5d3f69fc689695067cf1512aa652f806bb3.tar.bz2
busybox-w32-11d0c5d3f69fc689695067cf1512aa652f806bb3.zip
ash: cleanup part 2.2
git-svn-id: svn://busybox.net/trunk/busybox@17964 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c294
1 files changed, 146 insertions, 148 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 664a6fa16..6f3142952 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2983,6 +2983,7 @@ static int shiftcmd(int, char **);
2983static int setcmd(int, char **); 2983static int setcmd(int, char **);
2984static int nextopt(const char *); 2984static int nextopt(const char *);
2985 2985
2986
2986/* redir.h */ 2987/* redir.h */
2987 2988
2988/* flags passed to redirect */ 2989/* flags passed to redirect */
@@ -2995,13 +2996,6 @@ static void clearredir(int);
2995static int copyfd(int, int); 2996static int copyfd(int, int);
2996static int redirectsafe(union node *, int); 2997static int redirectsafe(union node *, int);
2997 2998
2998/* trap.h */
2999
3000static void clear_traps(void);
3001static void setsignal(int);
3002static int dotrap(void);
3003
3004
3005static int is_safe_applet(char *name) 2999static int is_safe_applet(char *name)
3006{ 3000{
3007 /* It isn't a bug to have non-existent applet here... */ 3001 /* It isn't a bug to have non-existent applet here... */
@@ -3038,6 +3032,7 @@ static int is_safe_applet(char *name)
3038 3032
3039 3033
3040/* ============ Alias handling */ 3034/* ============ Alias handling */
3035
3041#if ENABLE_ASH_ALIAS 3036#if ENABLE_ASH_ALIAS
3042 3037
3043#define ALIASINUSE 1 3038#define ALIASINUSE 1
@@ -3232,6 +3227,7 @@ unaliascmd(int argc, char **argv)
3232 3227
3233 return i; 3228 return i;
3234} 3229}
3230
3235#endif /* ASH_ALIAS */ 3231#endif /* ASH_ALIAS */
3236 3232
3237 3233
@@ -5653,6 +5649,43 @@ static int evalskip; /* set if we are skipping commands */
5653static int skipcount; /* number of levels to skip */ 5649static int skipcount; /* number of levels to skip */
5654static int funcnest; /* depth of function calls */ 5650static int funcnest; /* depth of function calls */
5655 5651
5652/* forward decl way out to parsing code - dotrap needs it */
5653static int evalstring(char *s, int mask);
5654
5655/*
5656 * Called to execute a trap. Perhaps we should avoid entering new trap
5657 * handlers while we are executing a trap handler.
5658 */
5659static int
5660dotrap(void)
5661{
5662 char *p;
5663 char *q;
5664 int i;
5665 int savestatus;
5666 int skip = 0;
5667
5668 savestatus = exitstatus;
5669 pendingsigs = 0;
5670 xbarrier();
5671
5672 for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
5673 if (!*q)
5674 continue;
5675 *q = '\0';
5676
5677 p = trap[i + 1];
5678 if (!p)
5679 continue;
5680 skip = evalstring(p, SKIPEVAL);
5681 exitstatus = savestatus;
5682 if (skip)
5683 break;
5684 }
5685
5686 return skip;
5687}
5688
5656/* forward declarations - evaluation is fairly recursive business... */ 5689/* forward declarations - evaluation is fairly recursive business... */
5657static void evalloop(union node *, int); 5690static void evalloop(union node *, int);
5658static void evalfor(union node *, int); 5691static void evalfor(union node *, int);
@@ -7319,6 +7352,93 @@ setinputstring(char *string)
7319 7352
7320/* ============ jobs.c */ 7353/* ============ jobs.c */
7321 7354
7355/*
7356 * Set the signal handler for the specified signal. The routine figures
7357 * out what it should be set to.
7358 */
7359static void
7360setsignal(int signo)
7361{
7362 int action;
7363 char *t, tsig;
7364 struct sigaction act;
7365
7366 t = trap[signo];
7367 if (t == NULL)
7368 action = S_DFL;
7369 else if (*t != '\0')
7370 action = S_CATCH;
7371 else
7372 action = S_IGN;
7373 if (rootshell && action == S_DFL) {
7374 switch (signo) {
7375 case SIGINT:
7376 if (iflag || minusc || sflag == 0)
7377 action = S_CATCH;
7378 break;
7379 case SIGQUIT:
7380#if DEBUG
7381 if (debug)
7382 break;
7383#endif
7384 /* FALLTHROUGH */
7385 case SIGTERM:
7386 if (iflag)
7387 action = S_IGN;
7388 break;
7389#if JOBS
7390 case SIGTSTP:
7391 case SIGTTOU:
7392 if (mflag)
7393 action = S_IGN;
7394 break;
7395#endif
7396 }
7397 }
7398
7399 t = &sigmode[signo - 1];
7400 tsig = *t;
7401 if (tsig == 0) {
7402 /*
7403 * current setting unknown
7404 */
7405 if (sigaction(signo, 0, &act) == -1) {
7406 /*
7407 * Pretend it worked; maybe we should give a warning
7408 * here, but other shells don't. We don't alter
7409 * sigmode, so that we retry every time.
7410 */
7411 return;
7412 }
7413 if (act.sa_handler == SIG_IGN) {
7414 if (mflag
7415 && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
7416 ) {
7417 tsig = S_IGN; /* don't hard ignore these */
7418 } else
7419 tsig = S_HARD_IGN;
7420 } else {
7421 tsig = S_RESET; /* force to be set */
7422 }
7423 }
7424 if (tsig == S_HARD_IGN || tsig == action)
7425 return;
7426 switch (action) {
7427 case S_CATCH:
7428 act.sa_handler = onsig;
7429 break;
7430 case S_IGN:
7431 act.sa_handler = SIG_IGN;
7432 break;
7433 default:
7434 act.sa_handler = SIG_DFL;
7435 }
7436 *t = action;
7437 act.sa_flags = 0;
7438 sigfillset(&act.sa_mask);
7439 sigaction(signo, &act, 0);
7440}
7441
7322/* mode flags for set_curjob */ 7442/* mode flags for set_curjob */
7323#define CUR_DELETE 2 7443#define CUR_DELETE 2
7324#define CUR_RUNNING 1 7444#define CUR_RUNNING 1
@@ -8497,6 +8617,25 @@ commandtext(union node *n)
8497 * 8617 *
8498 * Called with interrupts off. 8618 * Called with interrupts off.
8499 */ 8619 */
8620/*
8621 * Clear traps on a fork.
8622 */
8623static void
8624clear_traps(void)
8625{
8626 char **tp;
8627
8628 for (tp = trap; tp < &trap[NSIG]; tp++) {
8629 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
8630 INT_OFF;
8631 free(*tp);
8632 *tp = NULL;
8633 if (tp != &trap[0])
8634 setsignal(tp - trap);
8635 INT_ON;
8636 }
8637 }
8638}
8500static void 8639static void
8501forkchild(struct job *jp, union node *n, int mode) 8640forkchild(struct job *jp, union node *n, int mode)
8502{ 8641{
@@ -11264,147 +11403,6 @@ trapcmd(int argc, char **argv)
11264 return 0; 11403 return 0;
11265} 11404}
11266 11405
11267/*
11268 * Clear traps on a fork.
11269 */
11270static void
11271clear_traps(void)
11272{
11273 char **tp;
11274
11275 for (tp = trap; tp < &trap[NSIG]; tp++) {
11276 if (*tp && **tp) { /* trap not NULL or SIG_IGN */
11277 INT_OFF;
11278 free(*tp);
11279 *tp = NULL;
11280 if (tp != &trap[0])
11281 setsignal(tp - trap);
11282 INT_ON;
11283 }
11284 }
11285}
11286
11287/*
11288 * Set the signal handler for the specified signal. The routine figures
11289 * out what it should be set to.
11290 */
11291static void
11292setsignal(int signo)
11293{
11294 int action;
11295 char *t, tsig;
11296 struct sigaction act;
11297
11298 t = trap[signo];
11299 if (t == NULL)
11300 action = S_DFL;
11301 else if (*t != '\0')
11302 action = S_CATCH;
11303 else
11304 action = S_IGN;
11305 if (rootshell && action == S_DFL) {
11306 switch (signo) {
11307 case SIGINT:
11308 if (iflag || minusc || sflag == 0)
11309 action = S_CATCH;
11310 break;
11311 case SIGQUIT:
11312#if DEBUG
11313 if (debug)
11314 break;
11315#endif
11316 /* FALLTHROUGH */
11317 case SIGTERM:
11318 if (iflag)
11319 action = S_IGN;
11320 break;
11321#if JOBS
11322 case SIGTSTP:
11323 case SIGTTOU:
11324 if (mflag)
11325 action = S_IGN;
11326 break;
11327#endif
11328 }
11329 }
11330
11331 t = &sigmode[signo - 1];
11332 tsig = *t;
11333 if (tsig == 0) {
11334 /*
11335 * current setting unknown
11336 */
11337 if (sigaction(signo, 0, &act) == -1) {
11338 /*
11339 * Pretend it worked; maybe we should give a warning
11340 * here, but other shells don't. We don't alter
11341 * sigmode, so that we retry every time.
11342 */
11343 return;
11344 }
11345 if (act.sa_handler == SIG_IGN) {
11346 if (mflag
11347 && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
11348 ) {
11349 tsig = S_IGN; /* don't hard ignore these */
11350 } else
11351 tsig = S_HARD_IGN;
11352 } else {
11353 tsig = S_RESET; /* force to be set */
11354 }
11355 }
11356 if (tsig == S_HARD_IGN || tsig == action)
11357 return;
11358 switch (action) {
11359 case S_CATCH:
11360 act.sa_handler = onsig;
11361 break;
11362 case S_IGN:
11363 act.sa_handler = SIG_IGN;
11364 break;
11365 default:
11366 act.sa_handler = SIG_DFL;
11367 }
11368 *t = action;
11369 act.sa_flags = 0;
11370 sigfillset(&act.sa_mask);
11371 sigaction(signo, &act, 0);
11372}
11373
11374/*
11375 * Called to execute a trap. Perhaps we should avoid entering new trap
11376 * handlers while we are executing a trap handler.
11377 */
11378static int
11379dotrap(void)
11380{
11381 char *p;
11382 char *q;
11383 int i;
11384 int savestatus;
11385 int skip = 0;
11386
11387 savestatus = exitstatus;
11388 pendingsigs = 0;
11389 xbarrier();
11390
11391 for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
11392 if (!*q)
11393 continue;
11394 *q = '\0';
11395
11396 p = trap[i + 1];
11397 if (!p)
11398 continue;
11399 skip = evalstring(p, SKIPEVAL);
11400 exitstatus = savestatus;
11401 if (skip)
11402 break;
11403 }
11404
11405 return skip;
11406}
11407
11408 11406
11409/* ============ Builtins */ 11407/* ============ Builtins */
11410 11408