| ... | ... | @@ -197,6 +197,32 @@ pub const ChildProcess = struct { |
| 197 | 197 | stderr: []u8, |
| 198 | 198 | }; |
| 199 | 199 | |
| 200 | /// Collect the output from the process's stdout and stderr. Will return once all output |
| 201 | /// has been collected. This does not mean that the process has ended. `wait` should still |
| 202 | /// be called to wait for and clean up the process. |
| 203 | /// |
| 204 | /// The process must be started with stdout_behavior and stderr_behavior == .Pipe |
| 205 | pub fn collectOutput( |
| 206 | child: ChildProcess, |
| 207 | stdout: *std.ArrayList(u8), |
| 208 | stderr: *std.ArrayList(u8), |
| 209 | max_output_bytes: usize, |
| 210 | ) !void { |
| 211 | debug.assert(child.stdout_behavior == .Pipe); |
| 212 | debug.assert(child.stderr_behavior == .Pipe); |
| 213 | if (builtin.os.tag == .haiku) { |
| 214 | const stdout_in = child.stdout.?.reader(); |
| 215 | const stderr_in = child.stderr.?.reader(); |
| 216 | |
| 217 | try stdout_in.readAllArrayList(stdout, max_output_bytes); |
| 218 | try stderr_in.readAllArrayList(stderr, max_output_bytes); |
| 219 | } else if (builtin.os.tag == .windows) { |
| 220 | try collectOutputWindows(child, stdout, stderr, max_output_bytes); |
| 221 | } else { |
| 222 | try collectOutputPosix(child, stdout, stderr, max_output_bytes); |
| 223 | } |
| 224 | } |
| 225 | |
| 200 | 226 | fn collectOutputPosix( |
| 201 | 227 | child: ChildProcess, |
| 202 | 228 | stdout: *std.ArrayList(u8), |
| ... | ... | @@ -297,8 +323,12 @@ pub const ChildProcess = struct { |
| 297 | 323 | } |
| 298 | 324 | } |
| 299 | 325 | |
| 300 | | fn collectOutputWindows(child: ChildProcess, outs: [2]*std.ArrayList(u8), max_output_bytes: usize) !void { |
| 326 | fn collectOutputWindows(child: ChildProcess, stdout: *std.ArrayList(u8), stderr: *std.ArrayList(u8), max_output_bytes: usize) !void { |
| 301 | 327 | const bump_amt = 512; |
| 328 | const outs = [_]*std.ArrayList(u8){ |
| 329 | stdout, |
| 330 | stderr, |
| 331 | }; |
| 302 | 332 | const handles = [_]windows.HANDLE{ |
| 303 | 333 | child.stdout.?.handle, |
| 304 | 334 | child.stderr.?.handle, |
| ... | ... | @@ -391,24 +421,6 @@ pub const ChildProcess = struct { |
| 391 | 421 | child.env_map = args.env_map; |
| 392 | 422 | child.expand_arg0 = args.expand_arg0; |
| 393 | 423 | |
| 394 | | try child.spawn(); |
| 395 | | |
| 396 | | if (builtin.os.tag == .haiku) { |
| 397 | | const stdout_in = child.stdout.?.reader(); |
| 398 | | const stderr_in = child.stderr.?.reader(); |
| 399 | | |
| 400 | | const stdout = try stdout_in.readAllAlloc(args.allocator, args.max_output_bytes); |
| 401 | | errdefer args.allocator.free(stdout); |
| 402 | | const stderr = try stderr_in.readAllAlloc(args.allocator, args.max_output_bytes); |
| 403 | | errdefer args.allocator.free(stderr); |
| 404 | | |
| 405 | | return ExecResult{ |
| 406 | | .term = try child.wait(), |
| 407 | | .stdout = stdout, |
| 408 | | .stderr = stderr, |
| 409 | | }; |
| 410 | | } |
| 411 | | |
| 412 | 424 | var stdout = std.ArrayList(u8).init(args.allocator); |
| 413 | 425 | var stderr = std.ArrayList(u8).init(args.allocator); |
| 414 | 426 | errdefer { |
| ... | ... | @@ -416,11 +428,8 @@ pub const ChildProcess = struct { |
| 416 | 428 | stderr.deinit(); |
| 417 | 429 | } |
| 418 | 430 | |
| 419 | | if (builtin.os.tag == .windows) { |
| 420 | | try collectOutputWindows(child, [_]*std.ArrayList(u8){ &stdout, &stderr }, args.max_output_bytes); |
| 421 | | } else { |
| 422 | | try collectOutputPosix(child, &stdout, &stderr, args.max_output_bytes); |
| 423 | | } |
| 431 | try child.spawn(); |
| 432 | try child.collectOutput(&stdout, &stderr, args.max_output_bytes); |
| 424 | 433 | |
| 425 | 434 | return ExecResult{ |
| 426 | 435 | .term = try child.wait(), |