@ai-ecoverse/slicc-kernel 1.83.0 → 1.84.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 +10 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +85 -38
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +27 -5
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +215 -62
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +27 -5
- package/dist/process-worker.js.map +3 -3
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -448,8 +448,8 @@ async function inParent(g, op, path, old = false) {
|
|
|
448
448
|
if (!old) return void await need(g, op, parentOf(path), W_OK | X_OK, DIR, path);
|
|
449
449
|
const dir = await access(g.fs, g.cred, parentOf(path), W_OK | X_OK, DIR);
|
|
450
450
|
if (dir.denied === void 0) return stickyEntry(g, op, path, dir);
|
|
451
|
-
const
|
|
452
|
-
if (!
|
|
451
|
+
const lookup3 = dir.denied === dir.path && dir.perm && permits(g.cred, dir.perm, X_OK);
|
|
452
|
+
if (!lookup3 || await present(g.fs, entryIn(dir, path), false)) deny(g, op, path);
|
|
453
453
|
}
|
|
454
454
|
async function makeIn(g, op, path) {
|
|
455
455
|
for (let dir = parentOf(path); ; dir = parentOf(dir)) {
|
|
@@ -3467,10 +3467,10 @@ function translate(err, path, op = "lookup", mapped = true) {
|
|
|
3467
3467
|
var META_OPS = ["get", "update", "move", "remove", "links", "under", "all"];
|
|
3468
3468
|
function sidecar(meta) {
|
|
3469
3469
|
const pathOf = ([first]) => [first, "/"].flat().find((p) => typeof p === "string");
|
|
3470
|
-
const
|
|
3470
|
+
const guarded3 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
|
|
3471
3471
|
throw translate(err, pathOf(args), "sidecar", false);
|
|
3472
3472
|
});
|
|
3473
|
-
return Object.fromEntries(META_OPS.map((op) => [op,
|
|
3473
|
+
return Object.fromEntries(META_OPS.map((op) => [op, guarded3(op)]));
|
|
3474
3474
|
}
|
|
3475
3475
|
function missing2(err) {
|
|
3476
3476
|
const code = err?.code;
|
|
@@ -5907,9 +5907,13 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
5907
5907
|
// src/fs/fresh-modules.ts
|
|
5908
5908
|
var MAGIC = [0, 97, 115, 109];
|
|
5909
5909
|
var MAX_FRESH = 65536;
|
|
5910
|
+
var DEFAULT_UMASK = 18;
|
|
5910
5911
|
function isModule(bytes) {
|
|
5911
5912
|
return MAGIC.every((b, i) => bytes[i] === b);
|
|
5912
5913
|
}
|
|
5914
|
+
function within4(path, dir) {
|
|
5915
|
+
return path.startsWith(dir === "/" ? "/" : `${dir}/`);
|
|
5916
|
+
}
|
|
5913
5917
|
var FreshModules = class {
|
|
5914
5918
|
fresh = /* @__PURE__ */ new Map();
|
|
5915
5919
|
add(path, umask, pid) {
|
|
@@ -5917,17 +5921,40 @@ var FreshModules = class {
|
|
|
5917
5921
|
this.fresh.delete(key);
|
|
5918
5922
|
const oldest = this.fresh.size >= MAX_FRESH ? this.fresh.keys().next().value : void 0;
|
|
5919
5923
|
if (oldest !== void 0) this.fresh.delete(oldest);
|
|
5920
|
-
|
|
5924
|
+
const mask = umask & 511;
|
|
5925
|
+
this.fresh.set(key, { umask: mask, pid, added: 0, setup: mask !== DEFAULT_UMASK });
|
|
5921
5926
|
}
|
|
5922
5927
|
forget(pid) {
|
|
5923
5928
|
for (const [path, fresh2] of this.fresh) if (fresh2.pid === pid) this.fresh.delete(path);
|
|
5924
5929
|
}
|
|
5930
|
+
drop(fresh2) {
|
|
5931
|
+
for (const [key, note] of [...this.fresh]) if (note === fresh2) this.fresh.delete(key);
|
|
5932
|
+
}
|
|
5933
|
+
moved(from, to) {
|
|
5934
|
+
const source = normalizePath(from);
|
|
5935
|
+
const target = normalizePath(to);
|
|
5936
|
+
if (source === target) return;
|
|
5937
|
+
for (const key of [...this.fresh.keys()]) {
|
|
5938
|
+
if (key === target || within4(key, target)) this.fresh.delete(key);
|
|
5939
|
+
}
|
|
5940
|
+
for (const [key, fresh2] of [...this.fresh]) {
|
|
5941
|
+
if (key !== source && !within4(key, source)) continue;
|
|
5942
|
+
this.fresh.delete(key);
|
|
5943
|
+
this.fresh.set(target + key.slice(source.length), fresh2);
|
|
5944
|
+
}
|
|
5945
|
+
}
|
|
5925
5946
|
wrap(fs) {
|
|
5926
|
-
const
|
|
5947
|
+
const head = async (path) => {
|
|
5948
|
+
if (fs.pread) return fs.pread(path, 0, MAGIC.length);
|
|
5949
|
+
return (await fs.readFileBuffer(path)).subarray(0, MAGIC.length);
|
|
5950
|
+
};
|
|
5951
|
+
const decide = async (given, known) => {
|
|
5927
5952
|
const path = normalizePath(given);
|
|
5928
5953
|
const fresh2 = this.fresh.get(path);
|
|
5929
|
-
if (!fresh2
|
|
5954
|
+
if (!fresh2) return;
|
|
5955
|
+
const bytes = known && known.length >= MAGIC.length ? known : await head(path);
|
|
5930
5956
|
const want = isModule(bytes) ? 73 & ~fresh2.umask : 0;
|
|
5957
|
+
fresh2.setup = false;
|
|
5931
5958
|
if (want === fresh2.added) return;
|
|
5932
5959
|
const mode = (await fs.stat(path)).mode & 4095;
|
|
5933
5960
|
await fs.chmod(path, mode & ~fresh2.added | want);
|
|
@@ -5936,32 +5963,47 @@ var FreshModules = class {
|
|
|
5936
5963
|
const overrides = {
|
|
5937
5964
|
writeFile: async (path, content, owner) => {
|
|
5938
5965
|
await fs.writeFile(path, content, owner);
|
|
5939
|
-
|
|
5966
|
+
if (this.fresh.has(normalizePath(path))) {
|
|
5967
|
+
await decide(
|
|
5968
|
+
path,
|
|
5969
|
+
typeof content === "string" ? new TextEncoder().encode(content) : content
|
|
5970
|
+
);
|
|
5971
|
+
}
|
|
5940
5972
|
},
|
|
5941
5973
|
chmod: async (path, mode) => {
|
|
5942
5974
|
const fresh2 = this.fresh.get(normalizePath(path));
|
|
5943
|
-
|
|
5944
|
-
if (
|
|
5975
|
+
if (fresh2?.setup && (mode & 4095) === (438 & ~fresh2.umask)) fresh2.setup = false;
|
|
5976
|
+
else if (fresh2) this.drop(fresh2);
|
|
5945
5977
|
await fs.chmod(path, mode);
|
|
5946
5978
|
},
|
|
5947
5979
|
rm: async (path, options) => {
|
|
5948
|
-
this.fresh.delete(normalizePath(path));
|
|
5949
5980
|
await fs.rm(path, options);
|
|
5981
|
+
const at = normalizePath(path);
|
|
5982
|
+
for (const key of [...this.fresh.keys()]) {
|
|
5983
|
+
if (key === at || within4(key, at)) this.fresh.delete(key);
|
|
5984
|
+
}
|
|
5950
5985
|
},
|
|
5951
5986
|
rename: async (from, to) => {
|
|
5952
5987
|
await fs.rename(from, to);
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5988
|
+
this.moved(from, to);
|
|
5989
|
+
},
|
|
5990
|
+
link: async (from, to, follow2) => {
|
|
5991
|
+
await fs.link(from, to, follow2);
|
|
5992
|
+
const source = follow2 && fs.realpath ? await fs.realpath(from, true) : from;
|
|
5993
|
+
const fresh2 = this.fresh.get(normalizePath(source));
|
|
5956
5994
|
if (fresh2) this.fresh.set(normalizePath(to), fresh2);
|
|
5957
5995
|
}
|
|
5958
5996
|
};
|
|
5959
5997
|
const ranged2 = rangedOps(fs);
|
|
5960
5998
|
if (ranged2) {
|
|
5961
5999
|
overrides.pwrite = async (path, at, bytes, transfer) => {
|
|
5962
|
-
const
|
|
6000
|
+
const touches2 = at < MAGIC.length && this.fresh.has(normalizePath(path));
|
|
5963
6001
|
await ranged2.pwrite(path, at, bytes, transfer);
|
|
5964
|
-
if (
|
|
6002
|
+
if (touches2) await decide(path);
|
|
6003
|
+
};
|
|
6004
|
+
overrides.truncate = async (path, size) => {
|
|
6005
|
+
await ranged2.truncate(path, size);
|
|
6006
|
+
if (size < MAGIC.length && this.fresh.has(normalizePath(path))) await decide(path);
|
|
5965
6007
|
};
|
|
5966
6008
|
}
|
|
5967
6009
|
const bound2 = /* @__PURE__ */ new WeakMap();
|
|
@@ -6701,7 +6743,7 @@ function parseSize(text) {
|
|
|
6701
6743
|
if (!match) throw errnoError("EINVAL", `not a size: ${text}`);
|
|
6702
6744
|
return Math.floor(Number(match[1]) * UNITS[match[2].toLowerCase()]);
|
|
6703
6745
|
}
|
|
6704
|
-
var
|
|
6746
|
+
var within5 = (path, target) => path === target || target === "/" || path.startsWith(`${target}/`);
|
|
6705
6747
|
var HeldSet = class extends Set {
|
|
6706
6748
|
idle;
|
|
6707
6749
|
constructor(idle) {
|
|
@@ -6720,7 +6762,7 @@ var HeldSet = class extends Set {
|
|
|
6720
6762
|
}
|
|
6721
6763
|
};
|
|
6722
6764
|
function heldUnder(held, target) {
|
|
6723
|
-
for (const paths of held) for (const path of paths.keys()) if (
|
|
6765
|
+
for (const paths of held) for (const path of paths.keys()) if (within5(path, target)) return true;
|
|
6724
6766
|
return false;
|
|
6725
6767
|
}
|
|
6726
6768
|
var HeldPaths = class extends Map {
|
|
@@ -6836,24 +6878,24 @@ var HeldPaths = class extends Map {
|
|
|
6836
6878
|
return this.owning === path;
|
|
6837
6879
|
}
|
|
6838
6880
|
revoke(prefix) {
|
|
6839
|
-
for (const path of this.keys()) if (
|
|
6881
|
+
for (const path of this.keys()) if (within5(path, prefix)) this.revoked.add(path);
|
|
6840
6882
|
}
|
|
6841
6883
|
renamed(from, to) {
|
|
6842
6884
|
for (const [path, count2] of [...this]) {
|
|
6843
|
-
if (!
|
|
6885
|
+
if (!within5(path, from)) continue;
|
|
6844
6886
|
const moved2 = to + path.slice(from.length);
|
|
6845
6887
|
this.delete(path);
|
|
6846
6888
|
this.set(moved2, (this.get(moved2) ?? 0) + count2);
|
|
6847
6889
|
if (this.revoked.delete(path)) this.revoked.add(moved2);
|
|
6848
6890
|
}
|
|
6849
6891
|
for (const [path, count2] of [...this.opens]) {
|
|
6850
|
-
if (!
|
|
6892
|
+
if (!within5(path, from)) continue;
|
|
6851
6893
|
const moved2 = to + path.slice(from.length);
|
|
6852
6894
|
this.opens.delete(path);
|
|
6853
6895
|
this.opens.set(moved2, (this.opens.get(moved2) ?? 0) + count2);
|
|
6854
6896
|
}
|
|
6855
6897
|
for (const [id2, key] of this.handles) {
|
|
6856
|
-
if (
|
|
6898
|
+
if (within5(key, from)) this.handles.set(id2, to + key.slice(from.length));
|
|
6857
6899
|
}
|
|
6858
6900
|
}
|
|
6859
6901
|
isRevoked(path) {
|
|
@@ -6960,7 +7002,7 @@ var MountTable = class {
|
|
|
6960
7002
|
locate(path) {
|
|
6961
7003
|
let best;
|
|
6962
7004
|
for (const mount of this.mounts.values()) {
|
|
6963
|
-
if (
|
|
7005
|
+
if (within5(path, mount.target) && (!best || mount.target.length > best.target.length))
|
|
6964
7006
|
best = mount;
|
|
6965
7007
|
}
|
|
6966
7008
|
if (!best) return void 0;
|
|
@@ -7103,7 +7145,7 @@ var MountTable = class {
|
|
|
7103
7145
|
async commitUnder(prefix) {
|
|
7104
7146
|
const at = normalizePath(prefix);
|
|
7105
7147
|
await Promise.all(
|
|
7106
|
-
[...this.sessions.keys()].filter((p) =>
|
|
7148
|
+
[...this.sessions.keys()].filter((p) => within5(p, at)).map((p) => this.commit(p))
|
|
7107
7149
|
);
|
|
7108
7150
|
}
|
|
7109
7151
|
async commitOverlapping(real, offset, length2) {
|
|
@@ -7138,10 +7180,10 @@ var MountTable = class {
|
|
|
7138
7180
|
}
|
|
7139
7181
|
forget(mount, path) {
|
|
7140
7182
|
mount.epoch++;
|
|
7141
|
-
for (const key of [...mount.attrs.keys()]) if (
|
|
7183
|
+
for (const key of [...mount.attrs.keys()]) if (within5(key, path)) mount.attrs.delete(key);
|
|
7142
7184
|
mount.lists.delete(path);
|
|
7143
7185
|
mount.lists.delete(parentOf7(path));
|
|
7144
|
-
for (const key of [...mount.lists.keys()]) if (
|
|
7186
|
+
for (const key of [...mount.lists.keys()]) if (within5(key, path)) mount.lists.delete(key);
|
|
7145
7187
|
}
|
|
7146
7188
|
async getattr(mount, path, rel2, settled = false) {
|
|
7147
7189
|
for (let round = 1; ; round++) {
|
|
@@ -7776,6 +7818,11 @@ function statJson(s) {
|
|
|
7776
7818
|
async function readdirStat(fs, dir) {
|
|
7777
7819
|
return (await fs.readdirStat(dir)).map(([name2, stat]) => [name2, stat && statJson(stat)]);
|
|
7778
7820
|
}
|
|
7821
|
+
async function usageAt(entry, path) {
|
|
7822
|
+
if (!entry.statfs) return void 0;
|
|
7823
|
+
const real = await realTarget(entry.fs, path).catch(() => path);
|
|
7824
|
+
return entry.statfs(real);
|
|
7825
|
+
}
|
|
7779
7826
|
async function storageUsage() {
|
|
7780
7827
|
const estimate = await globalThis.navigator?.storage?.estimate?.();
|
|
7781
7828
|
if (typeof estimate?.quota !== "number") return null;
|
|
@@ -7996,8 +8043,8 @@ async function guarded(entry, path, req) {
|
|
|
7996
8043
|
await guard(g, path, req, entry.cwd);
|
|
7997
8044
|
return void 0;
|
|
7998
8045
|
} catch (err) {
|
|
7999
|
-
const
|
|
8000
|
-
return req.op === "exists" &&
|
|
8046
|
+
const refusal2 = err.code === "EACCES";
|
|
8047
|
+
return req.op === "exists" && refusal2 ? json2(false) : toErrno(err);
|
|
8001
8048
|
}
|
|
8002
8049
|
}
|
|
8003
8050
|
async function createExclusive(fs, path, owner) {
|
|
@@ -8092,7 +8139,7 @@ async function dispatchOne(entry, req) {
|
|
|
8092
8139
|
if (req.op === "hold") return await holdOp(entry, path, req);
|
|
8093
8140
|
const refused2 = await guarded(entry, path, req);
|
|
8094
8141
|
if (refused2) return refused2;
|
|
8095
|
-
if (req.op === "statfs") return json2(await entry
|
|
8142
|
+
if (req.op === "statfs") return json2(await usageAt(entry, path) ?? await storageUsage());
|
|
8096
8143
|
if (entry.revoked?.(path)) return { ok: false, errno: "EIO", message: `${path} was unmounted` };
|
|
8097
8144
|
if (req.op === "write" && req.mode === 1 || UNLINKED_OPS.has(req.op)) {
|
|
8098
8145
|
const serve = async () => run(entry, await keptOr(entry, path, req.handle), req);
|
|
@@ -10776,7 +10823,7 @@ function parsePrefix(text) {
|
|
|
10776
10823
|
if (length2 < 0 || length2 > max) return void 0;
|
|
10777
10824
|
return { ...parsed2, length: length2 };
|
|
10778
10825
|
}
|
|
10779
|
-
function
|
|
10826
|
+
function within6(prefix, addr) {
|
|
10780
10827
|
if (prefix.v6 !== addr.v6) return false;
|
|
10781
10828
|
const shift = BigInt((prefix.v6 ? 128 : 32) - prefix.length);
|
|
10782
10829
|
return addr.bits >> shift === prefix.bits >> shift;
|
|
@@ -10816,9 +10863,9 @@ var Routes = class {
|
|
|
10816
10863
|
if (!addr) return "unreachable";
|
|
10817
10864
|
if (addr.v6 && addr.bits === 1n) return "loopback";
|
|
10818
10865
|
if (!addr.v6 && addr.bits >> 24n === 127n) return "loopback";
|
|
10819
|
-
if (RESERVED.some((p) =>
|
|
10866
|
+
if (RESERVED.some((p) => within6(p, addr))) return "reserved";
|
|
10820
10867
|
if (addr.v6 && !this.ipv6) return "unreachable";
|
|
10821
|
-
if (this.exit || this.table.some((p) =>
|
|
10868
|
+
if (this.exit || this.table.some((p) => within6(p, addr))) return "uplink";
|
|
10822
10869
|
return "unreachable";
|
|
10823
10870
|
}
|
|
10824
10871
|
};
|
|
@@ -10884,14 +10931,14 @@ var Resolver = class {
|
|
|
10884
10931
|
if (hit && hit.expires > this.now()) return hit.addresses;
|
|
10885
10932
|
const signal = blocking?.();
|
|
10886
10933
|
if (signal?.aborted) throw new KernelError("EINTR");
|
|
10887
|
-
let
|
|
10888
|
-
if (!
|
|
10934
|
+
let lookup3 = this.pending.get(id2);
|
|
10935
|
+
if (!lookup3) {
|
|
10889
10936
|
const abort = new AbortController();
|
|
10890
|
-
|
|
10891
|
-
this.pending.set(id2,
|
|
10892
|
-
void
|
|
10937
|
+
lookup3 = { work: this.lookup(key, asked, id2, abort.signal), abort, waiters: 0 };
|
|
10938
|
+
this.pending.set(id2, lookup3);
|
|
10939
|
+
void lookup3.work.then(() => this.pending.delete(id2));
|
|
10893
10940
|
}
|
|
10894
|
-
return waitFor(
|
|
10941
|
+
return waitFor(lookup3, signal);
|
|
10895
10942
|
}
|
|
10896
10943
|
async lookup(name2, family, id2, abandoned) {
|
|
10897
10944
|
const uplink = this.uplink;
|
|
@@ -10932,17 +10979,17 @@ var Resolver = class {
|
|
|
10932
10979
|
}
|
|
10933
10980
|
}
|
|
10934
10981
|
};
|
|
10935
|
-
function waitFor(
|
|
10936
|
-
|
|
10982
|
+
function waitFor(lookup3, signal) {
|
|
10983
|
+
lookup3.waiters++;
|
|
10937
10984
|
return new Promise((resolve2, reject) => {
|
|
10938
10985
|
const abort = () => {
|
|
10939
|
-
if (--
|
|
10986
|
+
if (--lookup3.waiters === 0) lookup3.abort.abort(new KernelError("EINTR"));
|
|
10940
10987
|
reject(new KernelError("EINTR"));
|
|
10941
10988
|
};
|
|
10942
10989
|
signal?.addEventListener("abort", abort, { once: true });
|
|
10943
|
-
void
|
|
10990
|
+
void lookup3.work.then((value) => {
|
|
10944
10991
|
if (signal?.aborted) return;
|
|
10945
|
-
|
|
10992
|
+
lookup3.waiters--;
|
|
10946
10993
|
signal?.removeEventListener("abort", abort);
|
|
10947
10994
|
resolve2(value);
|
|
10948
10995
|
});
|
|
@@ -11674,7 +11721,7 @@ function isMissing(err) {
|
|
|
11674
11721
|
if (err?.code === "ENOENT") return true;
|
|
11675
11722
|
return err instanceof Error && err.message.startsWith("ENOENT");
|
|
11676
11723
|
}
|
|
11677
|
-
function
|
|
11724
|
+
function within7(path, root) {
|
|
11678
11725
|
return path === root || path.startsWith(root.endsWith("/") ? root : `${root}/`);
|
|
11679
11726
|
}
|
|
11680
11727
|
var VfsNode = class {
|
|
@@ -11995,12 +12042,12 @@ var VfsNodes = class {
|
|
|
11995
12042
|
return node;
|
|
11996
12043
|
}
|
|
11997
12044
|
holds(prefix) {
|
|
11998
|
-
for (const path of this.byPath.keys()) if (
|
|
12045
|
+
for (const path of this.byPath.keys()) if (within7(path, prefix)) return true;
|
|
11999
12046
|
return false;
|
|
12000
12047
|
}
|
|
12001
12048
|
writes(prefix) {
|
|
12002
12049
|
for (const [path, node] of this.byPath)
|
|
12003
|
-
if (node.writers > 0 &&
|
|
12050
|
+
if (node.writers > 0 && within7(path, prefix)) return true;
|
|
12004
12051
|
return false;
|
|
12005
12052
|
}
|
|
12006
12053
|
closed(node, writable2 = false) {
|
|
@@ -12044,11 +12091,11 @@ var VfsNodes = class {
|
|
|
12044
12091
|
this.kept.delete(node);
|
|
12045
12092
|
}
|
|
12046
12093
|
async flush(path) {
|
|
12047
|
-
for (const [p, node] of this.byPath) if (
|
|
12094
|
+
for (const [p, node] of this.byPath) if (within7(p, path)) await node.serial(() => node.flush());
|
|
12048
12095
|
}
|
|
12049
12096
|
async unlinking(path) {
|
|
12050
12097
|
for (const [held, node] of [...this.byPath]) {
|
|
12051
|
-
if (!
|
|
12098
|
+
if (!within7(held, path)) continue;
|
|
12052
12099
|
await node.serial(async () => {
|
|
12053
12100
|
await Promise.all([this.keepsOnDisk || node.keep(), node.limit()]);
|
|
12054
12101
|
});
|
|
@@ -12056,14 +12103,14 @@ var VfsNodes = class {
|
|
|
12056
12103
|
}
|
|
12057
12104
|
revoke(prefix) {
|
|
12058
12105
|
for (const [path, node] of [...this.byPath]) {
|
|
12059
|
-
if (!
|
|
12106
|
+
if (!within7(path, prefix)) continue;
|
|
12060
12107
|
node.revoke();
|
|
12061
12108
|
this.forget(node);
|
|
12062
12109
|
}
|
|
12063
12110
|
}
|
|
12064
12111
|
unlinked(path) {
|
|
12065
12112
|
for (const [held, node] of [...this.byPath]) {
|
|
12066
|
-
if (!
|
|
12113
|
+
if (!within7(held, path) || this.byPath.get(held) !== node) continue;
|
|
12067
12114
|
if (!this.dropName(held, node)) this.orphan(node);
|
|
12068
12115
|
}
|
|
12069
12116
|
}
|
|
@@ -12071,8 +12118,8 @@ var VfsNodes = class {
|
|
|
12071
12118
|
if (from === to) return;
|
|
12072
12119
|
const moved2 = [];
|
|
12073
12120
|
for (const [p, node] of [...this.byPath]) {
|
|
12074
|
-
if (
|
|
12075
|
-
else if (
|
|
12121
|
+
if (within7(p, from)) moved2.push([p, node]);
|
|
12122
|
+
else if (within7(p, to) && this.byPath.get(p) === node && !this.dropName(p, node)) {
|
|
12076
12123
|
this.orphan(node);
|
|
12077
12124
|
}
|
|
12078
12125
|
}
|
|
@@ -12351,7 +12398,7 @@ function isWasmSyscall(req) {
|
|
|
12351
12398
|
var MAX_READ = 1024 * 1024;
|
|
12352
12399
|
var WRITE_ACCESS = 3;
|
|
12353
12400
|
var KEYBOARD = /* @__PURE__ */ new Set([SIG.INT, SIG.QUIT, SIG.TSTP]);
|
|
12354
|
-
var
|
|
12401
|
+
var DEFAULT_UMASK2 = 18;
|
|
12355
12402
|
function words(value) {
|
|
12356
12403
|
if (!Array.isArray(value) || !value.every((w) => typeof w === "string")) {
|
|
12357
12404
|
throw new KernelError("EINVAL");
|
|
@@ -12379,7 +12426,7 @@ var WasmProcess = class {
|
|
|
12379
12426
|
interrupt = new AbortController();
|
|
12380
12427
|
gone = new AbortController();
|
|
12381
12428
|
dying = false;
|
|
12382
|
-
umask =
|
|
12429
|
+
umask = DEFAULT_UMASK2;
|
|
12383
12430
|
cred;
|
|
12384
12431
|
execChild;
|
|
12385
12432
|
killed = false;
|
|
@@ -12401,7 +12448,7 @@ var WasmProcess = class {
|
|
|
12401
12448
|
this.fds = fds;
|
|
12402
12449
|
this.options = options;
|
|
12403
12450
|
this.inherited = options.ignored ?? 0;
|
|
12404
|
-
this.umask = options.umask ??
|
|
12451
|
+
this.umask = options.umask ?? DEFAULT_UMASK2;
|
|
12405
12452
|
this.cred = copyCred(options.cred ?? ROOT);
|
|
12406
12453
|
this.children = new ChildTable(fds, options.spawner, options.forker);
|
|
12407
12454
|
this.nodes = options.nodes ?? new VfsNodes(options.fs);
|
|
@@ -18087,7 +18134,7 @@ var Launcher = class {
|
|
|
18087
18134
|
}
|
|
18088
18135
|
}
|
|
18089
18136
|
umaskOf(pid) {
|
|
18090
|
-
return this.processes.get(pid)?.umask?.() ??
|
|
18137
|
+
return this.processes.get(pid)?.umask?.() ?? DEFAULT_UMASK2;
|
|
18091
18138
|
}
|
|
18092
18139
|
imageOf(pid) {
|
|
18093
18140
|
const members = this.jobs.list();
|
|
@@ -18597,6 +18644,111 @@ var Launcher = class {
|
|
|
18597
18644
|
}
|
|
18598
18645
|
};
|
|
18599
18646
|
|
|
18647
|
+
// src/node/loopback.ts
|
|
18648
|
+
import { lookup } from "node:dns/promises";
|
|
18649
|
+
import { isIP } from "node:net";
|
|
18650
|
+
var DEVTOOLS_PORTS = [9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229];
|
|
18651
|
+
var METADATA_V6 = [64768, 3778, 0, 0, 0, 0, 0, 596].join(":");
|
|
18652
|
+
var resolveHost = async (host) => (await lookup(host, { all: true, verbatim: true })).map((a) => a.address);
|
|
18653
|
+
function ipv4Place(address) {
|
|
18654
|
+
const [a, b] = address.split(".").map(Number);
|
|
18655
|
+
if (a === 127 || a === 0) return "loopback";
|
|
18656
|
+
if (a === 169 && b === 254) return "link-local";
|
|
18657
|
+
return void 0;
|
|
18658
|
+
}
|
|
18659
|
+
function placeOf(address) {
|
|
18660
|
+
const plain = address.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
18661
|
+
const kind = isIP(plain);
|
|
18662
|
+
if (kind === 4) return ipv4Place(plain);
|
|
18663
|
+
if (kind !== 6) return void 0;
|
|
18664
|
+
const words2 = hextets2(plain);
|
|
18665
|
+
const embedded2 = words2.slice(0, 5).every((w) => w === 0) && (words2[5] === 65535 || words2[5] === 0);
|
|
18666
|
+
if (embedded2 && (words2[5] === 65535 || words2[6] !== 0)) return ipv4Place(ipv4Of(words2));
|
|
18667
|
+
if (words2.slice(0, 7).every((w) => w === 0) && (words2[7] ?? 0) <= 1) return "loopback";
|
|
18668
|
+
if (((words2[0] ?? 0) & 65472) === 65152) return "link-local";
|
|
18669
|
+
if (words2.join(":") === METADATA_V6) return "link-local";
|
|
18670
|
+
return void 0;
|
|
18671
|
+
}
|
|
18672
|
+
function ipv4Of(words2) {
|
|
18673
|
+
const [high = 0, low = 0] = words2.slice(6);
|
|
18674
|
+
return [high >> 8, high & 255, low >> 8, low & 255].join(".");
|
|
18675
|
+
}
|
|
18676
|
+
function hextets2(address) {
|
|
18677
|
+
const dotted = /(\d+\.\d+\.\d+\.\d+)$/.exec(address)?.[1];
|
|
18678
|
+
let text = address;
|
|
18679
|
+
if (dotted) {
|
|
18680
|
+
const [a, b, c, d] = dotted.split(".").map(Number);
|
|
18681
|
+
text = `${address.slice(0, -dotted.length)}${(a << 8 | b).toString(16)}:${(c << 8 | d).toString(16)}`;
|
|
18682
|
+
}
|
|
18683
|
+
const [head = "", tail] = text.split("::");
|
|
18684
|
+
const part = (side) => side ? side.split(":").map((w) => Number.parseInt(w, 16)) : [];
|
|
18685
|
+
const left = part(head);
|
|
18686
|
+
const right = tail === void 0 ? [] : part(tail);
|
|
18687
|
+
const gap = Array(8 - left.length - right.length).fill(0);
|
|
18688
|
+
return [...left, ...gap, ...right];
|
|
18689
|
+
}
|
|
18690
|
+
function loopbackName2(host) {
|
|
18691
|
+
const name2 = host.toLowerCase().replace(/\.$/, "");
|
|
18692
|
+
return name2 === "localhost" || name2.endsWith(".localhost");
|
|
18693
|
+
}
|
|
18694
|
+
function portOf(url) {
|
|
18695
|
+
if (url.port) return Number(url.port);
|
|
18696
|
+
return url.protocol === "https:" || url.protocol === "wss:" ? 443 : 80;
|
|
18697
|
+
}
|
|
18698
|
+
function allows(policy, port) {
|
|
18699
|
+
if (Array.isArray(policy)) return policy.includes(port);
|
|
18700
|
+
return policy === true && !DEVTOOLS_PORTS.includes(port);
|
|
18701
|
+
}
|
|
18702
|
+
function refusal(url, address, place) {
|
|
18703
|
+
const where = `${address}:${portOf(url)}`;
|
|
18704
|
+
const why = place === "link-local" ? `nodeTransport refuses link-local ${where}` : `nodeTransport refuses the host's loopback ${where} (see nodeTransport({ hostLoopback }))`;
|
|
18705
|
+
return Object.assign(new Error(why), { status: 403, code: "EACCES" });
|
|
18706
|
+
}
|
|
18707
|
+
async function addressesOf(host, resolve2) {
|
|
18708
|
+
const plain = host.replace(/^\[(.*)\]$/, "$1");
|
|
18709
|
+
if (isIP(plain)) return [plain];
|
|
18710
|
+
if (loopbackName2(plain)) return ["127.0.0.1"];
|
|
18711
|
+
return resolve2(plain).catch(() => []);
|
|
18712
|
+
}
|
|
18713
|
+
async function checkDestination(target, policy, resolve2 = resolveHost) {
|
|
18714
|
+
const url = new URL(target);
|
|
18715
|
+
for (const address of await addressesOf(url.hostname, resolve2)) {
|
|
18716
|
+
const place = placeOf(address);
|
|
18717
|
+
if (!place) continue;
|
|
18718
|
+
if (place === "loopback" && allows(policy, portOf(url))) continue;
|
|
18719
|
+
throw refusal(url, address, place);
|
|
18720
|
+
}
|
|
18721
|
+
}
|
|
18722
|
+
function guarded2(check, signal) {
|
|
18723
|
+
if (!signal) return check;
|
|
18724
|
+
signal.throwIfAborted();
|
|
18725
|
+
let stop = () => {
|
|
18726
|
+
};
|
|
18727
|
+
const aborted2 = new Promise((_, reject) => {
|
|
18728
|
+
stop = () => reject(signal.reason);
|
|
18729
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
18730
|
+
});
|
|
18731
|
+
return Promise.race([check, aborted2]).finally(() => signal.removeEventListener("abort", stop));
|
|
18732
|
+
}
|
|
18733
|
+
function guardedLoopback(transport, policy, resolve2) {
|
|
18734
|
+
const open = transport.websocket?.bind(transport);
|
|
18735
|
+
return {
|
|
18736
|
+
get traits() {
|
|
18737
|
+
return transport.traits;
|
|
18738
|
+
},
|
|
18739
|
+
fetch: async (request, owner) => {
|
|
18740
|
+
await guarded2(checkDestination(request.url, policy, resolve2), request.signal);
|
|
18741
|
+
return transport.fetch(request, owner);
|
|
18742
|
+
},
|
|
18743
|
+
...open ? {
|
|
18744
|
+
websocket: async (request) => {
|
|
18745
|
+
await guarded2(checkDestination(request.url, policy, resolve2), request.signal);
|
|
18746
|
+
return open(request);
|
|
18747
|
+
}
|
|
18748
|
+
} : {}
|
|
18749
|
+
};
|
|
18750
|
+
}
|
|
18751
|
+
|
|
18600
18752
|
// src/node/memory-root.ts
|
|
18601
18753
|
var fail2 = (name2) => {
|
|
18602
18754
|
throw new DOMException(name2, name2);
|
|
@@ -18803,8 +18955,8 @@ function isMemoryRoot(handle) {
|
|
|
18803
18955
|
}
|
|
18804
18956
|
|
|
18805
18957
|
// src/node/ws-diagnose.ts
|
|
18806
|
-
import { lookup } from "node:dns/promises";
|
|
18807
|
-
import { isIP, connect as tcp } from "node:net";
|
|
18958
|
+
import { lookup as lookup2 } from "node:dns/promises";
|
|
18959
|
+
import { isIP as isIP2, connect as tcp } from "node:net";
|
|
18808
18960
|
import { connect as tls } from "node:tls";
|
|
18809
18961
|
var PROBE_MS = 3e3;
|
|
18810
18962
|
var PASSED = /* @__PURE__ */ new Set(["ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ETIMEDOUT", "ECONNRESET"]);
|
|
@@ -18815,7 +18967,7 @@ function codeOf5(e) {
|
|
|
18815
18967
|
}
|
|
18816
18968
|
function probe(secure, host, port, ms) {
|
|
18817
18969
|
return new Promise((resolve2) => {
|
|
18818
|
-
const socket = secure ? tls({ host, port, ...
|
|
18970
|
+
const socket = secure ? tls({ host, port, ...isIP2(host) ? {} : { servername: host } }) : tcp({ host, port });
|
|
18819
18971
|
const done4 = (code) => {
|
|
18820
18972
|
clearTimeout(timer);
|
|
18821
18973
|
socket.destroy();
|
|
@@ -18835,7 +18987,7 @@ async function diagnose(url, ms = PROBE_MS) {
|
|
|
18835
18987
|
const secure = at.protocol === "wss:";
|
|
18836
18988
|
const port = Number(at.port) || (secure ? 443 : 80);
|
|
18837
18989
|
try {
|
|
18838
|
-
await
|
|
18990
|
+
await lookup2(host);
|
|
18839
18991
|
} catch (e) {
|
|
18840
18992
|
return NO_NAME.has(codeOf5(e) ?? "") ? "EAI_NONAME" : void 0;
|
|
18841
18993
|
}
|
|
@@ -19684,9 +19836,10 @@ function hostfsFetchOf(options) {
|
|
|
19684
19836
|
}
|
|
19685
19837
|
};
|
|
19686
19838
|
}
|
|
19687
|
-
function nodeTransport() {
|
|
19839
|
+
function nodeTransport(options = {}) {
|
|
19688
19840
|
const transport = fetchTransport({ webSocket: true, webSocketHeaders: true, redirect: "manual" });
|
|
19689
|
-
|
|
19841
|
+
const open = { ...transport, traits: { ...transport.traits, crossOrigin: "any" } };
|
|
19842
|
+
return diagnosing(guardedLoopback(open, options.hostLoopback ?? false));
|
|
19690
19843
|
}
|
|
19691
19844
|
var TERMINATED = "the kernel is terminated";
|
|
19692
19845
|
var EXIT_GRACE_MS = 50;
|