diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-09 17:36:18 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-09 17:36:18 +0200 |
| commit | df154028dc1257a03cbbcf322a6c31eb9552a661 (patch) | |
| tree | 58cb0eff7d98f8cfa29625a3ef81d6d898e7a9b1 /shell | |
| parent | 9f490785e00bd5c4deee09d9fee3badd8d70ada4 (diff) | |
| download | busybox-w32-df154028dc1257a03cbbcf322a6c31eb9552a661.tar.gz busybox-w32-df154028dc1257a03cbbcf322a6c31eb9552a661.tar.bz2 busybox-w32-df154028dc1257a03cbbcf322a6c31eb9552a661.zip | |
ash: eval: Add vfork support
Upstream commit:
Date: Sat, 19 May 2018 02:39:56 +0800
eval: Add vfork support
This patch adds basic vfork support for the case of a simple command.
Upstream commit:
Date: Tue, 12 Jan 2021 17:11:19 +1100
jobs: Always reset SIGINT/SIGQUIT handlers
On Fri, Jan 08, 2021 at 08:55:41PM +0000, Harald van Dijk wrote:
> On 18/05/2018 19:39, Herbert Xu wrote:
> > This patch adds basic vfork support for the case of a simple command.
> > ... @@ -879,17 +892,30 @@ forkchild(struct job *jp, union node *n, int
> > mode)
> > }
> > }
> > if (!oldlvl && iflag) {
> > - setsignal(SIGINT);
> > - setsignal(SIGQUIT);
> > + if (mode != FORK_BG) {
> > + setsignal(SIGINT);
> > + setsignal(SIGQUIT);
> > + }
> > setsignal(SIGTERM);
> > }
> > +
> > + if (lvforked)
> > + return;
> > +
> > for (jp = curjob; jp; jp = jp->prev_job)
> > freejob(jp);
> > }
>
> This leaves SIGQUIT ignored in background jobs in interactive shells.
>
> ENV= dash -ic 'dash -c "kill -QUIT \$\$; echo huh" & wait'
>
> As of dash 0.5.11, this prints "huh". Before, the subprocess process killed
> itself before it could print anything. Other shells do not leave SIGQUIT
> ignored.
>
> (In a few other shells, this also prints "huh", but in those other shells,
> that is because the inner shell chooses to ignore SIGQUIT, not because the
> outer shell leaves it ignored.)
Thanks for catching this. I have no idea how that got in there
and it makes no sense whatsoever. This patch removes the if
conditional.
Fixes: e94a964e7dd0 ("eval: Add vfork support")
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 137 | ||||
| -rw-r--r-- | shell/hush.c | 3 |
2 files changed, 103 insertions, 37 deletions
diff --git a/shell/ash.c b/shell/ash.c index 81b4a8951..40f207d99 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -408,6 +408,7 @@ struct globals_misc { | |||
| 408 | uint8_t back_exitstatus;/* exit status of backquoted command */ | 408 | uint8_t back_exitstatus;/* exit status of backquoted command */ |
| 409 | smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */ | 409 | smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */ |
| 410 | smallint inps4; /* Prevent PS4 nesting. */ | 410 | smallint inps4; /* Prevent PS4 nesting. */ |
| 411 | smallint vforked; | ||
| 411 | int savestatus; /* exit status of last command outside traps */ | 412 | int savestatus; /* exit status of last command outside traps */ |
| 412 | int rootpid; /* pid of main shell */ | 413 | int rootpid; /* pid of main shell */ |
| 413 | /* shell level: 0 for the main shell, 1 for its children, and so on */ | 414 | /* shell level: 0 for the main shell, 1 for its children, and so on */ |
| @@ -431,7 +432,7 @@ struct globals_misc { | |||
| 431 | * but we do read it async. | 432 | * but we do read it async. |
| 432 | */ | 433 | */ |
| 433 | volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */ | 434 | volatile /*sig_atomic_t*/ smallint pending_int; /* 1 = got SIGINT */ |
| 434 | volatile /*sig_atomic_t*/ smallint gotsigchld; /* 1 = got SIGCHLD */ | 435 | volatile /*sig_atomic_t*/ smallint gotsigchld; /* 1 = got SIGCHLD */ |
| 435 | volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */ | 436 | volatile /*sig_atomic_t*/ smallint pending_sig; /* last pending signal */ |
| 436 | smallint exception_type; /* kind of exception: */ | 437 | smallint exception_type; /* kind of exception: */ |
| 437 | #define EXINT 0 /* SIGINT received */ | 438 | #define EXINT 0 /* SIGINT received */ |
| @@ -506,6 +507,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc; | |||
| 506 | #define back_exitstatus (G_misc.back_exitstatus ) | 507 | #define back_exitstatus (G_misc.back_exitstatus ) |
| 507 | #define job_warning (G_misc.job_warning) | 508 | #define job_warning (G_misc.job_warning) |
| 508 | #define inps4 (G_misc.inps4 ) | 509 | #define inps4 (G_misc.inps4 ) |
| 510 | #define vforked (G_misc.vforked ) | ||
| 509 | #define savestatus (G_misc.savestatus ) | 511 | #define savestatus (G_misc.savestatus ) |
| 510 | #define rootpid (G_misc.rootpid ) | 512 | #define rootpid (G_misc.rootpid ) |
| 511 | #define shlvl (G_misc.shlvl ) | 513 | #define shlvl (G_misc.shlvl ) |
| @@ -580,6 +582,17 @@ var_end(const char *var) | |||
| 580 | return var; | 582 | return var; |
| 581 | } | 583 | } |
| 582 | 584 | ||
| 585 | /* Our signal logic never blocks individual signals | ||
| 586 | * using signal mask - only by setting SIG_IGN handler. | ||
| 587 | * Therefore just unmasking all of them instead of "restore old mask" | ||
| 588 | * approach is safe, modulo a case where the shell itself inherited | ||
| 589 | * a _masked_ signal. | ||
| 590 | */ | ||
| 591 | static void | ||
| 592 | sigclearmask(void) | ||
| 593 | { | ||
| 594 | sigprocmask_allsigs(SIG_UNBLOCK); | ||
| 595 | } | ||
| 583 | 596 | ||
| 584 | /* ============ Parser data */ | 597 | /* ============ Parser data */ |
| 585 | 598 | ||
| @@ -678,6 +691,10 @@ raise_exception(int e) | |||
| 678 | if (exception_handler == NULL) | 691 | if (exception_handler == NULL) |
| 679 | abort(); | 692 | abort(); |
| 680 | #endif | 693 | #endif |
| 694 | |||
| 695 | if (vforked) | ||
| 696 | _exit(exitstatus); | ||
| 697 | |||
| 681 | INTOFF; | 698 | INTOFF; |
| 682 | exception_type = e; | 699 | exception_type = e; |
| 683 | longjmp(exception_handler->loc, 1); | 700 | longjmp(exception_handler->loc, 1); |
| @@ -1481,6 +1498,7 @@ ash_vmsg_and_raise(int cond, const char *msg, va_list ap) | |||
| 1481 | /* NOTREACHED */ | 1498 | /* NOTREACHED */ |
| 1482 | } | 1499 | } |
| 1483 | 1500 | ||
| 1501 | /* This function is called sh_error() in dash */ | ||
| 1484 | static void ash_msg_and_raise_error(const char *, ...) NORETURN; | 1502 | static void ash_msg_and_raise_error(const char *, ...) NORETURN; |
| 1485 | static void | 1503 | static void |
| 1486 | ash_msg_and_raise_error(const char *msg, ...) | 1504 | ash_msg_and_raise_error(const char *msg, ...) |
| @@ -3665,7 +3683,6 @@ struct job { | |||
| 3665 | struct job *prev_job; /* previous job */ | 3683 | struct job *prev_job; /* previous job */ |
| 3666 | }; | 3684 | }; |
| 3667 | 3685 | ||
| 3668 | static struct job *makejob(int); | ||
| 3669 | static int forkshell(struct job *, union node *, int); | 3686 | static int forkshell(struct job *, union node *, int); |
| 3670 | static int waitforjob(struct job *); | 3687 | static int waitforjob(struct job *); |
| 3671 | 3688 | ||
| @@ -3688,15 +3705,23 @@ ignoresig(int signo) | |||
| 3688 | /* No, need to do it */ | 3705 | /* No, need to do it */ |
| 3689 | signal(signo, SIG_IGN); | 3706 | signal(signo, SIG_IGN); |
| 3690 | } | 3707 | } |
| 3691 | sigmode[signo - 1] = S_HARD_IGN; | 3708 | if (!vforked) |
| 3709 | sigmode[signo - 1] = S_HARD_IGN; | ||
| 3692 | } | 3710 | } |
| 3693 | 3711 | ||
| 3694 | /* | 3712 | /* |
| 3695 | * Only one usage site - in setsignal() | 3713 | * Only one usage site - in setsignal() |
| 3714 | * This function is called onsig() in dash | ||
| 3696 | */ | 3715 | */ |
| 3697 | static void | 3716 | static void |
| 3698 | signal_handler(int signo) | 3717 | signal_handler(int signo) |
| 3699 | { | 3718 | { |
| 3719 | // parent momentarily has vforked == 1 too, but it masks | ||
| 3720 | // all signals until after it resets vforked to 0. | ||
| 3721 | if (vforked) | ||
| 3722 | /* We are vfork child, DO NOT MODIFY ANY VARIABLES! */ | ||
| 3723 | return; | ||
| 3724 | |||
| 3700 | if (signo == SIGCHLD) { | 3725 | if (signo == SIGCHLD) { |
| 3701 | gotsigchld = 1; | 3726 | gotsigchld = 1; |
| 3702 | if (!trap[SIGCHLD]) | 3727 | if (!trap[SIGCHLD]) |
| @@ -3724,10 +3749,13 @@ signal_handler(int signo) | |||
| 3724 | static void | 3749 | static void |
| 3725 | setsignal(int signo) | 3750 | setsignal(int signo) |
| 3726 | { | 3751 | { |
| 3752 | int lvforked; | ||
| 3727 | char *t; | 3753 | char *t; |
| 3728 | char cur_act, new_act; | 3754 | char cur_act, new_act; |
| 3729 | struct sigaction act; | 3755 | struct sigaction act; |
| 3730 | 3756 | ||
| 3757 | lvforked = vforked; | ||
| 3758 | |||
| 3731 | t = trap[signo]; | 3759 | t = trap[signo]; |
| 3732 | new_act = S_DFL; | 3760 | new_act = S_DFL; |
| 3733 | if (t != NULL) { /* trap for this sig is set */ | 3761 | if (t != NULL) { /* trap for this sig is set */ |
| @@ -3736,7 +3764,7 @@ setsignal(int signo) | |||
| 3736 | new_act = S_IGN; | 3764 | new_act = S_IGN; |
| 3737 | } | 3765 | } |
| 3738 | 3766 | ||
| 3739 | if (rootshell && new_act == S_DFL) { | 3767 | if (rootshell && new_act == S_DFL && !lvforked) { |
| 3740 | switch (signo) { | 3768 | switch (signo) { |
| 3741 | case SIGINT: | 3769 | case SIGINT: |
| 3742 | if (iflag || minusc || sflag == 0) | 3770 | if (iflag || minusc || sflag == 0) |
| @@ -3806,8 +3834,8 @@ setsignal(int signo) | |||
| 3806 | if (cur_act == S_HARD_IGN || cur_act == new_act) | 3834 | if (cur_act == S_HARD_IGN || cur_act == new_act) |
| 3807 | return; | 3835 | return; |
| 3808 | 3836 | ||
| 3809 | *t = new_act; | 3837 | if (!lvforked) |
| 3810 | 3838 | *t = new_act; | |
| 3811 | act.sa_handler = SIG_DFL; | 3839 | act.sa_handler = SIG_DFL; |
| 3812 | switch (new_act) { | 3840 | switch (new_act) { |
| 3813 | case S_CATCH: | 3841 | case S_CATCH: |
| @@ -4342,15 +4370,16 @@ waitproc(int block, int *status) | |||
| 4342 | if (err || (err = -!block)) | 4370 | if (err || (err = -!block)) |
| 4343 | break; | 4371 | break; |
| 4344 | 4372 | ||
| 4345 | sigfillset(&oldmask); | ||
| 4346 | sigprocmask2(SIG_SETMASK, &oldmask); /* mask is updated */ | ||
| 4347 | while (!gotsigchld && !pending_sig) | ||
| 4348 | sigsuspend(&oldmask); | ||
| 4349 | sigprocmask(SIG_SETMASK, &oldmask, NULL); | ||
| 4350 | //simpler, but unsafe: a signal can set pending_sig after check, but before pause(): | 4373 | //simpler, but unsafe: a signal can set pending_sig after check, but before pause(): |
| 4351 | //while (!gotsigchld && !pending_sig) | 4374 | //while (!gotsigchld && !pending_sig) |
| 4352 | // pause(); | 4375 | // pause(); |
| 4353 | 4376 | ||
| 4377 | sigblockall(&oldmask); | ||
| 4378 | |||
| 4379 | while (!gotsigchld && !pending_sig) | ||
| 4380 | sigsuspend(&oldmask); | ||
| 4381 | |||
| 4382 | sigclearmask(); | ||
| 4354 | } while (gotsigchld); | 4383 | } while (gotsigchld); |
| 4355 | 4384 | ||
| 4356 | return err; | 4385 | return err; |
| @@ -5187,18 +5216,28 @@ static void closescript(void); | |||
| 5187 | static NOINLINE void | 5216 | static NOINLINE void |
| 5188 | forkchild(struct job *jp, union node *n, int mode) | 5217 | forkchild(struct job *jp, union node *n, int mode) |
| 5189 | { | 5218 | { |
| 5219 | int lvforked; | ||
| 5190 | int oldlvl; | 5220 | int oldlvl; |
| 5191 | 5221 | ||
| 5192 | TRACE(("Child shell %d\n", getpid())); | 5222 | TRACE(("Child shell %d\n", getpid())); |
| 5193 | oldlvl = shlvl; | 5223 | oldlvl = shlvl; |
| 5194 | shlvl++; | 5224 | lvforked = vforked; |
| 5225 | |||
| 5226 | if (!lvforked) { | ||
| 5227 | shlvl++; | ||
| 5228 | |||
| 5229 | closescript(); | ||
| 5230 | |||
| 5231 | #if JOBS | ||
| 5232 | /* do job control only in root shell */ | ||
| 5233 | jobctl = 0; | ||
| 5234 | #endif | ||
| 5235 | } | ||
| 5195 | 5236 | ||
| 5196 | /* man bash: "Non-builtin commands run by bash have signal handlers | 5237 | /* man bash: "Non-builtin commands run by bash have signal handlers |
| 5197 | * set to the values inherited by the shell from its parent". | 5238 | * set to the values inherited by the shell from its parent". |
| 5198 | * Do we do it correctly? */ | 5239 | * Do we do it correctly? */ |
| 5199 | 5240 | ||
| 5200 | closescript(); | ||
| 5201 | |||
| 5202 | if (n && n->type == NCMD /* is it single cmd? */ | 5241 | if (n && n->type == NCMD /* is it single cmd? */ |
| 5203 | /* && n->ncmd.args->type == NARG - always true? */ | 5242 | /* && n->ncmd.args->type == NARG - always true? */ |
| 5204 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 | 5243 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 |
| @@ -5244,10 +5283,9 @@ forkchild(struct job *jp, union node *n, int mode) | |||
| 5244 | trap_ptr = xmemdup(trap, sizeof(trap)); | 5283 | trap_ptr = xmemdup(trap, sizeof(trap)); |
| 5245 | /* Fall through into clearing traps */ | 5284 | /* Fall through into clearing traps */ |
| 5246 | } | 5285 | } |
| 5247 | clear_traps(); | 5286 | if (!lvforked) |
| 5287 | clear_traps(); | ||
| 5248 | #if JOBS | 5288 | #if JOBS |
| 5249 | /* do job control only in root shell */ | ||
| 5250 | jobctl = 0; | ||
| 5251 | if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) { | 5289 | if (mode != FORK_NOJOB && jp->jobctl && oldlvl == 0) { |
| 5252 | pid_t pgrp; | 5290 | pid_t pgrp; |
| 5253 | 5291 | ||
| @@ -5302,6 +5340,10 @@ forkchild(struct job *jp, union node *n, int mode) | |||
| 5302 | return; | 5340 | return; |
| 5303 | } | 5341 | } |
| 5304 | #endif | 5342 | #endif |
| 5343 | |||
| 5344 | if (lvforked) | ||
| 5345 | return; | ||
| 5346 | |||
| 5305 | for (jp = curjob; jp; jp = jp->prev_job) | 5347 | for (jp = curjob; jp; jp = jp->prev_job) |
| 5306 | freejob(jp); | 5348 | freejob(jp); |
| 5307 | } | 5349 | } |
| @@ -5313,7 +5355,15 @@ forkchild(struct job *jp, union node *n, int mode) | |||
| 5313 | static void | 5355 | static void |
| 5314 | forkparent(struct job *jp, union node *n, int mode, pid_t pid) | 5356 | forkparent(struct job *jp, union node *n, int mode, pid_t pid) |
| 5315 | { | 5357 | { |
| 5316 | TRACE(("In parent shell: child = %d\n", pid)); | 5358 | if (pid < 0) { |
| 5359 | TRACE(("Fork failed, errno=%d", errno)); | ||
| 5360 | if (jp) | ||
| 5361 | freejob(jp); | ||
| 5362 | ash_msg_and_raise_perror("can't fork"); | ||
| 5363 | /* NOTREACHED */ | ||
| 5364 | } | ||
| 5365 | |||
| 5366 | TRACE(("In parent shell: child = %d\n", pid)); | ||
| 5317 | if (!jp) /* jp is NULL when called by openhere() for heredoc support */ | 5367 | if (!jp) /* jp is NULL when called by openhere() for heredoc support */ |
| 5318 | return; | 5368 | return; |
| 5319 | #if JOBS | 5369 | #if JOBS |
| @@ -5352,21 +5402,44 @@ forkshell(struct job *jp, union node *n, int mode) | |||
| 5352 | 5402 | ||
| 5353 | TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode)); | 5403 | TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode)); |
| 5354 | pid = fork(); | 5404 | pid = fork(); |
| 5355 | if (pid < 0) { | ||
| 5356 | TRACE(("Fork failed, errno=%d", errno)); | ||
| 5357 | if (jp) | ||
| 5358 | freejob(jp); | ||
| 5359 | ash_msg_and_raise_perror("can't fork"); | ||
| 5360 | } | ||
| 5361 | if (pid == 0) { | 5405 | if (pid == 0) { |
| 5362 | CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */ | 5406 | CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */ |
| 5363 | forkchild(jp, n, mode); | 5407 | forkchild(jp, n, mode); |
| 5364 | } else { | 5408 | } else |
| 5365 | forkparent(jp, n, mode, pid); | 5409 | forkparent(jp, n, mode, pid); |
| 5366 | } | 5410 | |
| 5367 | return pid; | 5411 | return pid; |
| 5368 | } | 5412 | } |
| 5369 | 5413 | ||
| 5414 | static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN; | ||
| 5415 | |||
| 5416 | static struct job* | ||
| 5417 | vforkexec(union node *n, char **argv, const char *path, int idx) | ||
| 5418 | { | ||
| 5419 | struct job *jp; | ||
| 5420 | int pid; | ||
| 5421 | |||
| 5422 | jp = makejob(1); | ||
| 5423 | |||
| 5424 | sigblockall(NULL); | ||
| 5425 | vforked = 1; | ||
| 5426 | |||
| 5427 | pid = vfork(); | ||
| 5428 | |||
| 5429 | if (!pid) { | ||
| 5430 | forkchild(jp, n, FORK_FG); | ||
| 5431 | sigclearmask(); | ||
| 5432 | shellexec(argv[0], argv, path, idx); | ||
| 5433 | /* NOTREACHED */ | ||
| 5434 | } | ||
| 5435 | |||
| 5436 | vforked = 0; | ||
| 5437 | sigclearmask(); | ||
| 5438 | forkparent(jp, n, FORK_FG, pid); | ||
| 5439 | |||
| 5440 | return jp; | ||
| 5441 | } | ||
| 5442 | |||
| 5370 | /* | 5443 | /* |
| 5371 | * Wait for job to finish. | 5444 | * Wait for job to finish. |
| 5372 | * | 5445 | * |
| @@ -8341,7 +8414,6 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c | |||
| 8341 | * have to change the find_command routine as well. | 8414 | * have to change the find_command routine as well. |
| 8342 | * argv[-1] must exist and be writable! See tryexec() for why. | 8415 | * argv[-1] must exist and be writable! See tryexec() for why. |
| 8343 | */ | 8416 | */ |
| 8344 | static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN; | ||
| 8345 | static void shellexec(char *prog, char **argv, const char *path, int idx) | 8417 | static void shellexec(char *prog, char **argv, const char *path, int idx) |
| 8346 | { | 8418 | { |
| 8347 | char *cmdname; | 8419 | char *cmdname; |
| @@ -10612,6 +10684,7 @@ evalcommand(union node *cmd, int flags) | |||
| 10612 | break; | 10684 | break; |
| 10613 | } | 10685 | } |
| 10614 | #endif | 10686 | #endif |
| 10687 | /* Fork off a child process if necessary. */ | ||
| 10615 | /* Can we avoid forking? For example, very last command | 10688 | /* Can we avoid forking? For example, very last command |
| 10616 | * in a script or a subshell does not need forking, | 10689 | * in a script or a subshell does not need forking, |
| 10617 | * we can just exec it. | 10690 | * we can just exec it. |
| @@ -10620,14 +10693,8 @@ evalcommand(union node *cmd, int flags) | |||
| 10620 | /* No, forking off a child is necessary */ | 10693 | /* No, forking off a child is necessary */ |
| 10621 | INTOFF; | 10694 | INTOFF; |
| 10622 | get_tty_state(); | 10695 | get_tty_state(); |
| 10623 | jp = makejob(1); | 10696 | jp = vforkexec(cmd, argv, path, cmdentry.u.index); |
| 10624 | if (forkshell(jp, cmd, FORK_FG) != 0) { | 10697 | break; |
| 10625 | /* parent */ | ||
| 10626 | break; | ||
| 10627 | } | ||
| 10628 | /* child */ | ||
| 10629 | FORCEINTON; | ||
| 10630 | /* fall through to exec'ing external program */ | ||
| 10631 | } | 10698 | } |
| 10632 | shellexec(argv[0], argv, path, cmdentry.u.index); | 10699 | shellexec(argv[0], argv, path, cmdentry.u.index); |
| 10633 | /* NOTREACHED */ | 10700 | /* NOTREACHED */ |
diff --git a/shell/hush.c b/shell/hush.c index 2cceef25a..ad078ee54 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -12160,8 +12160,7 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid | |||
| 12160 | * Or else we may race with SIGCHLD, lose it, | 12160 | * Or else we may race with SIGCHLD, lose it, |
| 12161 | * and get stuck in sigsuspend... | 12161 | * and get stuck in sigsuspend... |
| 12162 | */ | 12162 | */ |
| 12163 | sigfillset(&oldset); /* block all signals, remember old set */ | 12163 | sigblockall(&oldset); /* block all signals, remember old set */ |
| 12164 | sigprocmask2(SIG_SETMASK, &oldset); | ||
| 12165 | 12164 | ||
| 12166 | if (!sigisemptyset(&G.pending_set)) { | 12165 | if (!sigisemptyset(&G.pending_set)) { |
| 12167 | /* Crap! we raced with some signal! */ | 12166 | /* Crap! we raced with some signal! */ |
