diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-04-02 19:14:23 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-04-02 19:14:23 -0400 |
| commit | 640389bb2b04766e58e206c53ee2048c54534eb9 (patch) | |
| tree | 5d0d463ee30fedce1678f018294ca1b51aae2a10 | |
| parent | 8fd0fddce5d44344dd7914ae86a4d976b99f9cc3 (diff) | |
| download | zig-640389bb2b04766e58e206c53ee2048c54534eb9.tar.gz zig-640389bb2b04766e58e206c53ee2048c54534eb9.zip | |
expose environment variables in standard library
closes #118
| -rw-r--r-- | std/os/index.zig | 21 | ||||
| -rw-r--r-- | std/special/bootstrap.zig | 29 |
2 files changed, 42 insertions, 8 deletions
diff --git a/std/os/index.zig b/std/os/index.zig index baa43e23de..bae1a8ec5a 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -7,6 +7,7 @@ pub const posix = switch(@compileVar("os")) { Os.windows => windows, else => @compileError("Unsupported OS"), }; + const debug = @import("../debug.zig"); const assert = debug.assert; @@ -385,6 +386,8 @@ pub const ChildProcess = struct { .stdin = if (stdin == StdIo.Pipe) { io.OutStream { .fd = stdin_pipe[1], + .buffer = undefined, + .index = 0, } } else { null @@ -392,8 +395,6 @@ pub const ChildProcess = struct { .stdout = if (stdout == StdIo.Pipe) { io.InStream { .fd = stdout_pipe[0], - .buffer = undefined, - .index = 0, } } else { null @@ -401,8 +402,6 @@ pub const ChildProcess = struct { .stderr = if (stderr == StdIo.Pipe) { io.InStream { .fd = stderr_pipe[0], - .buffer = undefined, - .index = 0, } } else { null @@ -419,3 +418,17 @@ pub const ChildProcess = struct { } } }; + +pub const EnvPair = struct { + key: []const u8, + value: []const u8, +}; +pub var environ: []const EnvPair = undefined; + +pub fn getEnv(key: []const u8) -> ?[]const u8 { + for (environ) |pair| { + if (mem.eql(u8, pair.key, key)) + return pair.value; + } + return null; +} diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index 92cac016d7..0705fbb296 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -32,21 +32,42 @@ export nakedcc fn _start() -> noreturn { callMainAndExit() } -fn callMain() -> %void { +fn callMain(envp: &?&u8) -> %void { const args = @alloca([]u8, argc); for (args) |_, i| { const ptr = argv[i]; args[i] = ptr[0...std.cstr.len(ptr)]; } + + var env_count: usize = 0; + while (envp[env_count] != null; env_count += 1) {} + const environ = @alloca(std.os.EnvPair, env_count); + for (environ) |_, env_i| { + const ptr = ??envp[env_i]; + + var line_i: usize = 0; + while (ptr[line_i] != 0 and ptr[line_i] != '='; line_i += 1) {} + + var end_i: usize = line_i; + while (ptr[end_i] != 0; end_i += 1) {} + + environ[env_i] = std.os.EnvPair { + .key = ptr[0...line_i], + .value = ptr[line_i + 1...end_i], + }; + } + std.os.environ = environ; + return root.main(args); } fn callMainAndExit() -> noreturn { - callMain() %% exit(1); + const envp = @ptrcast(&?&u8, &argv[argc + 1]); + callMain(envp) %% exit(1); exit(0); } -export fn main(c_argc: i32, c_argv: &&u8) -> i32 { +export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { @setGlobalLinkage(main, if (want_main_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal); if (!want_main_symbol) { unreachable; @@ -54,6 +75,6 @@ export fn main(c_argc: i32, c_argv: &&u8) -> i32 { argc = usize(c_argc); argv = c_argv; - callMain() %% return 1; + callMain(c_envp) %% return 1; return 0; } |
