@@ -534,6 +534,7 @@ const ChildArg = struct {
534
534
dev_null_fd : posix.fd_t ,
535
535
argv_buf : [:null ]? [* :0 ]const u8 ,
536
536
envp : [* :null ]const ? [* :0 ]const u8 ,
537
+ sigmask : ? * posix.sigset_t ,
537
538
ret_err : RetErr ,
538
539
};
539
540
@@ -567,6 +568,28 @@ fn spawnPosixChildHelper(arg: usize) callconv(.c) u8 {
567
568
posix .setpgid (0 , pid ) catch | err | return forkChildErrReport (& child_arg .ret_err , err );
568
569
}
569
570
571
+ if (native_os == .linux and child_arg .sigmask != null ) {
572
+ std .debug .assert (linux .SIG .DFL == null );
573
+ for (1.. linux .NSIG ) | sig | {
574
+ if (sig == posix .SIG .KILL or sig == posix .SIG .STOP ) {
575
+ continue ;
576
+ }
577
+ if (sig > std .math .maxInt (u6 )) {
578
+ // XXX: We cannot disable all signals.
579
+ // sigaction accepts u6, which is too narrow.
580
+ break ;
581
+ }
582
+ var old_act : posix.Sigaction = undefined ;
583
+ const new_act = mem .zeroes (posix .Sigaction );
584
+ // Do not use posix.sigaction. It reaches unreachable.
585
+ _ = linux .sigaction (@intCast (sig ), & new_act , & old_act );
586
+ if (old_act .handler .handler == linux .SIG .IGN ) {
587
+ _ = linux .sigaction (@intCast (sig ), & old_act , null );
588
+ }
589
+ }
590
+ posix .sigprocmask (posix .SIG .SETMASK , child_arg .sigmask , null );
591
+ }
592
+
570
593
const err = switch (child_arg .self .expand_arg0 ) {
571
594
.expand = > posix .execvpeZ_expandArg0 (.expand , child_arg .argv_buf .ptr [0 ].? , child_arg .argv_buf .ptr , child_arg .envp ),
572
595
.no_expand = > posix .execvpeZ_expandArg0 (.no_expand , child_arg .argv_buf .ptr [0 ].? , child_arg .argv_buf .ptr , child_arg .envp ),
@@ -692,6 +715,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
692
715
.dev_null_fd = dev_null_fd ,
693
716
.argv_buf = argv_buf ,
694
717
.envp = envp ,
718
+ .sigmask = null ,
695
719
.ret_err = undefined ,
696
720
};
697
721
@@ -703,6 +727,10 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
703
727
immediateExit (spawnPosixChildHelper (@intFromPtr (& child_arg )));
704
728
}
705
729
} else {
730
+ var old_mask : posix.sigset_t = undefined ;
731
+ posix .sigprocmask (posix .SIG .SETMASK , & linux .all_mask , & old_mask );
732
+ defer posix .sigprocmask (posix .SIG .SETMASK , & old_mask , null );
733
+ child_arg .sigmask = & old_mask ;
706
734
child_arg .ret_err = null ;
707
735
// Although the stack is fixed sized, we alloc it here,
708
736
// because stack-smashing protection may have higher overhead than allocation.
0 commit comments