@ai-ecoverse/slicc-kernel 1.26.3 → 1.26.5
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 -1
- package/dist/kernel-worker.js +64 -14
- package/dist/kernel-worker.js.map +2 -2
- package/dist/node-process-worker.js +171 -195
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +64 -14
- package/dist/node.js.map +2 -2
- package/dist/process-worker.js +171 -195
- package/dist/process-worker.js.map +4 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -300,7 +300,7 @@ 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.
|
|
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.
|
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;
|
|
@@ -7182,6 +7202,7 @@ var WasmProcess = class {
|
|
|
7182
7202
|
children;
|
|
7183
7203
|
caught = 0;
|
|
7184
7204
|
ignored = 0;
|
|
7205
|
+
inherited = 0;
|
|
7185
7206
|
interrupt = new AbortController();
|
|
7186
7207
|
execChild;
|
|
7187
7208
|
execTermsig;
|
|
@@ -7199,12 +7220,19 @@ var WasmProcess = class {
|
|
|
7199
7220
|
this.pid = pid;
|
|
7200
7221
|
this.fds = fds;
|
|
7201
7222
|
this.options = options;
|
|
7223
|
+
this.inherited = options.ignored ?? 0;
|
|
7202
7224
|
this.children = new ChildTable(fds, options.spawner, options.forker);
|
|
7203
|
-
this.nodes = new VfsNodes(options.fs);
|
|
7204
|
-
options.openFiles?.add(this.nodes);
|
|
7225
|
+
this.nodes = options.nodes ?? new VfsNodes(options.fs);
|
|
7226
|
+
if (!options.nodes) options.openFiles?.add(this.nodes);
|
|
7205
7227
|
this.children.onChildState = () => this.signal(SIG.CHLD);
|
|
7206
7228
|
this.children.onReap = options.onReap;
|
|
7207
7229
|
}
|
|
7230
|
+
ignores(bit) {
|
|
7231
|
+
return ((this.ignored | this.inherited & ~this.caught) & bit) !== 0;
|
|
7232
|
+
}
|
|
7233
|
+
inheritable(fork = false) {
|
|
7234
|
+
return ((fork ? 0 : this.ignored) | this.inherited) & ~this.caught;
|
|
7235
|
+
}
|
|
7208
7236
|
signal(sig) {
|
|
7209
7237
|
if (this.execChild !== void 0) {
|
|
7210
7238
|
void Promise.resolve(this.options.kill?.(this.execChild, sig)).catch(() => void 0);
|
|
@@ -7214,7 +7242,7 @@ var WasmProcess = class {
|
|
|
7214
7242
|
if (sig === SIG.CONT) this.cont();
|
|
7215
7243
|
if (sig === SIG.STOP) return this.stop(sig);
|
|
7216
7244
|
const bit = sigbit(sig);
|
|
7217
|
-
if (this.
|
|
7245
|
+
if (this.ignores(bit)) return "ignore";
|
|
7218
7246
|
if (!(this.caught & bit)) {
|
|
7219
7247
|
const action = defaultAction(sig);
|
|
7220
7248
|
return action === "stop" ? this.stop(sig) : action;
|
|
@@ -7513,7 +7541,7 @@ var WasmProcess = class {
|
|
|
7513
7541
|
if (session !== void 0 && session !== tty) return;
|
|
7514
7542
|
const pgid = this.pgid();
|
|
7515
7543
|
if (jobs.tcgetpgrp(tty, this.sid()) === pgid) return;
|
|
7516
|
-
if (this.
|
|
7544
|
+
if (this.ignores(sigbit(SIG.TTIN))) throw new KernelError("EIO");
|
|
7517
7545
|
jobs.killGroup(pgid, SIG.TTIN);
|
|
7518
7546
|
throw new KernelError("EINTR");
|
|
7519
7547
|
}
|
|
@@ -7698,7 +7726,7 @@ var WasmProcess = class {
|
|
|
7698
7726
|
this.asyncOps.close();
|
|
7699
7727
|
for (const pid of this.children.pids()) this.options.onReap?.(pid);
|
|
7700
7728
|
await this.fds.closeAll();
|
|
7701
|
-
this.options.openFiles?.delete(this.nodes);
|
|
7729
|
+
if (!this.options.nodes) this.options.openFiles?.delete(this.nodes);
|
|
7702
7730
|
await this.options.http?.closeAll();
|
|
7703
7731
|
}
|
|
7704
7732
|
};
|
|
@@ -7741,12 +7769,14 @@ function spawnWasmProcess(opts) {
|
|
|
7741
7769
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
7742
7770
|
const header2 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
7743
7771
|
const process = new WasmProcess(opts.pid, opts.fds, {
|
|
7772
|
+
...opts.ignored ? { ignored: opts.ignored } : {},
|
|
7744
7773
|
spawner: opts.spawner,
|
|
7745
7774
|
forker: opts.forker,
|
|
7746
7775
|
fs: opts.fs,
|
|
7747
7776
|
kill: opts.kill,
|
|
7748
7777
|
processes: opts.processes,
|
|
7749
7778
|
openFiles: opts.openFiles,
|
|
7779
|
+
...opts.nodes ? { nodes: opts.nodes } : {},
|
|
7750
7780
|
mounts: opts.mounts,
|
|
7751
7781
|
...opts.mount ? { mount: opts.mount } : {},
|
|
7752
7782
|
...opts.umount ? { umount: opts.umount } : {},
|
|
@@ -7883,7 +7913,8 @@ function spawnWasmProcess(opts) {
|
|
|
7883
7913
|
signal,
|
|
7884
7914
|
termsig: () => endedBy,
|
|
7885
7915
|
onState: (listener) => process.onState(listener),
|
|
7886
|
-
memory: () => Atomics.load(header2, SAB_I_MEMORY) * 65536
|
|
7916
|
+
memory: () => Atomics.load(header2, SAB_I_MEMORY) * 65536,
|
|
7917
|
+
ignoredSignals: (fork) => process.inheritable(fork)
|
|
7887
7918
|
};
|
|
7888
7919
|
}
|
|
7889
7920
|
|
|
@@ -9304,6 +9335,7 @@ var Launcher = class {
|
|
|
9304
9335
|
fstabRetries;
|
|
9305
9336
|
inserted = /* @__PURE__ */ new Map();
|
|
9306
9337
|
openFiles = /* @__PURE__ */ new Set();
|
|
9338
|
+
nodes;
|
|
9307
9339
|
held = /* @__PURE__ */ new Set();
|
|
9308
9340
|
processMounts;
|
|
9309
9341
|
booting = new AbortController();
|
|
@@ -9337,7 +9369,10 @@ var Launcher = class {
|
|
|
9337
9369
|
ca: this.ca
|
|
9338
9370
|
});
|
|
9339
9371
|
enableCdp(this.net, this.cdp);
|
|
9340
|
-
|
|
9372
|
+
const fs = withCommandDirs(this.base, async () => new Set((await this.commands()).keys()));
|
|
9373
|
+
this.nodes = new VfsNodes(fs);
|
|
9374
|
+
this.openFiles.add(this.nodes);
|
|
9375
|
+
this.fs = keepingOpen(fs, this.nodes);
|
|
9341
9376
|
this.watchers.watch([this.modulesDir, this.pnpmHome], { recursive: true }, () => {
|
|
9342
9377
|
this.catalog = void 0;
|
|
9343
9378
|
});
|
|
@@ -9495,6 +9530,7 @@ var Launcher = class {
|
|
|
9495
9530
|
const terminal = req.fds.stdioTerminal();
|
|
9496
9531
|
const handle = spawnWasmProcess({
|
|
9497
9532
|
pid,
|
|
9533
|
+
...req.ignored ? { ignored: req.ignored } : {},
|
|
9498
9534
|
program: req.program,
|
|
9499
9535
|
argv0: req.argv0,
|
|
9500
9536
|
args: req.args,
|
|
@@ -9509,6 +9545,7 @@ var Launcher = class {
|
|
|
9509
9545
|
kill: (target, sig) => this.kill(target, sig),
|
|
9510
9546
|
processes: () => ({ boot: this.boot, processes: this.list() }),
|
|
9511
9547
|
openFiles: this.openFiles,
|
|
9548
|
+
nodes: this.nodes,
|
|
9512
9549
|
held: this.held,
|
|
9513
9550
|
statfs: (path) => this.mounts.statfs(path),
|
|
9514
9551
|
mounts: () => this.mounts.list(),
|
|
@@ -9599,6 +9636,7 @@ var Launcher = class {
|
|
|
9599
9636
|
fds,
|
|
9600
9637
|
report,
|
|
9601
9638
|
ppid,
|
|
9639
|
+
ignored: this.ignoredBy(ppid),
|
|
9602
9640
|
...exec
|
|
9603
9641
|
});
|
|
9604
9642
|
return childHandle(handle);
|
|
@@ -9606,7 +9644,19 @@ var Launcher = class {
|
|
|
9606
9644
|
}
|
|
9607
9645
|
forker(ppid, parent) {
|
|
9608
9646
|
const { exec: _exec, ...image } = parent;
|
|
9609
|
-
return async (state, fds) => childHandle(
|
|
9647
|
+
return async (state, fds) => childHandle(
|
|
9648
|
+
this.start({
|
|
9649
|
+
...image,
|
|
9650
|
+
cwd: state.cwd ?? parent.cwd,
|
|
9651
|
+
fds,
|
|
9652
|
+
ppid,
|
|
9653
|
+
fork: state,
|
|
9654
|
+
ignored: this.ignoredBy(ppid, true)
|
|
9655
|
+
})
|
|
9656
|
+
);
|
|
9657
|
+
}
|
|
9658
|
+
ignoredBy(pid, fork = false) {
|
|
9659
|
+
return this.processes.get(pid)?.ignoredSignals(fork) ?? 0;
|
|
9610
9660
|
}
|
|
9611
9661
|
kill(pid, sig) {
|
|
9612
9662
|
if (pid < 0) return this.jobs.killGroup(-pid, sig);
|