diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-02-23 21:09:35 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-02-23 21:09:35 +0000 |
commit | 11d0c5d3f69fc689695067cf1512aa652f806bb3 (patch) | |
tree | 82d3cd99bd7939dbdb708b9866ca5f6092692767 /shell | |
parent | 96dd882fef3ec81174c00f2ec05267cbe67a144c (diff) | |
download | busybox-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.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 | ||