aboutsummaryrefslogtreecommitdiff
path: root/std/os
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-12-12 14:35:53 -0500
committerAndrew Kelley <superjoe30@gmail.com>2017-12-12 14:35:53 -0500
commitcd5fd653d7dd738d4c67b304e9cb17fb211f0163 (patch)
treedc0ae70eb9cde19118df13359a1fdca7ae68d20c /std/os
parentcaa6433b5636af968aa7018a3bea8e658bca05a3 (diff)
downloadzig-cd5fd653d7dd738d4c67b304e9cb17fb211f0163.tar.gz
zig-cd5fd653d7dd738d4c67b304e9cb17fb211f0163.zip
self-hosted: move code to std.os.ChildProcess.exec
Diffstat (limited to 'std/os')
-rw-r--r--std/os/child_process.zig46
1 files changed, 43 insertions, 3 deletions
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();