@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
package/dist/process-worker.js
CHANGED
|
@@ -1266,8 +1266,8 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
1266
1266
|
rename: (from, to) => {
|
|
1267
1267
|
run({ op: "rename", path: from, arg2: to }, from);
|
|
1268
1268
|
},
|
|
1269
|
-
link: (from, to,
|
|
1270
|
-
run({ op: "link", path: from, arg2: to, ...
|
|
1269
|
+
link: (from, to, follow3) => {
|
|
1270
|
+
run({ op: "link", path: from, arg2: to, ...follow3 ? { mode: 1 } : {} }, from);
|
|
1271
1271
|
},
|
|
1272
1272
|
unlink: (path) => {
|
|
1273
1273
|
run({ op: "unlink", path }, path);
|
|
@@ -1310,11 +1310,11 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
1310
1310
|
const flags = { ...mode !== void 0 ? { mode } : {}, ...opening2 ? { opening: opening2 } : {} };
|
|
1311
1311
|
run({ op: "create", path, ...flags }, path);
|
|
1312
1312
|
},
|
|
1313
|
-
chown: (path, uid, gid,
|
|
1313
|
+
chown: (path, uid, gid, follow3, handle) => {
|
|
1314
1314
|
const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
|
|
1315
1315
|
changing(
|
|
1316
1316
|
{
|
|
1317
|
-
op:
|
|
1317
|
+
op: follow3 ? "chown" : "lchown",
|
|
1318
1318
|
path,
|
|
1319
1319
|
...ids,
|
|
1320
1320
|
...handle !== void 0 ? { handle } : {}
|
|
@@ -2345,9 +2345,9 @@ function guardVanished(Fs) {
|
|
|
2345
2345
|
const drop = forget;
|
|
2346
2346
|
const lookupPath = Fs.lookupPath.bind(Fs);
|
|
2347
2347
|
const ops = Fs;
|
|
2348
|
-
const cached = (path,
|
|
2348
|
+
const cached = (path, follow3) => {
|
|
2349
2349
|
try {
|
|
2350
|
-
const node = lookupPath(path, { follow:
|
|
2350
|
+
const node = lookupPath(path, { follow: follow3 }).node;
|
|
2351
2351
|
return node.live && node.live.openCount === 0 && !node.live.dirty ? node : void 0;
|
|
2352
2352
|
} catch {
|
|
2353
2353
|
return void 0;
|
|
@@ -2454,11 +2454,11 @@ function linkable(bridge, path) {
|
|
|
2454
2454
|
return false;
|
|
2455
2455
|
}
|
|
2456
2456
|
}
|
|
2457
|
-
function linkLive(Fs, from, to,
|
|
2457
|
+
function linkLive(Fs, from, to, follow3) {
|
|
2458
2458
|
const target = to.replace(/\/+$/, "");
|
|
2459
2459
|
const slash = target.lastIndexOf("/");
|
|
2460
2460
|
const name2 = target.slice(slash + 1);
|
|
2461
|
-
const source = Fs.lookupPath(from, { follow:
|
|
2461
|
+
const source = Fs.lookupPath(from, { follow: follow3 }).node;
|
|
2462
2462
|
const parent = Fs.lookupPath(target.slice(0, slash) || "/", { follow: true }).node;
|
|
2463
2463
|
if (!source.live || !parent.live) return false;
|
|
2464
2464
|
flushOne(Fs, source);
|
|
@@ -2647,7 +2647,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
2647
2647
|
var init_version = __esm({
|
|
2648
2648
|
"src/version.ts"() {
|
|
2649
2649
|
"use strict";
|
|
2650
|
-
KERNEL_VERSION = true ? "1.
|
|
2650
|
+
KERNEL_VERSION = true ? "1.125.0" : "0.0.0-dev";
|
|
2651
2651
|
OS_RELEASE = "6.0.0-slicc";
|
|
2652
2652
|
}
|
|
2653
2653
|
});
|
|
@@ -3482,13 +3482,13 @@ function readonlyRefusal(Fs, memory, call2) {
|
|
|
3482
3482
|
try {
|
|
3483
3483
|
const name2 = cString(memory, call2.path);
|
|
3484
3484
|
const abs = name2.startsWith("/") ? name2 : `${baseOf2(Fs, call2.dirfd)}/${name2}`;
|
|
3485
|
-
const
|
|
3485
|
+
const follow3 = (call2.flags & AT_SYMLINK_NOFOLLOW) === 0;
|
|
3486
3486
|
const { node } = Fs.lookupPath.call(Fs, abs, {
|
|
3487
|
-
follow:
|
|
3487
|
+
follow: follow3
|
|
3488
3488
|
});
|
|
3489
3489
|
const bridge = node.live ? node.mount.opts.bridge : void 0;
|
|
3490
3490
|
const stats = bridge;
|
|
3491
|
-
const stat =
|
|
3491
|
+
const stat = follow3 ? stats?.stat : stats?.lstat;
|
|
3492
3492
|
return stat?.call(stats, liveNodePath(node)).readonly ? -wasiErrno("EROFS") : 0;
|
|
3493
3493
|
} catch {
|
|
3494
3494
|
return 0;
|
|
@@ -3537,8 +3537,8 @@ function kernelLink(imports, fs, memory, glue) {
|
|
|
3537
3537
|
try {
|
|
3538
3538
|
const from = at(olddirfd, oldpath);
|
|
3539
3539
|
const to = at(newdirfd, newpath);
|
|
3540
|
-
const
|
|
3541
|
-
if (linkLive(Fs, from, to,
|
|
3540
|
+
const follow3 = (flags & AT_SYMLINK_FOLLOW) !== 0;
|
|
3541
|
+
if (linkLive(Fs, from, to, follow3)) return 0;
|
|
3542
3542
|
} catch (err) {
|
|
3543
3543
|
return -errnoOf2(err);
|
|
3544
3544
|
}
|
|
@@ -3761,9 +3761,9 @@ function useKernelFdMetadata(Fs, sys, call2) {
|
|
|
3761
3761
|
}
|
|
3762
3762
|
return void 0;
|
|
3763
3763
|
};
|
|
3764
|
-
const ofPath = (path,
|
|
3764
|
+
const ofPath = (path, follow3) => {
|
|
3765
3765
|
if (typeof path !== "string") return find((s) => s.node === path);
|
|
3766
|
-
const fd =
|
|
3766
|
+
const fd = follow3 ? fdOfPath(path, Fs.cwd()) : void 0;
|
|
3767
3767
|
if (fd !== void 0) return kernelFd(Fs.getStream(fd));
|
|
3768
3768
|
return find((s) => s.path === path);
|
|
3769
3769
|
};
|
|
@@ -6747,7 +6747,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
6747
6747
|
mkdir: (p) => mutating(() => bridge.mkdir(p), ...entry(p)),
|
|
6748
6748
|
rm: (p) => mutating(() => bridge.rm(p)),
|
|
6749
6749
|
rename: (from, to) => mutating(() => bridge.rename(from, to)),
|
|
6750
|
-
link: (from, to,
|
|
6750
|
+
link: (from, to, follow3) => mutating(() => bridge.link(from, to, follow3)),
|
|
6751
6751
|
unlink: (p) => mutating(() => bridge.unlink(p)),
|
|
6752
6752
|
rmdir: (p) => mutating(() => bridge.rmdir(p)),
|
|
6753
6753
|
symlink: (target, link) => mutating(() => bridge.symlink(target, link), ...entry(link)),
|
|
@@ -7693,7 +7693,7 @@ function devFdStat(fd) {
|
|
|
7693
7693
|
function linkStat(target) {
|
|
7694
7694
|
return nodeStat(LINK | 511, target.length);
|
|
7695
7695
|
}
|
|
7696
|
-
function* devStat(abs,
|
|
7696
|
+
function* devStat(abs, follow3) {
|
|
7697
7697
|
const node = yield* lookup(abs);
|
|
7698
7698
|
switch (node.kind) {
|
|
7699
7699
|
case "dir":
|
|
@@ -7706,10 +7706,10 @@ function* devStat(abs, follow2) {
|
|
|
7706
7706
|
case "terminal":
|
|
7707
7707
|
return yield* terminalStat(node.name);
|
|
7708
7708
|
case "link":
|
|
7709
|
-
if (!
|
|
7709
|
+
if (!follow3) return linkStat(node.target);
|
|
7710
7710
|
return node.fd === void 0 ? nodeStat(DIR | 365) : yield* fdStat(node.fd, abs);
|
|
7711
7711
|
case "fd":
|
|
7712
|
-
return
|
|
7712
|
+
return follow3 ? yield* fdStat(node.fd, abs) : linkStat(yield* fdTarget(node.fd, abs));
|
|
7713
7713
|
}
|
|
7714
7714
|
}
|
|
7715
7715
|
function* devExists(abs) {
|
|
@@ -9170,7 +9170,7 @@ function writeEvents(mem, ptr, events) {
|
|
|
9170
9170
|
v.setUint16(p + 8, ev.error, true);
|
|
9171
9171
|
v.setUint8(p + 10, ev.type);
|
|
9172
9172
|
if (ev.type !== EVENTTYPE.CLOCK) {
|
|
9173
|
-
v.setBigUint64(p + 16,
|
|
9173
|
+
v.setBigUint64(p + 16, BigInt(ev.nbytes ?? 1), true);
|
|
9174
9174
|
if (ev.hangup) v.setUint16(p + 24, EVENT_FD_READWRITE_HANGUP, true);
|
|
9175
9175
|
}
|
|
9176
9176
|
});
|
|
@@ -9189,6 +9189,10 @@ function classify(fds, subs) {
|
|
|
9189
9189
|
}
|
|
9190
9190
|
return { events, read: read2, write: write2 };
|
|
9191
9191
|
}
|
|
9192
|
+
function nbytesOf(s, ready) {
|
|
9193
|
+
const n = s.type === EVENTTYPE.FD_READ ? ready.nread?.[s.fd] : void 0;
|
|
9194
|
+
return n === void 0 ? {} : { nbytes: n };
|
|
9195
|
+
}
|
|
9192
9196
|
function readyEvents(subs, ready) {
|
|
9193
9197
|
return subs.filter(
|
|
9194
9198
|
(s) => s.type === EVENTTYPE.FD_READ && ready.read.includes(s.fd) || s.type === EVENTTYPE.FD_WRITE && ready.write.includes(s.fd)
|
|
@@ -9196,7 +9200,8 @@ function readyEvents(subs, ready) {
|
|
|
9196
9200
|
userdata: s.userdata,
|
|
9197
9201
|
error: E.SUCCESS,
|
|
9198
9202
|
type: s.type,
|
|
9199
|
-
hangup: ready.hangup?.includes(s.fd) === true
|
|
9203
|
+
hangup: ready.hangup?.includes(s.fd) === true,
|
|
9204
|
+
...nbytesOf(s, ready)
|
|
9200
9205
|
}));
|
|
9201
9206
|
}
|
|
9202
9207
|
function selectOnce(deps, read2, write2, timeoutMs2) {
|
|
@@ -10117,10 +10122,10 @@ var init_wasi_host = __esm({
|
|
|
10117
10122
|
return path;
|
|
10118
10123
|
};
|
|
10119
10124
|
const modeOf2 = (st) => (st.mode ?? 0) & 4095;
|
|
10120
|
-
const chown = (path, uid, gid,
|
|
10125
|
+
const chown = (path, uid, gid, follow3, handle) => {
|
|
10121
10126
|
const { chown: own } = this.o.fs;
|
|
10122
10127
|
if (!own) throw new WasiError("ENOSYS");
|
|
10123
|
-
own.call(this.o.fs, path, idOf3(uid), idOf3(gid),
|
|
10128
|
+
own.call(this.o.fs, path, idOf3(uid), idOf3(gid), follow3, handle);
|
|
10124
10129
|
};
|
|
10125
10130
|
const caller = () => {
|
|
10126
10131
|
const cred = this.creds.get();
|
|
@@ -10160,16 +10165,16 @@ var init_wasi_host = __esm({
|
|
|
10160
10165
|
return devSync(dev, devFdStat(fd)).mode ?? DEVICE_MODE;
|
|
10161
10166
|
return modeOf2(this.o.fs.stat(pathOf(fd)));
|
|
10162
10167
|
};
|
|
10163
|
-
const pathOwned = (path,
|
|
10168
|
+
const pathOwned = (path, follow3) => {
|
|
10164
10169
|
const alias = this.fdAlias(path);
|
|
10165
|
-
if (alias && !
|
|
10170
|
+
if (alias && !follow3) return alias.stdio ? ROOT_IDS : void 0;
|
|
10166
10171
|
if (alias) {
|
|
10167
10172
|
this.openFd(alias.fd);
|
|
10168
10173
|
return fdOwned(alias.fd);
|
|
10169
10174
|
}
|
|
10170
10175
|
if (this.synthetic(path)) return ROOT_IDS;
|
|
10171
|
-
if (kernelDev(path)) return devSync(dev, devStat(path,
|
|
10172
|
-
return
|
|
10176
|
+
if (kernelDev(path)) return devSync(dev, devStat(path, follow3));
|
|
10177
|
+
return follow3 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
|
|
10173
10178
|
};
|
|
10174
10179
|
return wrap({
|
|
10175
10180
|
fd_chown: (fd, uid, gid) => {
|
|
@@ -10565,7 +10570,7 @@ var init_wasi_host = __esm({
|
|
|
10565
10570
|
const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
|
|
10566
10571
|
return {
|
|
10567
10572
|
path_open: (dirfd, lookup2, p, l, oflags, rights, _inheriting, fdflags, out) => {
|
|
10568
|
-
const
|
|
10573
|
+
const follow3 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
10569
10574
|
try {
|
|
10570
10575
|
const asked = at(dirfd, p, l);
|
|
10571
10576
|
const alias = this.fdAlias(asked);
|
|
@@ -10579,7 +10584,7 @@ var init_wasi_host = __esm({
|
|
|
10579
10584
|
if (err.code !== "ENOENT") throw err;
|
|
10580
10585
|
const raw = mem.string(p, l);
|
|
10581
10586
|
const joined2 = raw.startsWith("/") ? raw : `${fds.dir(dirfd).path}/${raw}`;
|
|
10582
|
-
const resolved2 = this.resolveForDev(joined2,
|
|
10587
|
+
const resolved2 = this.resolveForDev(joined2, follow3);
|
|
10583
10588
|
if (!resolved2) throw err;
|
|
10584
10589
|
mem.view().setUint32(out, fds.open(resolved2, oflags, rights, fdflags), true);
|
|
10585
10590
|
}
|
|
@@ -10642,11 +10647,11 @@ var init_wasi_host = __esm({
|
|
|
10642
10647
|
path_link: (fd, lookup2, p, l, fd2, p2, l2) => {
|
|
10643
10648
|
const from = at(fd, p, l);
|
|
10644
10649
|
const to = at(fd2, p2, l2);
|
|
10645
|
-
const
|
|
10646
|
-
const source =
|
|
10650
|
+
const follow3 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
10651
|
+
const source = follow3 ? physicalPath(o.fs, from) : from;
|
|
10647
10652
|
fds.flushPath(from);
|
|
10648
10653
|
if (source !== from) fds.flushPath(source);
|
|
10649
|
-
o.fs.link(from, to,
|
|
10654
|
+
o.fs.link(from, to, follow3);
|
|
10650
10655
|
fds.linked(from, to);
|
|
10651
10656
|
if (source !== from) fds.linked(source, to);
|
|
10652
10657
|
}
|
|
@@ -10959,18 +10964,18 @@ var init_wasi_host = __esm({
|
|
|
10959
10964
|
synthetic(path) {
|
|
10960
10965
|
return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH2 && !!this.o.kernel.sys.openClipboard;
|
|
10961
10966
|
}
|
|
10962
|
-
devChar(path,
|
|
10967
|
+
devChar(path, follow3) {
|
|
10963
10968
|
try {
|
|
10964
10969
|
const json2 = (req) => this.o.kernel.call(req);
|
|
10965
|
-
const st = devSync({ json: json2 }, devStat(path,
|
|
10970
|
+
const st = devSync({ json: json2 }, devStat(path, follow3));
|
|
10966
10971
|
return ((st.mode ?? 0) & 61440) === 8192;
|
|
10967
10972
|
} catch {
|
|
10968
10973
|
return false;
|
|
10969
10974
|
}
|
|
10970
10975
|
}
|
|
10971
|
-
resolveForDev(path,
|
|
10976
|
+
resolveForDev(path, follow3 = true) {
|
|
10972
10977
|
try {
|
|
10973
|
-
if (!
|
|
10978
|
+
if (!follow3) {
|
|
10974
10979
|
const slash = path.lastIndexOf("/");
|
|
10975
10980
|
if (slash <= 0) return void 0;
|
|
10976
10981
|
const parent = physicalPath(this.o.fs, path.slice(0, slash));
|
|
@@ -11061,12 +11066,12 @@ var init_wasi_host = __esm({
|
|
|
11061
11066
|
});
|
|
11062
11067
|
}
|
|
11063
11068
|
this.fds.flushPath(path);
|
|
11064
|
-
const
|
|
11069
|
+
const follow3 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
11065
11070
|
try {
|
|
11066
|
-
return filestatOf(path,
|
|
11071
|
+
return filestatOf(path, follow3 ? this.o.fs.stat(path) : this.o.fs.lstat(path));
|
|
11067
11072
|
} catch (err) {
|
|
11068
11073
|
if (err.code !== "ENOENT") throw err;
|
|
11069
|
-
if (kernelDev(path) && this.devChar(path,
|
|
11074
|
+
if (kernelDev(path) && this.devChar(path, follow3)) {
|
|
11070
11075
|
return this.local({
|
|
11071
11076
|
filetype: FILETYPE.CHARACTER_DEVICE,
|
|
11072
11077
|
size: 0n,
|
|
@@ -11074,7 +11079,7 @@ var init_wasi_host = __esm({
|
|
|
11074
11079
|
mtimeNs: 0n
|
|
11075
11080
|
});
|
|
11076
11081
|
}
|
|
11077
|
-
const resolved2 = this.resolveForDev(path,
|
|
11082
|
+
const resolved2 = this.resolveForDev(path, follow3);
|
|
11078
11083
|
if (!resolved2) throw err;
|
|
11079
11084
|
return this.local({
|
|
11080
11085
|
filetype: FILETYPE.CHARACTER_DEVICE,
|
|
@@ -11084,18 +11089,18 @@ var init_wasi_host = __esm({
|
|
|
11084
11089
|
});
|
|
11085
11090
|
}
|
|
11086
11091
|
}
|
|
11087
|
-
setTimes(path, atim, mtim, flags,
|
|
11092
|
+
setTimes(path, atim, mtim, flags, follow3 = true) {
|
|
11088
11093
|
const asked = FSTFLAGS.ATIM | FSTFLAGS.ATIM_NOW | FSTFLAGS.MTIM | FSTFLAGS.MTIM_NOW;
|
|
11089
11094
|
if (this.o.fs.owners && (flags & asked) === 0) return;
|
|
11090
11095
|
const now = Date.now();
|
|
11091
11096
|
let current;
|
|
11092
|
-
const statOf =
|
|
11097
|
+
const statOf = follow3 ? this.o.fs.stat.bind(this.o.fs) : this.o.fs.lstat.bind(this.o.fs);
|
|
11093
11098
|
const kept = (field2) => {
|
|
11094
11099
|
current ??= statOf(path);
|
|
11095
11100
|
return current[field2] ?? current.mtimeMs ?? now;
|
|
11096
11101
|
};
|
|
11097
11102
|
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS4) : kept(field2);
|
|
11098
|
-
(
|
|
11103
|
+
(follow3 ? this.o.fs.utimes : this.o.fs.lutimes).call(
|
|
11099
11104
|
this.o.fs,
|
|
11100
11105
|
path,
|
|
11101
11106
|
pick(FSTFLAGS.ATIM, FSTFLAGS.ATIM_NOW, atim, "atimeMs"),
|
|
@@ -11728,7 +11733,7 @@ var init_wasi_module = __esm({
|
|
|
11728
11733
|
function inProc(path) {
|
|
11729
11734
|
return path === "/proc" || path.startsWith("/proc/");
|
|
11730
11735
|
}
|
|
11731
|
-
function* procWalk(path,
|
|
11736
|
+
function* procWalk(path, follow3) {
|
|
11732
11737
|
let done = [];
|
|
11733
11738
|
let todo = path.split("/").filter((part) => part !== "");
|
|
11734
11739
|
let hops = 0;
|
|
@@ -11743,7 +11748,7 @@ function* procWalk(path, follow2) {
|
|
|
11743
11748
|
const at = `/${[...done, part].join("/")}`;
|
|
11744
11749
|
const whole = normalize(`/${[...done, part, ...todo].join("/")}`);
|
|
11745
11750
|
if (inProc(at) && inProc(whole)) return broken ?? whole;
|
|
11746
|
-
if (!
|
|
11751
|
+
if (!follow3 && todo.length === 0) return void 0;
|
|
11747
11752
|
const target = yield { at, check: todo.find((next2) => next2 !== ".") === ".." };
|
|
11748
11753
|
if (typeof target === "string") {
|
|
11749
11754
|
if (++hops > MAX_HOPS2) return void 0;
|
|
@@ -11767,8 +11772,8 @@ function throughLink(target, done, todo) {
|
|
|
11767
11772
|
const parts = target.split("/").filter((part) => part !== "");
|
|
11768
11773
|
return [target.startsWith("/") ? [] : done, [...parts, ...todo]];
|
|
11769
11774
|
}
|
|
11770
|
-
function procPath(fs, path,
|
|
11771
|
-
const walk = procWalk(path,
|
|
11775
|
+
function procPath(fs, path, follow3) {
|
|
11776
|
+
const walk = procWalk(path, follow3);
|
|
11772
11777
|
let step = walk.next();
|
|
11773
11778
|
while (!step.done) {
|
|
11774
11779
|
const { at, check } = step.value;
|
|
@@ -11826,26 +11831,26 @@ function physicalProc(fs) {
|
|
|
11826
11831
|
};
|
|
11827
11832
|
}
|
|
11828
11833
|
function procfsBridge(fs, tree) {
|
|
11829
|
-
const toProc = (path,
|
|
11834
|
+
const toProc = (path, follow3) => procPath(fs, path, follow3);
|
|
11830
11835
|
const shadowing = physicalProc(fs);
|
|
11831
|
-
const via = (p, proc, own,
|
|
11836
|
+
const via = (p, proc, own, follow3 = true) => {
|
|
11832
11837
|
if (inProc(p)) return proc(p);
|
|
11833
11838
|
if (shadowing()) {
|
|
11834
|
-
const real = toProc(p,
|
|
11839
|
+
const real = toProc(p, follow3);
|
|
11835
11840
|
if (real !== void 0) return proc(real);
|
|
11836
11841
|
}
|
|
11837
11842
|
try {
|
|
11838
11843
|
return own();
|
|
11839
11844
|
} catch (err) {
|
|
11840
|
-
const real = toProc(p,
|
|
11845
|
+
const real = toProc(p, follow3);
|
|
11841
11846
|
if (real === void 0) throw err;
|
|
11842
11847
|
return proc(real);
|
|
11843
11848
|
}
|
|
11844
11849
|
};
|
|
11845
11850
|
const readOnly2 = (paths, run) => {
|
|
11846
11851
|
const physical2 = shadowing();
|
|
11847
|
-
for (const [p,
|
|
11848
|
-
if (inProc(p) || physical2 && toProc(p,
|
|
11852
|
+
for (const [p, follow3] of paths) {
|
|
11853
|
+
if (inProc(p) || physical2 && toProc(p, follow3) !== void 0) throw syncError("EROFS", p);
|
|
11849
11854
|
}
|
|
11850
11855
|
return run();
|
|
11851
11856
|
};
|
|
@@ -11930,12 +11935,12 @@ function procfsBridge(fs, tree) {
|
|
|
11930
11935
|
() => fs.rename(from, to)
|
|
11931
11936
|
),
|
|
11932
11937
|
symlink: (target, link) => readOnly2([[link, false]], () => fs.symlink(target, link)),
|
|
11933
|
-
link: (from, to,
|
|
11938
|
+
link: (from, to, follow3) => readOnly2(
|
|
11934
11939
|
[
|
|
11935
|
-
[from,
|
|
11940
|
+
[from, follow3 === true],
|
|
11936
11941
|
[to, false]
|
|
11937
11942
|
],
|
|
11938
|
-
() => fs.link(from, to,
|
|
11943
|
+
() => fs.link(from, to, follow3)
|
|
11939
11944
|
),
|
|
11940
11945
|
hold: (p, held2, open, handle, want, seen) => {
|
|
11941
11946
|
if (handle !== void 0 && snapshots.delete(handle)) return void 0;
|
|
@@ -11955,14 +11960,14 @@ function procfsBridge(fs, tree) {
|
|
|
11955
11960
|
)
|
|
11956
11961
|
} : {}
|
|
11957
11962
|
};
|
|
11958
|
-
for (const [names,
|
|
11963
|
+
for (const [names, follow3] of [
|
|
11959
11964
|
[FOLLOWING, true],
|
|
11960
11965
|
[NOT_FOLLOWING, false]
|
|
11961
11966
|
]) {
|
|
11962
11967
|
for (const name2 of names) {
|
|
11963
11968
|
const fn = fs[name2];
|
|
11964
11969
|
if (!fn) continue;
|
|
11965
|
-
over[name2] = (p, ...rest2) => readOnly2([[p,
|
|
11970
|
+
over[name2] = (p, ...rest2) => readOnly2([[p, follow3]], () => fn.call(fs, p, ...rest2));
|
|
11966
11971
|
}
|
|
11967
11972
|
}
|
|
11968
11973
|
const { chown } = fs;
|
|
@@ -12071,18 +12076,18 @@ var init_wasi_procfs = __esm({
|
|
|
12071
12076
|
}
|
|
12072
12077
|
};
|
|
12073
12078
|
}
|
|
12074
|
-
parts(path,
|
|
12079
|
+
parts(path, follow3) {
|
|
12075
12080
|
const parts = path.split("/").filter((p) => p !== "").slice(1);
|
|
12076
|
-
if (parts[0] === "self" && (
|
|
12081
|
+
if (parts[0] === "self" && (follow3 || parts.length > 1)) parts[0] = String(this.pid);
|
|
12077
12082
|
return parts;
|
|
12078
12083
|
}
|
|
12079
|
-
find(path,
|
|
12080
|
-
const node = this.node(this.parts(path,
|
|
12084
|
+
find(path, follow3) {
|
|
12085
|
+
const node = this.node(this.parts(path, follow3));
|
|
12081
12086
|
if (!node) throw syncError("ENOENT", path);
|
|
12082
12087
|
return node;
|
|
12083
12088
|
}
|
|
12084
|
-
stat(path,
|
|
12085
|
-
const node = this.find(path,
|
|
12089
|
+
stat(path, follow3 = true) {
|
|
12090
|
+
const node = this.find(path, follow3);
|
|
12086
12091
|
const base = {
|
|
12087
12092
|
isFile: false,
|
|
12088
12093
|
isDirectory: false,
|
|
@@ -15265,8 +15270,8 @@ function fetchOp(kernel) {
|
|
|
15265
15270
|
for (let hops = 0; ; hops++) {
|
|
15266
15271
|
const head = await send(hop, signal);
|
|
15267
15272
|
const location = head.headers.find(([name2]) => name2.toLowerCase() === "location")?.[1];
|
|
15268
|
-
const
|
|
15269
|
-
if (!
|
|
15273
|
+
const follow3 = known.manualRedirects && REDIRECTS.has(head.status) && location !== void 0 && request.redirect !== "manual";
|
|
15274
|
+
if (!follow3) {
|
|
15270
15275
|
const redirected = hops > 0 || head.redirected === true;
|
|
15271
15276
|
return respond(head, hop.method, redirected, known.encodedBodies, request);
|
|
15272
15277
|
}
|
|
@@ -16298,6 +16303,50 @@ var init_js_tty = __esm({
|
|
|
16298
16303
|
}
|
|
16299
16304
|
});
|
|
16300
16305
|
|
|
16306
|
+
// src/process/js/js-watch.ts
|
|
16307
|
+
function watchRequest(path, options) {
|
|
16308
|
+
return { op: "watch-open", path, ...options?.recursive ? { recursive: true } : {} };
|
|
16309
|
+
}
|
|
16310
|
+
function watchArgs(options, listener) {
|
|
16311
|
+
const onNote = typeof options === "function" ? options : listener;
|
|
16312
|
+
if (typeof onNote !== "function") throw new TypeError("watch needs a listener");
|
|
16313
|
+
return [typeof options === "object" && options !== null ? options : {}, onNote];
|
|
16314
|
+
}
|
|
16315
|
+
function follow2(kernel, id, onNote) {
|
|
16316
|
+
const stop = new AbortController();
|
|
16317
|
+
let closed = false;
|
|
16318
|
+
const close = () => {
|
|
16319
|
+
if (closed) return;
|
|
16320
|
+
closed = true;
|
|
16321
|
+
stop.abort();
|
|
16322
|
+
kernel.call({ op: "watch-close", id }).catch(() => void 0);
|
|
16323
|
+
};
|
|
16324
|
+
const pump2 = async () => {
|
|
16325
|
+
while (!closed) {
|
|
16326
|
+
let notes;
|
|
16327
|
+
try {
|
|
16328
|
+
const r = await kernel.blocking({ op: "watch-next", id }, stop.signal);
|
|
16329
|
+
notes = r.ok && r.kind === "json" ? r.json : [];
|
|
16330
|
+
} catch {
|
|
16331
|
+
closed = true;
|
|
16332
|
+
return;
|
|
16333
|
+
}
|
|
16334
|
+
for (const note of notes) {
|
|
16335
|
+
if (closed) return;
|
|
16336
|
+
if ("ended" in note) closed = true;
|
|
16337
|
+
onNote(note);
|
|
16338
|
+
}
|
|
16339
|
+
}
|
|
16340
|
+
};
|
|
16341
|
+
void pump2();
|
|
16342
|
+
return { close };
|
|
16343
|
+
}
|
|
16344
|
+
var init_js_watch = __esm({
|
|
16345
|
+
"src/process/js/js-watch.ts"() {
|
|
16346
|
+
"use strict";
|
|
16347
|
+
}
|
|
16348
|
+
});
|
|
16349
|
+
|
|
16301
16350
|
// src/process/js/js-websocket.ts
|
|
16302
16351
|
function failed4(err) {
|
|
16303
16352
|
return new TypeError("websocket failed", { cause: err });
|
|
@@ -16661,6 +16710,15 @@ async function vfsOpen(kernel, abs, options, statOf, io, whole) {
|
|
|
16661
16710
|
handles.set(fd, handle.invalidate);
|
|
16662
16711
|
return handle.file;
|
|
16663
16712
|
}
|
|
16713
|
+
function watchingSyncOps(kernel, syncKernel, shared) {
|
|
16714
|
+
const ops = syncOps(syncKernel, shared);
|
|
16715
|
+
const watch = (path, options, listener) => {
|
|
16716
|
+
const [given, onNote] = watchArgs(options, listener);
|
|
16717
|
+
const id = syncKernel.json(watchRequest(shared.resolve(path), given));
|
|
16718
|
+
return follow2(kernel, id, onNote);
|
|
16719
|
+
};
|
|
16720
|
+
return { ...ops, fs: { ...ops.fs, watch } };
|
|
16721
|
+
}
|
|
16664
16722
|
function createContext(o) {
|
|
16665
16723
|
const { kernel } = o;
|
|
16666
16724
|
const infos = /* @__PURE__ */ new Map();
|
|
@@ -16736,7 +16794,7 @@ function createContext(o) {
|
|
|
16736
16794
|
const terminal = ttyOps(kernel);
|
|
16737
16795
|
const sync = {
|
|
16738
16796
|
kernel: KERNEL_INFO,
|
|
16739
|
-
...
|
|
16797
|
+
...watchingSyncOps(kernel, syncKernel, { pid: o.pid, resolve, random, infos, handles }),
|
|
16740
16798
|
run: (options) => runSync(syncKernel, { env: o.env, cwd: o.cwd, resolve, signal: signalNumber }, options),
|
|
16741
16799
|
spawn: (options) => spawnSync(options),
|
|
16742
16800
|
exit: (status2 = 0) => {
|
|
@@ -16968,6 +17026,11 @@ function pathOps(kernel, resolve, statOf, open, tryDev) {
|
|
|
16968
17026
|
await statOf("stat", abs);
|
|
16969
17027
|
return statFsOf(await kernel.json({ op: "statfs", path: abs }));
|
|
16970
17028
|
},
|
|
17029
|
+
async watch(path, options, listener) {
|
|
17030
|
+
const [given, onNote] = watchArgs(options, listener);
|
|
17031
|
+
const id = await kernel.json(watchRequest(resolve(path), given));
|
|
17032
|
+
return follow2(kernel, id, onNote);
|
|
17033
|
+
},
|
|
16971
17034
|
async readFile(path) {
|
|
16972
17035
|
const abs = resolve(path);
|
|
16973
17036
|
if (inDev(abs)) return readWhole(await open(abs));
|
|
@@ -17015,6 +17078,7 @@ var init_js_context = __esm({
|
|
|
17015
17078
|
init_js_run();
|
|
17016
17079
|
init_js_sync();
|
|
17017
17080
|
init_js_tty();
|
|
17081
|
+
init_js_watch();
|
|
17018
17082
|
init_js_websocket();
|
|
17019
17083
|
KERNEL_INFO = Object.freeze({ version: KERNEL_VERSION });
|
|
17020
17084
|
JsExit = class extends Error {
|