aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c47
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;
384struct strlist; 384struct strlist;
385struct job; 385struct job;
386 386
387#if defined(_WIN64)
388# define ALIGN64 ALIGNED(16)
389#else
390# define ALIGN64
391#endif
392
387struct forkshell { 393struct 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
432enum { 438enum {
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 */
815static void
816reset_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
17400enum {GVP, GMP, CMDTABLE, NODE, ARGV, ATAB, HISTORY, JOBTAB, FUNCSTRING}; 17420enum {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 */
17403static void 17423static 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) {