@ai-ecoverse/slicc-kernel 1.124.13 → 1.125.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 +17 -3
- package/dist/kernel-worker.js +246 -43
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +132 -68
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +246 -43
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +132 -68
- package/dist/process-worker.js.map +4 -4
- package/dist/types/fs/watch.d.ts +19 -0
- package/dist/types/kernel/fd-table.d.ts +1 -0
- package/dist/types/kernel/host.d.ts +1 -0
- package/dist/types/kernel/process.d.ts +4 -1
- package/dist/types/kernel/select.d.ts +1 -0
- package/dist/types/kernel/watch-ops.d.ts +30 -0
- package/dist/types/launcher.d.ts +1 -0
- package/dist/types/process/js/js-context.d.ts +2 -0
- package/dist/types/process/js/js-sync.d.ts +5 -1
- package/dist/types/process/js/js-watch.d.ts +17 -0
- package/package.json +3 -3
|
@@ -864,7 +864,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
864
864
|
mkdir: (p) => mutating(() => bridge.mkdir(p), ...entry(p)),
|
|
865
865
|
rm: (p) => mutating(() => bridge.rm(p)),
|
|
866
866
|
rename: (from, to) => mutating(() => bridge.rename(from, to)),
|
|
867
|
-
link: (from, to,
|
|
867
|
+
link: (from, to, follow3) => mutating(() => bridge.link(from, to, follow3)),
|
|
868
868
|
unlink: (p) => mutating(() => bridge.unlink(p)),
|
|
869
869
|
rmdir: (p) => mutating(() => bridge.rmdir(p)),
|
|
870
870
|
symlink: (target, link) => mutating(() => bridge.symlink(target, link), ...entry(link)),
|
|
@@ -2264,7 +2264,7 @@ function devFdStat(fd) {
|
|
|
2264
2264
|
function linkStat(target) {
|
|
2265
2265
|
return nodeStat(LINK | 511, target.length);
|
|
2266
2266
|
}
|
|
2267
|
-
function* devStat(abs,
|
|
2267
|
+
function* devStat(abs, follow3) {
|
|
2268
2268
|
const node = yield* lookup(abs);
|
|
2269
2269
|
switch (node.kind) {
|
|
2270
2270
|
case "dir":
|
|
@@ -2277,10 +2277,10 @@ function* devStat(abs, follow2) {
|
|
|
2277
2277
|
case "terminal":
|
|
2278
2278
|
return yield* terminalStat(node.name);
|
|
2279
2279
|
case "link":
|
|
2280
|
-
if (!
|
|
2280
|
+
if (!follow3) return linkStat(node.target);
|
|
2281
2281
|
return node.fd === void 0 ? nodeStat(DIR | 365) : yield* fdStat(node.fd, abs);
|
|
2282
2282
|
case "fd":
|
|
2283
|
-
return
|
|
2283
|
+
return follow3 ? yield* fdStat(node.fd, abs) : linkStat(yield* fdTarget(node.fd, abs));
|
|
2284
2284
|
}
|
|
2285
2285
|
}
|
|
2286
2286
|
function* devExists(abs) {
|
|
@@ -3741,7 +3741,7 @@ function writeEvents(mem, ptr, events) {
|
|
|
3741
3741
|
v.setUint16(p + 8, ev.error, true);
|
|
3742
3742
|
v.setUint8(p + 10, ev.type);
|
|
3743
3743
|
if (ev.type !== EVENTTYPE.CLOCK) {
|
|
3744
|
-
v.setBigUint64(p + 16,
|
|
3744
|
+
v.setBigUint64(p + 16, BigInt(ev.nbytes ?? 1), true);
|
|
3745
3745
|
if (ev.hangup) v.setUint16(p + 24, EVENT_FD_READWRITE_HANGUP, true);
|
|
3746
3746
|
}
|
|
3747
3747
|
});
|
|
@@ -3760,6 +3760,10 @@ function classify(fds, subs) {
|
|
|
3760
3760
|
}
|
|
3761
3761
|
return { events, read: read2, write: write2 };
|
|
3762
3762
|
}
|
|
3763
|
+
function nbytesOf(s, ready) {
|
|
3764
|
+
const n = s.type === EVENTTYPE.FD_READ ? ready.nread?.[s.fd] : void 0;
|
|
3765
|
+
return n === void 0 ? {} : { nbytes: n };
|
|
3766
|
+
}
|
|
3763
3767
|
function readyEvents(subs, ready) {
|
|
3764
3768
|
return subs.filter(
|
|
3765
3769
|
(s) => s.type === EVENTTYPE.FD_READ && ready.read.includes(s.fd) || s.type === EVENTTYPE.FD_WRITE && ready.write.includes(s.fd)
|
|
@@ -3767,7 +3771,8 @@ function readyEvents(subs, ready) {
|
|
|
3767
3771
|
userdata: s.userdata,
|
|
3768
3772
|
error: E.SUCCESS,
|
|
3769
3773
|
type: s.type,
|
|
3770
|
-
hangup: ready.hangup?.includes(s.fd) === true
|
|
3774
|
+
hangup: ready.hangup?.includes(s.fd) === true,
|
|
3775
|
+
...nbytesOf(s, ready)
|
|
3771
3776
|
}));
|
|
3772
3777
|
}
|
|
3773
3778
|
function selectOnce(deps, read2, write2, timeoutMs2) {
|
|
@@ -4734,10 +4739,10 @@ var init_wasi_host = __esm({
|
|
|
4734
4739
|
return path;
|
|
4735
4740
|
};
|
|
4736
4741
|
const modeOf2 = (st) => (st.mode ?? 0) & 4095;
|
|
4737
|
-
const chown = (path, uid, gid,
|
|
4742
|
+
const chown = (path, uid, gid, follow3, handle) => {
|
|
4738
4743
|
const { chown: own } = this.o.fs;
|
|
4739
4744
|
if (!own) throw new WasiError("ENOSYS");
|
|
4740
|
-
own.call(this.o.fs, path, idOf(uid), idOf(gid),
|
|
4745
|
+
own.call(this.o.fs, path, idOf(uid), idOf(gid), follow3, handle);
|
|
4741
4746
|
};
|
|
4742
4747
|
const caller = () => {
|
|
4743
4748
|
const cred = this.creds.get();
|
|
@@ -4777,16 +4782,16 @@ var init_wasi_host = __esm({
|
|
|
4777
4782
|
return devSync(dev, devFdStat(fd)).mode ?? DEVICE_MODE;
|
|
4778
4783
|
return modeOf2(this.o.fs.stat(pathOf(fd)));
|
|
4779
4784
|
};
|
|
4780
|
-
const pathOwned = (path,
|
|
4785
|
+
const pathOwned = (path, follow3) => {
|
|
4781
4786
|
const alias = this.fdAlias(path);
|
|
4782
|
-
if (alias && !
|
|
4787
|
+
if (alias && !follow3) return alias.stdio ? ROOT_IDS : void 0;
|
|
4783
4788
|
if (alias) {
|
|
4784
4789
|
this.openFd(alias.fd);
|
|
4785
4790
|
return fdOwned(alias.fd);
|
|
4786
4791
|
}
|
|
4787
4792
|
if (this.synthetic(path)) return ROOT_IDS;
|
|
4788
|
-
if (kernelDev(path)) return devSync(dev, devStat(path,
|
|
4789
|
-
return
|
|
4793
|
+
if (kernelDev(path)) return devSync(dev, devStat(path, follow3));
|
|
4794
|
+
return follow3 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
|
|
4790
4795
|
};
|
|
4791
4796
|
return wrap({
|
|
4792
4797
|
fd_chown: (fd, uid, gid) => {
|
|
@@ -5182,7 +5187,7 @@ var init_wasi_host = __esm({
|
|
|
5182
5187
|
const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
|
|
5183
5188
|
return {
|
|
5184
5189
|
path_open: (dirfd, lookup2, p, l, oflags, rights, _inheriting, fdflags, out) => {
|
|
5185
|
-
const
|
|
5190
|
+
const follow3 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
5186
5191
|
try {
|
|
5187
5192
|
const asked = at(dirfd, p, l);
|
|
5188
5193
|
const alias = this.fdAlias(asked);
|
|
@@ -5196,7 +5201,7 @@ var init_wasi_host = __esm({
|
|
|
5196
5201
|
if (err.code !== "ENOENT") throw err;
|
|
5197
5202
|
const raw = mem.string(p, l);
|
|
5198
5203
|
const joined2 = raw.startsWith("/") ? raw : `${fds.dir(dirfd).path}/${raw}`;
|
|
5199
|
-
const resolved2 = this.resolveForDev(joined2,
|
|
5204
|
+
const resolved2 = this.resolveForDev(joined2, follow3);
|
|
5200
5205
|
if (!resolved2) throw err;
|
|
5201
5206
|
mem.view().setUint32(out, fds.open(resolved2, oflags, rights, fdflags), true);
|
|
5202
5207
|
}
|
|
@@ -5259,11 +5264,11 @@ var init_wasi_host = __esm({
|
|
|
5259
5264
|
path_link: (fd, lookup2, p, l, fd2, p2, l2) => {
|
|
5260
5265
|
const from = at(fd, p, l);
|
|
5261
5266
|
const to = at(fd2, p2, l2);
|
|
5262
|
-
const
|
|
5263
|
-
const source =
|
|
5267
|
+
const follow3 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
5268
|
+
const source = follow3 ? physicalPath(o.fs, from) : from;
|
|
5264
5269
|
fds.flushPath(from);
|
|
5265
5270
|
if (source !== from) fds.flushPath(source);
|
|
5266
|
-
o.fs.link(from, to,
|
|
5271
|
+
o.fs.link(from, to, follow3);
|
|
5267
5272
|
fds.linked(from, to);
|
|
5268
5273
|
if (source !== from) fds.linked(source, to);
|
|
5269
5274
|
}
|
|
@@ -5576,18 +5581,18 @@ var init_wasi_host = __esm({
|
|
|
5576
5581
|
synthetic(path) {
|
|
5577
5582
|
return deviceOf(path) !== void 0 || path === SEALED_PATH && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH && !!this.o.kernel.sys.openClipboard;
|
|
5578
5583
|
}
|
|
5579
|
-
devChar(path,
|
|
5584
|
+
devChar(path, follow3) {
|
|
5580
5585
|
try {
|
|
5581
5586
|
const json2 = (req) => this.o.kernel.call(req);
|
|
5582
|
-
const st = devSync({ json: json2 }, devStat(path,
|
|
5587
|
+
const st = devSync({ json: json2 }, devStat(path, follow3));
|
|
5583
5588
|
return ((st.mode ?? 0) & 61440) === 8192;
|
|
5584
5589
|
} catch {
|
|
5585
5590
|
return false;
|
|
5586
5591
|
}
|
|
5587
5592
|
}
|
|
5588
|
-
resolveForDev(path,
|
|
5593
|
+
resolveForDev(path, follow3 = true) {
|
|
5589
5594
|
try {
|
|
5590
|
-
if (!
|
|
5595
|
+
if (!follow3) {
|
|
5591
5596
|
const slash = path.lastIndexOf("/");
|
|
5592
5597
|
if (slash <= 0) return void 0;
|
|
5593
5598
|
const parent = physicalPath(this.o.fs, path.slice(0, slash));
|
|
@@ -5678,12 +5683,12 @@ var init_wasi_host = __esm({
|
|
|
5678
5683
|
});
|
|
5679
5684
|
}
|
|
5680
5685
|
this.fds.flushPath(path);
|
|
5681
|
-
const
|
|
5686
|
+
const follow3 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
5682
5687
|
try {
|
|
5683
|
-
return filestatOf(path,
|
|
5688
|
+
return filestatOf(path, follow3 ? this.o.fs.stat(path) : this.o.fs.lstat(path));
|
|
5684
5689
|
} catch (err) {
|
|
5685
5690
|
if (err.code !== "ENOENT") throw err;
|
|
5686
|
-
if (kernelDev(path) && this.devChar(path,
|
|
5691
|
+
if (kernelDev(path) && this.devChar(path, follow3)) {
|
|
5687
5692
|
return this.local({
|
|
5688
5693
|
filetype: FILETYPE.CHARACTER_DEVICE,
|
|
5689
5694
|
size: 0n,
|
|
@@ -5691,7 +5696,7 @@ var init_wasi_host = __esm({
|
|
|
5691
5696
|
mtimeNs: 0n
|
|
5692
5697
|
});
|
|
5693
5698
|
}
|
|
5694
|
-
const resolved2 = this.resolveForDev(path,
|
|
5699
|
+
const resolved2 = this.resolveForDev(path, follow3);
|
|
5695
5700
|
if (!resolved2) throw err;
|
|
5696
5701
|
return this.local({
|
|
5697
5702
|
filetype: FILETYPE.CHARACTER_DEVICE,
|
|
@@ -5701,18 +5706,18 @@ var init_wasi_host = __esm({
|
|
|
5701
5706
|
});
|
|
5702
5707
|
}
|
|
5703
5708
|
}
|
|
5704
|
-
setTimes(path, atim, mtim, flags,
|
|
5709
|
+
setTimes(path, atim, mtim, flags, follow3 = true) {
|
|
5705
5710
|
const asked = FSTFLAGS.ATIM | FSTFLAGS.ATIM_NOW | FSTFLAGS.MTIM | FSTFLAGS.MTIM_NOW;
|
|
5706
5711
|
if (this.o.fs.owners && (flags & asked) === 0) return;
|
|
5707
5712
|
const now = Date.now();
|
|
5708
5713
|
let current;
|
|
5709
|
-
const statOf =
|
|
5714
|
+
const statOf = follow3 ? this.o.fs.stat.bind(this.o.fs) : this.o.fs.lstat.bind(this.o.fs);
|
|
5710
5715
|
const kept = (field2) => {
|
|
5711
5716
|
current ??= statOf(path);
|
|
5712
5717
|
return current[field2] ?? current.mtimeMs ?? now;
|
|
5713
5718
|
};
|
|
5714
5719
|
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS4) : kept(field2);
|
|
5715
|
-
(
|
|
5720
|
+
(follow3 ? this.o.fs.utimes : this.o.fs.lutimes).call(
|
|
5716
5721
|
this.o.fs,
|
|
5717
5722
|
path,
|
|
5718
5723
|
pick(FSTFLAGS.ATIM, FSTFLAGS.ATIM_NOW, atim, "atimeMs"),
|
|
@@ -6253,7 +6258,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
6253
6258
|
var init_version = __esm({
|
|
6254
6259
|
"src/version.ts"() {
|
|
6255
6260
|
"use strict";
|
|
6256
|
-
KERNEL_VERSION = true ? "1.
|
|
6261
|
+
KERNEL_VERSION = true ? "1.125.0" : "0.0.0-dev";
|
|
6257
6262
|
OS_RELEASE = "6.0.0-slicc";
|
|
6258
6263
|
}
|
|
6259
6264
|
});
|
|
@@ -6914,8 +6919,8 @@ function fetchOp(kernel) {
|
|
|
6914
6919
|
for (let hops = 0; ; hops++) {
|
|
6915
6920
|
const head = await send(hop, signal);
|
|
6916
6921
|
const location = head.headers.find(([name2]) => name2.toLowerCase() === "location")?.[1];
|
|
6917
|
-
const
|
|
6918
|
-
if (!
|
|
6922
|
+
const follow3 = known.manualRedirects && REDIRECTS.has(head.status) && location !== void 0 && request.redirect !== "manual";
|
|
6923
|
+
if (!follow3) {
|
|
6919
6924
|
const redirected = hops > 0 || head.redirected === true;
|
|
6920
6925
|
return respond(head, hop.method, redirected, known.encodedBodies, request);
|
|
6921
6926
|
}
|
|
@@ -7622,8 +7627,8 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
7622
7627
|
rename: (from, to) => {
|
|
7623
7628
|
run({ op: "rename", path: from, arg2: to }, from);
|
|
7624
7629
|
},
|
|
7625
|
-
link: (from, to,
|
|
7626
|
-
run({ op: "link", path: from, arg2: to, ...
|
|
7630
|
+
link: (from, to, follow3) => {
|
|
7631
|
+
run({ op: "link", path: from, arg2: to, ...follow3 ? { mode: 1 } : {} }, from);
|
|
7627
7632
|
},
|
|
7628
7633
|
unlink: (path) => {
|
|
7629
7634
|
run({ op: "unlink", path }, path);
|
|
@@ -7666,11 +7671,11 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
7666
7671
|
const flags = { ...mode !== void 0 ? { mode } : {}, ...opening2 ? { opening: opening2 } : {} };
|
|
7667
7672
|
run({ op: "create", path, ...flags }, path);
|
|
7668
7673
|
},
|
|
7669
|
-
chown: (path, uid, gid,
|
|
7674
|
+
chown: (path, uid, gid, follow3, handle) => {
|
|
7670
7675
|
const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
|
|
7671
7676
|
changing(
|
|
7672
7677
|
{
|
|
7673
|
-
op:
|
|
7678
|
+
op: follow3 ? "chown" : "lchown",
|
|
7674
7679
|
path,
|
|
7675
7680
|
...ids,
|
|
7676
7681
|
...handle !== void 0 ? { handle } : {}
|
|
@@ -8701,9 +8706,9 @@ function guardVanished(Fs) {
|
|
|
8701
8706
|
const drop = forget;
|
|
8702
8707
|
const lookupPath = Fs.lookupPath.bind(Fs);
|
|
8703
8708
|
const ops = Fs;
|
|
8704
|
-
const cached = (path,
|
|
8709
|
+
const cached = (path, follow3) => {
|
|
8705
8710
|
try {
|
|
8706
|
-
const node = lookupPath(path, { follow:
|
|
8711
|
+
const node = lookupPath(path, { follow: follow3 }).node;
|
|
8707
8712
|
return node.live && node.live.openCount === 0 && !node.live.dirty ? node : void 0;
|
|
8708
8713
|
} catch {
|
|
8709
8714
|
return void 0;
|
|
@@ -8810,11 +8815,11 @@ function linkable(bridge, path) {
|
|
|
8810
8815
|
return false;
|
|
8811
8816
|
}
|
|
8812
8817
|
}
|
|
8813
|
-
function linkLive(Fs, from, to,
|
|
8818
|
+
function linkLive(Fs, from, to, follow3) {
|
|
8814
8819
|
const target = to.replace(/\/+$/, "");
|
|
8815
8820
|
const slash = target.lastIndexOf("/");
|
|
8816
8821
|
const name2 = target.slice(slash + 1);
|
|
8817
|
-
const source = Fs.lookupPath(from, { follow:
|
|
8822
|
+
const source = Fs.lookupPath(from, { follow: follow3 }).node;
|
|
8818
8823
|
const parent = Fs.lookupPath(target.slice(0, slash) || "/", { follow: true }).node;
|
|
8819
8824
|
if (!source.live || !parent.live) return false;
|
|
8820
8825
|
flushOne(Fs, source);
|
|
@@ -9713,13 +9718,13 @@ function readonlyRefusal(Fs, memory, call2) {
|
|
|
9713
9718
|
try {
|
|
9714
9719
|
const name2 = cString(memory, call2.path);
|
|
9715
9720
|
const abs = name2.startsWith("/") ? name2 : `${baseOf3(Fs, call2.dirfd)}/${name2}`;
|
|
9716
|
-
const
|
|
9721
|
+
const follow3 = (call2.flags & AT_SYMLINK_NOFOLLOW2) === 0;
|
|
9717
9722
|
const { node } = Fs.lookupPath.call(Fs, abs, {
|
|
9718
|
-
follow:
|
|
9723
|
+
follow: follow3
|
|
9719
9724
|
});
|
|
9720
9725
|
const bridge = node.live ? node.mount.opts.bridge : void 0;
|
|
9721
9726
|
const stats = bridge;
|
|
9722
|
-
const stat =
|
|
9727
|
+
const stat = follow3 ? stats?.stat : stats?.lstat;
|
|
9723
9728
|
return stat?.call(stats, liveNodePath(node)).readonly ? -wasiErrno("EROFS") : 0;
|
|
9724
9729
|
} catch {
|
|
9725
9730
|
return 0;
|
|
@@ -9768,8 +9773,8 @@ function kernelLink(imports, fs, memory, glue) {
|
|
|
9768
9773
|
try {
|
|
9769
9774
|
const from = at(olddirfd, oldpath);
|
|
9770
9775
|
const to = at(newdirfd, newpath);
|
|
9771
|
-
const
|
|
9772
|
-
if (linkLive(Fs, from, to,
|
|
9776
|
+
const follow3 = (flags & AT_SYMLINK_FOLLOW) !== 0;
|
|
9777
|
+
if (linkLive(Fs, from, to, follow3)) return 0;
|
|
9773
9778
|
} catch (err) {
|
|
9774
9779
|
return -errnoOf2(err);
|
|
9775
9780
|
}
|
|
@@ -10390,7 +10395,7 @@ var init_procfs = __esm({
|
|
|
10390
10395
|
function inProc(path) {
|
|
10391
10396
|
return path === "/proc" || path.startsWith("/proc/");
|
|
10392
10397
|
}
|
|
10393
|
-
function* procWalk(path,
|
|
10398
|
+
function* procWalk(path, follow3) {
|
|
10394
10399
|
let done = [];
|
|
10395
10400
|
let todo = path.split("/").filter((part) => part !== "");
|
|
10396
10401
|
let hops = 0;
|
|
@@ -10405,7 +10410,7 @@ function* procWalk(path, follow2) {
|
|
|
10405
10410
|
const at = `/${[...done, part].join("/")}`;
|
|
10406
10411
|
const whole = normalize(`/${[...done, part, ...todo].join("/")}`);
|
|
10407
10412
|
if (inProc(at) && inProc(whole)) return broken ?? whole;
|
|
10408
|
-
if (!
|
|
10413
|
+
if (!follow3 && todo.length === 0) return void 0;
|
|
10409
10414
|
const target = yield { at, check: todo.find((next2) => next2 !== ".") === ".." };
|
|
10410
10415
|
if (typeof target === "string") {
|
|
10411
10416
|
if (++hops > MAX_HOPS2) return void 0;
|
|
@@ -10429,8 +10434,8 @@ function throughLink(target, done, todo) {
|
|
|
10429
10434
|
const parts = target.split("/").filter((part) => part !== "");
|
|
10430
10435
|
return [target.startsWith("/") ? [] : done, [...parts, ...todo]];
|
|
10431
10436
|
}
|
|
10432
|
-
function procPath(fs, path,
|
|
10433
|
-
const walk = procWalk(path,
|
|
10437
|
+
function procPath(fs, path, follow3) {
|
|
10438
|
+
const walk = procWalk(path, follow3);
|
|
10434
10439
|
let step = walk.next();
|
|
10435
10440
|
while (!step.done) {
|
|
10436
10441
|
const { at, check } = step.value;
|
|
@@ -10488,26 +10493,26 @@ function physicalProc(fs) {
|
|
|
10488
10493
|
};
|
|
10489
10494
|
}
|
|
10490
10495
|
function procfsBridge(fs, tree) {
|
|
10491
|
-
const toProc = (path,
|
|
10496
|
+
const toProc = (path, follow3) => procPath(fs, path, follow3);
|
|
10492
10497
|
const shadowing = physicalProc(fs);
|
|
10493
|
-
const via = (p, proc, own,
|
|
10498
|
+
const via = (p, proc, own, follow3 = true) => {
|
|
10494
10499
|
if (inProc(p)) return proc(p);
|
|
10495
10500
|
if (shadowing()) {
|
|
10496
|
-
const real = toProc(p,
|
|
10501
|
+
const real = toProc(p, follow3);
|
|
10497
10502
|
if (real !== void 0) return proc(real);
|
|
10498
10503
|
}
|
|
10499
10504
|
try {
|
|
10500
10505
|
return own();
|
|
10501
10506
|
} catch (err) {
|
|
10502
|
-
const real = toProc(p,
|
|
10507
|
+
const real = toProc(p, follow3);
|
|
10503
10508
|
if (real === void 0) throw err;
|
|
10504
10509
|
return proc(real);
|
|
10505
10510
|
}
|
|
10506
10511
|
};
|
|
10507
10512
|
const readOnly2 = (paths, run) => {
|
|
10508
10513
|
const physical2 = shadowing();
|
|
10509
|
-
for (const [p,
|
|
10510
|
-
if (inProc(p) || physical2 && toProc(p,
|
|
10514
|
+
for (const [p, follow3] of paths) {
|
|
10515
|
+
if (inProc(p) || physical2 && toProc(p, follow3) !== void 0) throw syncError("EROFS", p);
|
|
10511
10516
|
}
|
|
10512
10517
|
return run();
|
|
10513
10518
|
};
|
|
@@ -10592,12 +10597,12 @@ function procfsBridge(fs, tree) {
|
|
|
10592
10597
|
() => fs.rename(from, to)
|
|
10593
10598
|
),
|
|
10594
10599
|
symlink: (target, link) => readOnly2([[link, false]], () => fs.symlink(target, link)),
|
|
10595
|
-
link: (from, to,
|
|
10600
|
+
link: (from, to, follow3) => readOnly2(
|
|
10596
10601
|
[
|
|
10597
|
-
[from,
|
|
10602
|
+
[from, follow3 === true],
|
|
10598
10603
|
[to, false]
|
|
10599
10604
|
],
|
|
10600
|
-
() => fs.link(from, to,
|
|
10605
|
+
() => fs.link(from, to, follow3)
|
|
10601
10606
|
),
|
|
10602
10607
|
hold: (p, held2, open, handle, want, seen) => {
|
|
10603
10608
|
if (handle !== void 0 && snapshots.delete(handle)) return void 0;
|
|
@@ -10617,14 +10622,14 @@ function procfsBridge(fs, tree) {
|
|
|
10617
10622
|
)
|
|
10618
10623
|
} : {}
|
|
10619
10624
|
};
|
|
10620
|
-
for (const [names,
|
|
10625
|
+
for (const [names, follow3] of [
|
|
10621
10626
|
[FOLLOWING, true],
|
|
10622
10627
|
[NOT_FOLLOWING, false]
|
|
10623
10628
|
]) {
|
|
10624
10629
|
for (const name2 of names) {
|
|
10625
10630
|
const fn = fs[name2];
|
|
10626
10631
|
if (!fn) continue;
|
|
10627
|
-
over[name2] = (p, ...rest2) => readOnly2([[p,
|
|
10632
|
+
over[name2] = (p, ...rest2) => readOnly2([[p, follow3]], () => fn.call(fs, p, ...rest2));
|
|
10628
10633
|
}
|
|
10629
10634
|
}
|
|
10630
10635
|
const { chown } = fs;
|
|
@@ -10733,18 +10738,18 @@ var init_wasi_procfs = __esm({
|
|
|
10733
10738
|
}
|
|
10734
10739
|
};
|
|
10735
10740
|
}
|
|
10736
|
-
parts(path,
|
|
10741
|
+
parts(path, follow3) {
|
|
10737
10742
|
const parts = path.split("/").filter((p) => p !== "").slice(1);
|
|
10738
|
-
if (parts[0] === "self" && (
|
|
10743
|
+
if (parts[0] === "self" && (follow3 || parts.length > 1)) parts[0] = String(this.pid);
|
|
10739
10744
|
return parts;
|
|
10740
10745
|
}
|
|
10741
|
-
find(path,
|
|
10742
|
-
const node = this.node(this.parts(path,
|
|
10746
|
+
find(path, follow3) {
|
|
10747
|
+
const node = this.node(this.parts(path, follow3));
|
|
10743
10748
|
if (!node) throw syncError("ENOENT", path);
|
|
10744
10749
|
return node;
|
|
10745
10750
|
}
|
|
10746
|
-
stat(path,
|
|
10747
|
-
const node = this.find(path,
|
|
10751
|
+
stat(path, follow3 = true) {
|
|
10752
|
+
const node = this.find(path, follow3);
|
|
10748
10753
|
const base = {
|
|
10749
10754
|
isFile: false,
|
|
10750
10755
|
isDirectory: false,
|
|
@@ -11424,6 +11429,50 @@ var init_js_tty = __esm({
|
|
|
11424
11429
|
}
|
|
11425
11430
|
});
|
|
11426
11431
|
|
|
11432
|
+
// src/process/js/js-watch.ts
|
|
11433
|
+
function watchRequest(path, options) {
|
|
11434
|
+
return { op: "watch-open", path, ...options?.recursive ? { recursive: true } : {} };
|
|
11435
|
+
}
|
|
11436
|
+
function watchArgs(options, listener) {
|
|
11437
|
+
const onNote = typeof options === "function" ? options : listener;
|
|
11438
|
+
if (typeof onNote !== "function") throw new TypeError("watch needs a listener");
|
|
11439
|
+
return [typeof options === "object" && options !== null ? options : {}, onNote];
|
|
11440
|
+
}
|
|
11441
|
+
function follow2(kernel, id, onNote) {
|
|
11442
|
+
const stop = new AbortController();
|
|
11443
|
+
let closed = false;
|
|
11444
|
+
const close = () => {
|
|
11445
|
+
if (closed) return;
|
|
11446
|
+
closed = true;
|
|
11447
|
+
stop.abort();
|
|
11448
|
+
kernel.call({ op: "watch-close", id }).catch(() => void 0);
|
|
11449
|
+
};
|
|
11450
|
+
const pump2 = async () => {
|
|
11451
|
+
while (!closed) {
|
|
11452
|
+
let notes;
|
|
11453
|
+
try {
|
|
11454
|
+
const r = await kernel.blocking({ op: "watch-next", id }, stop.signal);
|
|
11455
|
+
notes = r.ok && r.kind === "json" ? r.json : [];
|
|
11456
|
+
} catch {
|
|
11457
|
+
closed = true;
|
|
11458
|
+
return;
|
|
11459
|
+
}
|
|
11460
|
+
for (const note of notes) {
|
|
11461
|
+
if (closed) return;
|
|
11462
|
+
if ("ended" in note) closed = true;
|
|
11463
|
+
onNote(note);
|
|
11464
|
+
}
|
|
11465
|
+
}
|
|
11466
|
+
};
|
|
11467
|
+
void pump2();
|
|
11468
|
+
return { close };
|
|
11469
|
+
}
|
|
11470
|
+
var init_js_watch = __esm({
|
|
11471
|
+
"src/process/js/js-watch.ts"() {
|
|
11472
|
+
"use strict";
|
|
11473
|
+
}
|
|
11474
|
+
});
|
|
11475
|
+
|
|
11427
11476
|
// src/process/js/js-websocket.ts
|
|
11428
11477
|
function failed4(err) {
|
|
11429
11478
|
return new TypeError("websocket failed", { cause: err });
|
|
@@ -11787,6 +11836,15 @@ async function vfsOpen(kernel, abs, options, statOf, io, whole) {
|
|
|
11787
11836
|
handles.set(fd, handle.invalidate);
|
|
11788
11837
|
return handle.file;
|
|
11789
11838
|
}
|
|
11839
|
+
function watchingSyncOps(kernel, syncKernel, shared) {
|
|
11840
|
+
const ops = syncOps(syncKernel, shared);
|
|
11841
|
+
const watch = (path, options, listener) => {
|
|
11842
|
+
const [given, onNote] = watchArgs(options, listener);
|
|
11843
|
+
const id = syncKernel.json(watchRequest(shared.resolve(path), given));
|
|
11844
|
+
return follow2(kernel, id, onNote);
|
|
11845
|
+
};
|
|
11846
|
+
return { ...ops, fs: { ...ops.fs, watch } };
|
|
11847
|
+
}
|
|
11790
11848
|
function createContext(o) {
|
|
11791
11849
|
const { kernel } = o;
|
|
11792
11850
|
const infos = /* @__PURE__ */ new Map();
|
|
@@ -11862,7 +11920,7 @@ function createContext(o) {
|
|
|
11862
11920
|
const terminal = ttyOps(kernel);
|
|
11863
11921
|
const sync = {
|
|
11864
11922
|
kernel: KERNEL_INFO,
|
|
11865
|
-
...
|
|
11923
|
+
...watchingSyncOps(kernel, syncKernel, { pid: o.pid, resolve, random, infos, handles }),
|
|
11866
11924
|
run: (options) => runSync(syncKernel, { env: o.env, cwd: o.cwd, resolve, signal: signalNumber }, options),
|
|
11867
11925
|
spawn: (options) => spawnSync(options),
|
|
11868
11926
|
exit: (status2 = 0) => {
|
|
@@ -12094,6 +12152,11 @@ function pathOps(kernel, resolve, statOf, open, tryDev) {
|
|
|
12094
12152
|
await statOf("stat", abs);
|
|
12095
12153
|
return statFsOf(await kernel.json({ op: "statfs", path: abs }));
|
|
12096
12154
|
},
|
|
12155
|
+
async watch(path, options, listener) {
|
|
12156
|
+
const [given, onNote] = watchArgs(options, listener);
|
|
12157
|
+
const id = await kernel.json(watchRequest(resolve(path), given));
|
|
12158
|
+
return follow2(kernel, id, onNote);
|
|
12159
|
+
},
|
|
12097
12160
|
async readFile(path) {
|
|
12098
12161
|
const abs = resolve(path);
|
|
12099
12162
|
if (inDev(abs)) return readWhole(await open(abs));
|
|
@@ -12141,6 +12204,7 @@ var init_js_context = __esm({
|
|
|
12141
12204
|
init_js_run();
|
|
12142
12205
|
init_js_sync();
|
|
12143
12206
|
init_js_tty();
|
|
12207
|
+
init_js_watch();
|
|
12144
12208
|
init_js_websocket();
|
|
12145
12209
|
KERNEL_INFO = Object.freeze({ version: KERNEL_VERSION });
|
|
12146
12210
|
JsExit = class extends Error {
|
|
@@ -12378,9 +12442,9 @@ function useKernelFdMetadata(Fs, sys, call2) {
|
|
|
12378
12442
|
}
|
|
12379
12443
|
return void 0;
|
|
12380
12444
|
};
|
|
12381
|
-
const ofPath = (path,
|
|
12445
|
+
const ofPath = (path, follow3) => {
|
|
12382
12446
|
if (typeof path !== "string") return find((s) => s.node === path);
|
|
12383
|
-
const fd =
|
|
12447
|
+
const fd = follow3 ? fdOfPath(path, Fs.cwd()) : void 0;
|
|
12384
12448
|
if (fd !== void 0) return kernelFd(Fs.getStream(fd));
|
|
12385
12449
|
return find((s) => s.path === path);
|
|
12386
12450
|
};
|