authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2025-01-30 21:35:53-08:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2025-02-03 17:07:27-08:00
logb46f9945a81012ecd3ceca7152dd6faadf4815c9
tree5f120a7ec25babffda2b0104c24811ba1b82fe79
parent08d661fcfdfb0a7b99f8bfbf4912acd21cf72d6f

process.Child.collectOutput: Switch to Allocator/ArrayListUnmanaged

Removes an inadvisable comparison of Allocator.ptr fields

1 files changed, 24 insertions(+), 29 deletions(-)

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