aboutsummaryrefslogtreecommitdiff
path: root/lib/std/child_process.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-02-27 14:11:29 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-02-27 16:10:48 -0700
commitd399f8a489dd2ae62fae9b805778bfdc697a969b (patch)
tree60df6836102786a1e665dfc92d815a27d6f8c352 /lib/std/child_process.zig
parentb5b634e4e8a2a1fe32fba50ccd175257b4213936 (diff)
parentf6c934677315665c140151b8dd28a56f948205e2 (diff)
downloadzig-d399f8a489dd2ae62fae9b805778bfdc697a969b.tar.gz
zig-d399f8a489dd2ae62fae9b805778bfdc697a969b.zip
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'lib/std/child_process.zig')
-rw-r--r--lib/std/child_process.zig57
1 files changed, 33 insertions, 24 deletions
diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig
index 07dd1f27f5..c3bd53b880 100644
--- a/lib/std/child_process.zig
+++ b/lib/std/child_process.zig
@@ -197,6 +197,32 @@ pub const ChildProcess = struct {
stderr: []u8,
};
+ /// Collect the output from the process's stdout and stderr. Will return once all output
+ /// has been collected. This does not mean that the process has ended. `wait` should still
+ /// be called to wait for and clean up the process.
+ ///
+ /// The process must be started with stdout_behavior and stderr_behavior == .Pipe
+ pub fn collectOutput(
+ child: ChildProcess,
+ stdout: *std.ArrayList(u8),
+ stderr: *std.ArrayList(u8),
+ max_output_bytes: usize,
+ ) !void {
+ debug.assert(child.stdout_behavior == .Pipe);
+ debug.assert(child.stderr_behavior == .Pipe);
+ if (builtin.os.tag == .haiku) {
+ const stdout_in = child.stdout.?.reader();
+ const stderr_in = child.stderr.?.reader();
+
+ try stdout_in.readAllArrayList(stdout, max_output_bytes);
+ try stderr_in.readAllArrayList(stderr, max_output_bytes);
+ } else if (builtin.os.tag == .windows) {
+ try collectOutputWindows(child, stdout, stderr, max_output_bytes);
+ } else {
+ try collectOutputPosix(child, stdout, stderr, max_output_bytes);
+ }
+ }
+
fn collectOutputPosix(
child: ChildProcess,
stdout: *std.ArrayList(u8),
@@ -297,8 +323,12 @@ pub const ChildProcess = struct {
}
}
- fn collectOutputWindows(child: ChildProcess, outs: [2]*std.ArrayList(u8), max_output_bytes: usize) !void {
+ fn collectOutputWindows(child: ChildProcess, stdout: *std.ArrayList(u8), stderr: *std.ArrayList(u8), max_output_bytes: usize) !void {
const bump_amt = 512;
+ const outs = [_]*std.ArrayList(u8){
+ stdout,
+ stderr,
+ };
const handles = [_]windows.HANDLE{
child.stdout.?.handle,
child.stderr.?.handle,
@@ -391,24 +421,6 @@ pub const ChildProcess = struct {
child.env_map = args.env_map;
child.expand_arg0 = args.expand_arg0;
- try child.spawn();
-
- if (builtin.os.tag == .haiku) {
- const stdout_in = child.stdout.?.reader();
- const stderr_in = child.stderr.?.reader();
-
- const stdout = try stdout_in.readAllAlloc(args.allocator, args.max_output_bytes);
- errdefer args.allocator.free(stdout);
- const stderr = try stderr_in.readAllAlloc(args.allocator, args.max_output_bytes);
- errdefer args.allocator.free(stderr);
-
- return ExecResult{
- .term = try child.wait(),
- .stdout = stdout,
- .stderr = stderr,
- };
- }
-
var stdout = std.ArrayList(u8).init(args.allocator);
var stderr = std.ArrayList(u8).init(args.allocator);
errdefer {
@@ -416,11 +428,8 @@ pub const ChildProcess = struct {
stderr.deinit();
}
- if (builtin.os.tag == .windows) {
- try collectOutputWindows(child, [_]*std.ArrayList(u8){ &stdout, &stderr }, args.max_output_bytes);
- } else {
- try collectOutputPosix(child, &stdout, &stderr, args.max_output_bytes);
- }
+ try child.spawn();
+ try child.collectOutput(&stdout, &stderr, args.max_output_bytes);
return ExecResult{
.term = try child.wait(),