commit 8b7db053b1a414057a231c11dd40b3ef43e9140c
parent 2e2be8aef1a769d22595831ed0a040789f61eeb3
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 30 Jan 2021 18:49:12 -0500
os: add getenv, must_getenv
Diffstat:
2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/os/+linux/environ.ha b/os/+linux/environ.ha
@@ -1,3 +1,4 @@
+use bytes;
use rt;
use strings;
use types;
@@ -28,3 +29,20 @@ let args_static: [32]str = [""...];
free(args);
};
};
+
+// Looks up an environment variable and returns its value, or void if unset.
+export fn getenv(name: str) (str | void) = {
+ // TODO: Type promotion can simplify this null comparison
+ for (let i = 0z; rt::envp[i] != null: nullable *char; i += 1z) {
+ const item = rt::envp[i]: *[*]u8;
+ const eq: size = match (bytes::index(item[..], '=': u32: u8)) {
+ void => abort("Environment violates System-V invariants"),
+ i: size => i,
+ };
+ if (bytes::equal(strings::to_utf8(name), item[..eq])) {
+ const ln = strings::c_strlen(item: *const char);
+ return strings::from_utf8(item[eq+1z..ln]);
+ };
+ };
+ return void;
+};
diff --git a/os/environ.ha b/os/environ.ha
@@ -0,0 +1,8 @@
+// Looks up an environment variable and returns its value. Aborts if unset.
+export fn must_getenv(name: str) str = {
+ // TODO: It would be nice to print the name of the variable in the error
+ match (getenv(name)) {
+ s: str => s,
+ * => abort("required environment variable unset"),
+ };
+};