diff --git a/build.zig b/build.zig index a97142b090..223c225383 100644 --- a/build.zig +++ b/build.zig @@ -96,9 +96,9 @@ fn findLLVM(b: &Builder) -> LibraryDep { const args1 = [][]const u8{"llvm-config-5.0", "--libs", "--system-libs"}; const args2 = [][]const u8{"llvm-config", "--libs", "--system-libs"}; const max_output_size = 10 * 1024; - const good_result = exec(b.allocator, args1, null, null, max_output_size) %% |err| { + const good_result = os.ChildProcess.exec(b.allocator, args1, null, null, max_output_size) %% |err| { if (err == error.FileNotFound) { - exec(b.allocator, args2, null, null, max_output_size) %% |err2| { + os.ChildProcess.exec(b.allocator, args2, null, null, max_output_size) %% |err2| { std.debug.panic("unable to spawn {}: {}\n", args2[0], err2); } } else { @@ -121,9 +121,9 @@ fn findLLVM(b: &Builder) -> LibraryDep { const args1 = [][]const u8{"llvm-config-5.0", "--includedir"}; const args2 = [][]const u8{"llvm-config", "--includedir"}; const max_output_size = 10 * 1024; - const good_result = exec(b.allocator, args1, null, null, max_output_size) %% |err| { + const good_result = os.ChildProcess.exec(b.allocator, args1, null, null, max_output_size) %% |err| { if (err == error.FileNotFound) { - exec(b.allocator, args2, null, null, max_output_size) %% |err2| { + os.ChildProcess.exec(b.allocator, args2, null, null, max_output_size) %% |err2| { std.debug.panic("unable to spawn {}: {}\n", args2[0], err2); } } else { @@ -146,9 +146,9 @@ fn findLLVM(b: &Builder) -> LibraryDep { const args1 = [][]const u8{"llvm-config-5.0", "--libdir"}; const args2 = [][]const u8{"llvm-config", "--libdir"}; const max_output_size = 10 * 1024; - const good_result = exec(b.allocator, args1, null, null, max_output_size) %% |err| { + const good_result = os.ChildProcess.exec(b.allocator, args1, null, null, max_output_size) %% |err| { if (err == error.FileNotFound) { - exec(b.allocator, args2, null, null, max_output_size) %% |err2| { + os.ChildProcess.exec(b.allocator, args2, null, null, max_output_size) %% |err2| { std.debug.panic("unable to spawn {}: {}\n", args2[0], err2); } } else { @@ -203,41 +203,3 @@ fn findLLVM(b: &Builder) -> LibraryDep { } return result; } - - -// TODO move to std lib -const ExecResult = struct { - term: os.ChildProcess.Term, - stdout: []u8, - stderr: []u8, -}; - -fn exec(allocator: &std.mem.Allocator, argv: []const []const u8, cwd: ?[]const u8, env_map: ?&const BufMap, max_output_size: usize) -> %ExecResult { - const child = %%os.ChildProcess.init(argv, allocator); - defer child.deinit(); - - child.stdin_behavior = os.ChildProcess.StdIo.Ignore; - child.stdout_behavior = os.ChildProcess.StdIo.Pipe; - child.stderr_behavior = os.ChildProcess.StdIo.Pipe; - child.cwd = cwd; - child.env_map = env_map; - - %return child.spawn(); - - var stdout = Buffer.initNull(allocator); - var stderr = Buffer.initNull(allocator); - defer Buffer.deinit(&stdout); - defer Buffer.deinit(&stderr); - - var stdout_file_in_stream = io.FileInStream.init(&??child.stdout); - var stderr_file_in_stream = io.FileInStream.init(&??child.stderr); - - %return stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); - %return stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size); - - return ExecResult { - .term = %return child.wait(), - .stdout = stdout.toOwnedSlice(), - .stderr = stderr.toOwnedSlice(), - }; -} diff --git a/std/os/child_process.zig b/std/os/child_process.zig index 75a2dcf24d..5aa1578583 100644 --- a/std/os/child_process.zig +++ b/std/os/child_process.zig @@ -5,7 +5,6 @@ const os = std.os; const posix = os.posix; const windows = os.windows; const mem = std.mem; -const Allocator = mem.Allocator; const debug = std.debug; const assert = debug.assert; const BufMap = std.BufMap; @@ -74,7 +73,7 @@ pub const ChildProcess = struct { /// First argument in argv is the executable. /// On success must call deinit. - pub fn init(argv: []const []const u8, allocator: &Allocator) -> %&ChildProcess { + pub fn init(argv: []const []const u8, allocator: &mem.Allocator) -> %&ChildProcess { const child = %return allocator.create(ChildProcess); %defer allocator.destroy(child); @@ -180,6 +179,46 @@ pub const ChildProcess = struct { } } + pub const ExecResult = struct { + term: os.ChildProcess.Term, + stdout: []u8, + stderr: []u8, + }; + + /// 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(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8, + env_map: ?&const BufMap, max_output_size: usize) -> %ExecResult + { + const child = %%ChildProcess.init(argv, allocator); + defer child.deinit(); + + child.stdin_behavior = ChildProcess.StdIo.Ignore; + child.stdout_behavior = ChildProcess.StdIo.Pipe; + child.stderr_behavior = ChildProcess.StdIo.Pipe; + child.cwd = cwd; + child.env_map = env_map; + + %return child.spawn(); + + var stdout = Buffer.initNull(allocator); + var stderr = Buffer.initNull(allocator); + defer Buffer.deinit(&stdout); + defer Buffer.deinit(&stderr); + + var stdout_file_in_stream = io.FileInStream.init(&??child.stdout); + var stderr_file_in_stream = io.FileInStream.init(&??child.stderr); + + %return stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); + %return stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size); + + return ExecResult { + .term = %return child.wait(), + .stdout = stdout.toOwnedSlice(), + .stderr = stderr.toOwnedSlice(), + }; + } + fn waitWindows(self: &ChildProcess) -> %Term { if (self.term) |term| { self.cleanupStreams(); @@ -589,6 +628,7 @@ pub const ChildProcess = struct { StdIo.Ignore => %return os.posixDup2(dev_null_fd, std_fileno), } } + }; fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8, @@ -611,7 +651,7 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ? /// Caller must dealloc. /// Guarantees a null byte at result[result.len]. -fn windowsCreateCommandLine(allocator: &Allocator, argv: []const []const u8) -> %[]u8 { +fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) -> %[]u8 { var buf = %return Buffer.initSize(allocator, 0); defer buf.deinit();