expose environment variables in standard library

closes #118
master
Andrew Kelley 2017-04-02 19:14:23 -04:00
parent 8fd0fddce5
commit 640389bb2b
2 changed files with 42 additions and 8 deletions

View File

@ -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;
}

View File

@ -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;
}