authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-30 21:53:56-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-04 00:27:08-08:00
log42988fc5f43abdbac5ef5abc7cb5f74f8bc55ad4
tree81af082900114fe30ebce324b5e26ab596802b70
parentb85524d0c83686b7492aee78d5f766e76b59fc90

std.process.Environ.Block: enhance type safety


3 files changed, 14 insertions(+), 17 deletions(-)

lib/std/Io/Threaded.zig+2-1
......@@ -12688,7 +12688,8 @@ fn scanEnviron(t: *Threaded) void {
1268812688 }
1268912689 }
1269012690 } else {
12691 for (t.environ.block) |line| {
12691 for (t.environ.block) |opt_line| {
12692 const line = opt_line.?;
1269212693 var line_i: usize = 0;
1269312694 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
1269412695 const key = line[0..line_i];
lib/std/process/Environ.zig+9-13
......@@ -15,7 +15,7 @@ block: Block,
1515
1616pub const Block = switch (native_os) {
1717 .windows => []const u16,
18 else => []const [*:0]const u8,
18 else => [:null]const ?[*:0]const u8,
1919};
2020
2121pub const Map = struct {
......@@ -364,7 +364,8 @@ pub fn createMap(env: Environ, allocator: Allocator) CreateMapError!Map {
364364 }
365365 return result;
366366 } else {
367 for (env.block) |line| {
367 for (env.block) |opt_line| {
368 const line = opt_line.?;
368369 var line_i: usize = 0;
369370 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
370371 const key = line[0..line_i];
......@@ -579,15 +580,10 @@ pub const CreateBlockOptions = struct {
579580/// Creates a null-delimited environment variable block in the format expected
580581/// by POSIX, from a different one.
581582pub fn createBlock(existing: Environ, arena: Allocator, options: CreateBlockOptions) Allocator.Error![:null]?[*:0]u8 {
582 const existing_block: [*:null]const ?[*:0]const u8 = @ptrCast(existing.block);
583 const existing_count, const contains_zig_progress = c: {
584 var count: usize = 0;
585 var contains = false;
586 while (existing_block[count]) |line| : (count += 1) {
587 contains = contains or mem.eql(u8, mem.sliceTo(line, '='), "ZIG_PROGRESS");
588 }
589 break :c .{ count, contains };
590 };
583 const contains_zig_progress = for (existing.block) |opt_line| {
584 if (mem.eql(u8, mem.sliceTo(opt_line.?, '='), "ZIG_PROGRESS")) break true;
585 } else false;
586
591587 const ZigProgressAction = enum { nothing, edit, delete, add };
592588 const zig_progress_action: ZigProgressAction = a: {
593589 const fd = options.zig_progress_fd orelse break :a .nothing;
......@@ -600,7 +596,7 @@ pub fn createBlock(existing: Environ, arena: Allocator, options: CreateBlockOpti
600596 };
601597
602598 const envp_count: usize = c: {
603 var count: usize = existing_count;
599 var count: usize = existing.block.len;
604600 switch (zig_progress_action) {
605601 .add => count += 1,
606602 .delete => count -= 1,
......@@ -618,7 +614,7 @@ pub fn createBlock(existing: Environ, arena: Allocator, options: CreateBlockOpti
618614 i += 1;
619615 }
620616
621 while (existing_block[existing_index]) |line| : (existing_index += 1) {
617 while (existing.block[existing_index]) |line| : (existing_index += 1) {
622618 if (mem.eql(u8, mem.sliceTo(line, '='), "ZIG_PROGRESS")) switch (zig_progress_action) {
623619 .add => unreachable,
624620 .delete => continue,
lib/std/start.zig+3-3
......@@ -559,7 +559,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn {
559559 const envp_optional: [*:null]?[*:0]u8 = @ptrCast(@alignCast(argv + argc + 1));
560560 var envp_count: usize = 0;
561561 while (envp_optional[envp_count]) |_| : (envp_count += 1) {}
562 const envp = @as([*][*:0]u8, @ptrCast(envp_optional))[0..envp_count];
562 const envp = envp_optional[0..envp_count :null];
563563
564564 // Find the beginning of the auxiliary vector
565565 const auxv: [*]elf.Auxv = @ptrCast(@alignCast(envp.ptr + envp_count + 1));
......@@ -668,7 +668,7 @@ fn expandStackSize(phdrs: []elf.Phdr) void {
668668 }
669669}
670670
671inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
671inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [:null]?[*:0]u8) u8 {
672672 if (std.Options.debug_threaded_io) |t| {
673673 if (@sizeOf(std.Io.Threaded.Argv0) != 0) t.argv0.value = argv[0];
674674 t.environ = .{ .block = envp };
......@@ -680,7 +680,7 @@ inline fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
680680fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) callconv(.c) c_int {
681681 var env_count: usize = 0;
682682 while (c_envp[env_count] != null) : (env_count += 1) {}
683 const envp = @as([*][*:0]u8, @ptrCast(c_envp))[0..env_count];
683 const envp = c_envp[0..env_count :null];
684684
685685 if (builtin.os.tag == .linux) {
686686 const at_phdr = std.c.getauxval(elf.AT_PHDR);