authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-02 19:14:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-02 19:14:23-04:00
log640389bb2b04766e58e206c53ee2048c54534eb9
tree5d0d463ee30fedce1678f018294ca1b51aae2a10
parent8fd0fddce5d44344dd7914ae86a4d976b99f9cc3

expose environment variables in standard library

closes #118

2 files changed, 42 insertions(+), 8 deletions(-)

std/os/index.zig+17-4
......@@ -7,6 +7,7 @@ pub const posix = switch(@compileVar("os")) {
77 Os.windows => windows,
88 else => @compileError("Unsupported OS"),
99};
10
1011const debug = @import("../debug.zig");
1112const assert = debug.assert;
1213
......@@ -385,6 +386,8 @@ 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
......@@ -392,8 +395,6 @@ pub const ChildProcess = struct {
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
......@@ -401,8 +402,6 @@ pub const ChildProcess = struct {
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
422pub const EnvPair = struct {
423 key: []const u8,
424 value: []const u8,
425};
426pub var environ: []const EnvPair = undefined;
427
428pub 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+25-4
......@@ -32,21 +32,42 @@ export nakedcc fn _start() -> noreturn {
3232 callMainAndExit()
3333}
3434
35fn callMain() -> %void {
35fn 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
4464fn callMainAndExit() -> noreturn {
45 callMain() %% exit(1);
65 const envp = @ptrcast(&?&u8, &argv[argc + 1]);
66 callMain(envp) %% exit(1);
4667 exit(0);
4768}
4869
49export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
70export 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;
......@@ -54,6 +75,6 @@ export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
5475
5576 argc = usize(c_argc);
5677 argv = c_argv;
57 callMain() %% return 1;
78 callMain(c_envp) %% return 1;
5879 return 0;
5980}