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