| ... | ... | @@ -32,9 +32,6 @@ pub const ChildProcess = struct { |
| 32 | 32 | |
| 33 | 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 | 35 | /// Leave as null to use the current env map using the supplied allocator. |
| 39 | 36 | pub env_map: ?&const BufMap, |
| 40 | 37 | |
| ... | ... | @@ -102,7 +99,6 @@ pub const ChildProcess = struct { |
| 102 | 99 | .err_pipe = undefined, |
| 103 | 100 | .llnode = undefined, |
| 104 | 101 | .term = null, |
| 105 | | .onTerm = null, |
| 106 | 102 | .env_map = null, |
| 107 | 103 | .cwd = null, |
| 108 | 104 | .uid = if (is_windows) {} else null, |
| ... | ... | @@ -124,7 +120,6 @@ pub const ChildProcess = struct { |
| 124 | 120 | self.gid = user_info.gid; |
| 125 | 121 | } |
| 126 | 122 | |
| 127 | | /// onTerm can be called before `spawn` returns. |
| 128 | 123 | /// On success must call `kill` or `wait`. |
| 129 | 124 | pub fn spawn(self: &ChildProcess) !void { |
| 130 | 125 | if (is_windows) { |
| ... | ... | @@ -165,9 +160,6 @@ pub const ChildProcess = struct { |
| 165 | 160 | } |
| 166 | 161 | |
| 167 | 162 | pub fn killPosix(self: &ChildProcess) !Term { |
| 168 | | block_SIGCHLD(); |
| 169 | | defer restore_SIGCHLD(); |
| 170 | | |
| 171 | 163 | if (self.term) |term| { |
| 172 | 164 | self.cleanupStreams(); |
| 173 | 165 | return term; |
| ... | ... | @@ -246,9 +238,6 @@ pub const ChildProcess = struct { |
| 246 | 238 | } |
| 247 | 239 | |
| 248 | 240 | fn waitPosix(self: &ChildProcess) !Term { |
| 249 | | block_SIGCHLD(); |
| 250 | | defer restore_SIGCHLD(); |
| 251 | | |
| 252 | 241 | if (self.term) |term| { |
| 253 | 242 | self.cleanupStreams(); |
| 254 | 243 | return term; |
| ... | ... | @@ -298,10 +287,6 @@ pub const ChildProcess = struct { |
| 298 | 287 | |
| 299 | 288 | fn handleWaitResult(self: &ChildProcess, status: i32) void { |
| 300 | 289 | self.term = self.cleanupAfterWait(status); |
| 301 | | |
| 302 | | if (self.onTerm) |onTerm| { |
| 303 | | onTerm(self); |
| 304 | | } |
| 305 | 290 | } |
| 306 | 291 | |
| 307 | 292 | fn cleanupStreams(self: &ChildProcess) void { |
| ... | ... | @@ -347,9 +332,6 @@ pub const ChildProcess = struct { |
| 347 | 332 | } |
| 348 | 333 | |
| 349 | 334 | fn spawnPosix(self: &ChildProcess) !void { |
| 350 | | // TODO atomically set a flag saying that we already did this |
| 351 | | install_SIGCHLD_handler(); |
| 352 | | |
| 353 | 335 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined; |
| 354 | 336 | errdefer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); }; |
| 355 | 337 | |
| ... | ... | @@ -387,11 +369,9 @@ pub const ChildProcess = struct { |
| 387 | 369 | const err_pipe = try makePipe(); |
| 388 | 370 | errdefer destroyPipe(err_pipe); |
| 389 | 371 | |
| 390 | | block_SIGCHLD(); |
| 391 | 372 | const pid_result = posix.fork(); |
| 392 | 373 | const pid_err = posix.getErrno(pid_result); |
| 393 | 374 | if (pid_err > 0) { |
| 394 | | restore_SIGCHLD(); |
| 395 | 375 | return switch (pid_err) { |
| 396 | 376 | posix.EAGAIN, posix.ENOMEM, posix.ENOSYS => error.SystemResources, |
| 397 | 377 | else => os.unexpectedErrorPosix(pid_err), |
| ... | ... | @@ -399,7 +379,6 @@ pub const ChildProcess = struct { |
| 399 | 379 | } |
| 400 | 380 | if (pid_result == 0) { |
| 401 | 381 | // we are the child |
| 402 | | restore_SIGCHLD(); |
| 403 | 382 | |
| 404 | 383 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |
| 405 | 384 | |err| forkChildErrReport(err_pipe[1], err); |
| ... | ... | @@ -451,8 +430,6 @@ pub const ChildProcess = struct { |
| 451 | 430 | // TODO make this atomic so it works even with threads |
| 452 | 431 | children_nodes.prepend(&self.llnode); |
| 453 | 432 | |
| 454 | | restore_SIGCHLD(); |
| 455 | | |
| 456 | 433 | if (self.stdin_behavior == StdIo.Pipe) { os.close(stdin_pipe[0]); } |
| 457 | 434 | if (self.stdout_behavior == StdIo.Pipe) { os.close(stdout_pipe[1]); } |
| 458 | 435 | if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); } |
| ... | ... | @@ -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 | | } |