| ... | ... | @@ -344,15 +344,17 @@ pub const RunResult = struct { |
| 344 | 344 | stderr: []u8, |
| 345 | 345 | }; |
| 346 | 346 | |
| 347 | | fn fifoToOwnedArrayList(fifo: *std.io.PollFifo) std.ArrayList(u8) { |
| 347 | fn writeFifoDataToArrayList(allocator: Allocator, list: *std.ArrayListUnmanaged(u8), fifo: *std.io.PollFifo) !void { |
| 348 | 348 | if (fifo.head != 0) fifo.realign(); |
| 349 | | const result = std.ArrayList(u8){ |
| 350 | | .items = fifo.buf[0..fifo.count], |
| 351 | | .capacity = fifo.buf.len, |
| 352 | | .allocator = fifo.allocator, |
| 353 | | }; |
| 354 | | fifo.* = std.io.PollFifo.init(fifo.allocator); |
| 355 | | return result; |
| 349 | if (list.capacity == 0) { |
| 350 | list.* = .{ |
| 351 | .items = fifo.buf[0..fifo.count], |
| 352 | .capacity = fifo.buf.len, |
| 353 | }; |
| 354 | fifo.* = std.io.PollFifo.init(fifo.allocator); |
| 355 | } else { |
| 356 | try list.appendSlice(allocator, fifo.buf[0..fifo.count]); |
| 357 | } |
| 356 | 358 | } |
| 357 | 359 | |
| 358 | 360 | /// Collect the output from the process's stdout and stderr. Will return once all output |
| ... | ... | @@ -362,21 +364,16 @@ fn fifoToOwnedArrayList(fifo: *std.io.PollFifo) std.ArrayList(u8) { |
| 362 | 364 | /// The process must be started with stdout_behavior and stderr_behavior == .Pipe |
| 363 | 365 | pub fn collectOutput( |
| 364 | 366 | child: ChildProcess, |
| 365 | | stdout: *std.ArrayList(u8), |
| 366 | | stderr: *std.ArrayList(u8), |
| 367 | /// Used for `stdout` and `stderr`. |
| 368 | allocator: Allocator, |
| 369 | stdout: *std.ArrayListUnmanaged(u8), |
| 370 | stderr: *std.ArrayListUnmanaged(u8), |
| 367 | 371 | max_output_bytes: usize, |
| 368 | 372 | ) !void { |
| 369 | 373 | assert(child.stdout_behavior == .Pipe); |
| 370 | 374 | assert(child.stderr_behavior == .Pipe); |
| 371 | 375 | |
| 372 | | // we could make this work with multiple allocators but YAGNI |
| 373 | | if (stdout.allocator.ptr != stderr.allocator.ptr or |
| 374 | | stdout.allocator.vtable != stderr.allocator.vtable) |
| 375 | | { |
| 376 | | unreachable; // ChildProcess.collectOutput only supports 1 allocator |
| 377 | | } |
| 378 | | |
| 379 | | var poller = std.io.poll(stdout.allocator, enum { stdout, stderr }, .{ |
| 376 | var poller = std.io.poll(allocator, enum { stdout, stderr }, .{ |
| 380 | 377 | .stdout = child.stdout.?, |
| 381 | 378 | .stderr = child.stderr.?, |
| 382 | 379 | }); |
| ... | ... | @@ -389,8 +386,8 @@ pub fn collectOutput( |
| 389 | 386 | return error.StderrStreamTooLong; |
| 390 | 387 | } |
| 391 | 388 | |
| 392 | | stdout.* = fifoToOwnedArrayList(poller.fifo(.stdout)); |
| 393 | | stderr.* = fifoToOwnedArrayList(poller.fifo(.stderr)); |
| 389 | try writeFifoDataToArrayList(allocator, stdout, poller.fifo(.stdout)); |
| 390 | try writeFifoDataToArrayList(allocator, stderr, poller.fifo(.stderr)); |
| 394 | 391 | } |
| 395 | 392 | |
| 396 | 393 | pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix.PollError || error{ |
| ... | ... | @@ -420,22 +417,20 @@ pub fn run(args: struct { |
| 420 | 417 | child.expand_arg0 = args.expand_arg0; |
| 421 | 418 | child.progress_node = args.progress_node; |
| 422 | 419 | |
| 423 | | var stdout = std.ArrayList(u8).init(args.allocator); |
| 424 | | var stderr = std.ArrayList(u8).init(args.allocator); |
| 425 | | errdefer { |
| 426 | | stdout.deinit(); |
| 427 | | stderr.deinit(); |
| 428 | | } |
| 420 | var stdout: std.ArrayListUnmanaged(u8) = .empty; |
| 421 | errdefer stdout.deinit(args.allocator); |
| 422 | var stderr: std.ArrayListUnmanaged(u8) = .empty; |
| 423 | errdefer stderr.deinit(args.allocator); |
| 429 | 424 | |
| 430 | 425 | try child.spawn(); |
| 431 | 426 | errdefer { |
| 432 | 427 | _ = child.kill() catch {}; |
| 433 | 428 | } |
| 434 | | try child.collectOutput(&stdout, &stderr, args.max_output_bytes); |
| 429 | try child.collectOutput(args.allocator, &stdout, &stderr, args.max_output_bytes); |
| 435 | 430 | |
| 436 | 431 | return RunResult{ |
| 437 | | .stdout = try stdout.toOwnedSlice(), |
| 438 | | .stderr = try stderr.toOwnedSlice(), |
| 432 | .stdout = try stdout.toOwnedSlice(args.allocator), |
| 433 | .stderr = try stderr.toOwnedSlice(args.allocator), |
| 439 | 434 | .term = try child.wait(), |
| 440 | 435 | }; |
| 441 | 436 | } |