Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: expose ChildProcess's exec function #10436

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions doc/docgen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1326,7 +1326,7 @@ fn genHtml(
try shell_out.print("\n", .{});

if (expected_outcome == .BuildFail) {
const result = try ChildProcess.exec(.{
const result = try ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = build_args.items,
.env_map = &env_map,
Expand Down Expand Up @@ -1386,7 +1386,7 @@ fn genHtml(
var exited_with_signal = false;

const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
const result = try ChildProcess.exec(.{
const result = try ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = run_args,
.env_map = &env_map,
Expand Down Expand Up @@ -1490,7 +1490,7 @@ fn genHtml(
try shell_out.print("-O {s} ", .{@tagName(code.mode)});
},
}
const result = try ChildProcess.exec(.{
const result = try ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = test_args.items,
.env_map = &env_map,
Expand Down Expand Up @@ -1546,7 +1546,7 @@ fn genHtml(
},
}

const result = try ChildProcess.exec(.{
const result = try ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = test_args.items,
.env_map = &env_map,
Expand Down Expand Up @@ -1615,7 +1615,7 @@ fn genHtml(
}

if (maybe_error_match) |error_match| {
const result = try ChildProcess.exec(.{
const result = try ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = build_args.items,
.env_map = &env_map,
Expand Down Expand Up @@ -1709,7 +1709,7 @@ fn genHtml(
}

fn exec(allocator: Allocator, env_map: *std.BufMap, args: []const []const u8) !ChildProcess.ExecResult {
const result = try ChildProcess.exec(.{
const result = try ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = args,
.env_map = env_map,
Expand Down
22 changes: 13 additions & 9 deletions lib/std/child_process.zig
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ pub const ChildProcess = struct {

/// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
/// If it succeeds, the caller owns result.stdout and result.stderr memory.
pub fn exec(args: struct {
pub fn initAndExec(args: struct {
allocator: mem.Allocator,
argv: []const []const u8,
cwd: ?[]const u8 = null,
Expand All @@ -348,6 +348,10 @@ pub const ChildProcess = struct {
child.env_map = args.env_map;
child.expand_arg0 = args.expand_arg0;

return try child.exec(args.max_output_bytes);
}

pub fn exec(child: *ChildProcess, max_output_bytes: usize) !ExecResult {
try child.spawn();

// TODO collect output in a deadlock-avoiding way on Windows.
Expand All @@ -356,10 +360,10 @@ pub const ChildProcess = struct {
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);
const stdout = try stdout_in.readAllAlloc(child.allocator, max_output_bytes);
errdefer child.allocator.free(stdout);
const stderr = try stderr_in.readAllAlloc(child.allocator, max_output_bytes);
errdefer child.allocator.free(stderr);

return ExecResult{
.term = try child.wait(),
Expand All @@ -368,17 +372,17 @@ pub const ChildProcess = struct {
};
}

var stdout = std.ArrayList(u8).init(args.allocator);
var stderr = std.ArrayList(u8).init(args.allocator);
var stdout = std.ArrayList(u8).init(child.allocator);
var stderr = std.ArrayList(u8).init(child.allocator);
errdefer {
stdout.deinit();
stderr.deinit();
}

if (builtin.os.tag == .windows) {
try collectOutputWindows(child, [_]*std.ArrayList(u8){ &stdout, &stderr }, args.max_output_bytes);
try collectOutputWindows(child, [_]*std.ArrayList(u8){ &stdout, &stderr }, max_output_bytes);
} else {
try collectOutputPosix(child, &stdout, &stderr, args.max_output_bytes);
try collectOutputPosix(child, &stdout, &stderr, max_output_bytes);
}

return ExecResult{
Expand Down
6 changes: 3 additions & 3 deletions lib/std/zig/system/darwin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub const macos = @import("darwin/macos.zig");
/// https://github.com/Homebrew/brew/blob/e119bdc571dcb000305411bc1e26678b132afb98/Library/Homebrew/brew.sh#L630
pub fn isDarwinSDKInstalled(allocator: Allocator) bool {
const argv = &[_][]const u8{ "/usr/bin/xcode-select", "--print-path" };
const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return false;
const result = std.ChildProcess.initAndExec(.{ .allocator = allocator, .argv = argv }) catch return false;
defer {
allocator.free(result.stderr);
allocator.free(result.stdout);
Expand All @@ -40,7 +40,7 @@ pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK {
};
const path = path: {
const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-path" };
const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null;
const result = std.ChildProcess.initAndExec(.{ .allocator = allocator, .argv = argv }) catch return null;
defer {
allocator.free(result.stderr);
allocator.free(result.stdout);
Expand All @@ -55,7 +55,7 @@ pub fn getDarwinSDK(allocator: Allocator, target: Target) ?DarwinSDK {
};
const version = version: {
const argv = &[_][]const u8{ "/usr/bin/xcrun", "--sdk", sdk, "--show-sdk-version" };
const result = std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }) catch return null;
const result = std.ChildProcess.initAndExec(.{ .allocator = allocator, .argv = argv }) catch return null;
defer {
allocator.free(result.stderr);
allocator.free(result.stdout);
Expand Down
4 changes: 2 additions & 2 deletions src/libc_installation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ pub const LibCInstallation = struct {
dev_null,
});

const exec_res = std.ChildProcess.exec(.{
const exec_res = std.ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = argv.items,
.max_output_bytes = 1024 * 1024,
Expand Down Expand Up @@ -596,7 +596,7 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
try appendCcExe(&argv, skip_cc_env_var);
try argv.append(arg1);

const exec_res = std.ChildProcess.exec(.{
const exec_res = std.ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = argv.items,
.max_output_bytes = 1024 * 1024,
Expand Down
4 changes: 2 additions & 2 deletions src/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ pub const TestContext = struct {
try zig_args.append("-O");
try zig_args.append(@tagName(case.optimize_mode));

const result = try std.ChildProcess.exec(.{
const result = try std.ChildProcess.initAndExec(.{
.allocator = arena,
.argv = zig_args.items,
});
Expand Down Expand Up @@ -1195,7 +1195,7 @@ pub const TestContext = struct {

try comp.makeBinFileExecutable();

break :x std.ChildProcess.exec(.{
break :x std.ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = argv.items,
.cwd_dir = tmp.dir,
Expand Down
2 changes: 1 addition & 1 deletion test/cli.zig
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn printCmd(cwd: []const u8, argv: []const []const u8) void {

fn exec(cwd: []const u8, expect_0: bool, argv: []const []const u8) !ChildProcess.ExecResult {
const max_output_size = 100 * 1024;
const result = ChildProcess.exec(.{
const result = ChildProcess.initAndExec(.{
.allocator = a,
.argv = argv,
.cwd = cwd,
Expand Down
2 changes: 1 addition & 1 deletion tools/update_clang_options.zig
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ pub fn main() anyerror!void {
try std.fmt.allocPrint(allocator, "-I={s}/clang/include/clang/Driver", .{llvm_src_root}),
};

const child_result = try std.ChildProcess.exec(.{
const child_result = try std.ChildProcess.initAndExec(.{
.allocator = allocator,
.argv = &child_args,
.max_output_bytes = 100 * 1024 * 1024,
Expand Down
2 changes: 1 addition & 1 deletion tools/update_cpu_features.zig
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ fn processOneTarget(job: Job) anyerror!void {
}),
};

const child_result = try std.ChildProcess.exec(.{
const child_result = try std.ChildProcess.initAndExec(.{
.allocator = arena,
.argv = &child_args,
.max_output_bytes = 200 * 1024 * 1024,
Expand Down