From 73bbd4c56086ad110bd8dae7065dd680b1798a79 Mon Sep 17 00:00:00 2001 From: Mathew R Gordon <72643694+mgord9518@users.noreply.github.com> Date: Wed, 12 Jul 2023 07:11:48 -0600 Subject: [PATCH] Implement getenv for non-Windows OSes As Windows does not have a populated environ of U8s, it'll take a slightly different solution. I did some looking at the Zig stdlib os.getenv, and it uses the 0 byte to find the end of the environment variable, along with environ being a slice of [:0]const u8, so I have no clue why it isn't returned as [:0]const u8. Might be an issue in os.getenv --- src/cstd.zig | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/cstd.zig b/src/cstd.zig index e7cd213..0aea0b2 100644 --- a/src/cstd.zig +++ b/src/cstd.zig @@ -112,11 +112,24 @@ export fn abort() callconv(.C) noreturn { // TODO: can name be null? // TODO: should we detect and do something different if there is a '=' in name? -export fn getenv(name: [*:0]const u8) callconv(.C) ?[*:0]u8 { - trace.log("getenv {}", .{trace.fmtStr(name)}); - return null; // not implemented - //const name_len = std.mem.len(name); - //var e: ?[*:0]u8 = environ; +export fn getenv(key: [*:0]const u8) callconv(.C) ?[*:0]u8 { + trace.log("getenv {}", .{trace.fmtStr(key)}); + switch (builtin.os.tag) { + // Windows not yet implemented + // Maybe `environ` should be populated on the first call of getenv? + .windows => return null, + else => { + // Looking at the Zig stdlib implementation of getenvZ, this should + // be null terminated + const ret = std.os.getenvZ(key); + if (ret) |env| { + // Why does libc return a mutable pointer with getenv? + return @constCast(env[0.. :0].ptr); + } + + return null; + }, + } } export fn system(string: ?[*:0]const u8) callconv(.C) c_int {