| ... | @@ -32,9 +32,6 @@ pub const ChildProcess = struct { | ... | @@ -32,9 +32,6 @@ pub const ChildProcess = struct { |
| 32 | | 32 | |
| 33 | pub argv: []const []const u8, | 33 | pub argv: []const []const u8, |
| 34 | | 34 | |
| 35 | /// Possibly called from a signal handler. Must set this before calling `spawn`. | | |
| 36 | pub onTerm: ?fn(&ChildProcess)void, | | |
| 37 | | | |
| 38 | /// Leave as null to use the current env map using the supplied allocator. | 35 | /// Leave as null to use the current env map using the supplied allocator. |
| 39 | pub env_map: ?&const BufMap, | 36 | pub env_map: ?&const BufMap, |
| 40 | | 37 | |
| ... | @@ -102,7 +99,6 @@ pub const ChildProcess = struct { | ... | @@ -102,7 +99,6 @@ pub const ChildProcess = struct { |
| 102 | .err_pipe = undefined, | 99 | .err_pipe = undefined, |
| 103 | .llnode = undefined, | 100 | .llnode = undefined, |
| 104 | .term = null, | 101 | .term = null, |
| 105 | .onTerm = null, | | |
| 106 | .env_map = null, | 102 | .env_map = null, |
| 107 | .cwd = null, | 103 | .cwd = null, |
| 108 | .uid = if (is_windows) {} else null, | 104 | .uid = if (is_windows) {} else null, |
| ... | @@ -124,7 +120,6 @@ pub const ChildProcess = struct { | ... | @@ -124,7 +120,6 @@ pub const ChildProcess = struct { |
| 124 | self.gid = user_info.gid; | 120 | self.gid = user_info.gid; |
| 125 | } | 121 | } |
| 126 | | 122 | |
| 127 | /// onTerm can be called before `spawn` returns. | | |
| 128 | /// On success must call `kill` or `wait`. | 123 | /// On success must call `kill` or `wait`. |
| 129 | pub fn spawn(self: &ChildProcess) !void { | 124 | pub fn spawn(self: &ChildProcess) !void { |
| 130 | if (is_windows) { | 125 | if (is_windows) { |
| ... | @@ -165,9 +160,6 @@ pub const ChildProcess = struct { | ... | @@ -165,9 +160,6 @@ pub const ChildProcess = struct { |
| 165 | } | 160 | } |
| 166 | | 161 | |
| 167 | pub fn killPosix(self: &ChildProcess) !Term { | 162 | pub fn killPosix(self: &ChildProcess) !Term { |
| 168 | block_SIGCHLD(); | | |
| 169 | defer restore_SIGCHLD(); | | |
| 170 | | | |
| 171 | if (self.term) |term| { | 163 | if (self.term) |term| { |
| 172 | self.cleanupStreams(); | 164 | self.cleanupStreams(); |
| 173 | return term; | 165 | return term; |
| ... | @@ -246,9 +238,6 @@ pub const ChildProcess = struct { | ... | @@ -246,9 +238,6 @@ pub const ChildProcess = struct { |
| 246 | } | 238 | } |
| 247 | | 239 | |
| 248 | fn waitPosix(self: &ChildProcess) !Term { | 240 | fn waitPosix(self: &ChildProcess) !Term { |
| 249 | block_SIGCHLD(); | | |
| 250 | defer restore_SIGCHLD(); | | |
| 251 | | | |
| 252 | if (self.term) |term| { | 241 | if (self.term) |term| { |
| 253 | self.cleanupStreams(); | 242 | self.cleanupStreams(); |
| 254 | return term; | 243 | return term; |
| ... | @@ -298,10 +287,6 @@ pub const ChildProcess = struct { | ... | @@ -298,10 +287,6 @@ pub const ChildProcess = struct { |
| 298 | | 287 | |
| 299 | fn handleWaitResult(self: &ChildProcess, status: i32) void { | 288 | fn handleWaitResult(self: &ChildProcess, status: i32) void { |
| 300 | self.term = self.cleanupAfterWait(status); | 289 | self.term = self.cleanupAfterWait(status); |
| 301 | | | |
| 302 | if (self.onTerm) |onTerm| { | | |
| 303 | onTerm(self); | | |
| 304 | } | | |
| 305 | } | 290 | } |
| 306 | | 291 | |
| 307 | fn cleanupStreams(self: &ChildProcess) void { | 292 | fn cleanupStreams(self: &ChildProcess) void { |
| ... | @@ -347,9 +332,6 @@ pub const ChildProcess = struct { | ... | @@ -347,9 +332,6 @@ pub const ChildProcess = struct { |
| 347 | } | 332 | } |
| 348 | | 333 | |
| 349 | fn spawnPosix(self: &ChildProcess) !void { | 334 | fn spawnPosix(self: &ChildProcess) !void { |
| 350 | // TODO atomically set a flag saying that we already did this | | |
| 351 | install_SIGCHLD_handler(); | | |
| 352 | | | |
| 353 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined; | 335 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined; |
| 354 | errdefer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); }; | 336 | errdefer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); }; |
| 355 | | 337 | |
| ... | @@ -387,11 +369,9 @@ pub const ChildProcess = struct { | ... | @@ -387,11 +369,9 @@ pub const ChildProcess = struct { |
| 387 | const err_pipe = try makePipe(); | 369 | const err_pipe = try makePipe(); |
| 388 | errdefer destroyPipe(err_pipe); | 370 | errdefer destroyPipe(err_pipe); |
| 389 | | 371 | |
| 390 | block_SIGCHLD(); | | |
| 391 | const pid_result = posix.fork(); | 372 | const pid_result = posix.fork(); |
| 392 | const pid_err = posix.getErrno(pid_result); | 373 | const pid_err = posix.getErrno(pid_result); |
| 393 | if (pid_err > 0) { | 374 | if (pid_err > 0) { |
| 394 | restore_SIGCHLD(); | | |
| 395 | return switch (pid_err) { | 375 | return switch (pid_err) { |
| 396 | posix.EAGAIN, posix.ENOMEM, posix.ENOSYS => error.SystemResources, | 376 | posix.EAGAIN, posix.ENOMEM, posix.ENOSYS => error.SystemResources, |
| 397 | else => os.unexpectedErrorPosix(pid_err), | 377 | else => os.unexpectedErrorPosix(pid_err), |
| ... | @@ -399,7 +379,6 @@ pub const ChildProcess = struct { | ... | @@ -399,7 +379,6 @@ pub const ChildProcess = struct { |
| 399 | } | 379 | } |
| 400 | if (pid_result == 0) { | 380 | if (pid_result == 0) { |
| 401 | // we are the child | 381 | // we are the child |
| 402 | restore_SIGCHLD(); | | |
| 403 | | 382 | |
| 404 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch | 383 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |
| 405 | |err| forkChildErrReport(err_pipe[1], err); | 384 | |err| forkChildErrReport(err_pipe[1], err); |
| ... | @@ -451,8 +430,6 @@ pub const ChildProcess = struct { | ... | @@ -451,8 +430,6 @@ pub const ChildProcess = struct { |
| 451 | // TODO make this atomic so it works even with threads | 430 | // TODO make this atomic so it works even with threads |
| 452 | children_nodes.prepend(&self.llnode); | 431 | children_nodes.prepend(&self.llnode); |
| 453 | | 432 | |
| 454 | restore_SIGCHLD(); | | |
| 455 | | | |
| 456 | if (self.stdin_behavior == StdIo.Pipe) { os.close(stdin_pipe[0]); } | 433 | if (self.stdin_behavior == StdIo.Pipe) { os.close(stdin_pipe[0]); } |
| 457 | if (self.stdout_behavior == StdIo.Pipe) { os.close(stdout_pipe[1]); } | 434 | if (self.stdout_behavior == StdIo.Pipe) { os.close(stdout_pipe[1]); } |
| 458 | if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); } | 435 | if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); } |
| ... | @@ -824,30 +801,3 @@ fn handleTerm(pid: i32, status: i32) void { | ... | @@ -824,30 +801,3 @@ fn handleTerm(pid: i32, status: i32) void { |
| 824 | } | 801 | } |
| 825 | } | 802 | } |
| 826 | } | 803 | } |
| 827 | | | |
| 828 | const sigchld_set = x: { | | |
| 829 | var signal_set = posix.empty_sigset; | | |
| 830 | posix.sigaddset(&signal_set, posix.SIGCHLD); | | |
| 831 | break :x signal_set; | | |
| 832 | }; | | |
| 833 | | | |
| 834 | fn block_SIGCHLD() void { | | |
| 835 | const err = posix.getErrno(posix.sigprocmask(posix.SIG_BLOCK, &sigchld_set, null)); | | |
| 836 | assert(err == 0); | | |
| 837 | } | | |
| 838 | | | |
| 839 | fn restore_SIGCHLD() void { | | |
| 840 | const err = posix.getErrno(posix.sigprocmask(posix.SIG_UNBLOCK, &sigchld_set, null)); | | |
| 841 | assert(err == 0); | | |
| 842 | } | | |
| 843 | | | |
| 844 | const sigchld_action = posix.Sigaction { | | |
| 845 | .handler = sigchld_handler, | | |
| 846 | .mask = posix.empty_sigset, | | |
| 847 | .flags = posix.SA_RESTART | posix.SA_NOCLDSTOP, | | |
| 848 | }; | | |
| 849 | | | |
| 850 | fn install_SIGCHLD_handler() void { | | |
| 851 | const err = posix.getErrno(posix.sigaction(posix.SIGCHLD, &sigchld_action, null)); | | |
| 852 | assert(err == 0); | | |
| 853 | } | | |