self-hosted: move code to std.os.ChildProcess.exec

This commit is contained in:
Andrew Kelley 2017-12-12 14:35:53 -05:00
parent caa6433b56
commit cd5fd653d7
2 changed files with 49 additions and 47 deletions

View File

@ -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(),
};
}

View File

@ -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();