| ... | ... | @@ -225,11 +225,11 @@ pub const ChildProcess = struct { |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | 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 | 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 | 233 | // XXX: Calling zeroes([2]windows.OVERLAPPED) causes the stage1 compiler |
| 234 | 234 | // to crash and burn. |
| 235 | 235 | var overlapped = [_]windows.OVERLAPPED{ |
| ... | ... | @@ -241,38 +241,31 @@ pub const ChildProcess = struct { |
| 241 | 241 | // Kickstart the loop by issuing two async reads. |
| 242 | 242 | // ReadFile returns false and GetLastError returns ERROR_IO_PENDING if |
| 243 | 243 | // everything is ok. |
| 244 | | _ = windows.kernel32.ReadFile(wait_objects[1], &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]); |
| 244 | _ = windows.kernel32.ReadFile(wait_objects[0], &temp_buf[0], temp_buf[0].len, null, &overlapped[0]); |
| 245 | _ = windows.kernel32.ReadFile(wait_objects[1], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); |
| 246 | 246 | |
| 247 | | while (true) { |
| 248 | | const status = windows.kernel32.WaitForMultipleObjects(wait_objects.len, &wait_objects, 0, windows.INFINITE); |
| 249 | | std.debug.print("status {x}\n", .{status}); |
| 247 | poll: while (waiting_objects > 0) { |
| 248 | const status = windows.kernel32.WaitForMultipleObjects(waiting_objects, &wait_objects, 0, windows.INFINITE); |
| 250 | 249 | switch (status) { |
| 251 | | windows.WAIT_OBJECT_0 + 0 => { |
| 252 | | // The child process was terminated. |
| 253 | | break; |
| 254 | | }, |
| 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. |
| 250 | windows.WAIT_OBJECT_0 + 0...windows.WAIT_OBJECT_0 + 1 => { |
| 251 | // stdout (or stderr) is ready. |
| 252 | const object = status - windows.WAIT_OBJECT_0; |
| 253 | |
| 268 | 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 | 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 | 264 | else => |err| return windows.unexpectedError(err), |
| 272 | 265 | } |
| 273 | 266 | } |
| 274 | | try stdout.appendSlice(temp_buf[1][0..read_bytes]); |
| 275 | | _ = windows.kernel32.ReadFile(wait_objects[2], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); |
| 267 | try stdout.appendSlice(temp_buf[object][0..read_bytes]); |
| 268 | _ = windows.kernel32.ReadFile(wait_objects[object], &temp_buf[object], temp_buf[object].len, null, &overlapped[object]); |
| 276 | 269 | }, |
| 277 | 270 | windows.WAIT_FAILED => { |
| 278 | 271 | switch (windows.kernel32.GetLastError()) { |