platform_environ.ha (3069B)
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 @fini fn args() void = { 32 if (rt::argc >= len(args_static)) { 33 free(args); 34 }; 35 }; 36 37 // Returns a slice of the environment strings in form KEY=VALUE. 38 export fn getenvs() []str = { 39 if (len(envp) > 0) { 40 return envp; 41 }; 42 for (let i = 0z; rt::envp[i] != null; i += 1) { 43 let s = c::tostr(rt::envp[i]: *const c::char)!; 44 append(envp, strings::dup(s))!; 45 }; 46 return envp; 47 }; 48 49 // Returns the host kernel name 50 export fn sysname() const str = { 51 let name: [2]int = [rt::CTL_KERN, rt::KERN_OSTYPE]; 52 53 static let buf: [32]u8 = [0...]; 54 let buf_sz = len(buf); 55 56 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 57 return strings::fromutf8(buf[..(buf_sz -1)])!; 58 }; 59 60 // Returns the host system hostname 61 export fn hostname() const str = { 62 let name: [2]int = [rt::CTL_KERN, rt::KERN_HOSTNAME]; 63 64 static let buf: [rt::MAXHOSTNAMELEN]u8 = [0...]; 65 let buf_sz = len(buf); 66 67 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 68 return strings::fromutf8(buf[..(buf_sz -1)])!; 69 }; 70 71 // Returns the host operating system version 72 export fn version() const str = { 73 let name: [2]int = [rt::CTL_KERN, rt::KERN_OSRELEASE]; 74 75 static let buf: [32]u8 = [0...]; 76 let buf_sz = len(buf); 77 78 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 79 return strings::fromutf8(buf[..(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 let name: [2]int = [rt::CTL_HW, rt::HW_MACHINE]; 86 87 static let buf: [32]u8 = [0...]; 88 let buf_sz = len(buf); 89 90 rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; 91 92 return strings::fromutf8(buf[..(buf_sz - 1)])!; 93 }; 94 95 // Returns the host CPU architecture. 96 export fn architecture() arch = { 97 switch (machine()) { 98 case "arm64" => 99 return arch::AARCH64; 100 case "riscv64" => 101 return arch::RISCV64; 102 case "amd64" => 103 return arch::X86_64; 104 case => abort(); // unreachable 105 }; 106 }; 107 108 // Returns the number of usable CPUs. 109 export fn cpucount() (size | errors::error) = { 110 let name: [2]int = [rt::CTL_HW, rt::HW_NCPUONLINE]; 111 112 let ncpu: int = 0; 113 let ncpu_sz = size(int); 114 115 match (rt::sysctl(name, len(name): uint, &ncpu, &ncpu_sz, null, 0)) { 116 case void => 117 return ncpu: size; 118 case let err: rt::errno => 119 return errors::errno(err); 120 }; 121 };