Skip to content

Commit 9b729c1

Browse files
committed
process.Child.collectOutput: Take an allocator instead of array list pointers
1 parent e4c049e commit 9b729c1

File tree

1 file changed

+24
-27
lines changed

1 file changed

+24
-27
lines changed

lib/std/process/Child.zig

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -344,39 +344,36 @@ pub const RunResult = struct {
344344
stderr: []u8,
345345
};
346346

347-
fn fifoToOwnedArrayList(fifo: *std.io.PollFifo) std.ArrayList(u8) {
347+
fn fifoToOwnedSlice(fifo: *std.io.PollFifo) ![]u8 {
348348
if (fifo.head != 0) fifo.realign();
349-
const result = std.ArrayList(u8){
349+
var result = std.ArrayListUnmanaged(u8){
350350
.items = fifo.buf[0..fifo.count],
351351
.capacity = fifo.buf.len,
352-
.allocator = fifo.allocator,
353352
};
354353
fifo.* = std.io.PollFifo.init(fifo.allocator);
355-
return result;
354+
return result.toOwnedSlice(fifo.allocator);
356355
}
357356

357+
pub const Output = struct {
358+
stdout: []u8,
359+
stderr: []u8,
360+
};
361+
358362
/// Collect the output from the process's stdout and stderr. Will return once all output
359363
/// has been collected. This does not mean that the process has ended. `wait` should still
360364
/// be called to wait for and clean up the process.
361365
///
362366
/// The process must be started with stdout_behavior and stderr_behavior == .Pipe
363367
pub fn collectOutput(
364368
child: ChildProcess,
365-
stdout: *std.ArrayList(u8),
366-
stderr: *std.ArrayList(u8),
369+
/// Used for `stdout` and `stderr`.
370+
allocator: Allocator,
367371
max_output_bytes: usize,
368-
) !void {
372+
) !Output {
369373
assert(child.stdout_behavior == .Pipe);
370374
assert(child.stderr_behavior == .Pipe);
371375

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 }, .{
380377
.stdout = child.stdout.?,
381378
.stderr = child.stderr.?,
382379
});
@@ -389,8 +386,15 @@ pub fn collectOutput(
389386
return error.StderrStreamTooLong;
390387
}
391388

392-
stdout.* = fifoToOwnedArrayList(poller.fifo(.stdout));
393-
stderr.* = fifoToOwnedArrayList(poller.fifo(.stderr));
389+
const stdout = try fifoToOwnedSlice(poller.fifo(.stdout));
390+
errdefer allocator.free(stdout);
391+
const stderr = try fifoToOwnedSlice(poller.fifo(.stderr));
392+
errdefer allocator.free(stderr);
393+
394+
return .{
395+
.stdout = stdout,
396+
.stderr = stderr,
397+
};
394398
}
395399

396400
pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix.PollError || error{
@@ -420,20 +424,13 @@ pub fn run(args: struct {
420424
child.expand_arg0 = args.expand_arg0;
421425
child.progress_node = args.progress_node;
422426

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-
}
429-
430427
try child.spawn();
431-
try child.collectOutput(&stdout, &stderr, args.max_output_bytes);
428+
const output = try child.collectOutput(args.allocator, args.max_output_bytes);
432429

433430
return RunResult{
434431
.term = try child.wait(),
435-
.stdout = try stdout.toOwnedSlice(),
436-
.stderr = try stderr.toOwnedSlice(),
432+
.stdout = output.stdout,
433+
.stderr = output.stderr,
437434
};
438435
}
439436

0 commit comments

Comments
 (0)