| ... | @@ -225,11 +225,11 @@ pub const ChildProcess = struct { | ... | @@ -225,11 +225,11 @@ pub const ChildProcess = struct { |
| 225 | } | 225 | } |
| 226 | | 226 | |
| 227 | fn collectOutputWindows(child: *const ChildProcess, stdout: *std.ArrayList(u8), stderr: *std.ArrayList(u8), max_output_bytes: usize) !void { | 227 | fn collectOutputWindows(child: *const ChildProcess, stdout: *std.ArrayList(u8), stderr: *std.ArrayList(u8), max_output_bytes: usize) !void { |
| 228 | // The order of the objects here is important, WaitForMultipleObjects | | |
| 229 | // uses the same order when scanning the events. | | |
| 230 | var wait_objects = [_]windows.kernel32.HANDLE{ | 228 | var wait_objects = [_]windows.kernel32.HANDLE{ |
| 231 | child.handle, child.stdout.?.handle, child.stderr.?.handle, | 229 | child.stdout.?.handle, child.stderr.?.handle, |
| 232 | }; | 230 | }; |
| | 231 | var waiting_objects: u32 = wait_objects.len; |
| | 232 | |
| 233 | // XXX: Calling zeroes([2]windows.OVERLAPPED) causes the stage1 compiler | 233 | // XXX: Calling zeroes([2]windows.OVERLAPPED) causes the stage1 compiler |
| 234 | // to crash and burn. | 234 | // to crash and burn. |
| 235 | var overlapped = [_]windows.OVERLAPPED{ | 235 | var overlapped = [_]windows.OVERLAPPED{ |
| ... | @@ -241,38 +241,31 @@ pub const ChildProcess = struct { | ... | @@ -241,38 +241,31 @@ pub const ChildProcess = struct { |
| 241 | // Kickstart the loop by issuing two async reads. | 241 | // Kickstart the loop by issuing two async reads. |
| 242 | // ReadFile returns false and GetLastError returns ERROR_IO_PENDING if | 242 | // ReadFile returns false and GetLastError returns ERROR_IO_PENDING if |
| 243 | // everything is ok. | 243 | // everything is ok. |
| 244 | _ = windows.kernel32.ReadFile(wait_objects[1], &temp_buf[0], temp_buf[0].len, null, &overlapped[0]); | 244 | _ = windows.kernel32.ReadFile(wait_objects[0], &temp_buf[0], temp_buf[0].len, null, &overlapped[0]); |
| 245 | _ = windows.kernel32.ReadFile(wait_objects[2], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); | 245 | _ = windows.kernel32.ReadFile(wait_objects[1], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); |
| 246 | | 246 | |
| 247 | while (true) { | 247 | poll: while (waiting_objects > 0) { |
| 248 | const status = windows.kernel32.WaitForMultipleObjects(wait_objects.len, &wait_objects, 0, windows.INFINITE); | 248 | const status = windows.kernel32.WaitForMultipleObjects(waiting_objects, &wait_objects, 0, windows.INFINITE); |
| 249 | std.debug.print("status {x}\n", .{status}); | | |
| 250 | switch (status) { | 249 | switch (status) { |
| 251 | windows.WAIT_OBJECT_0 + 0 => { | 250 | windows.WAIT_OBJECT_0 + 0...windows.WAIT_OBJECT_0 + 1 => { |
| 252 | // The child process was terminated. | 251 | // stdout (or stderr) is ready. |
| 253 | break; | 252 | const object = status - windows.WAIT_OBJECT_0; |
| 254 | }, | 253 | |
| 255 | windows.WAIT_OBJECT_0 + 1 => { | | |
| 256 | // stdout is ready. | | |
| 257 | var read_bytes: u32 = undefined; | | |
| 258 | if (windows.kernel32.GetOverlappedResult(wait_objects[1], &overlapped[0], &read_bytes, 0) == 0) { | | |
| 259 | switch (windows.kernel32.GetLastError()) { | | |
| 260 | else => |err| return windows.unexpectedError(err), | | |
| 261 | } | | |
| 262 | } | | |
| 263 | try stdout.appendSlice(temp_buf[0][0..read_bytes]); | | |
| 264 | _ = windows.kernel32.ReadFile(wait_objects[1], &temp_buf[0], temp_buf[0].len, null, &overlapped[0]); | | |
| 265 | }, | | |
| 266 | windows.WAIT_OBJECT_0 + 2 => { | | |
| 267 | // stderr is ready. | | |
| 268 | var read_bytes: u32 = undefined; | 254 | var read_bytes: u32 = undefined; |
| 269 | if (windows.kernel32.GetOverlappedResult(wait_objects[2], &overlapped[1], &read_bytes, 0) == 0) { | 255 | if (windows.kernel32.GetOverlappedResult(wait_objects[object], &overlapped[object], &read_bytes, 0) == 0) { |
| 270 | switch (windows.kernel32.GetLastError()) { | 256 | switch (windows.kernel32.GetLastError()) { |
| | 257 | .BROKEN_PIPE => { |
| | 258 | // Move it to the end to remove it. |
| | 259 | if (object != waiting_objects - 1) |
| | 260 | mem.swap(windows.kernel32.HANDLE, &wait_objects[object], &wait_objects[waiting_objects - 1]); |
| | 261 | waiting_objects -= 1; |
| | 262 | continue :poll; |
| | 263 | }, |
| 271 | else => |err| return windows.unexpectedError(err), | 264 | else => |err| return windows.unexpectedError(err), |
| 272 | } | 265 | } |
| 273 | } | 266 | } |
| 274 | try stdout.appendSlice(temp_buf[1][0..read_bytes]); | 267 | try stdout.appendSlice(temp_buf[object][0..read_bytes]); |
| 275 | _ = windows.kernel32.ReadFile(wait_objects[2], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); | 268 | _ = windows.kernel32.ReadFile(wait_objects[object], &temp_buf[object], temp_buf[object].len, null, &overlapped[object]); |
| 276 | }, | 269 | }, |
| 277 | windows.WAIT_FAILED => { | 270 | windows.WAIT_FAILED => { |
| 278 | switch (windows.kernel32.GetLastError()) { | 271 | switch (windows.kernel32.GetLastError()) { |