|
5 | 5 | #include "xspawn.h" |
6 | 6 | #include "alloc.h" |
7 | 7 | #include "bfstd.h" |
| 8 | +#include "diag.h" |
8 | 9 | #include "list.h" |
9 | 10 | #include <errno.h> |
10 | 11 | #include <fcntl.h> |
| 12 | +#include <signal.h> |
11 | 13 | #include <stdlib.h> |
12 | 14 | #include <string.h> |
13 | 15 | #include <sys/resource.h> |
@@ -590,30 +592,49 @@ static pid_t bfs_fork_spawn(struct bfs_resolver *res, const struct bfs_spawn *ct |
590 | 592 | return -1; |
591 | 593 | } |
592 | 594 |
|
| 595 | + // Block signals before fork() so handlers don't run in the child |
| 596 | + sigset_t new_mask; |
| 597 | + if (sigfillset(&new_mask) != 0) { |
| 598 | + goto fail; |
| 599 | + } |
| 600 | + sigset_t old_mask; |
| 601 | + errno = pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); |
| 602 | + if (errno != 0) { |
| 603 | + goto fail; |
| 604 | + } |
| 605 | + |
593 | 606 | pid_t pid = fork(); |
594 | | - if (pid < 0) { |
595 | | - close_quietly(pipefd[1]); |
596 | | - close_quietly(pipefd[0]); |
597 | | - return -1; |
598 | | - } else if (pid == 0) { |
| 607 | + if (pid == 0) { |
599 | 608 | // Child |
600 | 609 | bfs_spawn_exec(res, ctx, argv, envp, pipefd); |
601 | 610 | } |
602 | 611 |
|
603 | | - // Parent |
| 612 | + // Restore the original signal mask |
| 613 | + int ret = pthread_sigmask(SIG_SETMASK, &old_mask, NULL); |
| 614 | + bfs_verify(ret == 0, "pthread_sigmask(): %s", xstrerror(ret)); |
| 615 | + |
| 616 | + if (pid < 0) { |
| 617 | + // fork() failed |
| 618 | + goto fail; |
| 619 | + } |
| 620 | + |
604 | 621 | xclose(pipefd[1]); |
605 | 622 |
|
606 | 623 | int error; |
607 | 624 | ssize_t nbytes = xread(pipefd[0], &error, sizeof(error)); |
608 | 625 | xclose(pipefd[0]); |
609 | 626 | if (nbytes == sizeof(error)) { |
610 | | - int wstatus; |
611 | | - xwaitpid(pid, &wstatus, 0); |
| 627 | + xwaitpid(pid, NULL, 0); |
612 | 628 | errno = error; |
613 | 629 | return -1; |
614 | 630 | } |
615 | 631 |
|
616 | 632 | return pid; |
| 633 | + |
| 634 | +fail: |
| 635 | + close_quietly(pipefd[1]); |
| 636 | + close_quietly(pipefd[0]); |
| 637 | + return -1; |
617 | 638 | } |
618 | 639 |
|
619 | 640 | /** Call the right bfs_spawn() implementation. */ |
|
0 commit comments