@ai-ecoverse/slicc-kernel 1.33.0 → 1.34.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 +3 -1
- package/dist/kernel-worker.js +59 -19
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +70 -17
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +59 -19
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +70 -17
- package/dist/process-worker.js.map +3 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ Starts `argv` as the session leader on a new terminal and resolves once it is ru
|
|
|
65
65
|
| --- | --- |
|
|
66
66
|
| `pid` | the session leader's pid |
|
|
67
67
|
| `onData` | the output listener; output that arrives while it is `null` is kept and delivered when one is set |
|
|
68
|
-
| `write(data)` | types a string or bytes into the terminal; with `ISIG` on, `^C`, `^Z` and `^\` signal the foreground process group. A key typed while a child of that group is still setting up is held until the child has finished, then sent to the group in the foreground at that point. Setting up means the child's calls before its first other one: `setpgid`, `tcsetpgrp
|
|
68
|
+
| `write(data)` | types a string or bytes into the terminal; with `ISIG` on, `^C`, `^Z` and `^\` signal the foreground process group. A key typed while a child of that group is still setting up is held until the child has finished, then sent to the group in the foreground at that point. Setting up means the child's calls before its first other one: `setpgid`, `tcsetpgrp`, signal masks, and starting the program it execs (which then sets itself up too). The hold ends 2 s after the child's first call at the latest. A key typed while the foreground group is busy, not reading the terminal (a shell between reading a command line and starting it), goes to that group and also to the job the group starts next, once that job has taken the terminal; the second copy is dropped when the group reads the terminal again. So `^C` or `^Z` right after a command line reaches the new job, as it does on Linux, where starting a job takes microseconds rather than a worker start. |
|
|
69
69
|
| `resize(cols, rows)` | sets the window size (`TIOCGWINSZ`) and sends `SIGWINCH` to the foreground process group |
|
|
70
70
|
| `signal(name)` | sends a signal (`'SIGINT'`, `'SIGTSTP'`, `'SIGQUIT'`, `'SIGHUP'`, …) to the foreground process group, regardless of termios |
|
|
71
71
|
| `exited` | resolves with the session leader's exit status (`128 + n` if killed by signal `n`) |
|
|
@@ -334,6 +334,8 @@ The proxy answers `200` with `Content-Type: application/vnd.slicc.raw-fetch`: a
|
|
|
334
334
|
|
|
335
335
|
Directories are renamed with `FileSystemHandle.move()` where available, else by copy and delete.
|
|
336
336
|
|
|
337
|
+
`mmap` of a regular file works on every file system, for Emscripten programs built with `mmap` (whose glue exports `emscripten_builtin_memalign`) as well as for WASIX ones: the kernel reads the mapped range into fresh memory of the process, as Emscripten's MEMFS does. A `MAP_PRIVATE` mapping may be written, and its changes stay in the process. A writable `MAP_SHARED` mapping of such a file is `ENODEV`; a file in the process's own in-memory file system (MEMFS, as under `/dev`) keeps Emscripten's own mapping, which writes back. A read-only `MAP_SHARED` mapping is a copy taken at `mmap`, so later changes to the file do not show in it.
|
|
338
|
+
|
|
337
339
|
### Mounts
|
|
338
340
|
|
|
339
341
|
`kernel.mount({ type, source, target, options })` mounts a file system on an existing directory. Every process sees it, Emscripten and WASI alike, and so does every attached client. `kernel.umount(target)` unmounts it, and fails with `EBUSY` while a process has a file open under it. `kernel.mounts()` lists the table, as does `/proc/mounts`. The Node entry and attached clients have the same three calls (client protocol 1.2).
|
package/dist/kernel-worker.js
CHANGED
|
@@ -6568,6 +6568,8 @@ var KernelTty = class {
|
|
|
6568
6568
|
waiters = [];
|
|
6569
6569
|
hungUp = false;
|
|
6570
6570
|
name;
|
|
6571
|
+
onRead;
|
|
6572
|
+
readers = 0;
|
|
6571
6573
|
screen;
|
|
6572
6574
|
signal;
|
|
6573
6575
|
constructor(screen, signal) {
|
|
@@ -6718,7 +6720,19 @@ var KernelTty = class {
|
|
|
6718
6720
|
}
|
|
6719
6721
|
this.screen.write(Uint8Array.from(out));
|
|
6720
6722
|
}
|
|
6723
|
+
get reading() {
|
|
6724
|
+
return this.readers > 0;
|
|
6725
|
+
}
|
|
6721
6726
|
async read(max, signal) {
|
|
6727
|
+
this.onRead?.();
|
|
6728
|
+
this.readers++;
|
|
6729
|
+
try {
|
|
6730
|
+
return await this.take(max, signal);
|
|
6731
|
+
} finally {
|
|
6732
|
+
this.readers--;
|
|
6733
|
+
}
|
|
6734
|
+
}
|
|
6735
|
+
async take(max, signal) {
|
|
6722
6736
|
while (this.readable.length === 0) {
|
|
6723
6737
|
if (this.hungUp) return new Uint8Array(0);
|
|
6724
6738
|
await this.changed(signal);
|
|
@@ -6783,13 +6797,14 @@ var PtyPair = class {
|
|
|
6783
6797
|
slaveSeen = false;
|
|
6784
6798
|
index;
|
|
6785
6799
|
onFree;
|
|
6786
|
-
constructor(index, signal, onFree) {
|
|
6800
|
+
constructor(index, signal, onFree, onRead) {
|
|
6787
6801
|
this.index = index;
|
|
6788
6802
|
this.onFree = onFree;
|
|
6789
6803
|
this.slave = new KernelTty(
|
|
6790
6804
|
{ write: (bytes) => this.fromSlave(bytes) },
|
|
6791
6805
|
(sig) => signal(this.slave, sig)
|
|
6792
6806
|
);
|
|
6807
|
+
if (onRead) this.slave.onRead = () => onRead(this.slave);
|
|
6793
6808
|
this.slave.name = `/dev/pts/${index}`;
|
|
6794
6809
|
}
|
|
6795
6810
|
master() {
|
|
@@ -6887,13 +6902,15 @@ var PtyPair = class {
|
|
|
6887
6902
|
var PtyTable = class {
|
|
6888
6903
|
pairs = /* @__PURE__ */ new Map();
|
|
6889
6904
|
signal;
|
|
6890
|
-
|
|
6905
|
+
onRead;
|
|
6906
|
+
constructor(signal, onRead) {
|
|
6891
6907
|
this.signal = signal;
|
|
6908
|
+
this.onRead = onRead;
|
|
6892
6909
|
}
|
|
6893
6910
|
open() {
|
|
6894
6911
|
let index = 0;
|
|
6895
6912
|
while (this.pairs.has(index)) index += 1;
|
|
6896
|
-
const pair = new PtyPair(index, this.signal, (p) => this.pairs.delete(p.index));
|
|
6913
|
+
const pair = new PtyPair(index, this.signal, (p) => this.pairs.delete(p.index), this.onRead);
|
|
6897
6914
|
this.pairs.set(index, pair);
|
|
6898
6915
|
return { pair, master: pair.master() };
|
|
6899
6916
|
}
|
|
@@ -8446,6 +8463,7 @@ var WasmProcess = class {
|
|
|
8446
8463
|
async exit() {
|
|
8447
8464
|
if (this.exited) return;
|
|
8448
8465
|
this.exited = true;
|
|
8466
|
+
this.die();
|
|
8449
8467
|
this.clearAlarm();
|
|
8450
8468
|
this.interrupt.abort();
|
|
8451
8469
|
this.options.locks?.release(this.pid);
|
|
@@ -8858,13 +8876,16 @@ var SETUP_OPS = /* @__PURE__ */ new Set([
|
|
|
8858
8876
|
"fd-info",
|
|
8859
8877
|
"sig-mask",
|
|
8860
8878
|
"proc-setpgid",
|
|
8861
|
-
"tty-pgrp-set"
|
|
8879
|
+
"tty-pgrp-set",
|
|
8880
|
+
"proc-exec",
|
|
8881
|
+
"proc-spawn"
|
|
8862
8882
|
]);
|
|
8863
|
-
var SETTLE_MS =
|
|
8883
|
+
var SETTLE_MS = 2e3;
|
|
8864
8884
|
var KEY_SIGNALS = /* @__PURE__ */ new Set([2, 3, 20]);
|
|
8865
8885
|
var SettlingChildren = class {
|
|
8866
8886
|
children = /* @__PURE__ */ new Map();
|
|
8867
8887
|
held = [];
|
|
8888
|
+
parked = [];
|
|
8868
8889
|
pgidOf;
|
|
8869
8890
|
settleMs;
|
|
8870
8891
|
constructor(pgidOf, settleMs = SETTLE_MS) {
|
|
@@ -8872,7 +8893,15 @@ var SettlingChildren = class {
|
|
|
8872
8893
|
this.settleMs = settleMs;
|
|
8873
8894
|
}
|
|
8874
8895
|
started(pid, ppid) {
|
|
8875
|
-
this.children.
|
|
8896
|
+
const parent = this.children.get(ppid);
|
|
8897
|
+
this.children.set(pid, parent ? { ppid: parent.ppid, execer: ppid } : { ppid });
|
|
8898
|
+
const group = this.pgidOf(ppid);
|
|
8899
|
+
for (const p of this.parked) if (p.pgid === group) this.held.push({ ...p, copy: true });
|
|
8900
|
+
this.parked = this.parked.filter((p) => p.pgid !== group);
|
|
8901
|
+
}
|
|
8902
|
+
reading(pgid) {
|
|
8903
|
+
this.parked = this.parked.filter((p) => p.pgid !== pgid);
|
|
8904
|
+
this.held = this.held.filter((h) => !(h.copy && h.pgid === pgid));
|
|
8876
8905
|
}
|
|
8877
8906
|
syscall(pid, op) {
|
|
8878
8907
|
const child = this.children.get(pid);
|
|
@@ -8888,13 +8917,25 @@ var SettlingChildren = class {
|
|
|
8888
8917
|
if (!child) return;
|
|
8889
8918
|
clearTimeout(child.timer);
|
|
8890
8919
|
this.children.delete(pid);
|
|
8920
|
+
if (child.execer !== void 0) this.settled(child.execer);
|
|
8891
8921
|
const ready2 = this.held.filter((h) => !this.blocking(h.pgid));
|
|
8892
8922
|
this.held = this.held.filter((h) => this.blocking(h.pgid));
|
|
8893
8923
|
for (const h of ready2) h.send();
|
|
8894
8924
|
}
|
|
8895
|
-
deliver(sig, pgid, send) {
|
|
8896
|
-
if (KEY_SIGNALS.has(sig)
|
|
8897
|
-
|
|
8925
|
+
deliver(sig, pgid, send, foreground) {
|
|
8926
|
+
if (!KEY_SIGNALS.has(sig)) {
|
|
8927
|
+
send();
|
|
8928
|
+
} else if (this.blocking(pgid)) {
|
|
8929
|
+
this.held.push({ pgid, send });
|
|
8930
|
+
} else if (foreground) {
|
|
8931
|
+
send();
|
|
8932
|
+
const moved2 = () => {
|
|
8933
|
+
if (foreground() !== pgid) send();
|
|
8934
|
+
};
|
|
8935
|
+
this.parked.push({ pgid, send: moved2 });
|
|
8936
|
+
} else {
|
|
8937
|
+
send();
|
|
8938
|
+
}
|
|
8898
8939
|
}
|
|
8899
8940
|
blocking(pgid) {
|
|
8900
8941
|
for (const { ppid } of this.children.values()) if (this.pgidOf(ppid) === pgid) return true;
|
|
@@ -10164,11 +10205,8 @@ var Launcher = class {
|
|
|
10164
10205
|
locks = new LockTable();
|
|
10165
10206
|
settling = new SettlingChildren((pid) => this.jobs.pgidOf(pid));
|
|
10166
10207
|
ptys = new PtyTable(
|
|
10167
|
-
(tty, sig) => this.
|
|
10168
|
-
|
|
10169
|
-
this.jobs.tcgetpgrp(tty, 0),
|
|
10170
|
-
() => this.jobs.signalOwnedForeground(tty, sig)
|
|
10171
|
-
)
|
|
10208
|
+
(tty, sig) => this.keySignal(tty, 0, sig, () => this.jobs.signalOwnedForeground(tty, sig)),
|
|
10209
|
+
(tty) => this.settling.reading(this.jobs.tcgetpgrp(tty, 0))
|
|
10172
10210
|
);
|
|
10173
10211
|
net = new LoopbackNet();
|
|
10174
10212
|
cdp;
|
|
@@ -10584,6 +10622,11 @@ var Launcher = class {
|
|
|
10584
10622
|
})
|
|
10585
10623
|
);
|
|
10586
10624
|
}
|
|
10625
|
+
keySignal(tty, fallback, sig, send) {
|
|
10626
|
+
const pgid = this.jobs.tcgetpgrp(tty, fallback);
|
|
10627
|
+
const foreground = () => this.jobs.tcgetpgrp(tty, fallback);
|
|
10628
|
+
this.settling.deliver(sig, pgid, send, tty.reading ? void 0 : foreground);
|
|
10629
|
+
}
|
|
10587
10630
|
ignoredBy(pid, fork = false) {
|
|
10588
10631
|
return this.processes.get(pid)?.ignoredSignals(fork) ?? 0;
|
|
10589
10632
|
}
|
|
@@ -10779,12 +10822,9 @@ var Launcher = class {
|
|
|
10779
10822
|
let leader = 0;
|
|
10780
10823
|
const tty = new KernelTty(
|
|
10781
10824
|
{ write: (bytes) => options.onData(bytes.slice()) },
|
|
10782
|
-
(sig) => this.
|
|
10783
|
-
sig,
|
|
10784
|
-
this.jobs.tcgetpgrp(tty, leader),
|
|
10785
|
-
() => this.jobs.signalForeground(tty, leader, sig)
|
|
10786
|
-
)
|
|
10825
|
+
(sig) => this.keySignal(tty, leader, sig, () => this.jobs.signalForeground(tty, leader, sig))
|
|
10787
10826
|
);
|
|
10827
|
+
tty.onRead = () => this.settling.reading(this.jobs.tcgetpgrp(tty, leader));
|
|
10788
10828
|
tty.name = `/dev/tty${++this.terminals}`;
|
|
10789
10829
|
tty.setSize(options.cols ?? 80, options.rows ?? 24);
|
|
10790
10830
|
const fds = new FdTable();
|