@ai-ecoverse/slicc-kernel 1.68.0 → 1.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/kernel-worker.js +20 -0
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +520 -62
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +20 -0
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +517 -59
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -250,6 +250,7 @@ The module's default export (or its `main` export) is called with a context and
|
|
|
250
250
|
- `fdStatus(fd)` (`{ type, tty, seekable }`, `type` being `file`, `pipe`, `tty`, `socket`, `device` or `directory`) and `isatty(fd)`, to tell `< file` from a pipe;
|
|
251
251
|
- `open(path, { read, write, append, create, exclusive, truncate })`, which returns a file with `read(position, length)`, `write(position, bytes)`, `size()`, `truncate(size)`, `sync()` and `close()`. Reads and writes go through the kernel's paged files at those positions, so a large file is never read whole;
|
|
252
252
|
- `fs`: `stat`, `lstat`, `exists`, `readdir`, `mkdir` (with parents), `rm` (recursive), `unlink`, `rename`, `symlink`, `readlink`, and `readFile`/`writeFile` for small files;
|
|
253
|
+
- `/dev`, in `open`, `fs` and their `sync` forms, as a WASI or Emscripten program sees it, with the same modes and owners as under `users`: `null`, `zero`, `full`, `random`, `urandom` and `tty` (character devices, `0666`, root's), `stdin`, `stdout` and `stderr` (links to `/proc/self/fd/0`, `1`, `2`), `fd` (a link to `/proc/self/fd`, so `/dev/fd/N` is descriptor N) and the kernel's terminals `/dev/ttyN` and `/dev/pts/N` (with users on, owned by the session's user or the master's opener, `0620`). `/dev/shm` and `/dev/ptmx` aren't there. `stat` through `/dev/stdin`, `/dev/stdout` or `/dev/fd/N` describes the program's own descriptor (the file it is redirected to, a pipe, a terminal), `readlink` of `/dev/fd/N` names it (`pipe:[N]` and `socket:[N]` for a pipe or a socket), and a closed descriptor is `ENOENT`. Opening a device gives a kernel descriptor on it; opening `/dev/std*` or `/dev/fd/N` opens the file again with the flags asked for when the descriptor is on a file (as Linux reopens `/proc/self/fd/N`, so `append` appends and `truncate` truncates), and otherwise duplicates the descriptor; `/dev/tty` is the program's controlling terminal (`ENXIO` without one); and `/dev/ttyN` and `/dev/pts/N` are opened by name through the kernel, so a terminal that isn't the user's is `EACCES` under `enforce`. A file on anything but a regular file reads and writes as a stream (the position is ignored) and only in the directions it was opened for (`EBADF` otherwise), its `size()` is 0 and `truncate` is `EINVAL`. `readFile` reads a device or a descriptor to its end, up to 64 MiB, and fails with `EFBIG` past that (where Node's `readFile` throws `ERR_FS_FILE_TOO_LARGE`), so `readFile('/dev/zero')` fails instead of hanging, while a bounded `read` of it works. Other paths pay only a prefix check: they make the same kernel calls as before. Creating, removing or renaming names in `/dev` goes to the root file system as before;
|
|
253
254
|
- `signals`: `on(signal, handler)` catches a signal (by number or as `'SIGINT'`), `ignore(signal)` ignores it and `reset(signal)` restores its default action. A call blocked in a read or write is restarted after a handler runs; signals without a handler keep their default actions, so an uncaught `SIGINT` ends the program with 130 and `SIGKILL` always does;
|
|
254
255
|
- `sync`: `read`, `write`, `close`, `open` (whose files' methods are synchronous too) and `fs`, made synchronously, for code that cannot `await`, such as a compiled program's file system or a `readFileSync`. A synchronous call holds the worker until the kernel answers, so nothing else of the program runs meanwhile, timers and callbacks included; a signal that arrives during a blocked read or write runs its handler, and the call is then restarted. Descriptors are shared with the rest of the context, so a file opened with `sync.open` can be closed with `close`, and the other way around; `sync.run` and `sync.exit` are described next;
|
|
255
256
|
- `sync.run({ argv, env, cwd, input, stdin, stdout, stderr, maxBuffer, timeout, killSignal })` runs a command to its end and answers `{ pid, status, signal, stdout, stderr, error }`, as Node's `spawnSync` does. It suits `execSync`, `spawnSync` and `execFileSync`. The kernel does the whole run while the program's worker waits; other processes go on.
|
package/dist/kernel-worker.js
CHANGED
|
@@ -1991,6 +1991,16 @@ function written(device, bytes) {
|
|
|
1991
1991
|
if (device === "full" && bytes.length > 0) throw new KernelError("ENOSPC");
|
|
1992
1992
|
return bytes.length;
|
|
1993
1993
|
}
|
|
1994
|
+
var DEVICE_PATHS = /* @__PURE__ */ new Map([
|
|
1995
|
+
["/dev/null", "null"],
|
|
1996
|
+
["/dev/zero", "zero"],
|
|
1997
|
+
["/dev/full", "full"],
|
|
1998
|
+
["/dev/urandom", "urandom"],
|
|
1999
|
+
["/dev/random", "urandom"]
|
|
2000
|
+
]);
|
|
2001
|
+
function deviceAt(path) {
|
|
2002
|
+
return DEVICE_PATHS.get(path);
|
|
2003
|
+
}
|
|
1994
2004
|
function deviceFile(device, access2) {
|
|
1995
2005
|
const read = async (max) => {
|
|
1996
2006
|
if (device === "null") return new Uint8Array(0);
|
|
@@ -11701,6 +11711,8 @@ var WasmProcess = class {
|
|
|
11701
11711
|
}
|
|
11702
11712
|
async openVfs(req) {
|
|
11703
11713
|
if (inProc(req.path)) return this.openProc(req, req.path);
|
|
11714
|
+
const device = req.orphan ? void 0 : deviceAt(req.path);
|
|
11715
|
+
if (device) return this.openDevice(req, device);
|
|
11704
11716
|
const alias = req.orphan ? void 0 : await procAlias(this.options.fs, req.path, !req.exclusive);
|
|
11705
11717
|
if (typeof alias === "object")
|
|
11706
11718
|
throw Object.assign(new Error(alias.refused), { code: alias.refused });
|
|
@@ -11738,6 +11750,14 @@ var WasmProcess = class {
|
|
|
11738
11750
|
}
|
|
11739
11751
|
return fd;
|
|
11740
11752
|
}
|
|
11753
|
+
openDevice(req, device) {
|
|
11754
|
+
if (req.exclusive) throw Object.assign(new Error(req.path), { code: "EEXIST" });
|
|
11755
|
+
const access2 = req.flags & WRITE_ACCESS;
|
|
11756
|
+
return this.fds.install(
|
|
11757
|
+
deviceFile(device, access2 === 0 ? "read" : access2 === 1 ? "write" : void 0),
|
|
11758
|
+
3
|
|
11759
|
+
);
|
|
11760
|
+
}
|
|
11741
11761
|
async identified(stat, known) {
|
|
11742
11762
|
const first = await stat();
|
|
11743
11763
|
if (first.orphan) return first;
|