| ... | ... | @@ -258,11 +258,11 @@ pub const ChildProcess = struct { |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | 260 | fn collectOutputWindows(child: *const ChildProcess, stdout: *std.ArrayList(u8), stderr: *std.ArrayList(u8), max_output_bytes: usize) !void { |
| 261 | | // The order of the objects here is important, WaitForMultipleObjects |
| 262 | | // uses the same order when scanning the events. |
| 263 | 261 | var wait_objects = [_]windows.kernel32.HANDLE{ |
| 264 | | child.handle, child.stdout.?.handle, child.stderr.?.handle, |
| 262 | child.stdout.?.handle, child.stderr.?.handle, |
| 265 | 263 | }; |
| 264 | var waiting_objects: u32 = wait_objects.len; |
| 265 | |
| 266 | 266 | // XXX: Calling zeroes([2]windows.OVERLAPPED) causes the stage1 compiler |
| 267 | 267 | // to crash and burn. |
| 268 | 268 | var overlapped = [_]windows.OVERLAPPED{ |
| ... | ... | @@ -274,38 +274,31 @@ pub const ChildProcess = struct { |
| 274 | 274 | // Kickstart the loop by issuing two async reads. |
| 275 | 275 | // ReadFile returns false and GetLastError returns ERROR_IO_PENDING if |
| 276 | 276 | // everything is ok. |
| 277 | | _ = windows.kernel32.ReadFile(wait_objects[1], &temp_buf[0], temp_buf[0].len, null, &overlapped[0]); |
| 278 | | _ = windows.kernel32.ReadFile(wait_objects[2], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); |
| 277 | _ = windows.kernel32.ReadFile(wait_objects[0], &temp_buf[0], temp_buf[0].len, null, &overlapped[0]); |
| 278 | _ = windows.kernel32.ReadFile(wait_objects[1], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); |
| 279 | 279 | |
| 280 | | while (true) { |
| 281 | | const status = windows.kernel32.WaitForMultipleObjects(wait_objects.len, &wait_objects, 0, windows.INFINITE); |
| 282 | | std.debug.print("status {x}\n", .{status}); |
| 280 | poll: while (waiting_objects > 0) { |
| 281 | const status = windows.kernel32.WaitForMultipleObjects(waiting_objects, &wait_objects, 0, windows.INFINITE); |
| 283 | 282 | switch (status) { |
| 284 | | windows.WAIT_OBJECT_0 + 0 => { |
| 285 | | // The child process was terminated. |
| 286 | | break; |
| 287 | | }, |
| 288 | | windows.WAIT_OBJECT_0 + 1 => { |
| 289 | | // stdout is ready. |
| 290 | | var read_bytes: u32 = undefined; |
| 291 | | if (windows.kernel32.GetOverlappedResult(wait_objects[1], &overlapped[0], &read_bytes, 0) == 0) { |
| 292 | | switch (windows.kernel32.GetLastError()) { |
| 293 | | else => |err| return windows.unexpectedError(err), |
| 294 | | } |
| 295 | | } |
| 296 | | try stdout.appendSlice(temp_buf[0][0..read_bytes]); |
| 297 | | _ = windows.kernel32.ReadFile(wait_objects[1], &temp_buf[0], temp_buf[0].len, null, &overlapped[0]); |
| 298 | | }, |
| 299 | | windows.WAIT_OBJECT_0 + 2 => { |
| 300 | | // stderr is ready. |
| 283 | windows.WAIT_OBJECT_0 + 0...windows.WAIT_OBJECT_0 + 1 => { |
| 284 | // stdout (or stderr) is ready. |
| 285 | const object = status - windows.WAIT_OBJECT_0; |
| 286 | |
| 301 | 287 | var read_bytes: u32 = undefined; |
| 302 | | if (windows.kernel32.GetOverlappedResult(wait_objects[2], &overlapped[1], &read_bytes, 0) == 0) { |
| 288 | if (windows.kernel32.GetOverlappedResult(wait_objects[object], &overlapped[object], &read_bytes, 0) == 0) { |
| 303 | 289 | switch (windows.kernel32.GetLastError()) { |
| 290 | .BROKEN_PIPE => { |
| 291 | // Move it to the end to remove it. |
| 292 | if (object != waiting_objects - 1) |
| 293 | mem.swap(windows.kernel32.HANDLE, &wait_objects[object], &wait_objects[waiting_objects - 1]); |
| 294 | waiting_objects -= 1; |
| 295 | continue :poll; |
| 296 | }, |
| 304 | 297 | else => |err| return windows.unexpectedError(err), |
| 305 | 298 | } |
| 306 | 299 | } |
| 307 | | try stdout.appendSlice(temp_buf[1][0..read_bytes]); |
| 308 | | _ = windows.kernel32.ReadFile(wait_objects[2], &temp_buf[1], temp_buf[1].len, null, &overlapped[1]); |
| 300 | try stdout.appendSlice(temp_buf[object][0..read_bytes]); |
| 301 | _ = windows.kernel32.ReadFile(wait_objects[object], &temp_buf[object], temp_buf[object].len, null, &overlapped[object]); |
| 309 | 302 | }, |
| 310 | 303 | windows.WAIT_FAILED => { |
| 311 | 304 | switch (windows.kernel32.GetLastError()) { |