diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-23 21:09:35 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-23 21:09:35 +0000 |
| commit | fc06f2968be9eb7a30833b63c58132e4eb24c79b (patch) | |
| tree | 82d3cd99bd7939dbdb708b9866ca5f6092692767 | |
| parent | 5651bfc204c02c3e2d687e114f257d7fb9e3c805 (diff) | |
| download | busybox-w32-fc06f2968be9eb7a30833b63c58132e4eb24c79b.tar.gz busybox-w32-fc06f2968be9eb7a30833b63c58132e4eb24c79b.tar.bz2 busybox-w32-fc06f2968be9eb7a30833b63c58132e4eb24c79b.zip | |
ash: cleanup part 2.2
| -rw-r--r-- | shell/ash.c | 294 |
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 **); | |||
| 2983 | static int setcmd(int, char **); | 2983 | static int setcmd(int, char **); |
| 2984 | static int nextopt(const char *); | 2984 | static 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); | |||
| 2995 | static int copyfd(int, int); | 2996 | static int copyfd(int, int); |
| 2996 | static int redirectsafe(union node *, int); | 2997 | static int redirectsafe(union node *, int); |
| 2997 | 2998 | ||
| 2998 | /* trap.h */ | ||
| 2999 | |||
| 3000 | static void clear_traps(void); | ||
| 3001 | static void setsignal(int); | ||
| 3002 | static int dotrap(void); | ||
| 3003 | |||
| 3004 | |||
| 3005 | static int is_safe_applet(char *name) | 2999 | static 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 */ | |||
| 5653 | static int skipcount; /* number of levels to skip */ | 5649 | static int skipcount; /* number of levels to skip */ |
| 5654 | static int funcnest; /* depth of function calls */ | 5650 | static int funcnest; /* depth of function calls */ |
| 5655 | 5651 | ||
| 5652 | /* forward decl way out to parsing code - dotrap needs it */ | ||
| 5653 | static 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 | */ | ||
| 5659 | static int | ||
| 5660 | dotrap(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... */ |
| 5657 | static void evalloop(union node *, int); | 5690 | static void evalloop(union node *, int); |
| 5658 | static void evalfor(union node *, int); | 5691 | static 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 | */ | ||
| 7359 | static void | ||
| 7360 | setsignal(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 | */ | ||
| 8623 | static void | ||
| 8624 | clear_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 | } | ||
| 8500 | static void | 8639 | static void |
| 8501 | forkchild(struct job *jp, union node *n, int mode) | 8640 | forkchild(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 | */ | ||
| 11270 | static void | ||
| 11271 | clear_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 | */ | ||
| 11291 | static void | ||
| 11292 | setsignal(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 | */ | ||
| 11378 | static int | ||
| 11379 | dotrap(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 | ||
