diff options
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/shell/ash.c b/shell/ash.c index 408027305..935b67f4e 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -384,10 +384,16 @@ union node; | |||
| 384 | struct strlist; | 384 | struct strlist; |
| 385 | struct job; | 385 | struct job; |
| 386 | 386 | ||
| 387 | #if defined(_WIN64) | ||
| 388 | # define ALIGN64 ALIGNED(16) | ||
| 389 | #else | ||
| 390 | # define ALIGN64 | ||
| 391 | #endif | ||
| 392 | |||
| 387 | struct forkshell { | 393 | struct forkshell { |
| 388 | /* filled by forkshell_copy() */ | 394 | /* filled by forkshell_copy() */ |
| 389 | struct globals_var *gvp; | ||
| 390 | struct globals_misc *gmp; | 395 | struct globals_misc *gmp; |
| 396 | struct globals_var *gvp; | ||
| 391 | struct tblentry **cmdtable; | 397 | struct tblentry **cmdtable; |
| 392 | #if ENABLE_ASH_ALIAS | 398 | #if ENABLE_ASH_ALIAS |
| 393 | struct alias **atab; | 399 | struct alias **atab; |
| @@ -427,7 +433,7 @@ struct forkshell { | |||
| 427 | union node *n; | 433 | union node *n; |
| 428 | char **argv; | 434 | char **argv; |
| 429 | char *path; | 435 | char *path; |
| 430 | }; | 436 | } ALIGN64; |
| 431 | 437 | ||
| 432 | enum { | 438 | enum { |
| 433 | FS_OPENHERE, | 439 | FS_OPENHERE, |
| @@ -674,6 +680,8 @@ struct globals_misc { | |||
| 674 | 680 | ||
| 675 | /* Rarely referenced stuff */ | 681 | /* Rarely referenced stuff */ |
| 676 | 682 | ||
| 683 | struct jmploc main_handler; | ||
| 684 | |||
| 677 | /* Cached supplementary group array (for testing executable'ity of files) */ | 685 | /* Cached supplementary group array (for testing executable'ity of files) */ |
| 678 | struct cached_groupinfo groupinfo; | 686 | struct cached_groupinfo groupinfo; |
| 679 | 687 | ||
| @@ -725,6 +733,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc; | |||
| 725 | #define may_have_traps (G_misc.may_have_traps ) | 733 | #define may_have_traps (G_misc.may_have_traps ) |
| 726 | #define trap (G_misc.trap ) | 734 | #define trap (G_misc.trap ) |
| 727 | #define trap_ptr (G_misc.trap_ptr ) | 735 | #define trap_ptr (G_misc.trap_ptr ) |
| 736 | #define main_handler (G_misc.main_handler ) | ||
| 728 | #define groupinfo (G_misc.groupinfo ) | 737 | #define groupinfo (G_misc.groupinfo ) |
| 729 | #define random_gen (G_misc.random_gen ) | 738 | #define random_gen (G_misc.random_gen ) |
| 730 | #define backgndpid (G_misc.backgndpid ) | 739 | #define backgndpid (G_misc.backgndpid ) |
| @@ -802,6 +811,14 @@ sigclearmask(void) | |||
| 802 | } | 811 | } |
| 803 | #endif | 812 | #endif |
| 804 | 813 | ||
| 814 | /* Reset handler when entering a subshell */ | ||
| 815 | static void | ||
| 816 | reset_exception_handler(void) | ||
| 817 | { | ||
| 818 | exception_handler = &main_handler; | ||
| 819 | } | ||
| 820 | |||
| 821 | |||
| 805 | /* ============ Parser data */ | 822 | /* ============ Parser data */ |
| 806 | 823 | ||
| 807 | /* | 824 | /* |
| @@ -7519,6 +7536,7 @@ evalbackcmd(union node *n, struct backcmd *result | |||
| 7519 | #else | 7536 | #else |
| 7520 | if (forkshell(jp, n, FORK_NOJOB) == 0) { | 7537 | if (forkshell(jp, n, FORK_NOJOB) == 0) { |
| 7521 | /* child */ | 7538 | /* child */ |
| 7539 | reset_exception_handler(); | ||
| 7522 | FORCEINTON; | 7540 | FORCEINTON; |
| 7523 | close(pip[ip]); | 7541 | close(pip[ip]); |
| 7524 | /* ic is index of child end of pipe *and* fd to connect it to */ | 7542 | /* ic is index of child end of pipe *and* fd to connect it to */ |
| @@ -10828,6 +10846,7 @@ evalsubshell(union node *n, int flags) | |||
| 10828 | 10846 | ||
| 10829 | #if ENABLE_PLATFORM_MINGW32 | 10847 | #if ENABLE_PLATFORM_MINGW32 |
| 10830 | if (!backgnd && (flags & EV_EXIT) && !may_have_traps) { | 10848 | if (!backgnd && (flags & EV_EXIT) && !may_have_traps) { |
| 10849 | reset_exception_handler(); | ||
| 10831 | expredir(n->nredir.redirect); | 10850 | expredir(n->nredir.redirect); |
| 10832 | redirect(n->nredir.redirect, 0); | 10851 | redirect(n->nredir.redirect, 0); |
| 10833 | evaltreenr(n->nredir.n, flags); | 10852 | evaltreenr(n->nredir.n, flags); |
| @@ -10856,6 +10875,7 @@ evalsubshell(union node *n, int flags) | |||
| 10856 | if (backgnd) | 10875 | if (backgnd) |
| 10857 | flags &= ~EV_TESTED; | 10876 | flags &= ~EV_TESTED; |
| 10858 | nofork: | 10877 | nofork: |
| 10878 | reset_exception_handler(); | ||
| 10859 | redirect(n->nredir.redirect, 0); | 10879 | redirect(n->nredir.redirect, 0); |
| 10860 | evaltreenr(n->nredir.n, flags); | 10880 | evaltreenr(n->nredir.n, flags); |
| 10861 | /* never returns */ | 10881 | /* never returns */ |
| @@ -10980,6 +11000,7 @@ evalpipe(union node *n, int flags) | |||
| 10980 | #else | 11000 | #else |
| 10981 | if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) { | 11001 | if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) { |
| 10982 | /* child */ | 11002 | /* child */ |
| 11003 | reset_exception_handler(); | ||
| 10983 | INTON; | 11004 | INTON; |
| 10984 | if (pip[1] >= 0) { | 11005 | if (pip[1] >= 0) { |
| 10985 | close(pip[0]); | 11006 | close(pip[0]); |
| @@ -16413,7 +16434,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 16413 | /* note: 'argc' is used only if embedded scripts are enabled */ | 16434 | /* note: 'argc' is used only if embedded scripts are enabled */ |
| 16414 | { | 16435 | { |
| 16415 | volatile smallint state; | 16436 | volatile smallint state; |
| 16416 | struct jmploc jmploc; | ||
| 16417 | struct stackmark smark; | 16437 | struct stackmark smark; |
| 16418 | int login_sh; | 16438 | int login_sh; |
| 16419 | 16439 | ||
| @@ -16447,7 +16467,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 16447 | #endif | 16467 | #endif |
| 16448 | 16468 | ||
| 16449 | state = 0; | 16469 | state = 0; |
| 16450 | if (setjmp(jmploc.loc)) { | 16470 | if (setjmp(main_handler.loc)) { |
| 16451 | smallint e; | 16471 | smallint e; |
| 16452 | smallint s; | 16472 | smallint s; |
| 16453 | 16473 | ||
| @@ -16475,7 +16495,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 16475 | goto state3; | 16495 | goto state3; |
| 16476 | goto state4; | 16496 | goto state4; |
| 16477 | } | 16497 | } |
| 16478 | exception_handler = &jmploc; | 16498 | exception_handler = &main_handler; |
| 16479 | rootpid = getpid(); | 16499 | rootpid = getpid(); |
| 16480 | 16500 | ||
| 16481 | init(); | 16501 | init(); |
| @@ -17323,8 +17343,8 @@ forkshell_size(struct forkshell *fs) | |||
| 17323 | if (fs->fpid == FS_OPENHERE) | 17343 | if (fs->fpid == FS_OPENHERE) |
| 17324 | return ds; | 17344 | return ds; |
| 17325 | 17345 | ||
| 17326 | ds = globals_var_size(ds); | ||
| 17327 | ds = globals_misc_size(ds); | 17346 | ds = globals_misc_size(ds); |
| 17347 | ds = globals_var_size(ds); | ||
| 17328 | ds = cmdtable_size(ds); | 17348 | ds = cmdtable_size(ds); |
| 17329 | 17349 | ||
| 17330 | ds.funcblocksize = calcsize(ds.funcblocksize, fs->n); | 17350 | ds.funcblocksize = calcsize(ds.funcblocksize, fs->n); |
| @@ -17356,11 +17376,11 @@ forkshell_copy(struct forkshell *fs, struct forkshell *new) | |||
| 17356 | if (fs->fpid == FS_OPENHERE) | 17376 | if (fs->fpid == FS_OPENHERE) |
| 17357 | return; | 17377 | return; |
| 17358 | 17378 | ||
| 17359 | new->gvp = globals_var_copy(); | ||
| 17360 | new->gmp = globals_misc_copy(); | 17379 | new->gmp = globals_misc_copy(); |
| 17380 | new->gvp = globals_var_copy(); | ||
| 17361 | new->cmdtable = cmdtable_copy(); | 17381 | new->cmdtable = cmdtable_copy(); |
| 17362 | SAVE_PTR(new->gvp, "gvp", NO_FREE); | ||
| 17363 | SAVE_PTR(new->gmp, "gmp", NO_FREE); | 17382 | SAVE_PTR(new->gmp, "gmp", NO_FREE); |
| 17383 | SAVE_PTR(new->gvp, "gvp", NO_FREE); | ||
| 17364 | SAVE_PTR(new->cmdtable, "cmdtable", NO_FREE); | 17384 | SAVE_PTR(new->cmdtable, "cmdtable", NO_FREE); |
| 17365 | 17385 | ||
| 17366 | new->n = copynode(fs->n); | 17386 | new->n = copynode(fs->n); |
| @@ -17397,7 +17417,7 @@ forkshell_copy(struct forkshell *fs, struct forkshell *new) | |||
| 17397 | 17417 | ||
| 17398 | #if FORKSHELL_DEBUG | 17418 | #if FORKSHELL_DEBUG |
| 17399 | #define NUM_BLOCKS FUNCSTRING | 17419 | #define NUM_BLOCKS FUNCSTRING |
| 17400 | enum {GVP, GMP, CMDTABLE, NODE, ARGV, ATAB, HISTORY, JOBTAB, FUNCSTRING}; | 17420 | enum {GMP, GVP, CMDTABLE, NODE, ARGV, ATAB, HISTORY, JOBTAB, FUNCSTRING}; |
| 17401 | 17421 | ||
| 17402 | /* fp0 and notes can each be NULL */ | 17422 | /* fp0 and notes can each be NULL */ |
| 17403 | static void | 17423 | static void |
| @@ -17462,8 +17482,8 @@ forkshell_print(FILE *fp0, struct forkshell *fs, const char **notes) | |||
| 17462 | lptr[ARGV] = fs->argv ? (char *)fs->argv : lptr[ATAB]; | 17482 | lptr[ARGV] = fs->argv ? (char *)fs->argv : lptr[ATAB]; |
| 17463 | lptr[NODE] = fs->n ? (char *)fs->n : lptr[ARGV]; | 17483 | lptr[NODE] = fs->n ? (char *)fs->n : lptr[ARGV]; |
| 17464 | lptr[CMDTABLE] = (char *)fs->cmdtable; | 17484 | lptr[CMDTABLE] = (char *)fs->cmdtable; |
| 17465 | lptr[GMP] = (char *)fs->gmp; | ||
| 17466 | lptr[GVP] = (char *)fs->gvp; | 17485 | lptr[GVP] = (char *)fs->gvp; |
| 17486 | lptr[GMP] = (char *)fs->gmp; | ||
| 17467 | 17487 | ||
| 17468 | fprintf(fp, "funcblocksize %6d = ", fs->funcblocksize); | 17488 | fprintf(fp, "funcblocksize %6d = ", fs->funcblocksize); |
| 17469 | total = 0; | 17489 | total = 0; |
| @@ -17605,7 +17625,6 @@ forkshell_init(const char *idstr) | |||
| 17605 | int i; | 17625 | int i; |
| 17606 | char **ptr; | 17626 | char **ptr; |
| 17607 | char *lrelocate; | 17627 | char *lrelocate; |
| 17608 | struct jmploc jmploc; | ||
| 17609 | 17628 | ||
| 17610 | if (sscanf(idstr, "%p", &map_handle) != 1) | 17629 | if (sscanf(idstr, "%p", &map_handle) != 1) |
| 17611 | return; | 17630 | return; |
| @@ -17644,8 +17663,8 @@ forkshell_init(const char *idstr) | |||
| 17644 | fs->gmp->trap_ptr = fs->gmp->trap; | 17663 | fs->gmp->trap_ptr = fs->gmp->trap; |
| 17645 | 17664 | ||
| 17646 | /* Set global variables */ | 17665 | /* Set global variables */ |
| 17647 | ASSIGN_CONST_PTR(&ash_ptr_to_globals_var, fs->gvp); | ||
| 17648 | ASSIGN_CONST_PTR(&ash_ptr_to_globals_misc, fs->gmp); | 17666 | ASSIGN_CONST_PTR(&ash_ptr_to_globals_misc, fs->gmp); |
| 17667 | ASSIGN_CONST_PTR(&ash_ptr_to_globals_var, fs->gvp); | ||
| 17649 | cmdtable = fs->cmdtable; | 17668 | cmdtable = fs->cmdtable; |
| 17650 | #if ENABLE_ASH_ALIAS | 17669 | #if ENABLE_ASH_ALIAS |
| 17651 | atab = fs->atab; /* will be NULL for FS_SHELLEXEC */ | 17670 | atab = fs->atab; /* will be NULL for FS_SHELLEXEC */ |
| @@ -17668,11 +17687,11 @@ forkshell_init(const char *idstr) | |||
| 17668 | 17687 | ||
| 17669 | reinitvar(); | 17688 | reinitvar(); |
| 17670 | 17689 | ||
| 17671 | if (setjmp(jmploc.loc)) { | 17690 | if (setjmp(main_handler.loc)) { |
| 17672 | exitreset(); | 17691 | exitreset(); |
| 17673 | exitshell(); | 17692 | exitshell(); |
| 17674 | } | 17693 | } |
| 17675 | exception_handler = &jmploc; | 17694 | exception_handler = &main_handler; |
| 17676 | 17695 | ||
| 17677 | shlvl++; | 17696 | shlvl++; |
| 17678 | if (fs->mode == FORK_BG) { | 17697 | if (fs->mode == FORK_BG) { |
