authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-08 18:46:55-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:08-08:00
log3725f72293c87a73e0c11e74739574c7b78bb53d
tree50318358ec9bcd51c85d90c080099625460833cc
parent9e3bda5efffb12dd6491b4f7c92ccc89b9043c64

update std.process.Child.run occurences to use io


10 files changed, 115 insertions(+), 135 deletions(-)

lib/compiler/libc.zig+5-6
...@@ -78,7 +78,7 @@ pub fn main() !void {...@@ -78,7 +78,7 @@ pub fn main() !void {
78 if (input_file) |libc_file| {78 if (input_file) |libc_file| {
79 const libc = try arena.create(LibCInstallation);79 const libc = try arena.create(LibCInstallation);
80 libc.* = LibCInstallation.parse(arena, libc_file, &target) catch |err| {80 libc.* = LibCInstallation.parse(arena, libc_file, &target) catch |err| {
81 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });81 fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err });
82 };82 };
83 break :libc libc;83 break :libc libc;
84 } else {84 } else {
...@@ -97,7 +97,7 @@ pub fn main() !void {...@@ -97,7 +97,7 @@ pub fn main() !void {
97 libc_installation,97 libc_installation,
98 ) catch |err| {98 ) catch |err| {
99 const zig_target = try target.zigTriple(arena);99 const zig_target = try target.zigTriple(arena);
100 fatal("unable to detect libc for target {s}: {s}", .{ zig_target, @errorName(err) });100 fatal("unable to detect libc for target {s}: {t}", .{ zig_target, err });
101 };101 };
102102
103 if (libc_dirs.libc_include_dir_list.len == 0) {103 if (libc_dirs.libc_include_dir_list.len == 0) {
...@@ -115,19 +115,18 @@ pub fn main() !void {...@@ -115,19 +115,18 @@ pub fn main() !void {
115115
116 if (input_file) |libc_file| {116 if (input_file) |libc_file| {
117 var libc = LibCInstallation.parse(gpa, libc_file, &target) catch |err| {117 var libc = LibCInstallation.parse(gpa, libc_file, &target) catch |err| {
118 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });118 fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err });
119 };119 };
120 defer libc.deinit(gpa);120 defer libc.deinit(gpa);
121 } else {121 } else {
122 if (!target_query.canDetectLibC()) {122 if (!target_query.canDetectLibC()) {
123 fatal("unable to detect libc for non-native target", .{});123 fatal("unable to detect libc for non-native target", .{});
124 }124 }
125 var libc = LibCInstallation.findNative(.{125 var libc = LibCInstallation.findNative(gpa, io, .{
126 .allocator = gpa,
127 .verbose = true,126 .verbose = true,
128 .target = &target,127 .target = &target,
129 }) catch |err| {128 }) catch |err| {
130 fatal("unable to detect native libc: {s}", .{@errorName(err)});129 fatal("unable to detect native libc: {t}", .{err});
131 };130 };
132 defer libc.deinit(gpa);131 defer libc.deinit(gpa);
133132
lib/compiler/reduce.zig+2-5
...@@ -307,11 +307,8 @@ fn termToInteresting(term: std.process.Child.Term) Interestingness {...@@ -307,11 +307,8 @@ fn termToInteresting(term: std.process.Child.Term) Interestingness {
307 };307 };
308}308}
309309
310fn runCheck(arena: std.mem.Allocator, argv: []const []const u8) !Interestingness {310fn runCheck(arena: Allocator, io: Io, argv: []const []const u8) !Interestingness {
311 const result = try std.process.Child.run(.{311 const result = try std.process.Child.run(arena, io, .{ .argv = argv });
312 .allocator = arena,
313 .argv = argv,
314 });
315 if (result.stderr.len != 0)312 if (result.stderr.len != 0)
316 std.debug.print("{s}", .{result.stderr});313 std.debug.print("{s}", .{result.stderr});
317 return termToInteresting(result.term);314 return termToInteresting(result.term);
lib/std/Build/Step.zig+2-2
...@@ -350,6 +350,7 @@ pub fn captureChildProcess(...@@ -350,6 +350,7 @@ pub fn captureChildProcess(
350 argv: []const []const u8,350 argv: []const []const u8,
351) !std.process.Child.RunResult {351) !std.process.Child.RunResult {
352 const arena = s.owner.allocator;352 const arena = s.owner.allocator;
353 const io = s.owner.graph.io;
353354
354 // If an error occurs, it's happened in this command:355 // If an error occurs, it's happened in this command:
355 assert(s.result_failed_command == null);356 assert(s.result_failed_command == null);
...@@ -358,8 +359,7 @@ pub fn captureChildProcess(...@@ -358,8 +359,7 @@ pub fn captureChildProcess(
358 try handleChildProcUnsupported(s);359 try handleChildProcUnsupported(s);
359 try handleVerbose(s.owner, null, argv);360 try handleVerbose(s.owner, null, argv);
360361
361 const result = std.process.Child.run(.{362 const result = std.process.Child.run(arena, io, .{
362 .allocator = arena,
363 .argv = argv,363 .argv = argv,
364 .progress_node = progress_node,364 .progress_node = progress_node,
365 }) catch |err| return s.fail("failed to run {s}: {t}", .{ argv[0], err });365 }) catch |err| return s.fail("failed to run {s}: {t}", .{ argv[0], err });
lib/std/zig/LibCInstallation.zig+48-70
...@@ -166,8 +166,6 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {...@@ -166,8 +166,6 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {
166}166}
167167
168pub const FindNativeOptions = struct {168pub const FindNativeOptions = struct {
169 allocator: Allocator,
170 io: Io,
171 target: *const std.Target,169 target: *const std.Target,
172170
173 /// If enabled, will print human-friendly errors to stderr.171 /// If enabled, will print human-friendly errors to stderr.
...@@ -175,10 +173,7 @@ pub const FindNativeOptions = struct {...@@ -175,10 +173,7 @@ pub const FindNativeOptions = struct {
175};173};
176174
177/// Finds the default, native libc.175/// Finds the default, native libc.
178pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {176pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!LibCInstallation {
179 const gpa = args.allocator;
180 const io = args.io;
181
182 var self: LibCInstallation = .{};177 var self: LibCInstallation = .{};
183178
184 if (is_darwin and args.target.os.tag.isDarwin()) {179 if (is_darwin and args.target.os.tag.isDarwin()) {
...@@ -203,14 +198,14 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {...@@ -203,14 +198,14 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
203 };198 };
204 defer sdk.free(gpa);199 defer sdk.free(gpa);
205200
206 try self.findNativeMsvcIncludeDir(args, sdk);201 try self.findNativeMsvcIncludeDir(gpa, io, sdk);
207 try self.findNativeMsvcLibDir(args, sdk);202 try self.findNativeMsvcLibDir(gpa, sdk);
208 try self.findNativeKernel32LibDir(args, sdk);203 try self.findNativeKernel32LibDir(gpa, io, args, sdk);
209 try self.findNativeIncludeDirWindows(args, sdk);204 try self.findNativeIncludeDirWindows(gpa, io, args, sdk);
210 try self.findNativeCrtDirWindows(args, sdk);205 try self.findNativeCrtDirWindows(gpa, io, args.target, sdk);
211 } else if (is_haiku) {206 } else if (is_haiku) {
212 try self.findNativeIncludeDirPosix(args);207 try self.findNativeIncludeDirPosix(args);
213 try self.findNativeGccDirHaiku(args);208 try self.findNativeGccDirHaiku(gpa, io, args);
214 self.crt_dir = try gpa.dupeZ(u8, "/system/develop/lib");209 self.crt_dir = try gpa.dupeZ(u8, "/system/develop/lib");
215 } else if (builtin.target.os.tag == .illumos) {210 } else if (builtin.target.os.tag == .illumos) {
216 // There is only one libc, and its headers/libraries are always in the same spot.211 // There is only one libc, and its headers/libraries are always in the same spot.
...@@ -221,7 +216,7 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {...@@ -221,7 +216,7 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
221 try self.findNativeIncludeDirPosix(args);216 try self.findNativeIncludeDirPosix(args);
222 switch (builtin.target.os.tag) {217 switch (builtin.target.os.tag) {
223 .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try gpa.dupeZ(u8, "/usr/lib"),218 .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try gpa.dupeZ(u8, "/usr/lib"),
224 .linux => try self.findNativeCrtDirPosix(args),219 .linux => try self.findNativeCrtDirPosix(gpa, io, args),
225 else => {},220 else => {},
226 }221 }
227 } else {222 } else {
...@@ -241,12 +236,9 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void {...@@ -241,12 +236,9 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void {
241 self.* = undefined;236 self.* = undefined;
242}237}
243238
244fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {239fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
245 const allocator = args.allocator;
246 const io = args.io;
247
248 // Detect infinite loops.240 // Detect infinite loops.
249 var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) {241 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {
250 error.Unexpected => unreachable, // WASI-only242 error.Unexpected => unreachable, // WASI-only
251 else => |e| return e,243 else => |e| return e,
252 };244 };
...@@ -265,7 +257,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -265,7 +257,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
265257
266 const dev_null = if (is_windows) "nul" else "/dev/null";258 const dev_null = if (is_windows) "nul" else "/dev/null";
267259
268 var argv = std.array_list.Managed([]const u8).init(allocator);260 var argv = std.array_list.Managed([]const u8).init(gpa);
269 defer argv.deinit();261 defer argv.deinit();
270262
271 try appendCcExe(&argv, skip_cc_env_var);263 try appendCcExe(&argv, skip_cc_env_var);
...@@ -276,8 +268,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -276,8 +268,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
276 dev_null,268 dev_null,
277 });269 });
278270
279 const run_res = std.process.Child.run(.{271 const run_res = std.process.Child.run(gpa, io, .{
280 .allocator = allocator,
281 .argv = argv.items,272 .argv = argv.items,
282 .max_output_bytes = 1024 * 1024,273 .max_output_bytes = 1024 * 1024,
283 .env_map = &env_map,274 .env_map = &env_map,
...@@ -294,8 +285,8 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -294,8 +285,8 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
294 },285 },
295 };286 };
296 defer {287 defer {
297 allocator.free(run_res.stdout);288 gpa.free(run_res.stdout);
298 allocator.free(run_res.stderr);289 gpa.free(run_res.stderr);
299 }290 }
300 switch (run_res.term) {291 switch (run_res.term) {
301 .Exited => |code| if (code != 0) {292 .Exited => |code| if (code != 0) {
...@@ -309,7 +300,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -309,7 +300,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
309 }300 }
310301
311 var it = std.mem.tokenizeAny(u8, run_res.stderr, "\n\r");302 var it = std.mem.tokenizeAny(u8, run_res.stderr, "\n\r");
312 var search_paths = std.array_list.Managed([]const u8).init(allocator);303 var search_paths = std.array_list.Managed([]const u8).init(gpa);
313 defer search_paths.deinit();304 defer search_paths.deinit();
314 while (it.next()) |line| {305 while (it.next()) |line| {
315 if (line.len != 0 and line[0] == ' ') {306 if (line.len != 0 and line[0] == ' ') {
...@@ -345,7 +336,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -345,7 +336,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
345336
346 if (self.include_dir == null) {337 if (self.include_dir == null) {
347 if (search_dir.access(include_dir_example_file, .{})) |_| {338 if (search_dir.access(include_dir_example_file, .{})) |_| {
348 self.include_dir = try allocator.dupeZ(u8, search_path);339 self.include_dir = try gpa.dupeZ(u8, search_path);
349 } else |err| switch (err) {340 } else |err| switch (err) {
350 error.FileNotFound => {},341 error.FileNotFound => {},
351 else => return error.FileSystem,342 else => return error.FileSystem,
...@@ -354,7 +345,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -354,7 +345,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
354345
355 if (self.sys_include_dir == null) {346 if (self.sys_include_dir == null) {
356 if (search_dir.access(io, sys_include_dir_example_file, .{})) |_| {347 if (search_dir.access(io, sys_include_dir_example_file, .{})) |_| {
357 self.sys_include_dir = try allocator.dupeZ(u8, search_path);348 self.sys_include_dir = try gpa.dupeZ(u8, search_path);
358 } else |err| switch (err) {349 } else |err| switch (err) {
359 error.FileNotFound => {},350 error.FileNotFound => {},
360 else => return error.FileSystem,351 else => return error.FileSystem,
...@@ -372,16 +363,14 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F...@@ -372,16 +363,14 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
372363
373fn findNativeIncludeDirWindows(364fn findNativeIncludeDirWindows(
374 self: *LibCInstallation,365 self: *LibCInstallation,
375 args: FindNativeOptions,366 gpa: Allocator,
367 io: Io,
376 sdk: std.zig.WindowsSdk,368 sdk: std.zig.WindowsSdk,
377) FindError!void {369) FindError!void {
378 const allocator = args.allocator;
379 const io = args.io;
380
381 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;370 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;
382 const installs = fillInstallations(&install_buf, sdk);371 const installs = fillInstallations(&install_buf, sdk);
383372
384 var result_buf = std.array_list.Managed(u8).init(allocator);373 var result_buf = std.array_list.Managed(u8).init(gpa);
385 defer result_buf.deinit();374 defer result_buf.deinit();
386375
387 for (installs) |install| {376 for (installs) |install| {
...@@ -412,19 +401,18 @@ fn findNativeIncludeDirWindows(...@@ -412,19 +401,18 @@ fn findNativeIncludeDirWindows(
412401
413fn findNativeCrtDirWindows(402fn findNativeCrtDirWindows(
414 self: *LibCInstallation,403 self: *LibCInstallation,
415 args: FindNativeOptions,404 gpa: Allocator,
405 io: Io,
406 target: *const std.Target,
416 sdk: std.zig.WindowsSdk,407 sdk: std.zig.WindowsSdk,
417) FindError!void {408) FindError!void {
418 const allocator = args.allocator;
419 const io = args.io;
420
421 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;409 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;
422 const installs = fillInstallations(&install_buf, sdk);410 const installs = fillInstallations(&install_buf, sdk);
423411
424 var result_buf = std.array_list.Managed(u8).init(allocator);412 var result_buf = std.array_list.Managed(u8).init(gpa);
425 defer result_buf.deinit();413 defer result_buf.deinit();
426414
427 const arch_sub_dir = switch (args.target.cpu.arch) {415 const arch_sub_dir = switch (target.cpu.arch) {
428 .x86 => "x86",416 .x86 => "x86",
429 .x86_64 => "x64",417 .x86_64 => "x64",
430 .arm, .armeb => "arm",418 .arm, .armeb => "arm",
...@@ -457,9 +445,8 @@ fn findNativeCrtDirWindows(...@@ -457,9 +445,8 @@ fn findNativeCrtDirWindows(
457 return error.LibCRuntimeNotFound;445 return error.LibCRuntimeNotFound;
458}446}
459447
460fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {448fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
461 self.crt_dir = try ccPrintFileName(.{449 self.crt_dir = try ccPrintFileName(gpa, io, .{
462 .allocator = args.allocator,
463 .search_basename = switch (args.target.os.tag) {450 .search_basename = switch (args.target.os.tag) {
464 .linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",451 .linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",
465 else => "crt1.o",452 else => "crt1.o",
...@@ -469,9 +456,8 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindE...@@ -469,9 +456,8 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindE
469 });456 });
470}457}
471458
472fn findNativeGccDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindError!void {459fn findNativeGccDirHaiku(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
473 self.gcc_dir = try ccPrintFileName(.{460 self.gcc_dir = try ccPrintFileName(gpa, io, .{
474 .allocator = args.allocator,
475 .search_basename = "crtbeginS.o",461 .search_basename = "crtbeginS.o",
476 .want_dirname = .only_dir,462 .want_dirname = .only_dir,
477 .verbose = args.verbose,463 .verbose = args.verbose,
...@@ -480,16 +466,15 @@ fn findNativeGccDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindE...@@ -480,16 +466,15 @@ fn findNativeGccDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindE
480466
481fn findNativeKernel32LibDir(467fn findNativeKernel32LibDir(
482 self: *LibCInstallation,468 self: *LibCInstallation,
469 gpa: Allocator,
470 io: Io,
483 args: FindNativeOptions,471 args: FindNativeOptions,
484 sdk: std.zig.WindowsSdk,472 sdk: std.zig.WindowsSdk,
485) FindError!void {473) FindError!void {
486 const allocator = args.allocator;
487 const io = args.io;
488
489 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;474 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;
490 const installs = fillInstallations(&install_buf, sdk);475 const installs = fillInstallations(&install_buf, sdk);
491476
492 var result_buf = std.array_list.Managed(u8).init(allocator);477 var result_buf = std.array_list.Managed(u8).init(gpa);
493 defer result_buf.deinit();478 defer result_buf.deinit();
494479
495 const arch_sub_dir = switch (args.target.cpu.arch) {480 const arch_sub_dir = switch (args.target.cpu.arch) {
...@@ -527,18 +512,16 @@ fn findNativeKernel32LibDir(...@@ -527,18 +512,16 @@ fn findNativeKernel32LibDir(
527512
528fn findNativeMsvcIncludeDir(513fn findNativeMsvcIncludeDir(
529 self: *LibCInstallation,514 self: *LibCInstallation,
530 args: FindNativeOptions,515 gpa: Allocator,
516 io: Io,
531 sdk: std.zig.WindowsSdk,517 sdk: std.zig.WindowsSdk,
532) FindError!void {518) FindError!void {
533 const allocator = args.allocator;
534 const io = args.io;
535
536 const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCStdLibHeaderNotFound;519 const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCStdLibHeaderNotFound;
537 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;520 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
538 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;521 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
539522
540 const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" });523 const dir_path = try fs.path.join(gpa, &[_][]const u8{ up2, "include" });
541 errdefer allocator.free(dir_path);524 errdefer gpa.free(dir_path);
542525
543 var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| switch (err) {526 var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| switch (err) {
544 error.FileNotFound,527 error.FileNotFound,
...@@ -560,27 +543,23 @@ fn findNativeMsvcIncludeDir(...@@ -560,27 +543,23 @@ fn findNativeMsvcIncludeDir(
560543
561fn findNativeMsvcLibDir(544fn findNativeMsvcLibDir(
562 self: *LibCInstallation,545 self: *LibCInstallation,
563 args: FindNativeOptions,546 gpa: Allocator,
564 sdk: std.zig.WindowsSdk,547 sdk: std.zig.WindowsSdk,
565) FindError!void {548) FindError!void {
566 const allocator = args.allocator;
567 const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCRuntimeNotFound;549 const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCRuntimeNotFound;
568 self.msvc_lib_dir = try allocator.dupe(u8, msvc_lib_dir);550 self.msvc_lib_dir = try gpa.dupe(u8, msvc_lib_dir);
569}551}
570552
571pub const CCPrintFileNameOptions = struct {553pub const CCPrintFileNameOptions = struct {
572 allocator: Allocator,
573 search_basename: []const u8,554 search_basename: []const u8,
574 want_dirname: enum { full_path, only_dir },555 want_dirname: enum { full_path, only_dir },
575 verbose: bool = false,556 verbose: bool = false,
576};557};
577558
578/// caller owns returned memory559/// caller owns returned memory
579fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {560fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8 {
580 const allocator = args.allocator;
581
582 // Detect infinite loops.561 // Detect infinite loops.
583 var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) {562 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {
584 error.Unexpected => unreachable, // WASI-only563 error.Unexpected => unreachable, // WASI-only
585 else => |e| return e,564 else => |e| return e,
586 };565 };
...@@ -597,17 +576,16 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {...@@ -597,17 +576,16 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
597 break :blk false;576 break :blk false;
598 };577 };
599578
600 var argv = std.array_list.Managed([]const u8).init(allocator);579 var argv = std.array_list.Managed([]const u8).init(gpa);
601 defer argv.deinit();580 defer argv.deinit();
602581
603 const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={s}", .{args.search_basename});582 const arg1 = try std.fmt.allocPrint(gpa, "-print-file-name={s}", .{args.search_basename});
604 defer allocator.free(arg1);583 defer gpa.free(arg1);
605584
606 try appendCcExe(&argv, skip_cc_env_var);585 try appendCcExe(&argv, skip_cc_env_var);
607 try argv.append(arg1);586 try argv.append(arg1);
608587
609 const run_res = std.process.Child.run(.{588 const run_res = std.process.Child.run(gpa, io, .{
610 .allocator = allocator,
611 .argv = argv.items,589 .argv = argv.items,
612 .max_output_bytes = 1024 * 1024,590 .max_output_bytes = 1024 * 1024,
613 .env_map = &env_map,591 .env_map = &env_map,
...@@ -621,8 +599,8 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {...@@ -621,8 +599,8 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
621 else => return error.UnableToSpawnCCompiler,599 else => return error.UnableToSpawnCCompiler,
622 };600 };
623 defer {601 defer {
624 allocator.free(run_res.stdout);602 gpa.free(run_res.stdout);
625 allocator.free(run_res.stderr);603 gpa.free(run_res.stderr);
626 }604 }
627 switch (run_res.term) {605 switch (run_res.term) {
628 .Exited => |code| if (code != 0) {606 .Exited => |code| if (code != 0) {
...@@ -641,10 +619,10 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {...@@ -641,10 +619,10 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
641 // So we detect failure by checking if the output matches exactly the input.619 // So we detect failure by checking if the output matches exactly the input.
642 if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound;620 if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound;
643 switch (args.want_dirname) {621 switch (args.want_dirname) {
644 .full_path => return allocator.dupeZ(u8, line),622 .full_path => return gpa.dupeZ(u8, line),
645 .only_dir => {623 .only_dir => {
646 const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;624 const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
647 return allocator.dupeZ(u8, dirname);625 return gpa.dupeZ(u8, dirname);
648 },626 },
649 }627 }
650}628}
lib/std/zig/system/darwin.zig+15-14
...@@ -1,28 +1,29 @@...@@ -1,28 +1,29 @@
1const std = @import("std");1const std = @import("std");
2const Io = std.Io;
2const mem = std.mem;3const mem = std.mem;
3const Allocator = mem.Allocator;4const Allocator = std.mem.Allocator;
4const Target = std.Target;5const Target = std.Target;
5const Version = std.SemanticVersion;6const Version = std.SemanticVersion;
67
7pub const macos = @import("darwin/macos.zig");8pub const macos = @import("darwin/macos.zig");
89
9/// Check if SDK is installed on Darwin without triggering CLT installation popup window.10/// Check if SDK is installed on Darwin without triggering CLT installation popup window.
10/// Note: simply invoking `xcrun` will inevitably trigger the CLT installation popup.11///
12/// Simply invoking `xcrun` will inevitably trigger the CLT installation popup.
11/// Therefore, we resort to invoking `xcode-select --print-path` and checking13/// Therefore, we resort to invoking `xcode-select --print-path` and checking
12/// if the status is nonzero.14/// if the status is nonzero.
15///
13/// stderr from xcode-select is ignored.16/// stderr from xcode-select is ignored.
17///
14/// If error.OutOfMemory occurs in Allocator, this function returns null.18/// If error.OutOfMemory occurs in Allocator, this function returns null.
15pub fn isSdkInstalled(allocator: Allocator) bool {19pub fn isSdkInstalled(gpa: Allocator, io: Io) bool {
16 const result = std.process.Child.run(.{20 const result = std.process.Child.run(gpa, io, .{
17 .allocator = allocator,
18 .argv = &.{ "xcode-select", "--print-path" },21 .argv = &.{ "xcode-select", "--print-path" },
19 }) catch return false;22 }) catch return false;
20
21 defer {23 defer {
22 allocator.free(result.stderr);24 gpa.free(result.stderr);
23 allocator.free(result.stdout);25 gpa.free(result.stdout);
24 }26 }
25
26 return switch (result.term) {27 return switch (result.term) {
27 .Exited => |code| if (code == 0) result.stdout.len > 0 else false,28 .Exited => |code| if (code == 0) result.stdout.len > 0 else false,
28 else => false,29 else => false,
...@@ -34,7 +35,7 @@ pub fn isSdkInstalled(allocator: Allocator) bool {...@@ -34,7 +35,7 @@ pub fn isSdkInstalled(allocator: Allocator) bool {
34/// Caller owns the memory.35/// Caller owns the memory.
35/// stderr from xcrun is ignored.36/// stderr from xcrun is ignored.
36/// If error.OutOfMemory occurs in Allocator, this function returns null.37/// If error.OutOfMemory occurs in Allocator, this function returns null.
37pub fn getSdk(allocator: Allocator, target: *const Target) ?[]const u8 {38pub fn getSdk(gpa: Allocator, io: Io, target: *const Target) ?[]const u8 {
38 const is_simulator_abi = target.abi == .simulator;39 const is_simulator_abi = target.abi == .simulator;
39 const sdk = switch (target.os.tag) {40 const sdk = switch (target.os.tag) {
40 .driverkit => "driverkit",41 .driverkit => "driverkit",
...@@ -46,16 +47,16 @@ pub fn getSdk(allocator: Allocator, target: *const Target) ?[]const u8 {...@@ -46,16 +47,16 @@ pub fn getSdk(allocator: Allocator, target: *const Target) ?[]const u8 {
46 else => return null,47 else => return null,
47 };48 };
48 const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" };49 const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" };
49 const result = std.process.Child.run(.{ .allocator = allocator, .argv = argv }) catch return null;50 const result = std.process.Child.run(gpa, io, .{ .argv = argv }) catch return null;
50 defer {51 defer {
51 allocator.free(result.stderr);52 gpa.free(result.stderr);
52 allocator.free(result.stdout);53 gpa.free(result.stdout);
53 }54 }
54 switch (result.term) {55 switch (result.term) {
55 .Exited => |code| if (code != 0) return null,56 .Exited => |code| if (code != 0) return null,
56 else => return null,57 else => return null,
57 }58 }
58 return allocator.dupe(u8, mem.trimEnd(u8, result.stdout, "\r\n")) catch null;59 return gpa.dupe(u8, mem.trimEnd(u8, result.stdout, "\r\n")) catch null;
59}60}
6061
61test {62test {
src/main.zig+1-2
...@@ -4017,8 +4017,7 @@ fn createModule(...@@ -4017,8 +4017,7 @@ fn createModule(
4017 any_name_queries_remaining)4017 any_name_queries_remaining)
4018 {4018 {
4019 if (create_module.libc_installation == null) {4019 if (create_module.libc_installation == null) {
4020 create_module.libc_installation = LibCInstallation.findNative(.{4020 create_module.libc_installation = LibCInstallation.findNative(arena, io, .{
4021 .allocator = arena,
4022 .verbose = true,4021 .verbose = true,
4023 .target = target,4022 .target = target,
4024 }) catch |err| {4023 }) catch |err| {
test/standalone/child_process/main.zig+1-1
...@@ -57,7 +57,7 @@ pub fn main() !void {...@@ -57,7 +57,7 @@ pub fn main() !void {
57 // Check that FileNotFound is consistent across platforms when trying to spawn an executable that doesn't exist57 // Check that FileNotFound is consistent across platforms when trying to spawn an executable that doesn't exist
58 const missing_child_path = try std.mem.concat(gpa, u8, &.{ child_path, "_intentionally_missing" });58 const missing_child_path = try std.mem.concat(gpa, u8, &.{ child_path, "_intentionally_missing" });
59 defer gpa.free(missing_child_path);59 defer gpa.free(missing_child_path);
60 try std.testing.expectError(error.FileNotFound, std.process.Child.run(.{ .allocator = gpa, .argv = &.{missing_child_path} }));60 try std.testing.expectError(error.FileNotFound, std.process.Child.run(gpa, io, .{ .argv = &.{missing_child_path} }));
61}61}
6262
63var parent_test_error = false;63var parent_test_error = false;
test/standalone/windows_bat_args/fuzz.zig+9-8
...@@ -1,5 +1,7 @@...@@ -1,5 +1,7 @@
1const std = @import("std");
2const builtin = @import("builtin");1const builtin = @import("builtin");
2
3const std = @import("std");
4const Io = std.Io;
3const Allocator = std.mem.Allocator;5const Allocator = std.mem.Allocator;
46
5pub fn main() anyerror!void {7pub fn main() anyerror!void {
...@@ -78,13 +80,13 @@ pub fn main() anyerror!void {...@@ -78,13 +80,13 @@ pub fn main() anyerror!void {
78 }80 }
79}81}
8082
81fn testExec(gpa: std.mem.Allocator, args: []const []const u8, env: ?*std.process.EnvMap) !void {83fn testExec(gpa: Allocator, io: Io, args: []const []const u8, env: ?*std.process.EnvMap) !void {
82 try testExecBat(gpa, "args1.bat", args, env);84 try testExecBat(gpa, io, "args1.bat", args, env);
83 try testExecBat(gpa, "args2.bat", args, env);85 try testExecBat(gpa, io, "args2.bat", args, env);
84 try testExecBat(gpa, "args3.bat", args, env);86 try testExecBat(gpa, io, "args3.bat", args, env);
85}87}
8688
87fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void {89fn testExecBat(gpa: Allocator, io: Io, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void {
88 const argv = try gpa.alloc([]const u8, 1 + args.len);90 const argv = try gpa.alloc([]const u8, 1 + args.len);
89 defer gpa.free(argv);91 defer gpa.free(argv);
90 argv[0] = bat;92 argv[0] = bat;
...@@ -92,8 +94,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8...@@ -92,8 +94,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8
9294
93 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");95 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");
9496
95 const result = try std.process.Child.run(.{97 const result = try std.process.Child.run(gpa, io, .{
96 .allocator = gpa,
97 .env_map = env,98 .env_map = env,
98 .argv = argv,99 .argv = argv,
99 });100 });
test/standalone/windows_bat_args/test.zig+6-5
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const Io = std.Io;
3const Allocator = std.mem.Allocator;
24
3pub fn main() anyerror!void {5pub fn main() anyerror!void {
4 var debug_alloc_inst: std.heap.DebugAllocator(.{}) = .init;6 var debug_alloc_inst: std.heap.DebugAllocator(.{}) = .init;
...@@ -121,17 +123,17 @@ pub fn main() anyerror!void {...@@ -121,17 +123,17 @@ pub fn main() anyerror!void {
121 try std.testing.expectError(error.FileNotFound, tmp.dir.access("file.txt", .{}));123 try std.testing.expectError(error.FileNotFound, tmp.dir.access("file.txt", .{}));
122}124}
123125
124fn testExecError(err: anyerror, gpa: std.mem.Allocator, args: []const []const u8) !void {126fn testExecError(err: anyerror, gpa: Allocator, args: []const []const u8) !void {
125 return std.testing.expectError(err, testExec(gpa, args, null));127 return std.testing.expectError(err, testExec(gpa, args, null));
126}128}
127129
128fn testExec(gpa: std.mem.Allocator, args: []const []const u8, env: ?*std.process.EnvMap) !void {130fn testExec(gpa: Allocator, args: []const []const u8, env: ?*std.process.EnvMap) !void {
129 try testExecBat(gpa, "args1.bat", args, env);131 try testExecBat(gpa, "args1.bat", args, env);
130 try testExecBat(gpa, "args2.bat", args, env);132 try testExecBat(gpa, "args2.bat", args, env);
131 try testExecBat(gpa, "args3.bat", args, env);133 try testExecBat(gpa, "args3.bat", args, env);
132}134}
133135
134fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void {136fn testExecBat(gpa: Allocator, io: Io, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void {
135 const argv = try gpa.alloc([]const u8, 1 + args.len);137 const argv = try gpa.alloc([]const u8, 1 + args.len);
136 defer gpa.free(argv);138 defer gpa.free(argv);
137 argv[0] = bat;139 argv[0] = bat;
...@@ -139,8 +141,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8...@@ -139,8 +141,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8
139141
140 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");142 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");
141143
142 const result = try std.process.Child.run(.{144 const result = try std.process.Child.run(gpa, io, .{
143 .allocator = gpa,
144 .env_map = env,145 .env_map = env,
145 .argv = argv,146 .argv = argv,
146 });147 });
test/standalone/windows_paths/test.zig+26-22
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const Io = std.Io;
23
3pub fn main() anyerror!void {4pub fn main() anyerror!void {
4 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);5 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
...@@ -9,6 +10,9 @@ pub fn main() anyerror!void {...@@ -9,6 +10,9 @@ pub fn main() anyerror!void {
910
10 if (args.len < 2) return error.MissingArgs;11 if (args.len < 2) return error.MissingArgs;
1112
13 var threaded: Io.Threaded = .init_single_threaded;
14 const io = threaded.io();
15
12 const exe_path = args[1];16 const exe_path = args[1];
1317
14 const cwd_path = try std.process.getCwdAlloc(arena);18 const cwd_path = try std.process.getCwdAlloc(arena);
...@@ -33,39 +37,39 @@ pub fn main() anyerror!void {...@@ -33,39 +37,39 @@ pub fn main() anyerror!void {
3337
34 // With the special =X: environment variable set, drive-relative paths that38 // With the special =X: environment variable set, drive-relative paths that
35 // don't match the CWD's drive letter are resolved against that env var.39 // don't match the CWD's drive letter are resolved against that env var.
36 try checkRelative(arena, "..\\..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &alt_drive_env_map);40 try checkRelative(arena, io, "..\\..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &alt_drive_env_map);
37 try checkRelative(arena, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &alt_drive_env_map);41 try checkRelative(arena, io, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &alt_drive_env_map);
3842
39 // Without that environment variable set, drive-relative paths that don't match the43 // Without that environment variable set, drive-relative paths that don't match the
40 // CWD's drive letter are resolved against the root of the drive.44 // CWD's drive letter are resolved against the root of the drive.
41 try checkRelative(arena, "..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env);45 try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env);
42 try checkRelative(arena, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);46 try checkRelative(arena, io, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);
4347
44 // Bare drive-relative path with no components48 // Bare drive-relative path with no components
45 try checkRelative(arena, "bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &empty_env);49 try checkRelative(arena, io, "bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &empty_env);
46 try checkRelative(arena, "..", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &empty_env);50 try checkRelative(arena, io, "..", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &empty_env);
4751
48 // Bare drive-relative path with no components, drive-CWD set52 // Bare drive-relative path with no components, drive-CWD set
49 try checkRelative(arena, "..\\bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &alt_drive_env_map);53 try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &alt_drive_env_map);
50 try checkRelative(arena, "..\\baz", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &alt_drive_env_map);54 try checkRelative(arena, io, "..\\baz", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &alt_drive_env_map);
5155
52 // Bare drive-relative path relative to the CWD should be equivalent if drive-CWD is set56 // Bare drive-relative path relative to the CWD should be equivalent if drive-CWD is set
53 try checkRelative(arena, "", &.{ exe_path, alt_drive_cwd, drive_rel[0..2] }, null, &alt_drive_env_map);57 try checkRelative(arena, io, "", &.{ exe_path, alt_drive_cwd, drive_rel[0..2] }, null, &alt_drive_env_map);
54 try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], alt_drive_cwd }, null, &alt_drive_env_map);58 try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], alt_drive_cwd }, null, &alt_drive_env_map);
5559
56 // Bare drive-relative should always be equivalent to itself60 // Bare drive-relative should always be equivalent to itself
57 try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map);61 try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map);
58 try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map);62 try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map);
59 try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env);63 try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env);
60 try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env);64 try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env);
61 }65 }
6266
63 if (parsed_cwd_path.kind == .unc_absolute) {67 if (parsed_cwd_path.kind == .unc_absolute) {
64 const drive_abs_path = try std.fmt.allocPrint(arena, "{c}:\\foo\\bar", .{alt_drive_letter});68 const drive_abs_path = try std.fmt.allocPrint(arena, "{c}:\\foo\\bar", .{alt_drive_letter});
6569
66 {70 {
67 try checkRelative(arena, drive_abs_path, &.{ exe_path, cwd_path, drive_abs_path }, null, &empty_env);71 try checkRelative(arena, io, drive_abs_path, &.{ exe_path, cwd_path, drive_abs_path }, null, &empty_env);
68 try checkRelative(arena, cwd_path, &.{ exe_path, drive_abs_path, cwd_path }, null, &empty_env);72 try checkRelative(arena, io, cwd_path, &.{ exe_path, drive_abs_path, cwd_path }, null, &empty_env);
69 }73 }
70 } else if (parsed_cwd_path.kind == .drive_absolute) {74 } else if (parsed_cwd_path.kind == .drive_absolute) {
71 const cur_drive_letter = parsed_cwd_path.root[0];75 const cur_drive_letter = parsed_cwd_path.root[0];
...@@ -73,14 +77,14 @@ pub fn main() anyerror!void {...@@ -73,14 +77,14 @@ pub fn main() anyerror!void {
73 const unc_cwd = try std.fmt.allocPrint(arena, "\\\\127.0.0.1\\{c}$\\{s}", .{ cur_drive_letter, path_beyond_root });77 const unc_cwd = try std.fmt.allocPrint(arena, "\\\\127.0.0.1\\{c}$\\{s}", .{ cur_drive_letter, path_beyond_root });
7478
75 {79 {
76 try checkRelative(arena, cwd_path, &.{ exe_path, unc_cwd, cwd_path }, null, &empty_env);80 try checkRelative(arena, io, cwd_path, &.{ exe_path, unc_cwd, cwd_path }, null, &empty_env);
77 try checkRelative(arena, unc_cwd, &.{ exe_path, cwd_path, unc_cwd }, null, &empty_env);81 try checkRelative(arena, io, unc_cwd, &.{ exe_path, cwd_path, unc_cwd }, null, &empty_env);
78 }82 }
79 {83 {
80 const drive_abs = cwd_path;84 const drive_abs = cwd_path;
81 const drive_rel = parsed_cwd_path.root[0..2];85 const drive_rel = parsed_cwd_path.root[0..2];
82 try checkRelative(arena, "", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);86 try checkRelative(arena, io, "", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);
83 try checkRelative(arena, "", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env);87 try checkRelative(arena, io, "", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env);
84 }88 }
85 } else {89 } else {
86 return error.UnexpectedPathType;90 return error.UnexpectedPathType;
...@@ -89,13 +93,13 @@ pub fn main() anyerror!void {...@@ -89,13 +93,13 @@ pub fn main() anyerror!void {
8993
90fn checkRelative(94fn checkRelative(
91 allocator: std.mem.Allocator,95 allocator: std.mem.Allocator,
96 io: Io,
92 expected_stdout: []const u8,97 expected_stdout: []const u8,
93 argv: []const []const u8,98 argv: []const []const u8,
94 cwd: ?[]const u8,99 cwd: ?[]const u8,
95 env_map: ?*const std.process.EnvMap,100 env_map: ?*const std.process.EnvMap,
96) !void {101) !void {
97 const result = try std.process.Child.run(.{102 const result = try std.process.Child.run(allocator, io, .{
98 .allocator = allocator,
99 .argv = argv,103 .argv = argv,
100 .cwd = cwd,104 .cwd = cwd,
101 .env_map = env_map,105 .env_map = env_map,