MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add os module and tests

+972 -1
+104
examples/spec/os.js
··· 1 + import { test, summary } from './helpers.js'; 2 + import os from 'ant:os'; 3 + 4 + console.log('OS Module Tests\n'); 5 + 6 + test('os.EOL exists', typeof os.EOL, 'string'); 7 + test('os.EOL is newline', os.EOL === '\n' || os.EOL === '\r\n', true); 8 + 9 + test('os.devNull exists', typeof os.devNull, 'string'); 10 + test('os.devNull value', os.devNull === '/dev/null' || os.devNull === '\\\\.\\nul', true); 11 + 12 + test('os.arch returns string', typeof os.arch(), 'string'); 13 + test('os.arch valid value', ['x64', 'arm64', 'arm', 'ia32', 'ppc64', 's390x', 'mips64', 'mipsel', 'loong64', 'riscv64'].includes(os.arch()), true); 14 + 15 + test('os.platform returns string', typeof os.platform(), 'string'); 16 + test('os.platform valid value', ['darwin', 'linux', 'win32', 'freebsd', 'openbsd', 'sunos', 'aix'].includes(os.platform()), true); 17 + 18 + test('os.type returns string', typeof os.type(), 'string'); 19 + test('os.type valid value', ['Darwin', 'Linux', 'Windows_NT', 'FreeBSD', 'OpenBSD'].includes(os.type()), true); 20 + 21 + test('os.release returns string', typeof os.release(), 'string'); 22 + test('os.release not empty', os.release().length > 0, true); 23 + 24 + test('os.version returns string', typeof os.version(), 'string'); 25 + 26 + test('os.machine returns string', typeof os.machine(), 'string'); 27 + test('os.machine not empty', os.machine().length > 0, true); 28 + 29 + test('os.hostname returns string', typeof os.hostname(), 'string'); 30 + test('os.hostname not empty', os.hostname().length > 0, true); 31 + 32 + test('os.homedir returns string', typeof os.homedir(), 'string'); 33 + test('os.homedir not empty', os.homedir().length > 0, true); 34 + 35 + test('os.tmpdir returns string', typeof os.tmpdir(), 'string'); 36 + test('os.tmpdir not empty', os.tmpdir().length > 0, true); 37 + 38 + test('os.endianness returns string', typeof os.endianness(), 'string'); 39 + test('os.endianness valid value', os.endianness() === 'LE' || os.endianness() === 'BE', true); 40 + 41 + test('os.uptime returns number', typeof os.uptime(), 'number'); 42 + test('os.uptime is positive', os.uptime() > 0, true); 43 + 44 + test('os.totalmem returns number', typeof os.totalmem(), 'number'); 45 + test('os.totalmem is positive', os.totalmem() > 0, true); 46 + 47 + test('os.freemem returns number', typeof os.freemem(), 'number'); 48 + test('os.freemem is positive', os.freemem() > 0, true); 49 + test('os.freemem <= totalmem', os.freemem() <= os.totalmem(), true); 50 + 51 + test('os.availableParallelism returns number', typeof os.availableParallelism(), 'number'); 52 + test('os.availableParallelism >= 1', os.availableParallelism() >= 1, true); 53 + 54 + const cpus = os.cpus(); 55 + test('os.cpus returns array', Array.isArray(cpus), true); 56 + test('os.cpus has entries', cpus.length > 0, true); 57 + if (cpus.length > 0) { 58 + test('os.cpus[0] has model', typeof cpus[0].model, 'string'); 59 + test('os.cpus[0] has speed', typeof cpus[0].speed, 'number'); 60 + test('os.cpus[0] has times', typeof cpus[0].times, 'object'); 61 + test('os.cpus[0].times has user', typeof cpus[0].times.user, 'number'); 62 + test('os.cpus[0].times has sys', typeof cpus[0].times.sys, 'number'); 63 + test('os.cpus[0].times has idle', typeof cpus[0].times.idle, 'number'); 64 + } 65 + 66 + const loadavg = os.loadavg(); 67 + test('os.loadavg returns array', Array.isArray(loadavg), true); 68 + test('os.loadavg has 3 entries', loadavg.length, 3); 69 + test('os.loadavg[0] is number', typeof loadavg[0], 'number'); 70 + test('os.loadavg[1] is number', typeof loadavg[1], 'number'); 71 + test('os.loadavg[2] is number', typeof loadavg[2], 'number'); 72 + 73 + const netInterfaces = os.networkInterfaces(); 74 + test('os.networkInterfaces returns object', typeof netInterfaces, 'object'); 75 + 76 + const userInfo = os.userInfo(); 77 + test('os.userInfo returns object', typeof userInfo, 'object'); 78 + test('os.userInfo has uid', typeof userInfo.uid, 'number'); 79 + test('os.userInfo has gid', typeof userInfo.gid, 'number'); 80 + test('os.userInfo has username', typeof userInfo.username, 'string'); 81 + test('os.userInfo has homedir', typeof userInfo.homedir, 'string'); 82 + 83 + test('os.getPriority returns number', typeof os.getPriority(), 'number'); 84 + test('os.getPriority(0) returns number', typeof os.getPriority(0), 'number'); 85 + 86 + test('os.constants exists', typeof os.constants, 'object'); 87 + test('os.constants.signals exists', typeof os.constants.signals, 'object'); 88 + test('os.constants.signals.SIGINT exists', typeof os.constants.signals.SIGINT, 'number'); 89 + test('os.constants.signals.SIGTERM exists', typeof os.constants.signals.SIGTERM, 'number'); 90 + test('os.constants.errno exists', typeof os.constants.errno, 'object'); 91 + test('os.constants.errno.ENOENT exists', typeof os.constants.errno.ENOENT, 'number'); 92 + test('os.constants.priority exists', typeof os.constants.priority, 'object'); 93 + test('os.constants.priority.PRIORITY_NORMAL', os.constants.priority.PRIORITY_NORMAL, 0); 94 + 95 + test('os.constants.dlopen exists', typeof os.constants.dlopen, 'object'); 96 + test('os.constants.dlopen.RTLD_LAZY exists', typeof os.constants.dlopen.RTLD_LAZY, 'number'); 97 + test('os.constants.dlopen.RTLD_NOW exists', typeof os.constants.dlopen.RTLD_NOW, 'number'); 98 + test('os.constants.dlopen.RTLD_GLOBAL exists', typeof os.constants.dlopen.RTLD_GLOBAL, 'number'); 99 + test('os.constants.dlopen.RTLD_LOCAL exists', typeof os.constants.dlopen.RTLD_LOCAL, 'number'); 100 + 101 + test('os.constants.UV_UDP_REUSEADDR exists', typeof os.constants.UV_UDP_REUSEADDR, 'number'); 102 + test('os.constants.UV_UDP_REUSEADDR value', os.constants.UV_UDP_REUSEADDR, 4); 103 + 104 + summary();
+8
include/modules/os.h
··· 1 + #ifndef ANT_OS_MODULE_H 2 + #define ANT_OS_MODULE_H 3 + 4 + #include "ant.h" 5 + 6 + jsval_t os_library(struct js *js); 7 + 8 + #endif
+1 -1
meson.build
··· 96 96 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 97 97 98 98 version_conf = configuration_data() 99 - version_conf.set('ANT_VERSION', '0.3.2.26') 99 + version_conf.set('ANT_VERSION', '0.3.2.27') 100 100 version_conf.set('ANT_GIT_HASH', git_hash) 101 101 version_conf.set('ANT_BUILD_DATE', build_date) 102 102
+2
src/main.c
··· 39 39 #include "modules/sessionstorage.h" 40 40 #include "modules/localstorage.h" 41 41 #include "modules/navigator.h" 42 + #include "modules/os.h" 42 43 43 44 int js_result = EXIT_SUCCESS; 44 45 ··· 220 221 ant_standard_library("fs", fs_library); 221 222 ant_standard_library("crypto", crypto_library); 222 223 ant_standard_library("events", events_library); 224 + ant_standard_library("os", os_library); 223 225 224 226 #ifndef ANT_SNAPSHOT_GENERATOR 225 227 jsval_t snapshot_result = ant_load_snapshot(js);
+857
src/modules/os.c
··· 1 + #include <stdio.h> 2 + #include <stdlib.h> 3 + #include <string.h> 4 + #include <unistd.h> 5 + #include <errno.h> 6 + #include <sys/resource.h> 7 + #include <sys/utsname.h> 8 + #include <pwd.h> 9 + #include <dlfcn.h> 10 + #include <ifaddrs.h> 11 + #include <net/if.h> 12 + #include <arpa/inet.h> 13 + #include <sys/socket.h> 14 + 15 + #ifdef __APPLE__ 16 + #include <net/if_dl.h> 17 + #elif defined(__linux__) 18 + #include <netpacket/packet.h> 19 + #endif 20 + 21 + #ifdef __APPLE__ 22 + #include <sys/sysctl.h> 23 + #include <mach/mach.h> 24 + #include <mach/mach_host.h> 25 + #elif defined(__linux__) 26 + #include <sys/sysinfo.h> 27 + #endif 28 + 29 + #include "ant.h" 30 + #include "modules/symbol.h" 31 + 32 + #ifdef _WIN32 33 + #define OS_EOL "\r\n" 34 + #define OS_DEVNULL "\\\\.\\nul" 35 + #else 36 + #define OS_EOL "\n" 37 + #define OS_DEVNULL "/dev/null" 38 + #endif 39 + 40 + static jsval_t os_arch(struct js *js, jsval_t *args, int nargs) { 41 + (void)args; (void)nargs; 42 + #if defined(__x86_64__) || defined(_M_X64) 43 + return js_mkstr(js, "x64", 3); 44 + #elif defined(__i386__) || defined(_M_IX86) 45 + return js_mkstr(js, "ia32", 4); 46 + #elif defined(__aarch64__) || defined(_M_ARM64) 47 + return js_mkstr(js, "arm64", 5); 48 + #elif defined(__arm__) || defined(_M_ARM) 49 + return js_mkstr(js, "arm", 3); 50 + #elif defined(__riscv) && __riscv_xlen == 64 51 + return js_mkstr(js, "riscv64", 7); 52 + #elif defined(__ppc64__) || defined(__PPC64__) 53 + return js_mkstr(js, "ppc64", 5); 54 + #elif defined(__s390x__) 55 + return js_mkstr(js, "s390x", 5); 56 + #elif defined(__mips64) 57 + return js_mkstr(js, "mips64", 6); 58 + #elif defined(__mips__) 59 + return js_mkstr(js, "mipsel", 6); 60 + #elif defined(__loongarch64) 61 + return js_mkstr(js, "loong64", 7); 62 + #else 63 + return js_mkstr(js, "unknown", 7); 64 + #endif 65 + } 66 + 67 + static jsval_t os_platform(struct js *js, jsval_t *args, int nargs) { 68 + (void)args; (void)nargs; 69 + #if defined(__APPLE__) 70 + return js_mkstr(js, "darwin", 6); 71 + #elif defined(__linux__) 72 + return js_mkstr(js, "linux", 5); 73 + #elif defined(_WIN32) || defined(_WIN64) 74 + return js_mkstr(js, "win32", 5); 75 + #elif defined(__FreeBSD__) 76 + return js_mkstr(js, "freebsd", 7); 77 + #elif defined(__OpenBSD__) 78 + return js_mkstr(js, "openbsd", 7); 79 + #elif defined(__sun) 80 + return js_mkstr(js, "sunos", 5); 81 + #elif defined(_AIX) 82 + return js_mkstr(js, "aix", 3); 83 + #else 84 + return js_mkstr(js, "unknown", 7); 85 + #endif 86 + } 87 + 88 + static jsval_t os_type(struct js *js, jsval_t *args, int nargs) { 89 + (void)args; (void)nargs; 90 + #if defined(__APPLE__) 91 + return js_mkstr(js, "Darwin", 6); 92 + #elif defined(__linux__) 93 + return js_mkstr(js, "Linux", 5); 94 + #elif defined(_WIN32) || defined(_WIN64) 95 + return js_mkstr(js, "Windows_NT", 10); 96 + #elif defined(__FreeBSD__) 97 + return js_mkstr(js, "FreeBSD", 7); 98 + #elif defined(__OpenBSD__) 99 + return js_mkstr(js, "OpenBSD", 7); 100 + #else 101 + struct utsname info; 102 + if (uname(&info) == 0) { 103 + return js_mkstr(js, info.sysname, strlen(info.sysname)); 104 + } 105 + return js_mkstr(js, "Unknown", 7); 106 + #endif 107 + } 108 + 109 + static jsval_t os_release(struct js *js, jsval_t *args, int nargs) { 110 + (void)args; (void)nargs; 111 + struct utsname info; 112 + if (uname(&info) == 0) { 113 + return js_mkstr(js, info.release, strlen(info.release)); 114 + } 115 + return js_mkstr(js, "", 0); 116 + } 117 + 118 + static jsval_t os_version(struct js *js, jsval_t *args, int nargs) { 119 + (void)args; (void)nargs; 120 + struct utsname info; 121 + if (uname(&info) == 0) { 122 + return js_mkstr(js, info.version, strlen(info.version)); 123 + } 124 + return js_mkstr(js, "", 0); 125 + } 126 + 127 + static jsval_t os_machine(struct js *js, jsval_t *args, int nargs) { 128 + (void)args; (void)nargs; 129 + struct utsname info; 130 + if (uname(&info) == 0) { 131 + return js_mkstr(js, info.machine, strlen(info.machine)); 132 + } 133 + return js_mkstr(js, "", 0); 134 + } 135 + 136 + static jsval_t os_hostname(struct js *js, jsval_t *args, int nargs) { 137 + (void)args; (void)nargs; 138 + char hostname[256]; 139 + if (gethostname(hostname, sizeof(hostname)) == 0) { 140 + return js_mkstr(js, hostname, strlen(hostname)); 141 + } 142 + return js_mkstr(js, "", 0); 143 + } 144 + 145 + static jsval_t os_homedir(struct js *js, jsval_t *args, int nargs) { 146 + (void)args; (void)nargs; 147 + const char *home = getenv("HOME"); 148 + if (home) { 149 + return js_mkstr(js, home, strlen(home)); 150 + } 151 + struct passwd *pw = getpwuid(getuid()); 152 + if (pw && pw->pw_dir) { 153 + return js_mkstr(js, pw->pw_dir, strlen(pw->pw_dir)); 154 + } 155 + return js_mkstr(js, "", 0); 156 + } 157 + 158 + static jsval_t os_tmpdir(struct js *js, jsval_t *args, int nargs) { 159 + (void)args; (void)nargs; 160 + const char *tmpdir = getenv("TMPDIR"); 161 + if (!tmpdir) tmpdir = getenv("TMP"); 162 + if (!tmpdir) tmpdir = getenv("TEMP"); 163 + if (!tmpdir) tmpdir = "/tmp"; 164 + return js_mkstr(js, tmpdir, strlen(tmpdir)); 165 + } 166 + 167 + static jsval_t os_endianness(struct js *js, jsval_t *args, int nargs) { 168 + (void)args; (void)nargs; 169 + uint16_t test = 1; 170 + if (*(uint8_t *)&test == 1) { 171 + return js_mkstr(js, "LE", 2); 172 + } 173 + return js_mkstr(js, "BE", 2); 174 + } 175 + 176 + static jsval_t os_uptime(struct js *js, jsval_t *args, int nargs) { 177 + (void)args; (void)nargs; 178 + #ifdef __APPLE__ 179 + struct timeval boottime; 180 + size_t len = sizeof(boottime); 181 + int mib[2] = { CTL_KERN, KERN_BOOTTIME }; 182 + if (sysctl(mib, 2, &boottime, &len, NULL, 0) == 0) { 183 + time_t now = time(NULL); 184 + return js_mknum((double)(now - boottime.tv_sec)); 185 + } 186 + return js_mknum(0); 187 + #elif defined(__linux__) 188 + struct sysinfo info; 189 + if (sysinfo(&info) == 0) { 190 + return js_mknum((double)info.uptime); 191 + } 192 + return js_mknum(0); 193 + #else 194 + return js_mknum(0); 195 + #endif 196 + } 197 + 198 + static jsval_t os_totalmem(struct js *js, jsval_t *args, int nargs) { 199 + (void)args; (void)nargs; 200 + #ifdef __APPLE__ 201 + int64_t memsize; 202 + size_t len = sizeof(memsize); 203 + if (sysctlbyname("hw.memsize", &memsize, &len, NULL, 0) == 0) { 204 + return js_mknum((double)memsize); 205 + } 206 + return js_mknum(0); 207 + #elif defined(__linux__) 208 + struct sysinfo info; 209 + if (sysinfo(&info) == 0) { 210 + return js_mknum((double)info.totalram * info.mem_unit); 211 + } 212 + return js_mknum(0); 213 + #else 214 + return js_mknum(0); 215 + #endif 216 + } 217 + 218 + static jsval_t os_freemem(struct js *js, jsval_t *args, int nargs) { 219 + (void)args; (void)nargs; 220 + #ifdef __APPLE__ 221 + vm_size_t page_size; 222 + mach_port_t mach_port = mach_host_self(); 223 + vm_statistics64_data_t vm_stats; 224 + mach_msg_type_number_t count = sizeof(vm_stats) / sizeof(natural_t); 225 + 226 + if (host_page_size(mach_port, &page_size) == KERN_SUCCESS && 227 + host_statistics64(mach_port, HOST_VM_INFO64, (host_info64_t)&vm_stats, &count) == KERN_SUCCESS) { 228 + return js_mknum((double)vm_stats.free_count * page_size); 229 + } 230 + return js_mknum(0); 231 + #elif defined(__linux__) 232 + struct sysinfo info; 233 + if (sysinfo(&info) == 0) { 234 + return js_mknum((double)info.freeram * info.mem_unit); 235 + } 236 + return js_mknum(0); 237 + #else 238 + return js_mknum(0); 239 + #endif 240 + } 241 + 242 + static jsval_t os_availableParallelism(struct js *js, jsval_t *args, int nargs) { 243 + (void)args; (void)nargs; 244 + #ifdef __APPLE__ 245 + int count; 246 + size_t size = sizeof(count); 247 + if (sysctlbyname("hw.ncpu", &count, &size, NULL, 0) == 0) { 248 + return js_mknum((double)count); 249 + } 250 + return js_mknum(1); 251 + #elif defined(__linux__) 252 + long count = sysconf(_SC_NPROCESSORS_ONLN); 253 + return js_mknum(count > 0 ? (double)count : 1); 254 + #else 255 + return js_mknum(1); 256 + #endif 257 + } 258 + 259 + typedef struct { 260 + double user, nice, sys, idle, irq; 261 + } cpu_times_t; 262 + 263 + static void push_cpu_entry(struct js *js, jsval_t arr, const char *model, double speed, cpu_times_t *times) { 264 + jsval_t cpu = js_mkobj(js); 265 + js_set(js, cpu, "model", js_mkstr(js, model, strlen(model))); 266 + js_set(js, cpu, "speed", js_mknum(speed)); 267 + 268 + jsval_t t = js_mkobj(js); 269 + js_set(js, t, "user", js_mknum(times->user)); 270 + js_set(js, t, "nice", js_mknum(times->nice)); 271 + js_set(js, t, "sys", js_mknum(times->sys)); 272 + js_set(js, t, "idle", js_mknum(times->idle)); 273 + js_set(js, t, "irq", js_mknum(times->irq)); 274 + js_set(js, cpu, "times", t); 275 + 276 + js_arr_push(js, arr, cpu); 277 + } 278 + 279 + #ifdef __APPLE__ 280 + static jsval_t os_cpus_darwin(struct js *js) { 281 + jsval_t arr = js_mkarr(js); 282 + 283 + natural_t ncpu; 284 + processor_info_array_t cpu_info; 285 + mach_msg_type_number_t info_count; 286 + 287 + if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &ncpu, &cpu_info, &info_count) != KERN_SUCCESS) 288 + return arr; 289 + 290 + char model[256] = "Unknown"; 291 + size_t len = sizeof(model); 292 + sysctlbyname("machdep.cpu.brand_string", model, &len, NULL, 0); 293 + 294 + uint64_t freq = 0; 295 + len = sizeof(freq); 296 + if (sysctlbyname("hw.cpufrequency", &freq, &len, NULL, 0) != 0) 297 + freq = 2400000000; 298 + double speed = freq / 1000000.0; 299 + 300 + processor_cpu_load_info_data_t *load = (processor_cpu_load_info_data_t *)cpu_info; 301 + 302 + for (natural_t i = 0; i < ncpu; i++) { 303 + cpu_times_t times = { 304 + .user = (double)load[i].cpu_ticks[CPU_STATE_USER] * 10, 305 + .nice = (double)load[i].cpu_ticks[CPU_STATE_NICE] * 10, 306 + .sys = (double)load[i].cpu_ticks[CPU_STATE_SYSTEM] * 10, 307 + .idle = (double)load[i].cpu_ticks[CPU_STATE_IDLE] * 10, 308 + .irq = 0 309 + }; 310 + push_cpu_entry(js, arr, model, speed, &times); 311 + } 312 + 313 + vm_deallocate(mach_task_self(), (vm_address_t)cpu_info, info_count * sizeof(integer_t)); 314 + return arr; 315 + } 316 + #endif 317 + 318 + #ifdef __linux__ 319 + static char *parse_colon_value(char *line) { 320 + char *colon = strchr(line, ':'); 321 + if (!colon) return NULL; 322 + colon++; 323 + while (*colon == ' ' || *colon == '\t') colon++; 324 + size_t len = strlen(colon); 325 + if (len > 0 && colon[len-1] == '\n') colon[len-1] = '\0'; 326 + return colon; 327 + } 328 + 329 + static jsval_t os_cpus_linux(struct js *js) { 330 + jsval_t arr = js_mkarr(js); 331 + char model[256] = "Unknown"; 332 + double speed = 0; 333 + int ncpu = 0; 334 + 335 + FILE *fp = fopen("/proc/cpuinfo", "r"); 336 + if (!fp) goto read_stat; 337 + 338 + char line[256]; 339 + while (fgets(line, sizeof(line), fp)) { 340 + if (strncmp(line, "processor", 9) == 0) { ncpu++; continue; } 341 + if (strncmp(line, "model name", 10) == 0) { 342 + char *val = parse_colon_value(line); 343 + if (val) strncpy(model, val, sizeof(model) - 1); 344 + continue; 345 + } 346 + if (strncmp(line, "cpu MHz", 7) == 0) { 347 + char *val = parse_colon_value(line); 348 + if (val) speed = atof(val); 349 + } 350 + } 351 + fclose(fp); 352 + 353 + read_stat: 354 + fp = fopen("/proc/stat", "r"); 355 + if (!fp) return arr; 356 + 357 + int cpu_idx = 0; 358 + while (fgets(line, sizeof(line), fp) && cpu_idx < ncpu) { 359 + if (strncmp(line, "cpu", 3) != 0 || line[3] < '0' || line[3] > '9') continue; 360 + 361 + unsigned long user, nice, sys, idle, iowait, irq, softirq; 362 + if (sscanf(line, "cpu%*d %lu %lu %lu %lu %lu %lu %lu", &user, &nice, &sys, &idle, &iowait, &irq, &softirq) < 4) 363 + continue; 364 + 365 + cpu_times_t times = { 366 + .user = (double)user * 10, 367 + .nice = (double)nice * 10, 368 + .sys = (double)sys * 10, 369 + .idle = (double)idle * 10, 370 + .irq = (double)(irq + softirq) * 10 371 + }; 372 + push_cpu_entry(js, arr, model, speed, &times); 373 + cpu_idx++; 374 + } 375 + fclose(fp); 376 + return arr; 377 + } 378 + #endif 379 + 380 + static jsval_t os_cpus(struct js *js, jsval_t *args, int nargs) { 381 + (void)args; (void)nargs; 382 + #ifdef __APPLE__ 383 + return os_cpus_darwin(js); 384 + #elif defined(__linux__) 385 + return os_cpus_linux(js); 386 + #else 387 + return js_mkarr(js); 388 + #endif 389 + } 390 + 391 + static jsval_t os_loadavg(struct js *js, jsval_t *args, int nargs) { 392 + (void)args; (void)nargs; 393 + jsval_t arr = js_mkarr(js); 394 + 395 + #if defined(__APPLE__) || defined(__linux__) 396 + double loadavg[3]; 397 + if (getloadavg(loadavg, 3) == 3) { 398 + js_arr_push(js, arr, js_mknum(loadavg[0])); 399 + js_arr_push(js, arr, js_mknum(loadavg[1])); 400 + js_arr_push(js, arr, js_mknum(loadavg[2])); 401 + } else { 402 + js_arr_push(js, arr, js_mknum(0)); 403 + js_arr_push(js, arr, js_mknum(0)); 404 + js_arr_push(js, arr, js_mknum(0)); 405 + } 406 + #else 407 + js_arr_push(js, arr, js_mknum(0)); 408 + js_arr_push(js, arr, js_mknum(0)); 409 + js_arr_push(js, arr, js_mknum(0)); 410 + #endif 411 + 412 + return arr; 413 + } 414 + 415 + static void format_mac_address(char *buf, size_t buflen, unsigned char *addr) { 416 + snprintf(buf, buflen, "%02x:%02x:%02x:%02x:%02x:%02x", 417 + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 418 + } 419 + 420 + static int calc_prefix_len(struct sockaddr *netmask, int family) { 421 + int prefix = 0; 422 + if (family == AF_INET) { 423 + uint32_t mask = ntohl(((struct sockaddr_in *)netmask)->sin_addr.s_addr); 424 + while (mask & 0x80000000) { prefix++; mask <<= 1; } 425 + } else if (family == AF_INET6) { 426 + uint8_t *bytes = ((struct sockaddr_in6 *)netmask)->sin6_addr.s6_addr; 427 + for (int i = 0; i < 16; i++) { 428 + uint8_t b = bytes[i]; 429 + while (b & 0x80) { prefix++; b <<= 1; } 430 + if (b) break; 431 + } 432 + } 433 + return prefix; 434 + } 435 + 436 + static void add_iface_entry(struct js *js, jsval_t iface_arr, struct ifaddrs *ifa, int family) { 437 + char addr_str[INET6_ADDRSTRLEN] = ""; 438 + char netmask_str[INET6_ADDRSTRLEN] = ""; 439 + char cidr[128]; 440 + bool internal = (ifa->ifa_flags & IFF_LOOPBACK) != 0; 441 + 442 + jsval_t entry = js_mkobj(js); 443 + js_set(js, entry, "mac", js_mkstr(js, "00:00:00:00:00:00", 17)); 444 + js_set(js, entry, "internal", internal ? js_mktrue() : js_mkfalse()); 445 + 446 + if (family == AF_INET) { 447 + struct sockaddr_in *sa = (struct sockaddr_in *)ifa->ifa_addr; 448 + inet_ntop(AF_INET, &sa->sin_addr, addr_str, sizeof(addr_str)); 449 + if (ifa->ifa_netmask) 450 + inet_ntop(AF_INET, &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr, netmask_str, sizeof(netmask_str)); 451 + 452 + int prefix = ifa->ifa_netmask ? calc_prefix_len(ifa->ifa_netmask, AF_INET) : 0; 453 + snprintf(cidr, sizeof(cidr), "%s/%d", addr_str, prefix); 454 + 455 + js_set(js, entry, "address", js_mkstr(js, addr_str, strlen(addr_str))); 456 + js_set(js, entry, "netmask", js_mkstr(js, netmask_str, strlen(netmask_str))); 457 + js_set(js, entry, "family", js_mkstr(js, "IPv4", 4)); 458 + js_set(js, entry, "cidr", js_mkstr(js, cidr, strlen(cidr))); 459 + goto push; 460 + } 461 + 462 + if (family == AF_INET6) { 463 + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ifa->ifa_addr; 464 + inet_ntop(AF_INET6, &sa6->sin6_addr, addr_str, sizeof(addr_str)); 465 + if (ifa->ifa_netmask) 466 + inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, netmask_str, sizeof(netmask_str)); 467 + 468 + int prefix = ifa->ifa_netmask ? calc_prefix_len(ifa->ifa_netmask, AF_INET6) : 0; 469 + snprintf(cidr, sizeof(cidr), "%s/%d", addr_str, prefix); 470 + 471 + js_set(js, entry, "address", js_mkstr(js, addr_str, strlen(addr_str))); 472 + js_set(js, entry, "netmask", js_mkstr(js, netmask_str, strlen(netmask_str))); 473 + js_set(js, entry, "family", js_mkstr(js, "IPv6", 4)); 474 + js_set(js, entry, "scopeid", js_mknum((double)sa6->sin6_scope_id)); 475 + js_set(js, entry, "cidr", js_mkstr(js, cidr, strlen(cidr))); 476 + goto push; 477 + } 478 + 479 + return; 480 + push: 481 + js_arr_push(js, iface_arr, entry); 482 + } 483 + 484 + static unsigned char *get_mac_bytes(struct ifaddrs *ifa) { 485 + #ifdef __APPLE__ 486 + if (ifa->ifa_addr->sa_family != AF_LINK) return NULL; 487 + struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr; 488 + return (sdl->sdl_alen == 6) ? (unsigned char *)LLADDR(sdl) : NULL; 489 + #elif defined(__linux__) 490 + if (ifa->ifa_addr->sa_family != AF_PACKET) return NULL; 491 + struct sockaddr_ll *sll = (struct sockaddr_ll *)ifa->ifa_addr; 492 + return (sll->sll_halen == 6) ? sll->sll_addr : NULL; 493 + #else 494 + return NULL; 495 + #endif 496 + } 497 + 498 + static void apply_mac_to_iface(struct js *js, jsval_t result, const char *name, unsigned char *mac_bytes) { 499 + char mac_str[18]; 500 + format_mac_address(mac_str, sizeof(mac_str), mac_bytes); 501 + 502 + jsval_t iface_arr = js_get(js, result, name); 503 + if (js_type(iface_arr) != JS_OBJ) return; 504 + 505 + jsval_t len_val = js_get(js, iface_arr, "length"); 506 + int len = (js_type(len_val) == JS_NUM) ? (int)js_getnum(len_val) : 0; 507 + 508 + for (int i = 0; i < len; i++) { 509 + char idx[16]; 510 + snprintf(idx, sizeof(idx), "%d", i); 511 + jsval_t entry = js_get(js, iface_arr, idx); 512 + if (js_type(entry) == JS_OBJ) 513 + js_set(js, entry, "mac", js_mkstr(js, mac_str, strlen(mac_str))); 514 + } 515 + } 516 + 517 + static jsval_t os_networkInterfaces(struct js *js, jsval_t *args, int nargs) { 518 + (void)args; (void)nargs; 519 + jsval_t result = js_mkobj(js); 520 + 521 + struct ifaddrs *addrs, *ifa; 522 + if (getifaddrs(&addrs) != 0) return result; 523 + 524 + for (ifa = addrs; ifa; ifa = ifa->ifa_next) { 525 + if (!ifa->ifa_addr) continue; 526 + 527 + int family = ifa->ifa_addr->sa_family; 528 + if (family != AF_INET && family != AF_INET6) continue; 529 + 530 + jsval_t iface_arr = js_get(js, result, ifa->ifa_name); 531 + if (js_type(iface_arr) != JS_OBJ) { 532 + iface_arr = js_mkarr(js); 533 + js_set(js, result, ifa->ifa_name, iface_arr); 534 + } 535 + 536 + add_iface_entry(js, iface_arr, ifa, family); 537 + } 538 + 539 + for (ifa = addrs; ifa; ifa = ifa->ifa_next) { 540 + if (!ifa->ifa_addr) continue; 541 + 542 + unsigned char *mac_bytes = get_mac_bytes(ifa); 543 + if (mac_bytes) 544 + apply_mac_to_iface(js, result, ifa->ifa_name, mac_bytes); 545 + } 546 + 547 + freeifaddrs(addrs); 548 + return result; 549 + } 550 + 551 + static jsval_t os_userInfo(struct js *js, jsval_t *args, int nargs) { 552 + (void)args; (void)nargs; 553 + jsval_t info = js_mkobj(js); 554 + 555 + uid_t uid = getuid(); 556 + gid_t gid = getgid(); 557 + struct passwd *pw = getpwuid(uid); 558 + 559 + js_set(js, info, "uid", js_mknum((double)uid)); 560 + js_set(js, info, "gid", js_mknum((double)gid)); 561 + 562 + if (pw) { 563 + if (pw->pw_name) js_set(js, info, "username", js_mkstr(js, pw->pw_name, strlen(pw->pw_name))); 564 + else js_set(js, info, "username", js_mkstr(js, "", 0)); 565 + 566 + if (pw->pw_dir) js_set(js, info, "homedir", js_mkstr(js, pw->pw_dir, strlen(pw->pw_dir))); 567 + else js_set(js, info, "homedir", js_mkstr(js, "", 0)); 568 + 569 + if (pw->pw_shell) js_set(js, info, "shell", js_mkstr(js, pw->pw_shell, strlen(pw->pw_shell))); 570 + else js_set(js, info, "shell", js_mknull()); 571 + } else { 572 + js_set(js, info, "username", js_mkstr(js, "", 0)); 573 + js_set(js, info, "homedir", js_mkstr(js, "", 0)); 574 + js_set(js, info, "shell", js_mknull()); 575 + } 576 + 577 + return info; 578 + } 579 + 580 + static jsval_t os_getPriority(struct js *js, jsval_t *args, int nargs) { 581 + int pid = 0; 582 + if (nargs > 0 && js_type(args[0]) == JS_NUM) { 583 + pid = (int)js_getnum(args[0]); 584 + } 585 + 586 + errno = 0; 587 + int priority = getpriority(PRIO_PROCESS, pid); 588 + if (errno != 0) { 589 + return js_mkerr(js, "Failed to get priority: %s", strerror(errno)); 590 + } 591 + return js_mknum((double)priority); 592 + } 593 + 594 + static jsval_t os_setPriority(struct js *js, jsval_t *args, int nargs) { 595 + int pid = 0; 596 + int priority = 0; 597 + 598 + if (nargs == 1) { 599 + if (js_type(args[0]) != JS_NUM) { 600 + return js_mkerr_typed(js, JS_ERR_TYPE, "priority must be a number"); 601 + } 602 + priority = (int)js_getnum(args[0]); 603 + } else if (nargs >= 2) { 604 + if (js_type(args[0]) != JS_NUM || js_type(args[1]) != JS_NUM) { 605 + return js_mkerr_typed(js, JS_ERR_TYPE, "pid and priority must be numbers"); 606 + } 607 + pid = (int)js_getnum(args[0]); 608 + priority = (int)js_getnum(args[1]); 609 + } else { 610 + return js_mkerr_typed(js, JS_ERR_TYPE, "setPriority requires at least 1 argument"); 611 + } 612 + 613 + if (setpriority(PRIO_PROCESS, pid, priority) != 0) { 614 + return js_mkerr(js, "Failed to set priority: %s", strerror(errno)); 615 + } 616 + return js_mkundef(); 617 + } 618 + 619 + static void add_signal_constants(struct js *js, jsval_t signals) { 620 + #ifdef SIGHUP 621 + js_set(js, signals, "SIGHUP", js_mknum(SIGHUP)); 622 + #endif 623 + #ifdef SIGINT 624 + js_set(js, signals, "SIGINT", js_mknum(SIGINT)); 625 + #endif 626 + #ifdef SIGQUIT 627 + js_set(js, signals, "SIGQUIT", js_mknum(SIGQUIT)); 628 + #endif 629 + #ifdef SIGILL 630 + js_set(js, signals, "SIGILL", js_mknum(SIGILL)); 631 + #endif 632 + #ifdef SIGTRAP 633 + js_set(js, signals, "SIGTRAP", js_mknum(SIGTRAP)); 634 + #endif 635 + #ifdef SIGABRT 636 + js_set(js, signals, "SIGABRT", js_mknum(SIGABRT)); 637 + #endif 638 + #ifdef SIGIOT 639 + js_set(js, signals, "SIGIOT", js_mknum(SIGIOT)); 640 + #endif 641 + #ifdef SIGBUS 642 + js_set(js, signals, "SIGBUS", js_mknum(SIGBUS)); 643 + #endif 644 + #ifdef SIGFPE 645 + js_set(js, signals, "SIGFPE", js_mknum(SIGFPE)); 646 + #endif 647 + #ifdef SIGKILL 648 + js_set(js, signals, "SIGKILL", js_mknum(SIGKILL)); 649 + #endif 650 + #ifdef SIGUSR1 651 + js_set(js, signals, "SIGUSR1", js_mknum(SIGUSR1)); 652 + #endif 653 + #ifdef SIGUSR2 654 + js_set(js, signals, "SIGUSR2", js_mknum(SIGUSR2)); 655 + #endif 656 + #ifdef SIGSEGV 657 + js_set(js, signals, "SIGSEGV", js_mknum(SIGSEGV)); 658 + #endif 659 + #ifdef SIGPIPE 660 + js_set(js, signals, "SIGPIPE", js_mknum(SIGPIPE)); 661 + #endif 662 + #ifdef SIGALRM 663 + js_set(js, signals, "SIGALRM", js_mknum(SIGALRM)); 664 + #endif 665 + #ifdef SIGTERM 666 + js_set(js, signals, "SIGTERM", js_mknum(SIGTERM)); 667 + #endif 668 + #ifdef SIGCHLD 669 + js_set(js, signals, "SIGCHLD", js_mknum(SIGCHLD)); 670 + #endif 671 + #ifdef SIGCONT 672 + js_set(js, signals, "SIGCONT", js_mknum(SIGCONT)); 673 + #endif 674 + #ifdef SIGSTOP 675 + js_set(js, signals, "SIGSTOP", js_mknum(SIGSTOP)); 676 + #endif 677 + #ifdef SIGTSTP 678 + js_set(js, signals, "SIGTSTP", js_mknum(SIGTSTP)); 679 + #endif 680 + #ifdef SIGTTIN 681 + js_set(js, signals, "SIGTTIN", js_mknum(SIGTTIN)); 682 + #endif 683 + #ifdef SIGTTOU 684 + js_set(js, signals, "SIGTTOU", js_mknum(SIGTTOU)); 685 + #endif 686 + #ifdef SIGURG 687 + js_set(js, signals, "SIGURG", js_mknum(SIGURG)); 688 + #endif 689 + #ifdef SIGXCPU 690 + js_set(js, signals, "SIGXCPU", js_mknum(SIGXCPU)); 691 + #endif 692 + #ifdef SIGXFSZ 693 + js_set(js, signals, "SIGXFSZ", js_mknum(SIGXFSZ)); 694 + #endif 695 + #ifdef SIGVTALRM 696 + js_set(js, signals, "SIGVTALRM", js_mknum(SIGVTALRM)); 697 + #endif 698 + #ifdef SIGPROF 699 + js_set(js, signals, "SIGPROF", js_mknum(SIGPROF)); 700 + #endif 701 + #ifdef SIGWINCH 702 + js_set(js, signals, "SIGWINCH", js_mknum(SIGWINCH)); 703 + #endif 704 + #ifdef SIGIO 705 + js_set(js, signals, "SIGIO", js_mknum(SIGIO)); 706 + #endif 707 + #ifdef SIGSYS 708 + js_set(js, signals, "SIGSYS", js_mknum(SIGSYS)); 709 + #endif 710 + } 711 + 712 + static void add_errno_constants(struct js *js, jsval_t errn) { 713 + js_set(js, errn, "E2BIG", js_mknum(E2BIG)); 714 + js_set(js, errn, "EACCES", js_mknum(EACCES)); 715 + js_set(js, errn, "EADDRINUSE", js_mknum(EADDRINUSE)); 716 + js_set(js, errn, "EADDRNOTAVAIL", js_mknum(EADDRNOTAVAIL)); 717 + js_set(js, errn, "EAFNOSUPPORT", js_mknum(EAFNOSUPPORT)); 718 + js_set(js, errn, "EAGAIN", js_mknum(EAGAIN)); 719 + js_set(js, errn, "EALREADY", js_mknum(EALREADY)); 720 + js_set(js, errn, "EBADF", js_mknum(EBADF)); 721 + js_set(js, errn, "EBUSY", js_mknum(EBUSY)); 722 + js_set(js, errn, "ECANCELED", js_mknum(ECANCELED)); 723 + js_set(js, errn, "ECHILD", js_mknum(ECHILD)); 724 + js_set(js, errn, "ECONNABORTED", js_mknum(ECONNABORTED)); 725 + js_set(js, errn, "ECONNREFUSED", js_mknum(ECONNREFUSED)); 726 + js_set(js, errn, "ECONNRESET", js_mknum(ECONNRESET)); 727 + js_set(js, errn, "EDEADLK", js_mknum(EDEADLK)); 728 + js_set(js, errn, "EDESTADDRREQ", js_mknum(EDESTADDRREQ)); 729 + js_set(js, errn, "EDOM", js_mknum(EDOM)); 730 + js_set(js, errn, "EEXIST", js_mknum(EEXIST)); 731 + js_set(js, errn, "EFAULT", js_mknum(EFAULT)); 732 + js_set(js, errn, "EFBIG", js_mknum(EFBIG)); 733 + js_set(js, errn, "EHOSTUNREACH", js_mknum(EHOSTUNREACH)); 734 + js_set(js, errn, "EINPROGRESS", js_mknum(EINPROGRESS)); 735 + js_set(js, errn, "EINTR", js_mknum(EINTR)); 736 + js_set(js, errn, "EINVAL", js_mknum(EINVAL)); 737 + js_set(js, errn, "EIO", js_mknum(EIO)); 738 + js_set(js, errn, "EISCONN", js_mknum(EISCONN)); 739 + js_set(js, errn, "EISDIR", js_mknum(EISDIR)); 740 + js_set(js, errn, "ELOOP", js_mknum(ELOOP)); 741 + js_set(js, errn, "EMFILE", js_mknum(EMFILE)); 742 + js_set(js, errn, "EMLINK", js_mknum(EMLINK)); 743 + js_set(js, errn, "EMSGSIZE", js_mknum(EMSGSIZE)); 744 + js_set(js, errn, "ENAMETOOLONG", js_mknum(ENAMETOOLONG)); 745 + js_set(js, errn, "ENETDOWN", js_mknum(ENETDOWN)); 746 + js_set(js, errn, "ENETRESET", js_mknum(ENETRESET)); 747 + js_set(js, errn, "ENETUNREACH", js_mknum(ENETUNREACH)); 748 + js_set(js, errn, "ENFILE", js_mknum(ENFILE)); 749 + js_set(js, errn, "ENOBUFS", js_mknum(ENOBUFS)); 750 + js_set(js, errn, "ENODEV", js_mknum(ENODEV)); 751 + js_set(js, errn, "ENOENT", js_mknum(ENOENT)); 752 + js_set(js, errn, "ENOEXEC", js_mknum(ENOEXEC)); 753 + js_set(js, errn, "ENOLCK", js_mknum(ENOLCK)); 754 + js_set(js, errn, "ENOMEM", js_mknum(ENOMEM)); 755 + js_set(js, errn, "ENOPROTOOPT", js_mknum(ENOPROTOOPT)); 756 + js_set(js, errn, "ENOSPC", js_mknum(ENOSPC)); 757 + js_set(js, errn, "ENOSYS", js_mknum(ENOSYS)); 758 + js_set(js, errn, "ENOTCONN", js_mknum(ENOTCONN)); 759 + js_set(js, errn, "ENOTDIR", js_mknum(ENOTDIR)); 760 + js_set(js, errn, "ENOTEMPTY", js_mknum(ENOTEMPTY)); 761 + js_set(js, errn, "ENOTSOCK", js_mknum(ENOTSOCK)); 762 + js_set(js, errn, "ENOTSUP", js_mknum(ENOTSUP)); 763 + js_set(js, errn, "ENOTTY", js_mknum(ENOTTY)); 764 + js_set(js, errn, "ENXIO", js_mknum(ENXIO)); 765 + js_set(js, errn, "EOPNOTSUPP", js_mknum(EOPNOTSUPP)); 766 + js_set(js, errn, "EOVERFLOW", js_mknum(EOVERFLOW)); 767 + js_set(js, errn, "EPERM", js_mknum(EPERM)); 768 + js_set(js, errn, "EPIPE", js_mknum(EPIPE)); 769 + js_set(js, errn, "EPROTONOSUPPORT", js_mknum(EPROTONOSUPPORT)); 770 + js_set(js, errn, "EPROTOTYPE", js_mknum(EPROTOTYPE)); 771 + js_set(js, errn, "ERANGE", js_mknum(ERANGE)); 772 + js_set(js, errn, "EROFS", js_mknum(EROFS)); 773 + js_set(js, errn, "ESPIPE", js_mknum(ESPIPE)); 774 + js_set(js, errn, "ESRCH", js_mknum(ESRCH)); 775 + js_set(js, errn, "ETIMEDOUT", js_mknum(ETIMEDOUT)); 776 + js_set(js, errn, "ETXTBSY", js_mknum(ETXTBSY)); 777 + js_set(js, errn, "EWOULDBLOCK", js_mknum(EWOULDBLOCK)); 778 + js_set(js, errn, "EXDEV", js_mknum(EXDEV)); 779 + } 780 + 781 + static void add_priority_constants(struct js *js, jsval_t priority) { 782 + js_set(js, priority, "PRIORITY_LOW", js_mknum(19)); 783 + js_set(js, priority, "PRIORITY_BELOW_NORMAL", js_mknum(10)); 784 + js_set(js, priority, "PRIORITY_NORMAL", js_mknum(0)); 785 + js_set(js, priority, "PRIORITY_ABOVE_NORMAL", js_mknum(-7)); 786 + js_set(js, priority, "PRIORITY_HIGH", js_mknum(-14)); 787 + js_set(js, priority, "PRIORITY_HIGHEST", js_mknum(-20)); 788 + } 789 + 790 + static void add_dlopen_constants(struct js *js, jsval_t dlopen_obj) { 791 + #ifdef RTLD_LAZY 792 + js_set(js, dlopen_obj, "RTLD_LAZY", js_mknum(RTLD_LAZY)); 793 + #endif 794 + #ifdef RTLD_NOW 795 + js_set(js, dlopen_obj, "RTLD_NOW", js_mknum(RTLD_NOW)); 796 + #endif 797 + #ifdef RTLD_GLOBAL 798 + js_set(js, dlopen_obj, "RTLD_GLOBAL", js_mknum(RTLD_GLOBAL)); 799 + #endif 800 + #ifdef RTLD_LOCAL 801 + js_set(js, dlopen_obj, "RTLD_LOCAL", js_mknum(RTLD_LOCAL)); 802 + #endif 803 + #ifdef RTLD_DEEPBIND 804 + js_set(js, dlopen_obj, "RTLD_DEEPBIND", js_mknum(RTLD_DEEPBIND)); 805 + #endif 806 + } 807 + 808 + jsval_t os_library(struct js *js) { 809 + jsval_t lib = js_mkobj(js); 810 + 811 + js_set(js, lib, "EOL", js_mkstr(js, OS_EOL, strlen(OS_EOL))); 812 + js_set(js, lib, "devNull", js_mkstr(js, OS_DEVNULL, strlen(OS_DEVNULL))); 813 + 814 + js_set(js, lib, "arch", js_mkfun(os_arch)); 815 + js_set(js, lib, "platform", js_mkfun(os_platform)); 816 + js_set(js, lib, "type", js_mkfun(os_type)); 817 + js_set(js, lib, "release", js_mkfun(os_release)); 818 + js_set(js, lib, "version", js_mkfun(os_version)); 819 + js_set(js, lib, "machine", js_mkfun(os_machine)); 820 + js_set(js, lib, "hostname", js_mkfun(os_hostname)); 821 + js_set(js, lib, "homedir", js_mkfun(os_homedir)); 822 + js_set(js, lib, "tmpdir", js_mkfun(os_tmpdir)); 823 + js_set(js, lib, "endianness", js_mkfun(os_endianness)); 824 + js_set(js, lib, "uptime", js_mkfun(os_uptime)); 825 + js_set(js, lib, "totalmem", js_mkfun(os_totalmem)); 826 + js_set(js, lib, "freemem", js_mkfun(os_freemem)); 827 + js_set(js, lib, "availableParallelism", js_mkfun(os_availableParallelism)); 828 + js_set(js, lib, "cpus", js_mkfun(os_cpus)); 829 + js_set(js, lib, "loadavg", js_mkfun(os_loadavg)); 830 + js_set(js, lib, "networkInterfaces", js_mkfun(os_networkInterfaces)); 831 + js_set(js, lib, "userInfo", js_mkfun(os_userInfo)); 832 + js_set(js, lib, "getPriority", js_mkfun(os_getPriority)); 833 + js_set(js, lib, "setPriority", js_mkfun(os_setPriority)); 834 + 835 + jsval_t constants = js_mkobj(js); 836 + jsval_t signals = js_mkobj(js); 837 + jsval_t errn = js_mkobj(js); 838 + jsval_t priority = js_mkobj(js); 839 + jsval_t dlopen_obj = js_mkobj(js); 840 + 841 + add_signal_constants(js, signals); 842 + add_errno_constants(js, errn); 843 + add_priority_constants(js, priority); 844 + add_dlopen_constants(js, dlopen_obj); 845 + 846 + js_set(js, constants, "signals", signals); 847 + js_set(js, constants, "errno", errn); 848 + js_set(js, constants, "priority", priority); 849 + js_set(js, constants, "dlopen", dlopen_obj); 850 + js_set(js, constants, "UV_UDP_REUSEADDR", js_mknum(4)); 851 + js_set(js, lib, "constants", constants); 852 + 853 + js_set(js, lib, get_toStringTag_sym_key(), js_mkstr(js, "os", 2)); 854 + js_set(js, lib, "default", lib); 855 + 856 + return lib; 857 + }