hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };