authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2023-02-21 18:26:55+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-02-21 12:26:55-05:00
log2737dce84f99a05af51b66fc12794b43dc10fa41
tree66f55e27ea6dffdf3e35f56cf33b9abf95bea397
parent7f691b3fe26f623d108a6b2b2018bbc3aa999224
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Introduce ChildProcess.collectOutput (#12295)

All the code for this function already exists, but only ChildProcess.exec was allowed to use the code.

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

lib/std/child_process.zig+33-24
......@@ -197,6 +197,32 @@ pub const ChildProcess = struct {
197197 stderr: []u8,
198198 };
199199
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
200226 fn collectOutputPosix(
201227 child: ChildProcess,
202228 stdout: *std.ArrayList(u8),
......@@ -297,8 +323,12 @@ pub const ChildProcess = struct {
297323 }
298324 }
299325
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 {
301327 const bump_amt = 512;
328 const outs = [_]*std.ArrayList(u8){
329 stdout,
330 stderr,
331 };
302332 const handles = [_]windows.HANDLE{
303333 child.stdout.?.handle,
304334 child.stderr.?.handle,
......@@ -391,24 +421,6 @@ pub const ChildProcess = struct {
391421 child.env_map = args.env_map;
392422 child.expand_arg0 = args.expand_arg0;
393423
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
412424 var stdout = std.ArrayList(u8).init(args.allocator);
413425 var stderr = std.ArrayList(u8).init(args.allocator);
414426 errdefer {
......@@ -416,11 +428,8 @@ pub const ChildProcess = struct {
416428 stderr.deinit();
417429 }
418430
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);
424433
425434 return ExecResult{
426435 .term = try child.wait(),