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