process.Child.collectOutput: Switch to Allocator/ArrayListUnmanaged

Removes an inadvisable comparison of Allocator.ptr fields
This commit is contained in:
Ryan Liptak 2025-01-30 21:35:53 -08:00
parent 08d661fcfd
commit b46f9945a8

View file

@ -344,15 +344,17 @@ pub const RunResult = struct {
stderr: []u8, stderr: []u8,
}; };
fn fifoToOwnedArrayList(fifo: *std.io.PollFifo) std.ArrayList(u8) { fn writeFifoDataToArrayList(allocator: Allocator, list: *std.ArrayListUnmanaged(u8), fifo: *std.io.PollFifo) !void {
if (fifo.head != 0) fifo.realign(); if (fifo.head != 0) fifo.realign();
const result = std.ArrayList(u8){ if (list.capacity == 0) {
list.* = .{
.items = fifo.buf[0..fifo.count], .items = fifo.buf[0..fifo.count],
.capacity = fifo.buf.len, .capacity = fifo.buf.len,
.allocator = fifo.allocator,
}; };
fifo.* = std.io.PollFifo.init(fifo.allocator); fifo.* = std.io.PollFifo.init(fifo.allocator);
return result; } else {
try list.appendSlice(allocator, fifo.buf[0..fifo.count]);
}
} }
/// Collect the output from the process's stdout and stderr. Will return once all output /// 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) {
/// The process must be started with stdout_behavior and stderr_behavior == .Pipe /// The process must be started with stdout_behavior and stderr_behavior == .Pipe
pub fn collectOutput( pub fn collectOutput(
child: ChildProcess, child: ChildProcess,
stdout: *std.ArrayList(u8), /// Used for `stdout` and `stderr`.
stderr: *std.ArrayList(u8), allocator: Allocator,
stdout: *std.ArrayListUnmanaged(u8),
stderr: *std.ArrayListUnmanaged(u8),
max_output_bytes: usize, max_output_bytes: usize,
) !void { ) !void {
assert(child.stdout_behavior == .Pipe); assert(child.stdout_behavior == .Pipe);
assert(child.stderr_behavior == .Pipe); assert(child.stderr_behavior == .Pipe);
// we could make this work with multiple allocators but YAGNI var poller = std.io.poll(allocator, enum { stdout, stderr }, .{
if (stdout.allocator.ptr != stderr.allocator.ptr or
stdout.allocator.vtable != stderr.allocator.vtable)
{
unreachable; // ChildProcess.collectOutput only supports 1 allocator
}
var poller = std.io.poll(stdout.allocator, enum { stdout, stderr }, .{
.stdout = child.stdout.?, .stdout = child.stdout.?,
.stderr = child.stderr.?, .stderr = child.stderr.?,
}); });
@ -389,8 +386,8 @@ pub fn collectOutput(
return error.StderrStreamTooLong; return error.StderrStreamTooLong;
} }
stdout.* = fifoToOwnedArrayList(poller.fifo(.stdout)); try writeFifoDataToArrayList(allocator, stdout, poller.fifo(.stdout));
stderr.* = fifoToOwnedArrayList(poller.fifo(.stderr)); try writeFifoDataToArrayList(allocator, stderr, poller.fifo(.stderr));
} }
pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix.PollError || error{ pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix.PollError || error{
@ -420,22 +417,20 @@ pub fn run(args: struct {
child.expand_arg0 = args.expand_arg0; child.expand_arg0 = args.expand_arg0;
child.progress_node = args.progress_node; child.progress_node = args.progress_node;
var stdout = std.ArrayList(u8).init(args.allocator); var stdout: std.ArrayListUnmanaged(u8) = .empty;
var stderr = std.ArrayList(u8).init(args.allocator); errdefer stdout.deinit(args.allocator);
errdefer { var stderr: std.ArrayListUnmanaged(u8) = .empty;
stdout.deinit(); errdefer stderr.deinit(args.allocator);
stderr.deinit();
}
try child.spawn(); try child.spawn();
errdefer { errdefer {
_ = child.kill() catch {}; _ = child.kill() catch {};
} }
try child.collectOutput(&stdout, &stderr, args.max_output_bytes); try child.collectOutput(args.allocator, &stdout, &stderr, args.max_output_bytes);
return RunResult{ return RunResult{
.stdout = try stdout.toOwnedSlice(), .stdout = try stdout.toOwnedSlice(args.allocator),
.stderr = try stderr.toOwnedSlice(), .stderr = try stderr.toOwnedSlice(args.allocator),
.term = try child.wait(), .term = try child.wait(),
}; };
} }