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")) {...@@ -7,6 +7,7 @@ pub const posix = switch(@compileVar("os")) {
7 Os.windows => windows,7 Os.windows => windows,
8 else => @compileError("Unsupported OS"),8 else => @compileError("Unsupported OS"),
9};9};
10
10const debug = @import("../debug.zig");11const debug = @import("../debug.zig");
11const assert = debug.assert;12const assert = debug.assert;
1213
...@@ -385,6 +386,8 @@ pub const ChildProcess = struct {...@@ -385,6 +386,8 @@ pub const ChildProcess = struct {
385 .stdin = if (stdin == StdIo.Pipe) {386 .stdin = if (stdin == StdIo.Pipe) {
386 io.OutStream {387 io.OutStream {
387 .fd = stdin_pipe[1],388 .fd = stdin_pipe[1],
389 .buffer = undefined,
390 .index = 0,
388 }391 }
389 } else {392 } else {
390 null393 null
...@@ -392,8 +395,6 @@ pub const ChildProcess = struct {...@@ -392,8 +395,6 @@ pub const ChildProcess = struct {
392 .stdout = if (stdout == StdIo.Pipe) {395 .stdout = if (stdout == StdIo.Pipe) {
393 io.InStream {396 io.InStream {
394 .fd = stdout_pipe[0],397 .fd = stdout_pipe[0],
395 .buffer = undefined,
396 .index = 0,
397 }398 }
398 } else {399 } else {
399 null400 null
...@@ -401,8 +402,6 @@ pub const ChildProcess = struct {...@@ -401,8 +402,6 @@ pub const ChildProcess = struct {
401 .stderr = if (stderr == StdIo.Pipe) {402 .stderr = if (stderr == StdIo.Pipe) {
402 io.InStream {403 io.InStream {
403 .fd = stderr_pipe[0],404 .fd = stderr_pipe[0],
404 .buffer = undefined,
405 .index = 0,
406 }405 }
407 } else {406 } else {
408 null407 null
...@@ -419,3 +418,17 @@ pub const ChildProcess = struct {...@@ -419,3 +418,17 @@ pub const ChildProcess = struct {
419 }418 }
420 }419 }
421};420};
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 {...@@ -32,21 +32,42 @@ export nakedcc fn _start() -> noreturn {
32 callMainAndExit()32 callMainAndExit()
33}33}
3434
35fn callMain() -> %void {35fn callMain(envp: &?&u8) -> %void {
36 const args = @alloca([]u8, argc);36 const args = @alloca([]u8, argc);
37 for (args) |_, i| {37 for (args) |_, i| {
38 const ptr = argv[i];38 const ptr = argv[i];
39 args[i] = ptr[0...std.cstr.len(ptr)];39 args[i] = ptr[0...std.cstr.len(ptr)];
40 }40 }
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
41 return root.main(args);61 return root.main(args);
42}62}
4363
44fn callMainAndExit() -> noreturn {64fn callMainAndExit() -> noreturn {
45 callMain() %% exit(1);65 const envp = @ptrcast(&?&u8, &argv[argc + 1]);
66 callMain(envp) %% exit(1);
46 exit(0);67 exit(0);
47}68}
4869
49export fn main(c_argc: i32, c_argv: &&u8) -> i32 {70export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {
50 @setGlobalLinkage(main, if (want_main_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal);71 @setGlobalLinkage(main, if (want_main_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal);
51 if (!want_main_symbol) {72 if (!want_main_symbol) {
52 unreachable;73 unreachable;
...@@ -54,6 +75,6 @@ export fn main(c_argc: i32, c_argv: &&u8) -> i32 {...@@ -54,6 +75,6 @@ export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
5475
55 argc = usize(c_argc);76 argc = usize(c_argc);
56 argv = c_argv;77 argv = c_argv;
57 callMain() %% return 1;78 callMain(c_envp) %% return 1;
58 return 0;79 return 0;
59}80}