platform_environ.ha (2986B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use errors; 5 use rt; 6 use strings; 7 use types::c; 8 9 // The command line arguments provided to the program. By convention, the first 10 // member is usually the name of the program. 11 export let args: []str = []; 12 13 // Statically allocate arg strings if there are few enough arguments, saves a 14 // syscall if we don't need it. 15 let args_static: [32]str = [""...]; 16 17 @init fn args() void = { 18 if (rt::argc < len(args_static)) { 19 args = args_static[..rt::argc]; 20 for (let i = 0z; i < rt::argc; i += 1) { 21 args[i] = c::tostr(rt::argv[i]: *const c::char)!; 22 }; 23 } else { 24 args = alloc([], rt::argc); 25 for (let i = 0z; i < rt::argc; i += 1) { 26 append(args, c::tostr(rt::argv[i]: *const c::char)!); 27 }; 28 }; 29 30 }; 31 32 @fini fn args() void = { 33 if (rt::argc >= len(args_static)) { 34 free(args); 35 }; 36 }; 37 38 // Returns a slice of the environment strings in the form KEY=VALUE. 39 export fn getenvs() []str = { 40 if (len(envp) != 0) { 41 return envp; 42 }; 43 for (let i = 0z; rt::envp[i] != null; i += 1) { 44 let s = c::tostr(rt::envp[i]: *const c::char)!; 45 append(envp, strings::dup(s)); 46 }; 47 return envp; 48 }; 49 50 // Returns the host kernel name 51 export fn sysname() const str = { 52 static let buf: [512]u8 = [0...]; 53 let sz: size = len(buf); 54 rt::sysctlbyname("kern.ostype", &buf, &sz, null, 0)!; 55 return strings::fromutf8(buf[..(sz - 1)])!; 56 }; 57 58 // Returns the host system hostname 59 export fn hostname() const str = { 60 static let buf: [512]u8 = [0...]; 61 let sz: size = len(buf); 62 rt::sysctlbyname("kern.hostname", &buf, &sz, null, 0)!; 63 return strings::fromutf8(buf[..(sz - 1)])!; 64 }; 65 66 // Returns the host kernel version 67 export fn release() const str = { 68 static let buf: [512]u8 = [0...]; 69 let sz: size = len(buf); 70 rt::sysctlbyname("kern.osrelease", &buf, &sz, null, 0)!; 71 return strings::fromutf8(buf[..(sz - 1)])!; 72 }; 73 74 // Returns the host operating system version 75 export fn version() const str = { 76 static let buf: [512]u8 = [0...]; 77 let sz: size = len(buf); 78 rt::sysctlbyname("kern.version", &buf, &sz, null, 0)!; 79 return strings::fromutf8(buf[..(sz - 1)])!; 80 }; 81 82 // Returns the host CPU architecture, in a platform-specific format. See 83 // [[architecture]] for a more portable wrapper. 84 export fn machine() const str = { 85 static let buf: [32]u8 = [0...]; 86 let sz: size = len(buf); 87 rt::sysctlbyname("hw.machine", &buf, &sz, null, 0)!; 88 return strings::fromutf8(buf[..sz - 1])!; 89 }; 90 91 // Returns the host CPU architecture. 92 export fn architecture() arch = { 93 switch (machine()) { 94 case "aarch64" => 95 return arch::AARCH64; 96 case "riscv64" => 97 return arch::RISCV64; 98 case "amd64" => 99 return arch::X86_64; 100 case => abort(); // unreachable 101 }; 102 }; 103 104 // Returns the number of usable CPUs. 105 export fn cpucount() (size | errors::error) = { 106 let count = 0; 107 let length = size(int); 108 match (rt::sysctlbyname("hw.ncpu", &count, &length, null, 0)) { 109 case void => void; 110 case let err: rt::errno => 111 return errors::errno(err); 112 }; 113 return count: size; 114 };