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 {
7878 if (input_file) |libc_file| {
7979 const libc = try arena.create(LibCInstallation);
8080 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 });
8282 };
8383 break :libc libc;
8484 } else {
......@@ -97,7 +97,7 @@ pub fn main() !void {
9797 libc_installation,
9898 ) catch |err| {
9999 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 });
101101 };
102102
103103 if (libc_dirs.libc_include_dir_list.len == 0) {
......@@ -115,19 +115,18 @@ pub fn main() !void {
115115
116116 if (input_file) |libc_file| {
117117 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 });
119119 };
120120 defer libc.deinit(gpa);
121121 } else {
122122 if (!target_query.canDetectLibC()) {
123123 fatal("unable to detect libc for non-native target", .{});
124124 }
125 var libc = LibCInstallation.findNative(.{
126 .allocator = gpa,
125 var libc = LibCInstallation.findNative(gpa, io, .{
127126 .verbose = true,
128127 .target = &target,
129128 }) catch |err| {
130 fatal("unable to detect native libc: {s}", .{@errorName(err)});
129 fatal("unable to detect native libc: {t}", .{err});
131130 };
132131 defer libc.deinit(gpa);
133132
lib/compiler/reduce.zig+2-5
......@@ -307,11 +307,8 @@ fn termToInteresting(term: std.process.Child.Term) Interestingness {
307307 };
308308}
309309
310fn runCheck(arena: std.mem.Allocator, argv: []const []const u8) !Interestingness {
311 const result = try std.process.Child.run(.{
312 .allocator = arena,
313 .argv = argv,
314 });
310fn runCheck(arena: Allocator, io: Io, argv: []const []const u8) !Interestingness {
311 const result = try std.process.Child.run(arena, io, .{ .argv = argv });
315312 if (result.stderr.len != 0)
316313 std.debug.print("{s}", .{result.stderr});
317314 return termToInteresting(result.term);
lib/std/Build/Step.zig+2-2
......@@ -350,6 +350,7 @@ pub fn captureChildProcess(
350350 argv: []const []const u8,
351351) !std.process.Child.RunResult {
352352 const arena = s.owner.allocator;
353 const io = s.owner.graph.io;
353354
354355 // If an error occurs, it's happened in this command:
355356 assert(s.result_failed_command == null);
......@@ -358,8 +359,7 @@ pub fn captureChildProcess(
358359 try handleChildProcUnsupported(s);
359360 try handleVerbose(s.owner, null, argv);
360361
361 const result = std.process.Child.run(.{
362 .allocator = arena,
362 const result = std.process.Child.run(arena, io, .{
363363 .argv = argv,
364364 .progress_node = progress_node,
365365 }) 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 {
166166}
167167
168168pub const FindNativeOptions = struct {
169 allocator: Allocator,
170 io: Io,
171169 target: *const std.Target,
172170
173171 /// If enabled, will print human-friendly errors to stderr.
......@@ -175,10 +173,7 @@ pub const FindNativeOptions = struct {
175173};
176174
177175/// Finds the default, native libc.
178pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
179 const gpa = args.allocator;
180 const io = args.io;
181
176pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!LibCInstallation {
182177 var self: LibCInstallation = .{};
183178
184179 if (is_darwin and args.target.os.tag.isDarwin()) {
......@@ -203,14 +198,14 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
203198 };
204199 defer sdk.free(gpa);
205200
206 try self.findNativeMsvcIncludeDir(args, sdk);
207 try self.findNativeMsvcLibDir(args, sdk);
208 try self.findNativeKernel32LibDir(args, sdk);
209 try self.findNativeIncludeDirWindows(args, sdk);
210 try self.findNativeCrtDirWindows(args, sdk);
201 try self.findNativeMsvcIncludeDir(gpa, io, sdk);
202 try self.findNativeMsvcLibDir(gpa, sdk);
203 try self.findNativeKernel32LibDir(gpa, io, args, sdk);
204 try self.findNativeIncludeDirWindows(gpa, io, args, sdk);
205 try self.findNativeCrtDirWindows(gpa, io, args.target, sdk);
211206 } else if (is_haiku) {
212207 try self.findNativeIncludeDirPosix(args);
213 try self.findNativeGccDirHaiku(args);
208 try self.findNativeGccDirHaiku(gpa, io, args);
214209 self.crt_dir = try gpa.dupeZ(u8, "/system/develop/lib");
215210 } else if (builtin.target.os.tag == .illumos) {
216211 // 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 {
221216 try self.findNativeIncludeDirPosix(args);
222217 switch (builtin.target.os.tag) {
223218 .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),
225220 else => {},
226221 }
227222 } else {
......@@ -241,12 +236,9 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void {
241236 self.* = undefined;
242237}
243238
244fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
245 const allocator = args.allocator;
246 const io = args.io;
247
239fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
248240 // 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) {
250242 error.Unexpected => unreachable, // WASI-only
251243 else => |e| return e,
252244 };
......@@ -265,7 +257,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
265257
266258 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);
269261 defer argv.deinit();
270262
271263 try appendCcExe(&argv, skip_cc_env_var);
......@@ -276,8 +268,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
276268 dev_null,
277269 });
278270
279 const run_res = std.process.Child.run(.{
280 .allocator = allocator,
271 const run_res = std.process.Child.run(gpa, io, .{
281272 .argv = argv.items,
282273 .max_output_bytes = 1024 * 1024,
283274 .env_map = &env_map,
......@@ -294,8 +285,8 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
294285 },
295286 };
296287 defer {
297 allocator.free(run_res.stdout);
298 allocator.free(run_res.stderr);
288 gpa.free(run_res.stdout);
289 gpa.free(run_res.stderr);
299290 }
300291 switch (run_res.term) {
301292 .Exited => |code| if (code != 0) {
......@@ -309,7 +300,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
309300 }
310301
311302 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);
313304 defer search_paths.deinit();
314305 while (it.next()) |line| {
315306 if (line.len != 0 and line[0] == ' ') {
......@@ -345,7 +336,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
345336
346337 if (self.include_dir == null) {
347338 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);
349340 } else |err| switch (err) {
350341 error.FileNotFound => {},
351342 else => return error.FileSystem,
......@@ -354,7 +345,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
354345
355346 if (self.sys_include_dir == null) {
356347 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);
358349 } else |err| switch (err) {
359350 error.FileNotFound => {},
360351 else => return error.FileSystem,
......@@ -372,16 +363,14 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F
372363
373364fn findNativeIncludeDirWindows(
374365 self: *LibCInstallation,
375 args: FindNativeOptions,
366 gpa: Allocator,
367 io: Io,
376368 sdk: std.zig.WindowsSdk,
377369) FindError!void {
378 const allocator = args.allocator;
379 const io = args.io;
380
381370 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;
382371 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);
385374 defer result_buf.deinit();
386375
387376 for (installs) |install| {
......@@ -412,19 +401,18 @@ fn findNativeIncludeDirWindows(
412401
413402fn findNativeCrtDirWindows(
414403 self: *LibCInstallation,
415 args: FindNativeOptions,
404 gpa: Allocator,
405 io: Io,
406 target: *const std.Target,
416407 sdk: std.zig.WindowsSdk,
417408) FindError!void {
418 const allocator = args.allocator;
419 const io = args.io;
420
421409 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;
422410 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);
425413 defer result_buf.deinit();
426414
427 const arch_sub_dir = switch (args.target.cpu.arch) {
415 const arch_sub_dir = switch (target.cpu.arch) {
428416 .x86 => "x86",
429417 .x86_64 => "x64",
430418 .arm, .armeb => "arm",
......@@ -457,9 +445,8 @@ fn findNativeCrtDirWindows(
457445 return error.LibCRuntimeNotFound;
458446}
459447
460fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
461 self.crt_dir = try ccPrintFileName(.{
462 .allocator = args.allocator,
448fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
449 self.crt_dir = try ccPrintFileName(gpa, io, .{
463450 .search_basename = switch (args.target.os.tag) {
464451 .linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",
465452 else => "crt1.o",
......@@ -469,9 +456,8 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindE
469456 });
470457}
471458
472fn findNativeGccDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
473 self.gcc_dir = try ccPrintFileName(.{
474 .allocator = args.allocator,
459fn findNativeGccDirHaiku(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
460 self.gcc_dir = try ccPrintFileName(gpa, io, .{
475461 .search_basename = "crtbeginS.o",
476462 .want_dirname = .only_dir,
477463 .verbose = args.verbose,
......@@ -480,16 +466,15 @@ fn findNativeGccDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindE
480466
481467fn findNativeKernel32LibDir(
482468 self: *LibCInstallation,
469 gpa: Allocator,
470 io: Io,
483471 args: FindNativeOptions,
484472 sdk: std.zig.WindowsSdk,
485473) FindError!void {
486 const allocator = args.allocator;
487 const io = args.io;
488
489474 var install_buf: [2]std.zig.WindowsSdk.Installation = undefined;
490475 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);
493478 defer result_buf.deinit();
494479
495480 const arch_sub_dir = switch (args.target.cpu.arch) {
......@@ -527,18 +512,16 @@ fn findNativeKernel32LibDir(
527512
528513fn findNativeMsvcIncludeDir(
529514 self: *LibCInstallation,
530 args: FindNativeOptions,
515 gpa: Allocator,
516 io: Io,
531517 sdk: std.zig.WindowsSdk,
532518) FindError!void {
533 const allocator = args.allocator;
534 const io = args.io;
535
536519 const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCStdLibHeaderNotFound;
537520 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
538521 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
539522
540 const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" });
541 errdefer allocator.free(dir_path);
523 const dir_path = try fs.path.join(gpa, &[_][]const u8{ up2, "include" });
524 errdefer gpa.free(dir_path);
542525
543526 var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| switch (err) {
544527 error.FileNotFound,
......@@ -560,27 +543,23 @@ fn findNativeMsvcIncludeDir(
560543
561544fn findNativeMsvcLibDir(
562545 self: *LibCInstallation,
563 args: FindNativeOptions,
546 gpa: Allocator,
564547 sdk: std.zig.WindowsSdk,
565548) FindError!void {
566 const allocator = args.allocator;
567549 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);
569551}
570552
571553pub const CCPrintFileNameOptions = struct {
572 allocator: Allocator,
573554 search_basename: []const u8,
574555 want_dirname: enum { full_path, only_dir },
575556 verbose: bool = false,
576557};
577558
578559/// caller owns returned memory
579fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
580 const allocator = args.allocator;
581
560fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8 {
582561 // 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) {
584563 error.Unexpected => unreachable, // WASI-only
585564 else => |e| return e,
586565 };
......@@ -597,17 +576,16 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
597576 break :blk false;
598577 };
599578
600 var argv = std.array_list.Managed([]const u8).init(allocator);
579 var argv = std.array_list.Managed([]const u8).init(gpa);
601580 defer argv.deinit();
602581
603 const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={s}", .{args.search_basename});
604 defer allocator.free(arg1);
582 const arg1 = try std.fmt.allocPrint(gpa, "-print-file-name={s}", .{args.search_basename});
583 defer gpa.free(arg1);
605584
606585 try appendCcExe(&argv, skip_cc_env_var);
607586 try argv.append(arg1);
608587
609 const run_res = std.process.Child.run(.{
610 .allocator = allocator,
588 const run_res = std.process.Child.run(gpa, io, .{
611589 .argv = argv.items,
612590 .max_output_bytes = 1024 * 1024,
613591 .env_map = &env_map,
......@@ -621,8 +599,8 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
621599 else => return error.UnableToSpawnCCompiler,
622600 };
623601 defer {
624 allocator.free(run_res.stdout);
625 allocator.free(run_res.stderr);
602 gpa.free(run_res.stdout);
603 gpa.free(run_res.stderr);
626604 }
627605 switch (run_res.term) {
628606 .Exited => |code| if (code != 0) {
......@@ -641,10 +619,10 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
641619 // So we detect failure by checking if the output matches exactly the input.
642620 if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound;
643621 switch (args.want_dirname) {
644 .full_path => return allocator.dupeZ(u8, line),
622 .full_path => return gpa.dupeZ(u8, line),
645623 .only_dir => {
646624 const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
647 return allocator.dupeZ(u8, dirname);
625 return gpa.dupeZ(u8, dirname);
648626 },
649627 }
650628}
lib/std/zig/system/darwin.zig+15-14
......@@ -1,28 +1,29 @@
11const std = @import("std");
2const Io = std.Io;
23const mem = std.mem;
3const Allocator = mem.Allocator;
4const Allocator = std.mem.Allocator;
45const Target = std.Target;
56const Version = std.SemanticVersion;
67
78pub const macos = @import("darwin/macos.zig");
89
910/// 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.
1113/// Therefore, we resort to invoking `xcode-select --print-path` and checking
1214/// if the status is nonzero.
15///
1316/// stderr from xcode-select is ignored.
17///
1418/// If error.OutOfMemory occurs in Allocator, this function returns null.
15pub fn isSdkInstalled(allocator: Allocator) bool {
16 const result = std.process.Child.run(.{
17 .allocator = allocator,
19pub fn isSdkInstalled(gpa: Allocator, io: Io) bool {
20 const result = std.process.Child.run(gpa, io, .{
1821 .argv = &.{ "xcode-select", "--print-path" },
1922 }) catch return false;
20
2123 defer {
22 allocator.free(result.stderr);
23 allocator.free(result.stdout);
24 gpa.free(result.stderr);
25 gpa.free(result.stdout);
2426 }
25
2627 return switch (result.term) {
2728 .Exited => |code| if (code == 0) result.stdout.len > 0 else false,
2829 else => false,
......@@ -34,7 +35,7 @@ pub fn isSdkInstalled(allocator: Allocator) bool {
3435/// Caller owns the memory.
3536/// stderr from xcrun is ignored.
3637/// 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 {
3839 const is_simulator_abi = target.abi == .simulator;
3940 const sdk = switch (target.os.tag) {
4041 .driverkit => "driverkit",
......@@ -46,16 +47,16 @@ pub fn getSdk(allocator: Allocator, target: *const Target) ?[]const u8 {
4647 else => return null,
4748 };
4849 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;
5051 defer {
51 allocator.free(result.stderr);
52 allocator.free(result.stdout);
52 gpa.free(result.stderr);
53 gpa.free(result.stdout);
5354 }
5455 switch (result.term) {
5556 .Exited => |code| if (code != 0) return null,
5657 else => return null,
5758 }
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;
5960}
6061
6162test {
src/main.zig+1-2
......@@ -4017,8 +4017,7 @@ fn createModule(
40174017 any_name_queries_remaining)
40184018 {
40194019 if (create_module.libc_installation == null) {
4020 create_module.libc_installation = LibCInstallation.findNative(.{
4021 .allocator = arena,
4020 create_module.libc_installation = LibCInstallation.findNative(arena, io, .{
40224021 .verbose = true,
40234022 .target = target,
40244023 }) catch |err| {
test/standalone/child_process/main.zig+1-1
......@@ -57,7 +57,7 @@ pub fn main() !void {
5757 // Check that FileNotFound is consistent across platforms when trying to spawn an executable that doesn't exist
5858 const missing_child_path = try std.mem.concat(gpa, u8, &.{ child_path, "_intentionally_missing" });
5959 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} }));
6161}
6262
6363var parent_test_error = false;
test/standalone/windows_bat_args/fuzz.zig+9-8
......@@ -1,5 +1,7 @@
1const std = @import("std");
21const builtin = @import("builtin");
2
3const std = @import("std");
4const Io = std.Io;
35const Allocator = std.mem.Allocator;
46
57pub fn main() anyerror!void {
......@@ -78,13 +80,13 @@ pub fn main() anyerror!void {
7880 }
7981}
8082
81fn testExec(gpa: std.mem.Allocator, args: []const []const u8, env: ?*std.process.EnvMap) !void {
82 try testExecBat(gpa, "args1.bat", args, env);
83 try testExecBat(gpa, "args2.bat", args, env);
84 try testExecBat(gpa, "args3.bat", args, env);
83fn testExec(gpa: Allocator, io: Io, args: []const []const u8, env: ?*std.process.EnvMap) !void {
84 try testExecBat(gpa, io, "args1.bat", args, env);
85 try testExecBat(gpa, io, "args2.bat", args, env);
86 try testExecBat(gpa, io, "args3.bat", args, env);
8587}
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 {
8890 const argv = try gpa.alloc([]const u8, 1 + args.len);
8991 defer gpa.free(argv);
9092 argv[0] = bat;
......@@ -92,8 +94,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8
9294
9395 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");
9496
95 const result = try std.process.Child.run(.{
96 .allocator = gpa,
97 const result = try std.process.Child.run(gpa, io, .{
9798 .env_map = env,
9899 .argv = argv,
99100 });
test/standalone/windows_bat_args/test.zig+6-5
......@@ -1,4 +1,6 @@
11const std = @import("std");
2const Io = std.Io;
3const Allocator = std.mem.Allocator;
24
35pub fn main() anyerror!void {
46 var debug_alloc_inst: std.heap.DebugAllocator(.{}) = .init;
......@@ -121,17 +123,17 @@ pub fn main() anyerror!void {
121123 try std.testing.expectError(error.FileNotFound, tmp.dir.access("file.txt", .{}));
122124}
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 {
125127 return std.testing.expectError(err, testExec(gpa, args, null));
126128}
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 {
129131 try testExecBat(gpa, "args1.bat", args, env);
130132 try testExecBat(gpa, "args2.bat", args, env);
131133 try testExecBat(gpa, "args3.bat", args, env);
132134}
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 {
135137 const argv = try gpa.alloc([]const u8, 1 + args.len);
136138 defer gpa.free(argv);
137139 argv[0] = bat;
......@@ -139,8 +141,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8
139141
140142 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat");
141143
142 const result = try std.process.Child.run(.{
143 .allocator = gpa,
144 const result = try std.process.Child.run(gpa, io, .{
144145 .env_map = env,
145146 .argv = argv,
146147 });
test/standalone/windows_paths/test.zig+26-22
......@@ -1,4 +1,5 @@
11const std = @import("std");
2const Io = std.Io;
23
34pub fn main() anyerror!void {
45 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
......@@ -9,6 +10,9 @@ pub fn main() anyerror!void {
910
1011 if (args.len < 2) return error.MissingArgs;
1112
13 var threaded: Io.Threaded = .init_single_threaded;
14 const io = threaded.io();
15
1216 const exe_path = args[1];
1317
1418 const cwd_path = try std.process.getCwdAlloc(arena);
......@@ -33,39 +37,39 @@ pub fn main() anyerror!void {
3337
3438 // With the special =X: environment variable set, drive-relative paths that
3539 // 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);
37 try checkRelative(arena, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &alt_drive_env_map);
40 try checkRelative(arena, io, "..\\..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &alt_drive_env_map);
41 try checkRelative(arena, io, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &alt_drive_env_map);
3842
3943 // Without that environment variable set, drive-relative paths that don't match the
4044 // 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);
42 try checkRelative(arena, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);
45 try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env);
46 try checkRelative(arena, io, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);
4347
4448 // Bare drive-relative path with no components
45 try checkRelative(arena, "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);
49 try checkRelative(arena, io, "bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &empty_env);
50 try checkRelative(arena, io, "..", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &empty_env);
4751
4852 // 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);
50 try checkRelative(arena, "..\\baz", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &alt_drive_env_map);
53 try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel[0..2], drive_abs }, 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
5256 // 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);
54 try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], alt_drive_cwd }, null, &alt_drive_env_map);
57 try checkRelative(arena, io, "", &.{ exe_path, alt_drive_cwd, drive_rel[0..2] }, 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
5660 // 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);
58 try checkRelative(arena, "", &.{ 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);
60 try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env);
61 try checkRelative(arena, io, "", &.{ 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);
63 try checkRelative(arena, io, "", &.{ 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);
6165 }
6266
6367 if (parsed_cwd_path.kind == .unc_absolute) {
6468 const drive_abs_path = try std.fmt.allocPrint(arena, "{c}:\\foo\\bar", .{alt_drive_letter});
6569
6670 {
67 try checkRelative(arena, 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);
71 try checkRelative(arena, io, drive_abs_path, &.{ exe_path, cwd_path, drive_abs_path }, null, &empty_env);
72 try checkRelative(arena, io, cwd_path, &.{ exe_path, drive_abs_path, cwd_path }, null, &empty_env);
6973 }
7074 } else if (parsed_cwd_path.kind == .drive_absolute) {
7175 const cur_drive_letter = parsed_cwd_path.root[0];
......@@ -73,14 +77,14 @@ pub fn main() anyerror!void {
7377 const unc_cwd = try std.fmt.allocPrint(arena, "\\\\127.0.0.1\\{c}$\\{s}", .{ cur_drive_letter, path_beyond_root });
7478
7579 {
76 try checkRelative(arena, 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);
80 try checkRelative(arena, io, cwd_path, &.{ exe_path, unc_cwd, cwd_path }, null, &empty_env);
81 try checkRelative(arena, io, unc_cwd, &.{ exe_path, cwd_path, unc_cwd }, null, &empty_env);
7882 }
7983 {
8084 const drive_abs = cwd_path;
8185 const drive_rel = parsed_cwd_path.root[0..2];
82 try checkRelative(arena, "", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);
83 try checkRelative(arena, "", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env);
86 try checkRelative(arena, io, "", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env);
87 try checkRelative(arena, io, "", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env);
8488 }
8589 } else {
8690 return error.UnexpectedPathType;
......@@ -89,13 +93,13 @@ pub fn main() anyerror!void {
8993
9094fn checkRelative(
9195 allocator: std.mem.Allocator,
96 io: Io,
9297 expected_stdout: []const u8,
9398 argv: []const []const u8,
9499 cwd: ?[]const u8,
95100 env_map: ?*const std.process.EnvMap,
96101) !void {
97 const result = try std.process.Child.run(.{
98 .allocator = allocator,
102 const result = try std.process.Child.run(allocator, io, .{
99103 .argv = argv,
100104 .cwd = cwd,
101105 .env_map = env_map,