@ai-ecoverse/slicc-kernel 1.26.4 → 1.26.6
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 +2 -2
- package/dist/kernel-worker.js +38 -11
- package/dist/kernel-worker.js.map +2 -2
- package/dist/node-process-worker.js +179 -196
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +38 -11
- package/dist/node.js.map +2 -2
- package/dist/process-worker.js +179 -196
- package/dist/process-worker.js.map +4 -4
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -300,14 +300,14 @@ Programs mount and unmount with `mount(2)` and `umount2(2)`, so a `mount`/`umoun
|
|
|
300
300
|
|
|
301
301
|
### Exec
|
|
302
302
|
|
|
303
|
-
An exec'd program takes over the pid of the process it replaces, as on Linux: `getpid()` and `$$` in the new image, `/proc`, `ps`, `kill` and the parent's `waitpid` all agree on that pid, and the image's parent pid is the replaced process's. Its own children see that pid as their parent. Signals a program ignores stay ignored in the image it execs and in the children it spawns or forks, as POSIX has it, so `nohup cmd` and `trap '' TERM; exec cmd` keep `cmd` safe from them; caught signals go back to their default. The kernel holds what was handed down, so a new image that sets one of those signals back to the default with `signal(SIG_DFL)` still ignores it, until it installs a handler.
|
|
303
|
+
An exec'd program takes over the pid of the process it replaces, as on Linux: `getpid()` and `$$` in the new image, `/proc`, `ps`, `kill` and the parent's `waitpid` all agree on that pid, and the image's parent pid is the replaced process's. Its own children see that pid as their parent. A file removed or renamed over while programs hold it open keeps its bytes for them, as on Linux: the kernel keeps one copy for all holders, shared by their descriptors (writes through one are seen through the others), and frees it when the last one closes. Signals a program ignores stay ignored in the image it execs and in the children it spawns or forks, as POSIX has it, so `nohup cmd` and `trap '' TERM; exec cmd` keep `cmd` safe from them; caught signals go back to their default. The kernel holds what was handed down, so a new image that sets one of those signals back to the default with `signal(SIG_DFL)` still ignores it, until it installs a handler.
|
|
304
304
|
|
|
305
305
|
- **Emscripten:** `Module.sliccKernel.execve(file, argv, env, cwd)` runs `file` as this process's new image on its fds 0, 1 and 2, waits for it, and returns its wait status, or a negative errno when it cannot start. `env` and `cwd` may be `null` for this process's own. An exec shim detects it with `typeof Module.sliccKernel.execve === 'function'` and exits with the status it returns, as `execve` never returns on success. Older shims spawn the program and then call `Module.sliccKernel.execWait(pid)`; that still works, but the image then reports a pid of its own from `getpid()`.
|
|
306
306
|
- **WASIX:** `proc_exec` does this by itself.
|
|
307
307
|
|
|
308
308
|
### `/proc`
|
|
309
309
|
|
|
310
|
-
Every process of the kernel has `/proc/<pid>/` with `cmdline`, `comm`, `stat`, `statm` and `status`, in the formats procps reads, and `/proc/self
|
|
310
|
+
Every process of the kernel has `/proc/<pid>/` with `cmdline`, `comm`, `stat`, `statm` and `status`, in the formats procps reads, and `/proc/self` is a link to the `/proc/<pid>` of the process that reads it, as on Linux (`readlink /proc/self` is its pid, the one it was exec'd under included). They come from the kernel's process table when they are opened, so a terminal sees the processes of every client; an exec'd program shows under the pid its parent knows. `/proc/uptime`, `/proc/loadavg`, `/proc/stat` and `/proc/meminfo` are there too, and `/proc/mounts`. A process with no parent in the kernel (one a page, a client or the Node entry started) has parent 1, as children of init do, in `getppid()`, `/proc/<pid>/stat` and `ps` alike. Pids, parents, process groups, sessions, command lines, terminals, start and boot times are real, and so is each process's memory: the size of its wasm memory (`VSZ` and `RSS` alike, as wasm has no paging), which `/proc/meminfo` counts as used. CPU times, load and `MemTotal` (from `navigator.deviceMemory`, else 4 GiB) are placeholders. Only Emscripten processes see this `/proc`.
|
|
311
311
|
|
|
312
312
|
While OPFS has no `/etc/passwd`, `/etc/group` or `/etc/mtab`, reading them gets per-process ones: root is uid 0 and the realm user, uid 1000, is named after `USER`, or `web_user` (Emscripten's default) without one, so it matches `$USER`, with `HOME` as its home, so `id`, `whoami`, `ls -l` and `ps` show names. Nothing is written to OPFS, and a real file there wins.
|
|
313
313
|
|
package/dist/kernel-worker.js
CHANGED
|
@@ -6919,8 +6919,10 @@ var VfsNodes = class {
|
|
|
6919
6919
|
for (const [p, node] of this.byPath) if (within3(p, path)) await node.serial(() => node.flush());
|
|
6920
6920
|
}
|
|
6921
6921
|
async unlinking(path) {
|
|
6922
|
-
const node
|
|
6923
|
-
|
|
6922
|
+
for (const [held, node] of [...this.byPath]) {
|
|
6923
|
+
if (!within3(held, path)) continue;
|
|
6924
|
+
await node.serial(async () => void await Promise.all([node.keep(), node.limit()]));
|
|
6925
|
+
}
|
|
6924
6926
|
}
|
|
6925
6927
|
revoke(prefix) {
|
|
6926
6928
|
for (const [path, node] of this.byPath) {
|
|
@@ -6930,10 +6932,11 @@ var VfsNodes = class {
|
|
|
6930
6932
|
}
|
|
6931
6933
|
}
|
|
6932
6934
|
unlinked(path) {
|
|
6933
|
-
const node
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6935
|
+
for (const [held, node] of [...this.byPath]) {
|
|
6936
|
+
if (!within3(held, path)) continue;
|
|
6937
|
+
node.orphaned = true;
|
|
6938
|
+
this.byPath.delete(held);
|
|
6939
|
+
}
|
|
6937
6940
|
}
|
|
6938
6941
|
renamed(from, to) {
|
|
6939
6942
|
if (from === to) return;
|
|
@@ -7007,6 +7010,23 @@ async function refuseReadonly(fs, path, flags, opts = {}) {
|
|
|
7007
7010
|
const st = own ?? await stat(await targetDir(fs, path));
|
|
7008
7011
|
if (st?.readonly) throw new KernelError("EROFS");
|
|
7009
7012
|
}
|
|
7013
|
+
function keepingOpen(fs, nodes) {
|
|
7014
|
+
return {
|
|
7015
|
+
...fs,
|
|
7016
|
+
async rm(path, options) {
|
|
7017
|
+
const at = fs.resolvePath("/", path);
|
|
7018
|
+
await nodes.unlinking(at);
|
|
7019
|
+
await fs.rm(path, options);
|
|
7020
|
+
nodes.unlinked(at);
|
|
7021
|
+
},
|
|
7022
|
+
async rename(from, to) {
|
|
7023
|
+
const [a, b] = [fs.resolvePath("/", from), fs.resolvePath("/", to)];
|
|
7024
|
+
await nodes.unlinking(b);
|
|
7025
|
+
await fs.rename(from, to);
|
|
7026
|
+
nodes.renamed(a, b);
|
|
7027
|
+
}
|
|
7028
|
+
};
|
|
7029
|
+
}
|
|
7010
7030
|
function vfsFile(fs, opts, nodes) {
|
|
7011
7031
|
const access = opts.flags & O_ACCMODE;
|
|
7012
7032
|
const readable = access !== O_WRONLY;
|
|
@@ -7202,8 +7222,8 @@ var WasmProcess = class {
|
|
|
7202
7222
|
this.options = options;
|
|
7203
7223
|
this.inherited = options.ignored ?? 0;
|
|
7204
7224
|
this.children = new ChildTable(fds, options.spawner, options.forker);
|
|
7205
|
-
this.nodes = new VfsNodes(options.fs);
|
|
7206
|
-
options.openFiles?.add(this.nodes);
|
|
7225
|
+
this.nodes = options.nodes ?? new VfsNodes(options.fs);
|
|
7226
|
+
if (!options.nodes) options.openFiles?.add(this.nodes);
|
|
7207
7227
|
this.children.onChildState = () => this.signal(SIG.CHLD);
|
|
7208
7228
|
this.children.onReap = options.onReap;
|
|
7209
7229
|
}
|
|
@@ -7706,7 +7726,7 @@ var WasmProcess = class {
|
|
|
7706
7726
|
this.asyncOps.close();
|
|
7707
7727
|
for (const pid of this.children.pids()) this.options.onReap?.(pid);
|
|
7708
7728
|
await this.fds.closeAll();
|
|
7709
|
-
this.options.openFiles?.delete(this.nodes);
|
|
7729
|
+
if (!this.options.nodes) this.options.openFiles?.delete(this.nodes);
|
|
7710
7730
|
await this.options.http?.closeAll();
|
|
7711
7731
|
}
|
|
7712
7732
|
};
|
|
@@ -7756,6 +7776,7 @@ function spawnWasmProcess(opts) {
|
|
|
7756
7776
|
kill: opts.kill,
|
|
7757
7777
|
processes: opts.processes,
|
|
7758
7778
|
openFiles: opts.openFiles,
|
|
7779
|
+
...opts.nodes ? { nodes: opts.nodes } : {},
|
|
7759
7780
|
mounts: opts.mounts,
|
|
7760
7781
|
...opts.mount ? { mount: opts.mount } : {},
|
|
7761
7782
|
...opts.umount ? { umount: opts.umount } : {},
|
|
@@ -9220,6 +9241,7 @@ var ENV_REFERENCE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
|
|
|
9220
9241
|
var WASM_MAGIC = [0, 97, 115, 109];
|
|
9221
9242
|
var SHEBANG_MAX = 256;
|
|
9222
9243
|
var NOT_FOUND = 127;
|
|
9244
|
+
var INIT_PID = 1;
|
|
9223
9245
|
var SHARED_DIRS = ["/tmp", "/home"];
|
|
9224
9246
|
var encoder3 = new TextEncoder();
|
|
9225
9247
|
function baseName(path) {
|
|
@@ -9314,6 +9336,7 @@ var Launcher = class {
|
|
|
9314
9336
|
fstabRetries;
|
|
9315
9337
|
inserted = /* @__PURE__ */ new Map();
|
|
9316
9338
|
openFiles = /* @__PURE__ */ new Set();
|
|
9339
|
+
nodes;
|
|
9317
9340
|
held = /* @__PURE__ */ new Set();
|
|
9318
9341
|
processMounts;
|
|
9319
9342
|
booting = new AbortController();
|
|
@@ -9347,7 +9370,10 @@ var Launcher = class {
|
|
|
9347
9370
|
ca: this.ca
|
|
9348
9371
|
});
|
|
9349
9372
|
enableCdp(this.net, this.cdp);
|
|
9350
|
-
|
|
9373
|
+
const fs = withCommandDirs(this.base, async () => new Set((await this.commands()).keys()));
|
|
9374
|
+
this.nodes = new VfsNodes(fs);
|
|
9375
|
+
this.openFiles.add(this.nodes);
|
|
9376
|
+
this.fs = keepingOpen(fs, this.nodes);
|
|
9351
9377
|
this.watchers.watch([this.modulesDir, this.pnpmHome], { recursive: true }, () => {
|
|
9352
9378
|
this.catalog = void 0;
|
|
9353
9379
|
});
|
|
@@ -9520,6 +9546,7 @@ var Launcher = class {
|
|
|
9520
9546
|
kill: (target, sig) => this.kill(target, sig),
|
|
9521
9547
|
processes: () => ({ boot: this.boot, processes: this.list() }),
|
|
9522
9548
|
openFiles: this.openFiles,
|
|
9549
|
+
nodes: this.nodes,
|
|
9523
9550
|
held: this.held,
|
|
9524
9551
|
statfs: (path) => this.mounts.statfs(path),
|
|
9525
9552
|
mounts: () => this.mounts.list(),
|
|
@@ -9575,7 +9602,7 @@ var Launcher = class {
|
|
|
9575
9602
|
};
|
|
9576
9603
|
const shown = (pid) => {
|
|
9577
9604
|
const member = pid === void 0 ? void 0 : members.get(pid);
|
|
9578
|
-
return member ? rootOf(member).pid :
|
|
9605
|
+
return member ? rootOf(member).pid : INIT_PID;
|
|
9579
9606
|
};
|
|
9580
9607
|
const listed = [];
|
|
9581
9608
|
for (const member of members.values()) {
|