Commit 6d47198303

Ben Crist <ben@magicmoremagic.com>
2022-11-20 19:20:14
return error.AlreadyTerminated from std.ChildProcess.kill when necessary
1 parent 7a9500f
Changed files (3)
lib/std/os/windows.zig
@@ -1593,11 +1593,12 @@ pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) Ge
     return buf_ptr[0..rc :0];
 }
 
-pub const TerminateProcessError = error{Unexpected};
+pub const TerminateProcessError = error{ PermissionDenied, Unexpected };
 
 pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) TerminateProcessError!void {
     if (kernel32.TerminateProcess(hProcess, uExitCode) == 0) {
         switch (kernel32.GetLastError()) {
+            Win32Error.ACCESS_DENIED => return error.PermissionDenied,
             else => |err| return unexpectedError(err),
         }
     }
lib/std/child_process.zig
@@ -221,7 +221,10 @@ pub const ChildProcess = struct {
             return term;
         }
 
-        try windows.TerminateProcess(self.id, exit_code);
+        windows.TerminateProcess(self.id, exit_code) catch |err| switch (err) {
+            error.PermissionDenied => return error.AlreadyTerminated,
+            else => return err,
+        };
         try self.waitUnwrappedWindows();
         return self.term.?;
     }
@@ -231,7 +234,10 @@ pub const ChildProcess = struct {
             self.cleanupStreams();
             return term;
         }
-        try os.kill(self.id, os.SIG.TERM);
+        os.kill(self.id, os.SIG.TERM) catch |err| switch (err) {
+            error.ProcessNotFound => return error.AlreadyTerminated,
+            else => return err,
+        };
         try self.waitUnwrapped();
         return self.term.?;
     }
lib/std/os.zig
@@ -639,14 +639,14 @@ pub fn raise(sig: u8) RaiseError!void {
     @compileError("std.os.raise unimplemented for this target");
 }
 
-pub const KillError = error{PermissionDenied} || UnexpectedError;
+pub const KillError = error{ ProcessNotFound, PermissionDenied } || UnexpectedError;
 
 pub fn kill(pid: pid_t, sig: u8) KillError!void {
     switch (errno(system.kill(pid, sig))) {
         .SUCCESS => return,
         .INVAL => unreachable, // invalid signal
         .PERM => return error.PermissionDenied,
-        .SRCH => unreachable, // always a race condition
+        .SRCH => return error.ProcessNotFound,
         else => |err| return unexpectedErrno(err),
     }
 }