From e2c04a46518f1c75076e642f56ae9d5bae3da3f3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 3 Jan 2026 03:17:01 -0800 Subject: [PATCH] fix some windows compilation errors --- lib/compiler/resinator/main.zig | 2 +- lib/std/process/Environ.zig | 7 ++++-- test/standalone/windows_argv/fuzz.zig | 24 ++++++++----------- test/standalone/windows_argv/lib.zig | 7 ++++-- .../standalone/windows_bat_args/echo-args.zig | 11 ++++----- test/standalone/windows_bat_args/fuzz.zig | 2 +- test/standalone/windows_bat_args/test.zig | 4 ++-- test/standalone/windows_paths/relative.zig | 19 +++++---------- test/standalone/windows_paths/test.zig | 12 ++++------ test/standalone/windows_spawn/main.zig | 5 ++-- 10 files changed, 41 insertions(+), 52 deletions(-) diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 9e654b4947..d1aaa24264 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -633,7 +633,7 @@ fn getIncludePaths( }; const target = std.zig.resolveTargetQueryOrFatal(io, target_query); const is_native_abi = target_query.isNativeAbi(); - const detected_libc = std.zig.LibCDirs.detect(arena, io, zig_lib_dir, &target, is_native_abi, true, null) catch { + const detected_libc = std.zig.LibCDirs.detect(arena, io, zig_lib_dir, &target, is_native_abi, true, null, environ_map) catch { if (includes == .any) { // fall back to mingw includes = .gnu; diff --git a/lib/std/process/Environ.zig b/lib/std/process/Environ.zig index 39ca80ca8b..ba2f70a843 100644 --- a/lib/std/process/Environ.zig +++ b/lib/std/process/Environ.zig @@ -542,14 +542,17 @@ pub fn getPosix(environ: Environ, key: []const u8) ?[:0]const u8 { /// * `contains` pub fn getWindows(environ: Environ, key: [*:0]const u16) ?[:0]const u16 { comptime assert(native_os == .windows); + comptime assert(@TypeOf(environ.block) == void); // '=' anywhere but the start makes this an invalid environment variable name. const key_slice = mem.sliceTo(key, 0); if (key_slice.len > 0 and mem.findScalar(u16, key_slice[1..], '=') != null) return null; + const ptr = std.os.windows.peb().ProcessParameters.Environment; + var i: usize = 0; - while (environ.block[i] != 0) { - const key_value = mem.sliceTo(environ.block[i..], 0); + while (ptr[i] != 0) { + const key_value = mem.sliceTo(ptr[i..], 0); // There are some special environment variables that start with =, // so we need a special case to not treat = as a key/value separator diff --git a/test/standalone/windows_argv/fuzz.zig b/test/standalone/windows_argv/fuzz.zig index bdf40aa4b1..7e7f43a6af 100644 --- a/test/standalone/windows_argv/fuzz.zig +++ b/test/standalone/windows_argv/fuzz.zig @@ -3,19 +3,15 @@ const builtin = @import("builtin"); const windows = std.os.windows; const Allocator = std.mem.Allocator; -pub fn main() !void { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - defer std.debug.assert(gpa.deinit() == .ok); - const allocator = gpa.allocator(); - - const args = try std.process.argsAlloc(allocator); - defer std.process.argsFree(allocator, args); +pub fn main(init: std.process.Init) !void { + const gpa = init.gpa; + const args = try init.minimal.args.toSlice(init.arena.allocator()); if (args.len < 2) return error.MissingArgs; const verify_path_wtf8 = args[1]; - const verify_path_w = try std.unicode.wtf8ToWtf16LeAllocZ(allocator, verify_path_wtf8); - defer allocator.free(verify_path_w); + const verify_path_w = try std.unicode.wtf8ToWtf16LeAllocZ(gpa, verify_path_wtf8); + defer gpa.free(verify_path_w); const iterations: u64 = iterations: { if (args.len < 3) break :iterations 0; @@ -41,14 +37,14 @@ pub fn main() !void { std.debug.print("rand seed: {}\n", .{seed}); } - var cmd_line_w_buf = std.array_list.Managed(u16).init(allocator); + var cmd_line_w_buf = std.array_list.Managed(u16).init(gpa); defer cmd_line_w_buf.deinit(); var i: u64 = 0; var errors: u64 = 0; while (iterations == 0 or i < iterations) { - const cmd_line_w = try randomCommandLineW(allocator, rand); - defer allocator.free(cmd_line_w); + const cmd_line_w = try randomCommandLineW(gpa, rand); + defer gpa.free(cmd_line_w); // avoid known difference for 0-length command lines if (cmd_line_w.len == 0 or cmd_line_w[0] == '\x00') continue; @@ -56,8 +52,8 @@ pub fn main() !void { const exit_code = try spawnVerify(verify_path_w, cmd_line_w); if (exit_code != 0) { std.debug.print(">>> found discrepancy <<<\n", .{}); - const cmd_line_wtf8 = try std.unicode.wtf16LeToWtf8Alloc(allocator, cmd_line_w); - defer allocator.free(cmd_line_wtf8); + const cmd_line_wtf8 = try std.unicode.wtf16LeToWtf8Alloc(gpa, cmd_line_w); + defer gpa.free(cmd_line_wtf8); std.debug.print("\"{f}\"\n\n", .{std.zig.fmtString(cmd_line_wtf8)}); errors += 1; diff --git a/test/standalone/windows_argv/lib.zig b/test/standalone/windows_argv/lib.zig index 4171d13dab..750501edd2 100644 --- a/test/standalone/windows_argv/lib.zig +++ b/test/standalone/windows_argv/lib.zig @@ -5,7 +5,7 @@ export fn verify(argc: c_int, argv: [*]const [*:0]const u16) c_int { const argv_slice = argv[0..@intCast(argc)]; testArgv(argv_slice) catch |err| switch (err) { error.OutOfMemory => @panic("oom"), - error.Overflow => @panic("bytes needed to contain args would overflow usize"), + error.Unexpected => @panic("unexpected error"), error.ArgvMismatch => return 0, }; return 1; @@ -16,7 +16,10 @@ fn testArgv(expected_args: []const [*:0]const u16) !void { defer arena_state.deinit(); const allocator = arena_state.allocator(); - const args = try std.process.argsAlloc(allocator); + const cmd_line = std.os.windows.peb().ProcessParameters.CommandLine; + const cmd_line_w = cmd_line.Buffer.?[0..@divExact(cmd_line.Length, 2)]; + const raw_args: std.process.Args = .{ .vector = cmd_line_w }; + const args = try raw_args.toSlice(allocator); var wtf8_buf = std.array_list.Managed(u8).init(allocator); var eql = true; diff --git a/test/standalone/windows_bat_args/echo-args.zig b/test/standalone/windows_bat_args/echo-args.zig index 6aeb43d56c..a867a1bb24 100644 --- a/test/standalone/windows_bat_args/echo-args.zig +++ b/test/standalone/windows_bat_args/echo-args.zig @@ -1,15 +1,12 @@ const std = @import("std"); -pub fn main() !void { - var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_state.deinit(); - const arena = arena_state.allocator(); - - const io = std.Options.debug_io; +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); const stdout = &stdout_writer.interface; - var args = try std.process.argsAlloc(arena); for (args[1..], 1..) |arg, i| { try stdout.writeAll(arg); if (i != args.len - 1) try stdout.writeByte('\x00'); diff --git a/test/standalone/windows_bat_args/fuzz.zig b/test/standalone/windows_bat_args/fuzz.zig index e5d84fa4b5..b82ec8b458 100644 --- a/test/standalone/windows_bat_args/fuzz.zig +++ b/test/standalone/windows_bat_args/fuzz.zig @@ -8,7 +8,7 @@ pub fn main(init: std.process.Init) !void { const gpa = init.gpa; const io = init.io; - var it = try init.minimal.argsAllocator(gpa); + var it = try init.minimal.args.iterateAllocator(gpa); defer it.deinit(); _ = it.next() orelse unreachable; // skip binary name const child_exe_path_orig = it.next() orelse unreachable; diff --git a/test/standalone/windows_bat_args/test.zig b/test/standalone/windows_bat_args/test.zig index 520617aa38..fde627a5fe 100644 --- a/test/standalone/windows_bat_args/test.zig +++ b/test/standalone/windows_bat_args/test.zig @@ -6,7 +6,7 @@ pub fn main(init: std.process.Init) !void { const gpa = init.gpa; const io = init.io; - var it = try init.minimal.argsAllocator(gpa); + var it = try init.minimal.args.iterateAllocator(gpa); defer it.deinit(); _ = it.next() orelse unreachable; // skip binary name const child_exe_path_orig = it.next() orelse unreachable; @@ -105,7 +105,7 @@ pub fn main(init: std.process.Init) !void { try std.testing.expectError(error.FileNotFound, testExecBat(gpa, io, absolute_with_trailing, &.{"abc"}, null)); var env = env: { - var env = try std.process.getEnvMap(gpa); + var env = try init.environ_map.clone(gpa); errdefer env.deinit(); // No escaping try env.put("FOO", "123"); diff --git a/test/standalone/windows_paths/relative.zig b/test/standalone/windows_paths/relative.zig index 7b6a51b283..7b3725e4ee 100644 --- a/test/standalone/windows_paths/relative.zig +++ b/test/standalone/windows_paths/relative.zig @@ -1,21 +1,14 @@ const std = @import("std"); -pub fn main() !void { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - defer std.debug.assert(gpa.deinit() == .ok); - const allocator = gpa.allocator(); - - const args = try std.process.argsAlloc(allocator); - defer std.process.argsFree(allocator, args); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const args = try init.minimal.args.toSlice(arena); + const io = init.io; + const cwd_path = try std.process.getCwdAlloc(arena); if (args.len < 3) return error.MissingArgs; - var threaded: std.Io.Threaded = .init(allocator, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - const relative = try std.fs.path.relative(allocator, args[1], args[2]); - defer allocator.free(relative); + const relative = try std.fs.path.relative(arena, cwd_path, init.environ_map, args[1], args[2]); var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); const stdout = &stdout_writer.interface; diff --git a/test/standalone/windows_paths/test.zig b/test/standalone/windows_paths/test.zig index b248cc9277..94afe16337 100644 --- a/test/standalone/windows_paths/test.zig +++ b/test/standalone/windows_paths/test.zig @@ -1,17 +1,13 @@ const std = @import("std"); const Io = std.Io; -pub fn main() anyerror!void { - var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_state.deinit(); - const arena = arena_state.allocator(); - - const args = try std.process.argsAlloc(arena); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const args = try init.minimal.args.toSlice(arena); + const io = init.io; if (args.len < 2) return error.MissingArgs; - const io = std.Io.Threaded.global_single_threaded.ioBasic(); - const exe_path = args[1]; const cwd_path = try std.process.getCwdAlloc(arena); diff --git a/test/standalone/windows_spawn/main.zig b/test/standalone/windows_spawn/main.zig index b1fba1bed6..4a64ca48d6 100644 --- a/test/standalone/windows_spawn/main.zig +++ b/test/standalone/windows_spawn/main.zig @@ -8,8 +8,9 @@ const utf16Literal = std.unicode.utf8ToUtf16LeStringLiteral; pub fn main(init: std.process.Init) !void { const gpa = init.gpa; const io = init.io; + const process_cwd_path = try std.process.getCwdAlloc(init.arena.allocator()); - var it = try init.minimal.argsAllocator(gpa); + var it = try init.minimal.args.iterateAllocator(gpa); defer it.deinit(); _ = it.next() orelse unreachable; // skip binary name const hello_exe_cache_path = it.next() orelse unreachable; @@ -23,7 +24,7 @@ pub fn main(init: std.process.Init) !void { defer gpa.free(tmp_absolute_path_w); const cwd_absolute_path = try Io.Dir.cwd().realPathFileAlloc(io, ".", gpa); defer gpa.free(cwd_absolute_path); - const tmp_relative_path = try std.fs.path.relative(gpa, cwd_absolute_path, tmp_absolute_path); + const tmp_relative_path = try std.fs.path.relative(gpa, process_cwd_path, init.environ_map, cwd_absolute_path, tmp_absolute_path); defer gpa.free(tmp_relative_path); // Clear PATH