platform_environ.ha (3076B)
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 @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 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 let name: [2]int = [rt::CTL_KERN, rt::KERN_OSTYPE]; 53 54 static let buf: [32]u8 = [0...]; 55 let buf_sz = len(buf); 56 57 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 58 return strings::fromutf8(buf[..(buf_sz -1)])!; 59 }; 60 61 // Returns the host system hostname 62 export fn hostname() const str = { 63 let name: [2]int = [rt::CTL_KERN, rt::KERN_HOSTNAME]; 64 65 static let buf: [rt::MAXHOSTNAMELEN]u8 = [0...]; 66 let buf_sz = len(buf); 67 68 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 69 return strings::fromutf8(buf[..(buf_sz -1)])!; 70 }; 71 72 // Returns the host operating system version 73 export fn version() const str = { 74 let name: [2]int = [rt::CTL_KERN, rt::KERN_OSRELEASE]; 75 76 static let buf: [32]u8 = [0...]; 77 let buf_sz = len(buf); 78 79 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 80 return strings::fromutf8(buf[..(buf_sz -1)])!; 81 }; 82 83 // Returns the host CPU architecture, in a platform-specific format. See 84 // [[architecture]] for a more portable wrapper. 85 export fn machine() const str = { 86 let name: [2]int = [rt::CTL_HW, rt::HW_MACHINE]; 87 88 static let buf: [32]u8 = [0...]; 89 let buf_sz = len(buf); 90 91 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 92 93 return strings::fromutf8(buf[..(buf_sz - 1)])!; 94 }; 95 96 // Returns the host CPU architecture. 97 export fn architecture() arch = { 98 switch (machine()) { 99 case "arm64" => 100 return arch::AARCH64; 101 case "riscv64" => 102 return arch::RISCV64; 103 case "amd64" => 104 return arch::X86_64; 105 case => abort(); // unreachable 106 }; 107 }; 108 109 // Returns the number of usable CPUs. 110 export fn cpucount() (size | errors::error) = { 111 let name: [2]int = [rt::CTL_HW, rt::HW_NCPUONLINE]; 112 113 let ncpu: int = 0; 114 let ncpu_sz = size(int); 115 116 match (rt::sysctl(name, len(name): uint, &ncpu, &ncpu_sz, null, 0)) { 117 case void => 118 return ncpu: size; 119 case let err: rt::errno => 120 return errors::errno(err); 121 }; 122 };