Path: blob/main/core/kernel/src/wasm/posix/stdlib.ts
1070 views
import { notImplemented } from "./util";1import debug from "debug";2const log = debug("posix:stdlib");34export default function stdlib({ child_process, os, recv, send, fs }) {5return {6setjmp: () => {7// Return 0 so it doesn't do the failure care of the setjmp.8log("STUB: setjmp - no op");9return 0;10},1112// void longjmp(jmp_buf env, int val);13longjmp: () => {14log("STUB: longjmp - no op");15return 0;16},1718siglongjmp: () => {19log("STUB: siglongjmp - no op");20return 0;21},2223sigsetjmp: () => {24log("STUB: sigsetjmp - no op");25return 0;26},2728// int getloadavg(double loadavg[], int nelem);29getloadavg: (loadavgDoubleArrayPtr: number, nelem: number): number => {30const { loadavg } = os;31if (loadavg == null) {32// load average is not attainable33return -1;34}35const avg = loadavg();36send.f64(loadavgDoubleArrayPtr, avg[0]);37send.f64(loadavgDoubleArrayPtr + 8, avg[1]); // double = 8 bytes in WASM38send.f64(loadavgDoubleArrayPtr + 16, avg[2]);3940// number of samples (not provided by loadavg). In python itself if you don't get41// all of them (3 are requested), it just gives an error.42return nelem;43},4445// int system(const char *command);46// This below is not exactly like system because it runs until the command completes with no visible output47// until it completes.48// TODO: this only works once then gets totally broken when using webworkers! It works fine49// for the blocking version only.50system: (commandPtr): number => {51if (child_process.spawnSync == null) {52notImplemented("system is not implemented yet");53}54const command = recv.string(commandPtr);55const { stdout, stderr, status } = child_process.spawnSync(command, {56shell: true,57});58console.log(stdout.toString());59console.warn(stderr.toString());60return status;61},6263// char *realpath(const char *path, char *resolved_path);64realpath: (pathPtr, resolvedPathPtr): number => {65try {66const path = recv.string(pathPtr);67log("realpath", { path });68const resolvedPath = fs.realpathSync(path);69return send.string(resolvedPath, { ptr: resolvedPathPtr, len: 4096 });70} catch (err) {71log("realpath error ", err);72// It can be normal to check for a file that doesn't exist only console.warn in case of low level debugging.73// console.warn("ERROR", err);74// return 0 to indicate error, NOT -1!75return 0;76}77},7879/*80We need mkstemp since it used in editline/readline.c to do history file truncation.81(Python doesn't use this since it has its own implementation.)82*/83// Commented out since we have a C implementation in stdlib.c; the one below should work fine though...?84/*85mkstemp: (templatePtr: number): number => {86let template = recv.string(templatePtr);87// template ends in XXXXXX88if (template.slice(-6) != "XXXXXX") {89throw Error("template must end in XXXXXX");90}91// the algorithm in musl is to try 100 randomizations of the last 6 characters92let retries = 100;93while (retries > 0) {94// See https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript95template =96template.slice(0, -6) +97(Math.random().toString(36) + "00000000000000000").slice(2, 8);98try {99return fs.openSync(100template,101fs.constants?.O_RDWR | fs.constants?.O_CREAT | fs.constants?.O_EXCL,1020o600103);104} catch (err) {105retries -= 1;106if (retries == 0) {107console.warn(err);108}109}110}111// failed112return -1;113},114*/115};116}117118119