Skip to content

Commit 640389b

Browse files
committed
expose environment variables in standard library
closes #118
1 parent 8fd0fdd commit 640389b

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

std/os/index.zig

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub const posix = switch(@compileVar("os")) {
77
Os.windows => windows,
88
else => @compileError("Unsupported OS"),
99
};
10+
1011
const debug = @import("../debug.zig");
1112
const assert = debug.assert;
1213

@@ -385,24 +386,22 @@ pub const ChildProcess = struct {
385386
.stdin = if (stdin == StdIo.Pipe) {
386387
io.OutStream {
387388
.fd = stdin_pipe[1],
389+
.buffer = undefined,
390+
.index = 0,
388391
}
389392
} else {
390393
null
391394
},
392395
.stdout = if (stdout == StdIo.Pipe) {
393396
io.InStream {
394397
.fd = stdout_pipe[0],
395-
.buffer = undefined,
396-
.index = 0,
397398
}
398399
} else {
399400
null
400401
},
401402
.stderr = if (stderr == StdIo.Pipe) {
402403
io.InStream {
403404
.fd = stderr_pipe[0],
404-
.buffer = undefined,
405-
.index = 0,
406405
}
407406
} else {
408407
null
@@ -419,3 +418,17 @@ pub const ChildProcess = struct {
419418
}
420419
}
421420
};
421+
422+
pub const EnvPair = struct {
423+
key: []const u8,
424+
value: []const u8,
425+
};
426+
pub var environ: []const EnvPair = undefined;
427+
428+
pub fn getEnv(key: []const u8) -> ?[]const u8 {
429+
for (environ) |pair| {
430+
if (mem.eql(u8, pair.key, key))
431+
return pair.value;
432+
}
433+
return null;
434+
}

std/special/bootstrap.zig

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,49 @@ export nakedcc fn _start() -> noreturn {
3232
callMainAndExit()
3333
}
3434

35-
fn callMain() -> %void {
35+
fn callMain(envp: &?&u8) -> %void {
3636
const args = @alloca([]u8, argc);
3737
for (args) |_, i| {
3838
const ptr = argv[i];
3939
args[i] = ptr[0...std.cstr.len(ptr)];
4040
}
41+
42+
var env_count: usize = 0;
43+
while (envp[env_count] != null; env_count += 1) {}
44+
const environ = @alloca(std.os.EnvPair, env_count);
45+
for (environ) |_, env_i| {
46+
const ptr = ??envp[env_i];
47+
48+
var line_i: usize = 0;
49+
while (ptr[line_i] != 0 and ptr[line_i] != '='; line_i += 1) {}
50+
51+
var end_i: usize = line_i;
52+
while (ptr[end_i] != 0; end_i += 1) {}
53+
54+
environ[env_i] = std.os.EnvPair {
55+
.key = ptr[0...line_i],
56+
.value = ptr[line_i + 1...end_i],
57+
};
58+
}
59+
std.os.environ = environ;
60+
4161
return root.main(args);
4262
}
4363

4464
fn callMainAndExit() -> noreturn {
45-
callMain() %% exit(1);
65+
const envp = @ptrcast(&?&u8, &argv[argc + 1]);
66+
callMain(envp) %% exit(1);
4667
exit(0);
4768
}
4869

49-
export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
70+
export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {
5071
@setGlobalLinkage(main, if (want_main_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal);
5172
if (!want_main_symbol) {
5273
unreachable;
5374
}
5475

5576
argc = usize(c_argc);
5677
argv = c_argv;
57-
callMain() %% return 1;
78+
callMain(c_envp) %% return 1;
5879
return 0;
5980
}

0 commit comments

Comments
 (0)