From 3725f72293c87a73e0c11e74739574c7b78bb53d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Dec 2025 18:46:55 -0800 Subject: [PATCH] update std.process.Child.run occurences to use io --- lib/compiler/libc.zig | 11 +- lib/compiler/reduce.zig | 7 +- lib/std/Build/Step.zig | 4 +- lib/std/zig/LibCInstallation.zig | 118 +++++++++------------- lib/std/zig/system/darwin.zig | 29 +++--- src/main.zig | 3 +- test/standalone/child_process/main.zig | 2 +- test/standalone/windows_bat_args/fuzz.zig | 17 ++-- test/standalone/windows_bat_args/test.zig | 11 +- test/standalone/windows_paths/test.zig | 48 +++++---- 10 files changed, 115 insertions(+), 135 deletions(-) diff --git a/lib/compiler/libc.zig b/lib/compiler/libc.zig index 142b87062e..7a6edf0c44 100644 --- a/lib/compiler/libc.zig +++ b/lib/compiler/libc.zig @@ -78,7 +78,7 @@ pub fn main() !void { if (input_file) |libc_file| { const libc = try arena.create(LibCInstallation); libc.* = LibCInstallation.parse(arena, libc_file, &target) catch |err| { - fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); + fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err }); }; break :libc libc; } else { @@ -97,7 +97,7 @@ pub fn main() !void { libc_installation, ) catch |err| { const zig_target = try target.zigTriple(arena); - fatal("unable to detect libc for target {s}: {s}", .{ zig_target, @errorName(err) }); + fatal("unable to detect libc for target {s}: {t}", .{ zig_target, err }); }; if (libc_dirs.libc_include_dir_list.len == 0) { @@ -115,19 +115,18 @@ pub fn main() !void { if (input_file) |libc_file| { var libc = LibCInstallation.parse(gpa, libc_file, &target) catch |err| { - fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); + fatal("unable to parse libc file at path {s}: {t}", .{ libc_file, err }); }; defer libc.deinit(gpa); } else { if (!target_query.canDetectLibC()) { fatal("unable to detect libc for non-native target", .{}); } - var libc = LibCInstallation.findNative(.{ - .allocator = gpa, + var libc = LibCInstallation.findNative(gpa, io, .{ .verbose = true, .target = &target, }) catch |err| { - fatal("unable to detect native libc: {s}", .{@errorName(err)}); + fatal("unable to detect native libc: {t}", .{err}); }; defer libc.deinit(gpa); diff --git a/lib/compiler/reduce.zig b/lib/compiler/reduce.zig index 0bfa1902ab..f10bd12e9d 100644 --- a/lib/compiler/reduce.zig +++ b/lib/compiler/reduce.zig @@ -307,11 +307,8 @@ fn termToInteresting(term: std.process.Child.Term) Interestingness { }; } -fn runCheck(arena: std.mem.Allocator, argv: []const []const u8) !Interestingness { - const result = try std.process.Child.run(.{ - .allocator = arena, - .argv = argv, - }); +fn runCheck(arena: Allocator, io: Io, argv: []const []const u8) !Interestingness { + const result = try std.process.Child.run(arena, io, .{ .argv = argv }); if (result.stderr.len != 0) std.debug.print("{s}", .{result.stderr}); return termToInteresting(result.term); diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig index f66f8df4c8..8115aaa1a1 100644 --- a/lib/std/Build/Step.zig +++ b/lib/std/Build/Step.zig @@ -350,6 +350,7 @@ pub fn captureChildProcess( argv: []const []const u8, ) !std.process.Child.RunResult { const arena = s.owner.allocator; + const io = s.owner.graph.io; // If an error occurs, it's happened in this command: assert(s.result_failed_command == null); @@ -358,8 +359,7 @@ pub fn captureChildProcess( try handleChildProcUnsupported(s); try handleVerbose(s.owner, null, argv); - const result = std.process.Child.run(.{ - .allocator = arena, + const result = std.process.Child.run(arena, io, .{ .argv = argv, .progress_node = progress_node, }) catch |err| return s.fail("failed to run {s}: {t}", .{ argv[0], err }); diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index 1463ff4a40..6051eecb94 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -166,8 +166,6 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void { } pub const FindNativeOptions = struct { - allocator: Allocator, - io: Io, target: *const std.Target, /// If enabled, will print human-friendly errors to stderr. @@ -175,10 +173,7 @@ pub const FindNativeOptions = struct { }; /// Finds the default, native libc. -pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { - const gpa = args.allocator; - const io = args.io; - +pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!LibCInstallation { var self: LibCInstallation = .{}; if (is_darwin and args.target.os.tag.isDarwin()) { @@ -203,14 +198,14 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { }; defer sdk.free(gpa); - try self.findNativeMsvcIncludeDir(args, sdk); - try self.findNativeMsvcLibDir(args, sdk); - try self.findNativeKernel32LibDir(args, sdk); - try self.findNativeIncludeDirWindows(args, sdk); - try self.findNativeCrtDirWindows(args, sdk); + try self.findNativeMsvcIncludeDir(gpa, io, sdk); + try self.findNativeMsvcLibDir(gpa, sdk); + try self.findNativeKernel32LibDir(gpa, io, args, sdk); + try self.findNativeIncludeDirWindows(gpa, io, args, sdk); + try self.findNativeCrtDirWindows(gpa, io, args.target, sdk); } else if (is_haiku) { try self.findNativeIncludeDirPosix(args); - try self.findNativeGccDirHaiku(args); + try self.findNativeGccDirHaiku(gpa, io, args); self.crt_dir = try gpa.dupeZ(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. @@ -221,7 +216,7 @@ pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation { try self.findNativeIncludeDirPosix(args); switch (builtin.target.os.tag) { .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try gpa.dupeZ(u8, "/usr/lib"), - .linux => try self.findNativeCrtDirPosix(args), + .linux => try self.findNativeCrtDirPosix(gpa, io, args), else => {}, } } else { @@ -241,12 +236,9 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void { self.* = undefined; } -fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void { - const allocator = args.allocator; - const io = args.io; - +fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void { // Detect infinite loops. - var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) { + var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) { error.Unexpected => unreachable, // WASI-only else => |e| return e, }; @@ -265,7 +257,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F const dev_null = if (is_windows) "nul" else "/dev/null"; - var argv = std.array_list.Managed([]const u8).init(allocator); + var argv = std.array_list.Managed([]const u8).init(gpa); defer argv.deinit(); try appendCcExe(&argv, skip_cc_env_var); @@ -276,8 +268,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F dev_null, }); - const run_res = std.process.Child.run(.{ - .allocator = allocator, + const run_res = std.process.Child.run(gpa, io, .{ .argv = argv.items, .max_output_bytes = 1024 * 1024, .env_map = &env_map, @@ -294,8 +285,8 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F }, }; defer { - allocator.free(run_res.stdout); - allocator.free(run_res.stderr); + gpa.free(run_res.stdout); + gpa.free(run_res.stderr); } switch (run_res.term) { .Exited => |code| if (code != 0) { @@ -309,7 +300,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F } var it = std.mem.tokenizeAny(u8, run_res.stderr, "\n\r"); - var search_paths = std.array_list.Managed([]const u8).init(allocator); + var search_paths = std.array_list.Managed([]const u8).init(gpa); defer search_paths.deinit(); while (it.next()) |line| { if (line.len != 0 and line[0] == ' ') { @@ -345,7 +336,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F if (self.include_dir == null) { if (search_dir.access(include_dir_example_file, .{})) |_| { - self.include_dir = try allocator.dupeZ(u8, search_path); + self.include_dir = try gpa.dupeZ(u8, search_path); } else |err| switch (err) { error.FileNotFound => {}, else => return error.FileSystem, @@ -354,7 +345,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F if (self.sys_include_dir == null) { if (search_dir.access(io, sys_include_dir_example_file, .{})) |_| { - self.sys_include_dir = try allocator.dupeZ(u8, search_path); + self.sys_include_dir = try gpa.dupeZ(u8, search_path); } else |err| switch (err) { error.FileNotFound => {}, else => return error.FileSystem, @@ -372,16 +363,14 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) F fn findNativeIncludeDirWindows( self: *LibCInstallation, - args: FindNativeOptions, + gpa: Allocator, + io: Io, sdk: std.zig.WindowsSdk, ) FindError!void { - const allocator = args.allocator; - const io = args.io; - var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; const installs = fillInstallations(&install_buf, sdk); - var result_buf = std.array_list.Managed(u8).init(allocator); + var result_buf = std.array_list.Managed(u8).init(gpa); defer result_buf.deinit(); for (installs) |install| { @@ -412,19 +401,18 @@ fn findNativeIncludeDirWindows( fn findNativeCrtDirWindows( self: *LibCInstallation, - args: FindNativeOptions, + gpa: Allocator, + io: Io, + target: *const std.Target, sdk: std.zig.WindowsSdk, ) FindError!void { - const allocator = args.allocator; - const io = args.io; - var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; const installs = fillInstallations(&install_buf, sdk); - var result_buf = std.array_list.Managed(u8).init(allocator); + var result_buf = std.array_list.Managed(u8).init(gpa); defer result_buf.deinit(); - const arch_sub_dir = switch (args.target.cpu.arch) { + const arch_sub_dir = switch (target.cpu.arch) { .x86 => "x86", .x86_64 => "x64", .arm, .armeb => "arm", @@ -457,9 +445,8 @@ fn findNativeCrtDirWindows( return error.LibCRuntimeNotFound; } -fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void { - self.crt_dir = try ccPrintFileName(.{ - .allocator = args.allocator, +fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void { + self.crt_dir = try ccPrintFileName(gpa, io, .{ .search_basename = switch (args.target.os.tag) { .linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o", else => "crt1.o", @@ -469,9 +456,8 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindE }); } -fn findNativeGccDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindError!void { - self.gcc_dir = try ccPrintFileName(.{ - .allocator = args.allocator, +fn findNativeGccDirHaiku(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void { + self.gcc_dir = try ccPrintFileName(gpa, io, .{ .search_basename = "crtbeginS.o", .want_dirname = .only_dir, .verbose = args.verbose, @@ -480,16 +466,15 @@ fn findNativeGccDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindE fn findNativeKernel32LibDir( self: *LibCInstallation, + gpa: Allocator, + io: Io, args: FindNativeOptions, sdk: std.zig.WindowsSdk, ) FindError!void { - const allocator = args.allocator; - const io = args.io; - var install_buf: [2]std.zig.WindowsSdk.Installation = undefined; const installs = fillInstallations(&install_buf, sdk); - var result_buf = std.array_list.Managed(u8).init(allocator); + var result_buf = std.array_list.Managed(u8).init(gpa); defer result_buf.deinit(); const arch_sub_dir = switch (args.target.cpu.arch) { @@ -527,18 +512,16 @@ fn findNativeKernel32LibDir( fn findNativeMsvcIncludeDir( self: *LibCInstallation, - args: FindNativeOptions, + gpa: Allocator, + io: Io, sdk: std.zig.WindowsSdk, ) FindError!void { - const allocator = args.allocator; - const io = args.io; - const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCStdLibHeaderNotFound; const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound; const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound; - const dir_path = try fs.path.join(allocator, &[_][]const u8{ up2, "include" }); - errdefer allocator.free(dir_path); + const dir_path = try fs.path.join(gpa, &[_][]const u8{ up2, "include" }); + errdefer gpa.free(dir_path); var dir = Io.Dir.cwd().openDir(io, dir_path, .{}) catch |err| switch (err) { error.FileNotFound, @@ -560,27 +543,23 @@ fn findNativeMsvcIncludeDir( fn findNativeMsvcLibDir( self: *LibCInstallation, - args: FindNativeOptions, + gpa: Allocator, sdk: std.zig.WindowsSdk, ) FindError!void { - const allocator = args.allocator; const msvc_lib_dir = sdk.msvc_lib_dir orelse return error.LibCRuntimeNotFound; - self.msvc_lib_dir = try allocator.dupe(u8, msvc_lib_dir); + self.msvc_lib_dir = try gpa.dupe(u8, msvc_lib_dir); } pub const CCPrintFileNameOptions = struct { - allocator: Allocator, search_basename: []const u8, want_dirname: enum { full_path, only_dir }, verbose: bool = false, }; /// caller owns returned memory -fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 { - const allocator = args.allocator; - +fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8 { // Detect infinite loops. - var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) { + var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) { error.Unexpected => unreachable, // WASI-only else => |e| return e, }; @@ -597,17 +576,16 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 { break :blk false; }; - var argv = std.array_list.Managed([]const u8).init(allocator); + var argv = std.array_list.Managed([]const u8).init(gpa); defer argv.deinit(); - const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={s}", .{args.search_basename}); - defer allocator.free(arg1); + const arg1 = try std.fmt.allocPrint(gpa, "-print-file-name={s}", .{args.search_basename}); + defer gpa.free(arg1); try appendCcExe(&argv, skip_cc_env_var); try argv.append(arg1); - const run_res = std.process.Child.run(.{ - .allocator = allocator, + const run_res = std.process.Child.run(gpa, io, .{ .argv = argv.items, .max_output_bytes = 1024 * 1024, .env_map = &env_map, @@ -621,8 +599,8 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 { else => return error.UnableToSpawnCCompiler, }; defer { - allocator.free(run_res.stdout); - allocator.free(run_res.stderr); + gpa.free(run_res.stdout); + gpa.free(run_res.stderr); } switch (run_res.term) { .Exited => |code| if (code != 0) { @@ -641,10 +619,10 @@ fn ccPrintFileName(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 allocator.dupeZ(u8, line), + .full_path => return gpa.dupeZ(u8, line), .only_dir => { const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound; - return allocator.dupeZ(u8, dirname); + return gpa.dupeZ(u8, dirname); }, } } diff --git a/lib/std/zig/system/darwin.zig b/lib/std/zig/system/darwin.zig index fbd6da2a9e..b493ccf0ec 100644 --- a/lib/std/zig/system/darwin.zig +++ b/lib/std/zig/system/darwin.zig @@ -1,28 +1,29 @@ const std = @import("std"); +const Io = std.Io; const mem = std.mem; -const Allocator = mem.Allocator; +const Allocator = std.mem.Allocator; const Target = std.Target; const Version = std.SemanticVersion; pub const macos = @import("darwin/macos.zig"); /// Check if SDK is installed on Darwin without triggering CLT installation popup window. -/// Note: simply invoking `xcrun` will inevitably trigger the CLT installation popup. +/// +/// Simply invoking `xcrun` will inevitably trigger the CLT installation popup. /// Therefore, we resort to invoking `xcode-select --print-path` and checking /// if the status is nonzero. +/// /// stderr from xcode-select is ignored. +/// /// If error.OutOfMemory occurs in Allocator, this function returns null. -pub fn isSdkInstalled(allocator: Allocator) bool { - const result = std.process.Child.run(.{ - .allocator = allocator, +pub fn isSdkInstalled(gpa: Allocator, io: Io) bool { + const result = std.process.Child.run(gpa, io, .{ .argv = &.{ "xcode-select", "--print-path" }, }) catch return false; - defer { - allocator.free(result.stderr); - allocator.free(result.stdout); + gpa.free(result.stderr); + gpa.free(result.stdout); } - return switch (result.term) { .Exited => |code| if (code == 0) result.stdout.len > 0 else false, else => false, @@ -34,7 +35,7 @@ pub fn isSdkInstalled(allocator: Allocator) bool { /// Caller owns the memory. /// stderr from xcrun is ignored. /// If error.OutOfMemory occurs in Allocator, this function returns null. -pub fn getSdk(allocator: Allocator, target: *const Target) ?[]const u8 { +pub fn getSdk(gpa: Allocator, io: Io, target: *const Target) ?[]const u8 { const is_simulator_abi = target.abi == .simulator; const sdk = switch (target.os.tag) { .driverkit => "driverkit", @@ -46,16 +47,16 @@ pub fn getSdk(allocator: Allocator, target: *const Target) ?[]const u8 { else => return null, }; const argv = &[_][]const u8{ "xcrun", "--sdk", sdk, "--show-sdk-path" }; - const result = std.process.Child.run(.{ .allocator = allocator, .argv = argv }) catch return null; + const result = std.process.Child.run(gpa, io, .{ .argv = argv }) catch return null; defer { - allocator.free(result.stderr); - allocator.free(result.stdout); + gpa.free(result.stderr); + gpa.free(result.stdout); } switch (result.term) { .Exited => |code| if (code != 0) return null, else => return null, } - return allocator.dupe(u8, mem.trimEnd(u8, result.stdout, "\r\n")) catch null; + return gpa.dupe(u8, mem.trimEnd(u8, result.stdout, "\r\n")) catch null; } test { diff --git a/src/main.zig b/src/main.zig index 9bb88d373b..58f0e68301 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4017,8 +4017,7 @@ fn createModule( any_name_queries_remaining) { if (create_module.libc_installation == null) { - create_module.libc_installation = LibCInstallation.findNative(.{ - .allocator = arena, + create_module.libc_installation = LibCInstallation.findNative(arena, io, .{ .verbose = true, .target = target, }) catch |err| { diff --git a/test/standalone/child_process/main.zig b/test/standalone/child_process/main.zig index 755beacb6d..2a28845a56 100644 --- a/test/standalone/child_process/main.zig +++ b/test/standalone/child_process/main.zig @@ -57,7 +57,7 @@ pub fn main() !void { // Check that FileNotFound is consistent across platforms when trying to spawn an executable that doesn't exist const missing_child_path = try std.mem.concat(gpa, u8, &.{ child_path, "_intentionally_missing" }); defer gpa.free(missing_child_path); - try std.testing.expectError(error.FileNotFound, std.process.Child.run(.{ .allocator = gpa, .argv = &.{missing_child_path} })); + try std.testing.expectError(error.FileNotFound, std.process.Child.run(gpa, io, .{ .argv = &.{missing_child_path} })); } var parent_test_error = false; diff --git a/test/standalone/windows_bat_args/fuzz.zig b/test/standalone/windows_bat_args/fuzz.zig index 8b9895b52d..bbc0d94077 100644 --- a/test/standalone/windows_bat_args/fuzz.zig +++ b/test/standalone/windows_bat_args/fuzz.zig @@ -1,5 +1,7 @@ -const std = @import("std"); const builtin = @import("builtin"); + +const std = @import("std"); +const Io = std.Io; const Allocator = std.mem.Allocator; pub fn main() anyerror!void { @@ -78,13 +80,13 @@ pub fn main() anyerror!void { } } -fn testExec(gpa: std.mem.Allocator, args: []const []const u8, env: ?*std.process.EnvMap) !void { - try testExecBat(gpa, "args1.bat", args, env); - try testExecBat(gpa, "args2.bat", args, env); - try testExecBat(gpa, "args3.bat", args, env); +fn testExec(gpa: Allocator, io: Io, args: []const []const u8, env: ?*std.process.EnvMap) !void { + try testExecBat(gpa, io, "args1.bat", args, env); + try testExecBat(gpa, io, "args2.bat", args, env); + try testExecBat(gpa, io, "args3.bat", args, env); } -fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void { +fn testExecBat(gpa: Allocator, io: Io, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void { const argv = try gpa.alloc([]const u8, 1 + args.len); defer gpa.free(argv); argv[0] = bat; @@ -92,8 +94,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat"); - const result = try std.process.Child.run(.{ - .allocator = gpa, + const result = try std.process.Child.run(gpa, io, .{ .env_map = env, .argv = argv, }); diff --git a/test/standalone/windows_bat_args/test.zig b/test/standalone/windows_bat_args/test.zig index 4690d983f3..558adc248f 100644 --- a/test/standalone/windows_bat_args/test.zig +++ b/test/standalone/windows_bat_args/test.zig @@ -1,4 +1,6 @@ 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; @@ -121,17 +123,17 @@ pub fn main() anyerror!void { try std.testing.expectError(error.FileNotFound, tmp.dir.access("file.txt", .{})); } -fn testExecError(err: anyerror, gpa: std.mem.Allocator, args: []const []const u8) !void { +fn testExecError(err: anyerror, gpa: Allocator, args: []const []const u8) !void { return std.testing.expectError(err, testExec(gpa, args, null)); } -fn testExec(gpa: std.mem.Allocator, args: []const []const u8, env: ?*std.process.EnvMap) !void { +fn testExec(gpa: Allocator, args: []const []const u8, env: ?*std.process.EnvMap) !void { try testExecBat(gpa, "args1.bat", args, env); try testExecBat(gpa, "args2.bat", args, env); try testExecBat(gpa, "args3.bat", args, env); } -fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void { +fn testExecBat(gpa: Allocator, io: Io, bat: []const u8, args: []const []const u8, env: ?*std.process.EnvMap) !void { const argv = try gpa.alloc([]const u8, 1 + args.len); defer gpa.free(argv); argv[0] = bat; @@ -139,8 +141,7 @@ fn testExecBat(gpa: std.mem.Allocator, bat: []const u8, args: []const []const u8 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat"); - const result = try std.process.Child.run(.{ - .allocator = gpa, + const result = try std.process.Child.run(gpa, io, .{ .env_map = env, .argv = argv, }); diff --git a/test/standalone/windows_paths/test.zig b/test/standalone/windows_paths/test.zig index 2ec23417e6..f5fa594766 100644 --- a/test/standalone/windows_paths/test.zig +++ b/test/standalone/windows_paths/test.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const Io = std.Io; pub fn main() anyerror!void { var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator); @@ -9,6 +10,9 @@ pub fn main() anyerror!void { if (args.len < 2) return error.MissingArgs; + var threaded: Io.Threaded = .init_single_threaded; + const io = threaded.io(); + const exe_path = args[1]; const cwd_path = try std.process.getCwdAlloc(arena); @@ -33,39 +37,39 @@ pub fn main() anyerror!void { // With the special =X: environment variable set, drive-relative paths that // don't match the CWD's drive letter are resolved against that env var. - try checkRelative(arena, "..\\..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &alt_drive_env_map); - try checkRelative(arena, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &alt_drive_env_map); + try checkRelative(arena, io, "..\\..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &alt_drive_env_map); + try checkRelative(arena, io, "..\\baz\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &alt_drive_env_map); // Without that environment variable set, drive-relative paths that don't match the // CWD's drive letter are resolved against the root of the drive. - try checkRelative(arena, "..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env); - try checkRelative(arena, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env); + try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env); + try checkRelative(arena, io, "..\\foo", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env); // Bare drive-relative path with no components - try checkRelative(arena, "bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &empty_env); - try checkRelative(arena, "..", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &empty_env); + try checkRelative(arena, io, "bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &empty_env); + try checkRelative(arena, io, "..", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &empty_env); // Bare drive-relative path with no components, drive-CWD set - try checkRelative(arena, "..\\bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &alt_drive_env_map); - try checkRelative(arena, "..\\baz", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &alt_drive_env_map); + try checkRelative(arena, io, "..\\bar", &.{ exe_path, drive_rel[0..2], drive_abs }, null, &alt_drive_env_map); + try checkRelative(arena, io, "..\\baz", &.{ exe_path, drive_abs, drive_rel[0..2] }, null, &alt_drive_env_map); // Bare drive-relative path relative to the CWD should be equivalent if drive-CWD is set - try checkRelative(arena, "", &.{ exe_path, alt_drive_cwd, drive_rel[0..2] }, null, &alt_drive_env_map); - try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], alt_drive_cwd }, null, &alt_drive_env_map); + try checkRelative(arena, io, "", &.{ exe_path, alt_drive_cwd, drive_rel[0..2] }, null, &alt_drive_env_map); + try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], alt_drive_cwd }, null, &alt_drive_env_map); // Bare drive-relative should always be equivalent to itself - try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map); - try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map); - try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env); - try checkRelative(arena, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env); + try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map); + try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &alt_drive_env_map); + try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env); + try checkRelative(arena, io, "", &.{ exe_path, drive_rel[0..2], drive_rel[0..2] }, null, &empty_env); } if (parsed_cwd_path.kind == .unc_absolute) { const drive_abs_path = try std.fmt.allocPrint(arena, "{c}:\\foo\\bar", .{alt_drive_letter}); { - try checkRelative(arena, drive_abs_path, &.{ exe_path, cwd_path, drive_abs_path }, null, &empty_env); - try checkRelative(arena, cwd_path, &.{ exe_path, drive_abs_path, cwd_path }, null, &empty_env); + try checkRelative(arena, io, drive_abs_path, &.{ exe_path, cwd_path, drive_abs_path }, null, &empty_env); + try checkRelative(arena, io, cwd_path, &.{ exe_path, drive_abs_path, cwd_path }, null, &empty_env); } } else if (parsed_cwd_path.kind == .drive_absolute) { const cur_drive_letter = parsed_cwd_path.root[0]; @@ -73,14 +77,14 @@ pub fn main() anyerror!void { const unc_cwd = try std.fmt.allocPrint(arena, "\\\\127.0.0.1\\{c}$\\{s}", .{ cur_drive_letter, path_beyond_root }); { - try checkRelative(arena, cwd_path, &.{ exe_path, unc_cwd, cwd_path }, null, &empty_env); - try checkRelative(arena, unc_cwd, &.{ exe_path, cwd_path, unc_cwd }, null, &empty_env); + try checkRelative(arena, io, cwd_path, &.{ exe_path, unc_cwd, cwd_path }, null, &empty_env); + try checkRelative(arena, io, unc_cwd, &.{ exe_path, cwd_path, unc_cwd }, null, &empty_env); } { const drive_abs = cwd_path; const drive_rel = parsed_cwd_path.root[0..2]; - try checkRelative(arena, "", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env); - try checkRelative(arena, "", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env); + try checkRelative(arena, io, "", &.{ exe_path, drive_abs, drive_rel }, null, &empty_env); + try checkRelative(arena, io, "", &.{ exe_path, drive_rel, drive_abs }, null, &empty_env); } } else { return error.UnexpectedPathType; @@ -89,13 +93,13 @@ pub fn main() anyerror!void { fn checkRelative( allocator: std.mem.Allocator, + io: Io, expected_stdout: []const u8, argv: []const []const u8, cwd: ?[]const u8, env_map: ?*const std.process.EnvMap, ) !void { - const result = try std.process.Child.run(.{ - .allocator = allocator, + const result = try std.process.Child.run(allocator, io, .{ .argv = argv, .cwd = cwd, .env_map = env_map,