Executes the provided command immediately, allowing failure.
If the program exits successfully, stdout is returned. Otherwise, returns an indication of failure.
See also:
run.pub fn runFallible(b: *Build, argv: []const []const u8, options: RunOptions) RunResult
pub fn runFallible(b: *Build, argv: []const []const u8, options: RunOptions) RunResult {
assert(argv.len != 0);
const graph = b.graph;
const io = graph.io;
const arena = graph.arena;
const print_opts: std.zig.AllocPrintCmdOptions = .{
.cwd = switch (options.cwd) {
.inherit => null,
.path => |p| p,
.dir => null, // Unknown without changing function signature of runFallible.
},
.child_env = options.environ_map,
.parent_env = &graph.environ_map,
};
if (graph.verbose) {
const text = std.zig.allocPrintCmd(arena, argv, print_opts) catch @panic("OOM");
std.log.scoped(.verbose).info("{s}", .{text});
}
var child = process.spawn(io, .{
.argv = argv,
.stdin = .ignore,
.stdout = .pipe,
.stderr = options.stderr_behavior,
.cwd = options.cwd,
.environ_map = &graph.environ_map,
.expand_arg0 = options.expand_arg0,
}) catch |err| return .{ .spawn_failed = err };
var stdout_reader = child.stdout.?.readerStreaming(io, &.{});
const stdout = stdout_reader.interface.allocRemaining(arena, options.stdout_limit) catch |err| switch (err) {
error.ReadFailed => panic("failed to read from child: {t}", .{stdout_reader.err.?}),
else => |e| panic("failed to read from child: {t}", .{e}),
};
const term = child.wait(io) catch @panic("unexpected");
return switch (term) {
.exited => |code| switch (code) {
0 => .{ .success = stdout },
else => .{ .bad_exit_code = code },
},
.signal, .stopped, .unknown => .crashed,
};
}