zig libc: fix subcommand

This branch regressed the child process "run" mechanism because it
didn't pass the correct stdin, stdout, stderr values to process.spawn

Fixed now.
This commit is contained in:
Andrew Kelley 2026-01-01 20:20:58 -08:00
parent 960c512efd
commit f28802a9c6
23 changed files with 167 additions and 199 deletions

View file

@ -18,7 +18,7 @@ var debug_allocator: std.heap.DebugAllocator(.{
.canary = @truncate(0xc647026dc6875134),
}) = .{};
pub fn main() u8 {
pub fn main(init: std.process.Init.Minimal) u8 {
const gpa = if (@import("builtin").link_libc)
std.heap.c_allocator
else
@ -37,7 +37,7 @@ pub fn main() u8 {
const fast_exit = @import("builtin").mode != .Debug;
const args = process.argsAlloc(arena) catch {
const args = init.args.toSlice(arena) catch {
std.debug.print("out of memory\n", .{});
if (fast_exit) process.exit(1);
return 1;

View file

@ -24,23 +24,19 @@ const usage_libc =
var stdout_buffer: [4096]u8 = undefined;
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_instance.deinit();
const arena = arena_instance.allocator();
const gpa = arena;
pub fn main(init: std.process.Init) !void {
const arena = init.arena.allocator();
const gpa = init.gpa;
const io = init.io;
const args = try init.minimal.args.toSlice(arena);
const env_map = init.env_map;
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
const args = try std.process.argsAlloc(arena);
const zig_lib_directory = args[1];
var input_file: ?[]const u8 = null;
var target_arch_os_abi: []const u8 = "native";
var print_includes: bool = false;
var stdout_writer = Io.File.stdout().writer(&stdout_buffer);
var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer);
const stdout = &stdout_writer.interface;
{
var i: usize = 2;
@ -77,7 +73,7 @@ pub fn main() !void {
const libc_installation: ?*LibCInstallation = libc: {
if (input_file) |libc_file| {
const libc = try arena.create(LibCInstallation);
libc.* = LibCInstallation.parse(arena, libc_file, &target) catch |err| {
libc.* = LibCInstallation.parse(arena, io, libc_file, &target) catch |err| {
fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err });
};
break :libc libc;
@ -90,11 +86,13 @@ pub fn main() !void {
const libc_dirs = std.zig.LibCDirs.detect(
arena,
io,
zig_lib_directory,
&target,
is_native_abi,
true,
libc_installation,
env_map,
) catch |err| {
const zig_target = try target.zigTriple(arena);
fatal("unable to detect libc for target {s}: {t}", .{ zig_target, err });
@ -114,7 +112,7 @@ pub fn main() !void {
}
if (input_file) |libc_file| {
var libc = LibCInstallation.parse(gpa, libc_file, &target) catch |err| {
var libc = LibCInstallation.parse(gpa, io, libc_file, &target) catch |err| {
fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err });
};
defer libc.deinit(gpa);
@ -125,6 +123,7 @@ pub fn main() !void {
var libc = LibCInstallation.findNative(gpa, io, .{
.verbose = true,
.target = &target,
.env_map = env_map,
}) catch |err| {
fatal("unable to detect native libc: {t}", .{err});
};

View file

@ -47,19 +47,11 @@ const Interestingness = enum { interesting, unknown, boring };
// - reduce flags sent to the compiler
// - integrate with the build system?
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_instance.deinit();
const arena = arena_instance.allocator();
var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init;
const gpa = general_purpose_allocator.allocator();
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
const args = try std.process.argsAlloc(arena);
pub fn main(init: std.process.Init) !void {
const arena = init.arena.allocator();
const gpa = init.gpa;
const io = init.io;
const args = try init.minimal.args.toSlice(arena);
var opt_checker_path: ?[]const u8 = null;
var opt_root_source_file_path: ?[]const u8 = null;
@ -73,8 +65,7 @@ pub fn main() !void {
const arg = args[i];
if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
const stdout = Io.File.stdout();
try stdout.writeAll(usage);
try Io.File.stdout().writeStreamingAll(io, usage);
return std.process.cleanExit(io);
} else if (mem.eql(u8, arg, "--")) {
argv = args[i + 1 ..];
@ -131,12 +122,10 @@ pub fn main() !void {
if (!skip_smoke_test) {
std.debug.print("smoke testing the interestingness check...\n", .{});
switch (try runCheck(arena, interestingness_argv.items)) {
switch (try runCheck(arena, io, interestingness_argv.items)) {
.interesting => {},
.boring, .unknown => |t| {
fatal("interestingness check returned {s} for unmodified input\n", .{
@tagName(t),
});
fatal("interestingness check returned {t} for unmodified input\n", .{t});
},
}
}
@ -238,7 +227,7 @@ pub fn main() !void {
try Io.Dir.cwd().writeFile(io, .{ .sub_path = root_source_file_path, .data = rendered.written() });
// std.debug.print("trying this code:\n{s}\n", .{rendered.items});
const interestingness = try runCheck(arena, interestingness_argv.items);
const interestingness = try runCheck(arena, io, interestingness_argv.items);
std.debug.print("{d} random transformations: {t}. {d}/{d}\n", .{
subset_size, interestingness, start_index, transformations.items.len,
});
@ -293,20 +282,24 @@ fn sortTransformations(transformations: []Walk.Transformation, rng: std.Random)
fn termToInteresting(term: std.process.Child.Term) Interestingness {
return switch (term) {
.Exited => |code| switch (code) {
.exited => |code| switch (code) {
0 => .interesting,
1 => .unknown,
else => .boring,
},
else => b: {
.signal => |sig| {
std.debug.print("interestingness check terminated with signal {t}\n", .{sig});
return .boring;
},
else => {
std.debug.print("interestingness check aborted unexpectedly\n", .{});
break :b .boring;
return .boring;
},
};
}
fn runCheck(arena: Allocator, io: Io, argv: []const []const u8) !Interestingness {
const result = try std.process.run(arena, io, .{ .spawn_options = .{ .argv = argv } });
const result = try std.process.run(arena, io, .{ .argv = argv });
if (result.stderr.len != 0)
std.debug.print("{s}", .{result.stderr});
return termToInteresting(result.term);

View file

@ -19,7 +19,7 @@ const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType;
const aro = @import("aro");
const compiler_util = @import("../util.zig");
pub fn main() !void {
pub fn main(init: std.process.Init.Minimal) !void {
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer std.debug.assert(debug_allocator.deinit() == .ok);
const gpa = debug_allocator.allocator();
@ -32,7 +32,7 @@ pub fn main() !void {
defer arena_state.deinit();
const arena = arena_state.allocator();
const args = try std.process.argsAlloc(arena);
const args = try init.args.toSlice(arena);
if (args.len < 2) {
const stderr = try io.lockStderr(&.{}, null);

View file

@ -14,7 +14,7 @@ pub fn main(init: std.process.Init) u8 {
const arena = init.arena.allocator();
const io = init.io;
const args = process.argsAlloc(arena) catch {
const args = init.minimal.args.toSlice(arena) catch {
std.debug.print("ran out of memory allocating arguments\n", .{});
if (fast_exit) process.exit(1);
return 1;

View file

@ -360,11 +360,11 @@ pub fn captureChildProcess(
try handleChildProcUnsupported(s);
try handleVerbose(s.owner, null, argv);
const result = std.process.run(arena, io, .{ .spawn_options = .{
const result = std.process.run(arena, io, .{
.argv = argv,
.env_map = &graph.env_map,
.progress_node = progress_node,
} }) catch |err| return s.fail("failed to run {s}: {t}", .{ argv[0], err });
}) catch |err| return s.fail("failed to run {s}: {t}", .{ argv[0], err });
if (result.stderr.len > 0) {
try s.result_error_msgs.append(arena, result.stderr);

View file

@ -123,14 +123,15 @@ fn mode(comptime x: comptime_int) comptime_int {
return if (builtin.mode == .Debug) x / 64 else x;
}
pub fn main() !void {
pub fn main(init: std.process.Init) !void {
const io = init.io;
const arena = init.arena.allocator();
var stdout_buffer: [0x100]u8 = undefined;
var stdout_writer = Io.File.stdout().writer(&stdout_buffer);
var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer);
const stdout = &stdout_writer.interface;
var buffer: [1024]u8 = undefined;
var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
const args = try std.process.argsAlloc(fixed.allocator());
const args = try init.minimal.args.toSlice(arena);
var filter: ?[]u8 = "";
var count: usize = mode(128 * MiB);

View file

@ -503,16 +503,16 @@ fn mode(comptime x: comptime_int) comptime_int {
return if (builtin.mode == .Debug) x / 64 else x;
}
pub fn main() !void {
pub fn main(init: std.process.Init) !void {
const io = init.io;
const arena = init.arena.allocator();
// Size of buffer is about size of printed message.
var stdout_buffer: [0x100]u8 = undefined;
var stdout_writer = Io.File.stdout().writer(&stdout_buffer);
var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer);
const stdout = &stdout_writer.interface;
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const arena_allocator = arena.allocator();
const args = try std.process.argsAlloc(arena_allocator);
const args = try init.minimal.args.toSlice(arena);
var filter: ?[]u8 = "";
@ -556,13 +556,9 @@ pub fn main() !void {
}
}
var io_threaded = std.Io.Threaded.init(arena_allocator, .{});
defer io_threaded.deinit();
const io = io_threaded.io();
inline for (parallel_hashes) |H| {
if (filter == null or std.mem.find(u8, H.name, filter.?) != null) {
const throughput = try benchmarkHashParallel(H.ty, mode(128 * MiB), arena_allocator, io);
const throughput = try benchmarkHashParallel(H.ty, mode(128 * MiB), arena, io);
try stdout.print("{s:>17}: {:10} MiB/s\n", .{ H.name, throughput / (1 * MiB) });
try stdout.flush();
}
@ -634,7 +630,7 @@ pub fn main() !void {
inline for (pwhashes) |H| {
if (filter == null or std.mem.find(u8, H.name, filter.?) != null) {
const throughput = try benchmarkPwhash(arena_allocator, H.ty, H.params, mode(64), io);
const throughput = try benchmarkPwhash(arena, H.ty, H.params, mode(64), io);
try stdout.print("{s:>17}: {d:10.3} s/ops\n", .{ H.name, throughput });
try stdout.flush();
}

View file

@ -353,14 +353,15 @@ fn mode(comptime x: comptime_int) comptime_int {
return if (builtin.mode == .Debug) x / 64 else x;
}
pub fn main() !void {
pub fn main(init: std.process.Init) !void {
const io = init.io;
const arena = init.arena.allocator();
var stdout_buffer: [0x100]u8 = undefined;
var stdout_writer = Io.File.stdout().writer(&stdout_buffer);
var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer);
const stdout = &stdout_writer.interface;
var buffer: [1024]u8 = undefined;
var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
const args = try std.process.argsAlloc(fixed.allocator());
const args = try init.minimal.args.toSlice(arena);
var filter: ?[]u8 = "";
var count: usize = mode(128 * MiB);

View file

@ -463,8 +463,33 @@ pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix
};
pub const RunOptions = struct {
spawn_options: SpawnOptions,
argv: []const []const u8,
max_output_bytes: usize = 50 * 1024,
/// Set to change the current working directory when spawning the child process.
cwd: ?[]const u8 = null,
/// Set to change the current working directory when spawning the child process.
/// This is not yet implemented for Windows. See https://github.com/ziglang/zig/issues/5190
/// Once that is done, `cwd` will be deprecated in favor of this field.
cwd_dir: ?Io.Dir = null,
/// Replaces the child environment when provided. The PATH value from here
/// is not used to resolve `argv[0]`; that resolution always uses parent
/// environment.
env_map: ?*const Environ.Map = null,
expand_arg0: ArgExpansion = .no_expand,
/// When populated, a pipe will be created for the child process to
/// communicate progress back to the parent. The file descriptor of the
/// write end of the pipe will be specified in the `ZIG_PROGRESS`
/// environment variable inside the child process. The progress reported by
/// the child will be attached to this progress node in the parent process.
///
/// The child's progress tree will be grafted into the parent's progress tree,
/// by substituting this node with the child's root node.
progress_node: std.Progress.Node = std.Progress.Node.none,
/// Windows-only. Sets the CREATE_NO_WINDOW flag in CreateProcess.
create_no_window: bool = true,
/// Darwin-only. Disable ASLR for the child process.
disable_aslr: bool = false,
};
pub const RunResult = struct {
@ -476,7 +501,20 @@ pub const RunResult = 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 run(gpa: Allocator, io: Io, options: RunOptions) RunError!RunResult {
var child = try spawn(io, options.spawn_options);
var child = try spawn(io, .{
.argv = options.argv,
.cwd = options.cwd,
.cwd_dir = options.cwd_dir,
.env_map = options.env_map,
.expand_arg0 = options.expand_arg0,
.progress_node = options.progress_node,
.create_no_window = options.create_no_window,
.disable_aslr = options.disable_aslr,
.stdin = .ignore,
.stdout = .pipe,
.stderr = .pipe,
});
defer child.kill(io);
var stdout: std.ArrayList(u8) = .empty;

View file

@ -208,16 +208,16 @@ pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!Lib
} else if (is_haiku) {
try self.findNativeIncludeDirPosix(gpa, io, args);
try self.findNativeGccDirHaiku(gpa, io, args);
self.crt_dir = try gpa.dupeZ(u8, "/system/develop/lib");
self.crt_dir = try gpa.dupe(u8, "/system/develop/lib");
} else if (builtin.target.os.tag == .illumos) {
// There is only one libc, and its headers/libraries are always in the same spot.
self.include_dir = try gpa.dupeZ(u8, "/usr/include");
self.sys_include_dir = try gpa.dupeZ(u8, "/usr/include");
self.crt_dir = try gpa.dupeZ(u8, "/usr/lib/64");
self.include_dir = try gpa.dupe(u8, "/usr/include");
self.sys_include_dir = try gpa.dupe(u8, "/usr/include");
self.crt_dir = try gpa.dupe(u8, "/usr/lib/64");
} else if (std.process.can_spawn) {
try self.findNativeIncludeDirPosix(gpa, io, args);
switch (builtin.target.os.tag) {
.freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try gpa.dupeZ(u8, "/usr/lib"),
.freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try gpa.dupe(u8, "/usr/lib"),
.linux => try self.findNativeCrtDirPosix(gpa, io, args),
else => {},
}
@ -269,7 +269,6 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
const run_res = std.process.run(gpa, io, .{
.max_output_bytes = 1024 * 1024,
.spawn_options = .{
.argv = argv.items,
.env_map = &env_map,
// Some C compilers, such as Clang, are known to rely on argv[0] to find the path
@ -277,7 +276,6 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
// error: unable to execute command: Executable "" doesn't exist!
// So we use the expandArg0 variant of ChildProcess to give them a helping hand.
.expand_arg0 = .expand,
},
}) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
else => {
@ -337,7 +335,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
if (self.include_dir == null) {
if (search_dir.access(io, include_dir_example_file, .{})) |_| {
self.include_dir = try gpa.dupeZ(u8, search_path);
self.include_dir = try gpa.dupe(u8, search_path);
} else |err| switch (err) {
error.FileNotFound => {},
else => return error.FileSystem,
@ -346,7 +344,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
if (self.sys_include_dir == null) {
if (search_dir.access(io, sys_include_dir_example_file, .{})) |_| {
self.sys_include_dir = try gpa.dupeZ(u8, search_path);
self.sys_include_dir = try gpa.dupe(u8, search_path);
} else |err| switch (err) {
error.FileNotFound => {},
else => return error.FileSystem,
@ -560,7 +558,7 @@ pub const CCPrintFileNameOptions = struct {
};
/// caller owns returned memory
fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8 {
fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![]u8 {
// Detect infinite loops.
var env_map = try args.env_map.clone(gpa);
defer env_map.deinit();
@ -587,7 +585,6 @@ fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8
const run_res = std.process.run(gpa, io, .{
.max_output_bytes = 1024 * 1024,
.spawn_options = .{
.argv = argv.items,
.env_map = &env_map,
// Some C compilers, such as Clang, are known to rely on argv[0] to find the path
@ -595,7 +592,6 @@ fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8
// error: unable to execute command: Executable "" doesn't exist!
// So we use the expandArg0 variant of ChildProcess to give them a helping hand.
.expand_arg0 = .expand,
},
}) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
else => return error.UnableToSpawnCCompiler,
@ -621,10 +617,10 @@ fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8
// So we detect failure by checking if the output matches exactly the input.
if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound;
switch (args.want_dirname) {
.full_path => return gpa.dupeZ(u8, line),
.full_path => return gpa.dupe(u8, line),
.only_dir => {
const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
return gpa.dupeZ(u8, dirname);
return gpa.dupe(u8, dirname);
},
}
}

View file

@ -17,9 +17,9 @@ pub const macos = @import("darwin/macos.zig");
///
/// If error.OutOfMemory occurs in Allocator, this function returns null.
pub fn isSdkInstalled(gpa: Allocator, io: Io) bool {
const result = std.process.run(gpa, io, .{ .spawn_options = .{
const result = std.process.run(gpa, io, .{
.argv = &.{ "xcode-select", "--print-path" },
} }) catch return false;
}) catch return false;
defer {
gpa.free(result.stderr);
gpa.free(result.stdout);
@ -47,7 +47,7 @@ pub fn getSdk(gpa: Allocator, io: Io, target: *const Target) ?[]const u8 {
else => return null,
};
const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" };
const result = std.process.run(gpa, io, .{ .spawn_options = .{ .argv = argv } }) catch return null;
const result = std.process.run(gpa, io, .{ .argv = argv }) catch return null;
defer {
gpa.free(result.stderr);
gpa.free(result.stdout);

View file

@ -4,31 +4,23 @@ const Io = std.Io;
// 42 is expected by parent; other values result in test failure
var exit_code: u8 = 42;
pub fn main() !void {
var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const arena = arena_state.allocator();
var threaded: std.Io.Threaded = .init(arena, .{});
defer threaded.deinit();
const io = threaded.io();
try run(arena, io);
arena_state.deinit();
pub fn main(init: std.process.Init) !void {
try run(init.arena.allocator(), init.io, init.minimal.args);
std.process.exit(exit_code);
}
fn run(allocator: std.mem.Allocator, io: Io) !void {
var args = try std.process.argsWithAllocator(allocator);
defer args.deinit();
_ = args.next() orelse unreachable; // skip binary name
fn run(arena: std.mem.Allocator, io: Io, args: std.process.Args) !void {
var it = try args.iterateAllocator(arena);
defer it.deinit();
_ = it.next() orelse unreachable; // skip binary name
// test cmd args
const hello_arg = "hello arg";
const a1 = args.next() orelse unreachable;
const a1 = it.next() orelse unreachable;
if (!std.mem.eql(u8, a1, hello_arg)) {
testError(io, "first arg: '{s}'; want '{s}'", .{ a1, hello_arg });
}
if (args.next()) |a2| {
if (it.next()) |a2| {
testError(io, "expected only one arg; got more: {s}", .{a2});
}

View file

@ -2,17 +2,13 @@ const std = @import("std");
/// Checks the existence of files relative to cwd.
/// A path starting with ! should not exist.
pub fn main() !void {
var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_state.deinit();
pub fn main(init: std.process.Init) !void {
const arena = init.arena.allocator();
const io = init.io;
const arena = arena_state.allocator();
var arg_it = try std.process.argsWithAllocator(arena);
var arg_it = try init.minimal.args.iterateAllocator(arena);
_ = arg_it.next();
const io = std.Io.Threaded.global_single_threaded.ioBasic();
const cwd = std.Io.Dir.cwd();
const cwd_realpath = try cwd.realPathFileAlloc(io, ".", arena);

View file

@ -6,19 +6,14 @@ fn testOne(in: abi.Slice) callconv(.c) void {
std.debug.assertReadable(in.toSlice());
}
pub fn main() !void {
var debug_gpa_ctx: std.heap.DebugAllocator(.{}) = .init;
defer _ = debug_gpa_ctx.deinit();
const gpa = debug_gpa_ctx.allocator();
pub fn main(init: std.process.Init) !void {
const gpa = init.gpa;
const io = init.io;
var args = try std.process.argsWithAllocator(gpa);
var args = try init.minimal.args.iterateAllocator(gpa);
defer args.deinit();
_ = args.skip(); // executable name
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
const cache_dir_path = args.next() orelse @panic("expected cache directory path argument");
var cache_dir = try std.Io.Dir.cwd().openDir(io, cache_dir_path, .{});
defer cache_dir.close(io);

View file

@ -1,8 +1,8 @@
const std = @import("std");
pub fn main() !void {
const io = std.Io.Threaded.global_single_threaded.ioBasic();
var args = try std.process.argsWithAllocator(std.heap.page_allocator);
pub fn main(init: std.process.Init) !void {
const io = init.io;
var args = try init.minimal.argsAllocator(init.arena.allocator());
_ = args.skip();
const filename = args.next().?;
const file = try std.Io.Dir.cwd().createFile(io, filename, .{});

View file

@ -4,16 +4,11 @@ const std = @import("std");
const Io = std.Io;
const Allocator = std.mem.Allocator;
pub fn main() anyerror!void {
var debug_alloc_inst: std.heap.DebugAllocator(.{}) = .init;
defer std.debug.assert(debug_alloc_inst.deinit() == .ok);
const gpa = debug_alloc_inst.allocator();
pub fn main(init: std.process.Init) !void {
const gpa = init.gpa;
const io = init.io;
var threaded: Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
var it = try std.process.argsWithAllocator(gpa);
var it = try init.minimal.argsAllocator(gpa);
defer it.deinit();
_ = it.next() orelse unreachable; // skip binary name
const child_exe_path_orig = it.next() orelse unreachable;

View file

@ -2,15 +2,11 @@ const std = @import("std");
const Io = std.Io;
const Allocator = std.mem.Allocator;
pub fn main() anyerror!void {
var debug_alloc_inst: std.heap.DebugAllocator(.{}) = .init;
defer std.debug.assert(debug_alloc_inst.deinit() == .ok);
const gpa = debug_alloc_inst.allocator();
pub fn main(init: std.process.Init) !void {
const gpa = init.gpa;
const io = init.io;
var threaded: Io.Threaded = .init(gpa, .{});
const io = threaded.io();
var it = try std.process.argsWithAllocator(gpa);
var it = try init.minimal.argsAllocator(gpa);
defer it.deinit();
_ = it.next() orelse unreachable; // skip binary name
const child_exe_path_orig = it.next() orelse unreachable;

View file

@ -5,16 +5,11 @@ const Allocator = std.mem.Allocator;
const windows = std.os.windows;
const utf16Literal = std.unicode.utf8ToUtf16LeStringLiteral;
pub fn main() anyerror!void {
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer if (debug_allocator.deinit() == .leak) @panic("found memory leaks");
const gpa = debug_allocator.allocator();
pub fn main(init: std.process.Init) !void {
const gpa = init.gpa;
const io = init.io;
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
var it = try std.process.argsWithAllocator(gpa);
var it = try init.minimal.argsAllocator(gpa);
defer it.deinit();
_ = it.next() orelse unreachable; // skip binary name
const hello_exe_cache_path = it.next() orelse unreachable;

View file

@ -28,21 +28,13 @@ const usage =
\\
;
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_instance.deinit();
pub fn main(init: std.process.Init) !void {
const arena = init.arena.allocator();
const io = init.io;
const arena = arena_instance.allocator();
var args_it = try process.argsWithAllocator(arena);
var args_it = try init.minimal.args.iterateAllocator(arena);
if (!args_it.skip()) @panic("expected self arg");
const gpa = arena;
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
var opt_code_dir: ?[]const u8 = null;
var opt_input: ?[]const u8 = null;
var opt_output: ?[]const u8 = null;

View file

@ -29,21 +29,13 @@ const usage =
\\
;
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_instance.deinit();
pub fn main(init: std.process.Init) !void {
const arena = init.arena.allocator();
const io = init.io;
const arena = arena_instance.allocator();
var args_it = try process.argsWithAllocator(arena);
var args_it = try init.minimal.args.iterateAllocator(arena);
if (!args_it.skip()) fatal("missing argv[0]", .{});
const gpa = arena;
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
var opt_input: ?[]const u8 = null;
var opt_output: ?[]const u8 = null;
var opt_zig: ?[]const u8 = null;

View file

@ -44,7 +44,7 @@ pub fn main(init: std.process.Init) !void {
var debug_log_args: std.ArrayList([]const u8) = .empty;
var arg_it = try std.process.argsWithAllocator(arena);
var arg_it = try init.minimal.argsIterator(arena);
_ = arg_it.skip();
while (arg_it.next()) |arg| {
if (arg.len > 0 and arg[0] == '-') {

View file

@ -1883,20 +1883,11 @@ const targets = [_]ArchTarget{
},
};
pub fn main() anyerror!void {
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer _ = debug_allocator.deinit();
const gpa = debug_allocator.allocator();
pub fn main(init: std.process.Init) !void {
const arena = init.arena_allocator.allocator();
const io = init.io;
var arena_state: std.heap.ArenaAllocator = .init(gpa);
defer arena_state.deinit();
const arena = arena_state.allocator();
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.io();
var args = try std.process.argsWithAllocator(arena);
var args = try init.minimal.args.iterateAllocator(arena);
const args0 = args.next().?;
const llvm_tblgen_exe = args.next() orelse