Merge pull request #365 from mitchellh/goonz/fix-zomby-subprocesses

termio/exec: don't leak zombie subprocesses
This commit is contained in:
Mitchell Hashimoto
2023-08-31 11:17:01 -07:00
committed by GitHub
2 changed files with 17 additions and 6 deletions

View File

@ -187,10 +187,20 @@ fn setupFd(src: File.Handle, target: i32) !void {
/// Wait for the command to exit and return information about how it exited.
pub fn wait(self: Command, block: bool) !Exit {
// We specify NOHANG because its not our fault if the process we launch
// for the tty doesn't properly waitpid its children. We don't want
// to hang the terminal over it.
const res = std.os.waitpid(self.pid.?, if (block) 0 else std.c.W.NOHANG);
const res = if (block) std.os.waitpid(self.pid.?, 0) else res: {
// We specify NOHANG because its not our fault if the process we launch
// for the tty doesn't properly waitpid its children. We don't want
// to hang the terminal over it.
// When NOHANG is specified, waitpid will return a pid of 0 if the process
// doesn't have a status to report. When that happens, it is as though the
// wait call has not been performed, so we need to keep trying until we get
// a non-zero pid back, otherwise we end up with zombie processes.
while (true) {
const res = std.os.waitpid(self.pid.?, std.c.W.NOHANG);
if (res.pid != 0) break :res res;
}
};
return Exit.init(res.status);
}

View File

@ -831,8 +831,9 @@ const Subprocess = struct {
}
/// Stop the subprocess. This is safe to call anytime. This will wait
/// for the subprocess to end so it will block. This does not close
/// the pty.
/// for the subprocess to register that it has been signalled, but not
/// for it to terminate, so it will not block.
/// This does not close the pty.
pub fn stop(self: *Subprocess) void {
// Kill our command
if (self.command) |*cmd| {