@ai-ecoverse/slicc-kernel 1.88.1 → 1.89.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 -8
- package/dist/index.js +3 -0
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +419 -124
- package/dist/kernel-worker.js.map +3 -3
- package/dist/meta.js.map +2 -2
- package/dist/node-process-worker.js +5507 -5256
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +417 -123
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +302 -51
- package/dist/process-worker.js.map +4 -4
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -383,6 +383,14 @@ function inodeOf(path) {
|
|
|
383
383
|
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
384
384
|
return 4294967296 * (2097151 & h2) + (h1 >>> 0) || 1;
|
|
385
385
|
}
|
|
386
|
+
function redirected(of, to) {
|
|
387
|
+
return Object.assign(fsError("EXDEV", `${of} leads to the mount at ${to}`), {
|
|
388
|
+
redirect: { of: normalizePath(of), to: normalizePath(to) }
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
function redirectOf(err) {
|
|
392
|
+
return err?.redirect;
|
|
393
|
+
}
|
|
386
394
|
|
|
387
395
|
// src/fs/owners.ts
|
|
388
396
|
var ROOT_OWNER = Object.freeze({ uid: 0, gid: 0 });
|
|
@@ -476,39 +484,47 @@ var Integrity = class {
|
|
|
476
484
|
this.unknown = integrityUnknown(options);
|
|
477
485
|
this.report = report;
|
|
478
486
|
}
|
|
479
|
-
async real(path) {
|
|
487
|
+
async real(path, asked) {
|
|
480
488
|
const at = normalizePath(path);
|
|
481
489
|
const real = await this.root.realpath?.(at, true).catch(() => void 0) ?? at;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
const
|
|
486
|
-
|
|
490
|
+
if (isProtected(this.prefixes, real)) return { real, name: real };
|
|
491
|
+
const names = asked === void 0 ? [] : await namesOf(this.root, asked);
|
|
492
|
+
if (real !== at) names.push(...await namesOf(this.root, at));
|
|
493
|
+
const name2 = names.findLast((p) => isProtected(this.prefixes, p));
|
|
494
|
+
return name2 === void 0 ? void 0 : { real, name: name2 };
|
|
495
|
+
}
|
|
496
|
+
async key(path, asked) {
|
|
497
|
+
const found = await this.real(path, asked);
|
|
498
|
+
if (found === void 0) return void 0;
|
|
499
|
+
const { real, name: name2 } = found;
|
|
500
|
+
if (name2 !== real) return `${name2}\0${real}\0`;
|
|
501
|
+
if (!this.root.version) return void 0;
|
|
487
502
|
return `${real}\0${await this.root.version(real)}`;
|
|
488
503
|
}
|
|
489
|
-
async read(path, caller, plain) {
|
|
490
|
-
return (await this.readKeyed(path, caller, plain)).bytes;
|
|
504
|
+
async read(path, caller, plain, asked) {
|
|
505
|
+
return (await this.readKeyed(path, caller, plain, asked)).bytes;
|
|
491
506
|
}
|
|
492
|
-
async readKeyed(path, caller, plain) {
|
|
493
|
-
const
|
|
494
|
-
if (
|
|
495
|
-
const
|
|
507
|
+
async readKeyed(path, caller, plain, asked) {
|
|
508
|
+
const found = await this.real(path, asked);
|
|
509
|
+
if (found === void 0) return { bytes: await plain() };
|
|
510
|
+
const { real, name: name2 } = found;
|
|
511
|
+
const read = name2 !== real ? { bytes: await plain(), version: void 0 } : this.root.readVersioned ? await this.root.readVersioned(real) : { bytes: await this.root.readFileBuffer(real), version: void 0 };
|
|
496
512
|
const { bytes } = read;
|
|
497
513
|
const keyed = read.version === void 0 ? { bytes } : { bytes, key: `${real}\0${read.version}` };
|
|
498
514
|
const actual = await sha256(bytes);
|
|
499
|
-
const denial = { pid: caller.pid, uid: caller.uid, path:
|
|
515
|
+
const denial = { pid: caller.pid, uid: caller.uid, path: name2, actual };
|
|
500
516
|
const tagged = caller.tag !== void 0 ? { tag: caller.tag } : {};
|
|
501
517
|
let expected;
|
|
502
518
|
try {
|
|
503
|
-
expected = await this.expected(
|
|
519
|
+
expected = await this.expected(name2);
|
|
504
520
|
} catch {
|
|
505
521
|
this.say({ ...denial, ...tagged, op: "exec-integrity", errno: "EACCES" });
|
|
506
|
-
throw fsError("EACCES", `integrity lookup failed: ${
|
|
522
|
+
throw fsError("EACCES", `integrity lookup failed: ${name2}`);
|
|
507
523
|
}
|
|
508
524
|
if (expected === void 0) {
|
|
509
525
|
if (this.unknown === "allow") {
|
|
510
|
-
if (!this.unverified.has(
|
|
511
|
-
this.unverified.add(
|
|
526
|
+
if (!this.unverified.has(name2)) {
|
|
527
|
+
this.unverified.add(name2);
|
|
512
528
|
this.say({ ...denial, ...tagged, op: "exec-unverified", errno: "ENODATA" });
|
|
513
529
|
}
|
|
514
530
|
return keyed;
|
|
@@ -518,7 +534,12 @@ var Integrity = class {
|
|
|
518
534
|
}
|
|
519
535
|
const known = expected !== void 0 ? { expected } : {};
|
|
520
536
|
this.say({ ...denial, ...tagged, ...known, op: "exec-integrity", errno: "EACCES" });
|
|
521
|
-
throw fsError("EACCES", `integrity check failed: ${
|
|
537
|
+
throw fsError("EACCES", `integrity check failed: ${name2}`);
|
|
538
|
+
}
|
|
539
|
+
forget(path) {
|
|
540
|
+
for (const name2 of [...this.unverified]) {
|
|
541
|
+
if (path === void 0 || isProtected([path], name2)) this.unverified.delete(name2);
|
|
542
|
+
}
|
|
522
543
|
}
|
|
523
544
|
async expected(path) {
|
|
524
545
|
const answer = await this.lookup(path);
|
|
@@ -572,10 +593,10 @@ function missing(err) {
|
|
|
572
593
|
const code = err?.code;
|
|
573
594
|
return code === "ENOENT" || code === "ENOTDIR";
|
|
574
595
|
}
|
|
575
|
-
async function resolved(fs, path, follow2) {
|
|
596
|
+
async function resolved(fs, path, follow2, hops = []) {
|
|
576
597
|
let done4 = [];
|
|
577
598
|
let todo = partsOf(path);
|
|
578
|
-
for (let
|
|
599
|
+
for (let links = 0; todo.length > 0; ) {
|
|
579
600
|
const part = todo.shift();
|
|
580
601
|
if (part === "..") {
|
|
581
602
|
done4.pop();
|
|
@@ -597,13 +618,20 @@ async function resolved(fs, path, follow2) {
|
|
|
597
618
|
done4.push(part);
|
|
598
619
|
continue;
|
|
599
620
|
}
|
|
600
|
-
if (++
|
|
621
|
+
if (++links > MAX_LINKS) throw fsError("ELOOP", path);
|
|
622
|
+
hops.push(normalizePath([at, ...todo].join("/")));
|
|
601
623
|
const link2 = await fs.readlink(at);
|
|
602
624
|
if (link2.startsWith("/")) done4 = [];
|
|
603
625
|
todo = [...partsOf(link2), ...todo];
|
|
604
626
|
}
|
|
605
627
|
return `/${done4.join("/")}`;
|
|
606
628
|
}
|
|
629
|
+
async function namesOf(fs, path) {
|
|
630
|
+
const lexical2 = normalizePath(path);
|
|
631
|
+
const hops = [];
|
|
632
|
+
await resolved(fs, lexical2, true, hops).catch(() => void 0);
|
|
633
|
+
return [lexical2, ...hops];
|
|
634
|
+
}
|
|
607
635
|
var ProtectedFs = class {
|
|
608
636
|
prefixes;
|
|
609
637
|
constructor(prefixes2) {
|
|
@@ -656,8 +684,8 @@ var ProtectedFs = class {
|
|
|
656
684
|
await check(path, true);
|
|
657
685
|
return fs.utimes(path, atime, mtime);
|
|
658
686
|
},
|
|
659
|
-
async mayChange(path, follow2) {
|
|
660
|
-
await check(path, follow2);
|
|
687
|
+
async mayChange(path, follow2, whole = false) {
|
|
688
|
+
await check(path, follow2, whole);
|
|
661
689
|
},
|
|
662
690
|
async stat(path) {
|
|
663
691
|
return marked(path, await fs.stat(path));
|
|
@@ -984,6 +1012,7 @@ var OpfsFs = class {
|
|
|
984
1012
|
remote;
|
|
985
1013
|
ranged;
|
|
986
1014
|
owners = false;
|
|
1015
|
+
mounts = {};
|
|
987
1016
|
constructor(root, meta = new MemoryMeta(), channel, options = {}) {
|
|
988
1017
|
this.root = root;
|
|
989
1018
|
this.meta = sidecar(meta);
|
|
@@ -1057,6 +1086,12 @@ var OpfsFs = class {
|
|
|
1057
1086
|
trackOwners() {
|
|
1058
1087
|
this.owners = true;
|
|
1059
1088
|
}
|
|
1089
|
+
crossings(mounted) {
|
|
1090
|
+
this.mounts.mounted = mounted;
|
|
1091
|
+
}
|
|
1092
|
+
crossing(of, to) {
|
|
1093
|
+
if (this.mounts.mounted?.(to)) throw redirected(of, to);
|
|
1094
|
+
}
|
|
1060
1095
|
async hasOwner(path) {
|
|
1061
1096
|
return ownOf((await this.meta.get([path]))[0]) !== void 0;
|
|
1062
1097
|
}
|
|
@@ -1251,12 +1286,13 @@ var OpfsFs = class {
|
|
|
1251
1286
|
if (!link2) throw err;
|
|
1252
1287
|
if (link2.path === current && !follow2) return { path: current, link: link2 };
|
|
1253
1288
|
const target = `${link2.link}${current.slice(link2.path.length)}`;
|
|
1254
|
-
current = target.split("/").includes("..") ? await this.physical(parentOf3(link2.path), target, hops + 1) : resolvePath(parentOf3(link2.path), target);
|
|
1289
|
+
current = target.split("/").includes("..") ? await this.physical(parentOf3(link2.path), target, hops + 1, path) : resolvePath(parentOf3(link2.path), target);
|
|
1290
|
+
this.crossing(path, current);
|
|
1255
1291
|
}
|
|
1256
1292
|
}
|
|
1257
1293
|
throw fsError("ELOOP", path);
|
|
1258
1294
|
}
|
|
1259
|
-
async physical(base, path, used) {
|
|
1295
|
+
async physical(base, path, used, of) {
|
|
1260
1296
|
let done4 = [];
|
|
1261
1297
|
let todo = (path.startsWith("/") ? path : `${base}/${path}`).split("/").filter((p) => p !== "" && p !== ".");
|
|
1262
1298
|
for (let hops = used; todo.length > 0; ) {
|
|
@@ -1265,6 +1301,7 @@ var OpfsFs = class {
|
|
|
1265
1301
|
else if (!todo.includes("..")) done4.push(part);
|
|
1266
1302
|
else {
|
|
1267
1303
|
const at = `/${[...done4, part].join("/")}`;
|
|
1304
|
+
this.crossing(of, [at, ...todo].join("/"));
|
|
1268
1305
|
const st = await this.lstat(at);
|
|
1269
1306
|
if (!st.isSymbolicLink && !st.isDirectory) throw fsError("ENOTDIR", at);
|
|
1270
1307
|
if (!st.isSymbolicLink) done4.push(part);
|
|
@@ -2159,7 +2196,10 @@ var Perms = class {
|
|
|
2159
2196
|
function parts(path) {
|
|
2160
2197
|
return path.split("/").filter((part) => part !== "" && part !== ".");
|
|
2161
2198
|
}
|
|
2162
|
-
|
|
2199
|
+
function trustedLink(perm, links) {
|
|
2200
|
+
return links === void 0 || perm.uid === 0 || perm.uid === links;
|
|
2201
|
+
}
|
|
2202
|
+
async function walk(fs, cred, path, follow2, links) {
|
|
2163
2203
|
const perms = new Perms(fs);
|
|
2164
2204
|
await perms.learn(path);
|
|
2165
2205
|
const queue = parts(path);
|
|
@@ -2177,6 +2217,7 @@ async function walk(fs, cred, path, follow2) {
|
|
|
2177
2217
|
const perm = await perms.at(next2);
|
|
2178
2218
|
const last = queue.length === 0;
|
|
2179
2219
|
if (perm?.link !== void 0 && (!last || follow2)) {
|
|
2220
|
+
if (!trustedLink(perm, links)) return { path, perm: void 0, denied: next2, link: true };
|
|
2180
2221
|
if (++hops > MAX_LINKS4) return { path: next2, perm: void 0 };
|
|
2181
2222
|
queue.unshift(...parts(perm.link));
|
|
2182
2223
|
if (perm.link.startsWith("/")) at = "/";
|
|
@@ -2201,9 +2242,9 @@ async function finalOf(fs, walked, want, options) {
|
|
|
2201
2242
|
return st ? [permOf(st), st.isDirectory] : [perm, false];
|
|
2202
2243
|
}
|
|
2203
2244
|
async function access(fs, cred, path, want, options = {}) {
|
|
2204
|
-
const walked = await walk(fs, cred, path, options.follow !== false);
|
|
2245
|
+
const walked = await walk(fs, cred, path, options.follow !== false, options.links);
|
|
2205
2246
|
if (walked.denied !== void 0) {
|
|
2206
|
-
if (await present(fs, walked.denied, true)) return walked;
|
|
2247
|
+
if (walked.link || await present(fs, walked.denied, true)) return walked;
|
|
2207
2248
|
return { path, perm: void 0, missing: true };
|
|
2208
2249
|
}
|
|
2209
2250
|
if (!walked.perm) return { ...walked, missing: true };
|
|
@@ -2270,6 +2311,9 @@ var Created = class {
|
|
|
2270
2311
|
return this.paths.delete(normalizePath(path));
|
|
2271
2312
|
}
|
|
2272
2313
|
};
|
|
2314
|
+
function linked(g, options) {
|
|
2315
|
+
return g.links === void 0 ? options : { ...options, links: g.links };
|
|
2316
|
+
}
|
|
2273
2317
|
function deny(g, op, path, errno = "EACCES") {
|
|
2274
2318
|
const tag = g.tag === void 0 ? {} : { tag: g.tag };
|
|
2275
2319
|
g.dac.denied({ pid: g.pid, uid: g.cred.euid, op, path, errno, ...tag });
|
|
@@ -2280,8 +2324,8 @@ function ttyOpenable(g, tty) {
|
|
|
2280
2324
|
deny(g, "open", tty.name ?? "/dev/tty");
|
|
2281
2325
|
}
|
|
2282
2326
|
async function need(g, op, path, want, options = {}, shown = path) {
|
|
2283
|
-
const walked = await access(g.fs, g.cred, path, want, options);
|
|
2284
|
-
if (walked.denied !== void 0) deny(g, op, shown);
|
|
2327
|
+
const walked = await access(g.fs, g.cred, path, want, linked(g, options));
|
|
2328
|
+
if (walked.denied !== void 0) deny(g, op, walked.link ? walked.denied : shown);
|
|
2285
2329
|
return walked;
|
|
2286
2330
|
}
|
|
2287
2331
|
function entryIn(dir, path) {
|
|
@@ -2300,14 +2344,16 @@ async function inParent(g, op, path, old = false) {
|
|
|
2300
2344
|
return dir2.denied === void 0 ? stickyEntry(g, op, path, dir2) : void 0;
|
|
2301
2345
|
}
|
|
2302
2346
|
if (!old) return void await need(g, op, parentOf4(path), W_OK | X_OK, DIR, path);
|
|
2303
|
-
const dir = await access(g.fs, g.cred, parentOf4(path), W_OK | X_OK, DIR);
|
|
2347
|
+
const dir = await access(g.fs, g.cred, parentOf4(path), W_OK | X_OK, linked(g, DIR));
|
|
2304
2348
|
if (dir.denied === void 0) return stickyEntry(g, op, path, dir);
|
|
2349
|
+
if (dir.link) return deny(g, op, dir.denied);
|
|
2305
2350
|
const lookup = dir.denied === dir.path && dir.perm && permits(g.cred, dir.perm, X_OK);
|
|
2306
2351
|
if (!lookup || await present(g.fs, entryIn(dir, path), false)) deny(g, op, path);
|
|
2307
2352
|
}
|
|
2308
2353
|
async function makeIn(g, op, path) {
|
|
2309
2354
|
for (let dir = parentOf4(path); ; dir = parentOf4(dir)) {
|
|
2310
|
-
const walked = await access(g.fs, g.cred, dir, W_OK | X_OK, DIR);
|
|
2355
|
+
const walked = await access(g.fs, g.cred, dir, W_OK | X_OK, linked(g, DIR));
|
|
2356
|
+
if (walked.link) return deny(g, op, walked.denied);
|
|
2311
2357
|
if (walked.denied !== void 0) {
|
|
2312
2358
|
if (!await present(g.fs, path, true)) deny(g, op, path);
|
|
2313
2359
|
return;
|
|
@@ -6599,7 +6645,7 @@ var RemoteTransport = class {
|
|
|
6599
6645
|
finish();
|
|
6600
6646
|
throw e;
|
|
6601
6647
|
}
|
|
6602
|
-
const { status, statusText, headers, url, redirected, redirects } = head;
|
|
6648
|
+
const { status, statusText, headers, url, redirected: redirected2, redirects } = head;
|
|
6603
6649
|
const read = async () => {
|
|
6604
6650
|
if (finished) return void 0;
|
|
6605
6651
|
const reply = await this.ask({ net: "read", nid }).catch((e) => {
|
|
@@ -6616,7 +6662,7 @@ var RemoteTransport = class {
|
|
|
6616
6662
|
this.cancel(nid);
|
|
6617
6663
|
};
|
|
6618
6664
|
return {
|
|
6619
|
-
...
|
|
6665
|
+
...redirected2 ? { url, redirected: redirected2 } : {},
|
|
6620
6666
|
...redirects ? { redirects } : {},
|
|
6621
6667
|
status,
|
|
6622
6668
|
statusText,
|
|
@@ -7641,14 +7687,14 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7641
7687
|
const own = await userDir(dir);
|
|
7642
7688
|
return own?.has(path.slice(slash + 1)) ? owned4(synthetic(false, path), dir) : void 0;
|
|
7643
7689
|
}
|
|
7644
|
-
async function
|
|
7690
|
+
async function linked2(path) {
|
|
7645
7691
|
return await virtual(path) ?? virtual(await followLinks(fs, path));
|
|
7646
7692
|
}
|
|
7647
7693
|
async function stat(path, real) {
|
|
7648
7694
|
try {
|
|
7649
7695
|
return await real(path);
|
|
7650
7696
|
} catch (err) {
|
|
7651
|
-
const found = missing3(err) ? await
|
|
7697
|
+
const found = missing3(err) ? await linked2(path) : void 0;
|
|
7652
7698
|
if (found) return found;
|
|
7653
7699
|
throw err;
|
|
7654
7700
|
}
|
|
@@ -7660,7 +7706,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7660
7706
|
try {
|
|
7661
7707
|
return await fs.readFileBuffer(path);
|
|
7662
7708
|
} catch (err) {
|
|
7663
|
-
if (missing3(err) && (await
|
|
7709
|
+
if (missing3(err) && (await linked2(path))?.isFile) return new Uint8Array(0);
|
|
7664
7710
|
throw err;
|
|
7665
7711
|
}
|
|
7666
7712
|
},
|
|
@@ -7668,7 +7714,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7668
7714
|
link: (from, to, follow2) => fs.link(from, to, follow2),
|
|
7669
7715
|
links: (path) => mayLink(fs, path),
|
|
7670
7716
|
async exists(path) {
|
|
7671
|
-
return await fs.exists(path) || await
|
|
7717
|
+
return await fs.exists(path) || await linked2(path) !== void 0;
|
|
7672
7718
|
},
|
|
7673
7719
|
stat: (path) => stat(path, (p) => fs.stat(p)),
|
|
7674
7720
|
lstat: (path) => stat(path, (p) => fs.lstat(p)),
|
|
@@ -9093,6 +9139,7 @@ var MountTable = class {
|
|
|
9093
9139
|
return { quota: st.blocks * st.bsize, usage: (st.blocks - st.bfree) * st.bsize };
|
|
9094
9140
|
}
|
|
9095
9141
|
wrap(base) {
|
|
9142
|
+
base.crossings?.((path) => this.locate(normalizePath(path)) !== void 0);
|
|
9096
9143
|
return new MountFs(this, base);
|
|
9097
9144
|
}
|
|
9098
9145
|
};
|
|
@@ -9116,6 +9163,37 @@ var MountFs = class {
|
|
|
9116
9163
|
writable(mount, path) {
|
|
9117
9164
|
if (readonly(mount)) throw errnoError("EROFS", path);
|
|
9118
9165
|
}
|
|
9166
|
+
async through(path) {
|
|
9167
|
+
const real = normalizePath(path);
|
|
9168
|
+
if (this.at(real)) return real;
|
|
9169
|
+
try {
|
|
9170
|
+
await this.base.stat(parentOf7(real));
|
|
9171
|
+
return real;
|
|
9172
|
+
} catch (err) {
|
|
9173
|
+
const moved2 = redirectOf(err);
|
|
9174
|
+
return moved2 ? normalizePath(moved2.to + real.slice(moved2.of.length)) : real;
|
|
9175
|
+
}
|
|
9176
|
+
}
|
|
9177
|
+
async across(from, to, redirects) {
|
|
9178
|
+
const moved2 = [await this.through(from), await this.through(to)];
|
|
9179
|
+
const same = moved2[0] === normalizePath(from) && moved2[1] === normalizePath(to);
|
|
9180
|
+
if (same || redirects >= MAX_LINKS7) throw errnoError("EXDEV", `${from} -> ${to}`);
|
|
9181
|
+
return moved2;
|
|
9182
|
+
}
|
|
9183
|
+
async based(paths, redirects, run2, again) {
|
|
9184
|
+
try {
|
|
9185
|
+
return await run2();
|
|
9186
|
+
} catch (err) {
|
|
9187
|
+
const moved2 = redirectOf(err);
|
|
9188
|
+
if (!moved2) throw err;
|
|
9189
|
+
if (redirects >= MAX_LINKS7) throw errnoError("ELOOP", paths[0]);
|
|
9190
|
+
const at = paths.map((path) => {
|
|
9191
|
+
const real = normalizePath(path);
|
|
9192
|
+
return within6(real, moved2.of) ? normalizePath(moved2.to + real.slice(moved2.of.length)) : real;
|
|
9193
|
+
});
|
|
9194
|
+
return again(at, redirects + 1);
|
|
9195
|
+
}
|
|
9196
|
+
}
|
|
9119
9197
|
async follow(path, hops = 0, create = false) {
|
|
9120
9198
|
const found = this.at(path);
|
|
9121
9199
|
if (!found) return path;
|
|
@@ -9163,10 +9241,17 @@ var MountFs = class {
|
|
|
9163
9241
|
async readFile(path) {
|
|
9164
9242
|
return new TextDecoder().decode(await this.readFileBuffer(path));
|
|
9165
9243
|
}
|
|
9166
|
-
async readFileBuffer(path) {
|
|
9244
|
+
async readFileBuffer(path, redirects = 0) {
|
|
9167
9245
|
const real = await this.follow(path);
|
|
9168
9246
|
const found = this.at(real);
|
|
9169
|
-
if (!found)
|
|
9247
|
+
if (!found) {
|
|
9248
|
+
return this.based(
|
|
9249
|
+
[real],
|
|
9250
|
+
redirects,
|
|
9251
|
+
() => this.base.readFileBuffer(real),
|
|
9252
|
+
([to], n) => this.readFileBuffer(to, n)
|
|
9253
|
+
);
|
|
9254
|
+
}
|
|
9170
9255
|
for (let attempt = 1; ; attempt++) {
|
|
9171
9256
|
try {
|
|
9172
9257
|
return await this.readWhole(found.mount, real, found.rel);
|
|
@@ -9205,10 +9290,18 @@ var MountFs = class {
|
|
|
9205
9290
|
}
|
|
9206
9291
|
return concat4(chunks, total);
|
|
9207
9292
|
}
|
|
9208
|
-
async writeFile(path, content, owner) {
|
|
9293
|
+
async writeFile(path, content, owner, redirects = 0) {
|
|
9209
9294
|
const real = await this.follow(path, 0, true);
|
|
9210
9295
|
const found = this.at(real);
|
|
9211
|
-
if (!found)
|
|
9296
|
+
if (!found) {
|
|
9297
|
+
const write = () => this.base.writeFile(real, content, owner);
|
|
9298
|
+
return this.based(
|
|
9299
|
+
[real],
|
|
9300
|
+
redirects,
|
|
9301
|
+
write,
|
|
9302
|
+
([to], n) => this.writeFile(to, content, owner, n)
|
|
9303
|
+
);
|
|
9304
|
+
}
|
|
9212
9305
|
const { mount, rel: rel2 } = found;
|
|
9213
9306
|
this.writable(mount, real);
|
|
9214
9307
|
const bytes = typeof content === "string" ? new TextEncoder().encode(content) : content;
|
|
@@ -9242,10 +9335,18 @@ var MountFs = class {
|
|
|
9242
9335
|
this.table.forget(mount, real);
|
|
9243
9336
|
}
|
|
9244
9337
|
}
|
|
9245
|
-
async pread(path, offset, length2, version) {
|
|
9338
|
+
async pread(path, offset, length2, version, redirects = 0) {
|
|
9246
9339
|
const real = await this.follow(path);
|
|
9247
9340
|
const found = this.at(real);
|
|
9248
|
-
|
|
9341
|
+
const { pread } = this.base;
|
|
9342
|
+
if (!found && pread) {
|
|
9343
|
+
return this.based(
|
|
9344
|
+
[real],
|
|
9345
|
+
redirects,
|
|
9346
|
+
() => pread.call(this.base, real, offset, length2),
|
|
9347
|
+
([to], n) => this.pread(to, offset, length2, version, n)
|
|
9348
|
+
);
|
|
9349
|
+
}
|
|
9249
9350
|
if (!found) return (await this.base.readFileBuffer(real)).slice(offset, offset + length2);
|
|
9250
9351
|
const { mount, rel: rel2 } = found;
|
|
9251
9352
|
if ((await this.table.getattr(mount, real, rel2)).kind === "directory") {
|
|
@@ -9292,10 +9393,18 @@ var MountFs = class {
|
|
|
9292
9393
|
);
|
|
9293
9394
|
}
|
|
9294
9395
|
}
|
|
9295
|
-
async pwrite(path, offset, bytes, transfer = false) {
|
|
9396
|
+
async pwrite(path, offset, bytes, transfer = false, redirects = 0) {
|
|
9296
9397
|
const real = await this.follow(path, 0, true);
|
|
9297
9398
|
const found = this.at(real);
|
|
9298
|
-
|
|
9399
|
+
const { pwrite } = this.base;
|
|
9400
|
+
if (!found && pwrite) {
|
|
9401
|
+
return this.based(
|
|
9402
|
+
[real],
|
|
9403
|
+
redirects,
|
|
9404
|
+
() => pwrite.call(this.base, real, offset, bytes),
|
|
9405
|
+
([to], n) => this.pwrite(to, offset, bytes, transfer, n)
|
|
9406
|
+
);
|
|
9407
|
+
}
|
|
9299
9408
|
if (!found)
|
|
9300
9409
|
return this.base.writeFile(
|
|
9301
9410
|
real,
|
|
@@ -9335,10 +9444,18 @@ var MountFs = class {
|
|
|
9335
9444
|
await mount.conn.call({ op: "write", fh, offset: offset + at, bytes: part }, [part.buffer]);
|
|
9336
9445
|
}
|
|
9337
9446
|
}
|
|
9338
|
-
async truncate(path, size) {
|
|
9447
|
+
async truncate(path, size, redirects = 0) {
|
|
9339
9448
|
const real = await this.follow(path);
|
|
9340
9449
|
const found = this.at(real);
|
|
9341
|
-
|
|
9450
|
+
const { truncate } = this.base;
|
|
9451
|
+
if (!found && truncate) {
|
|
9452
|
+
return this.based(
|
|
9453
|
+
[real],
|
|
9454
|
+
redirects,
|
|
9455
|
+
() => truncate.call(this.base, real, size),
|
|
9456
|
+
([to], n) => this.truncate(to, size, n)
|
|
9457
|
+
);
|
|
9458
|
+
}
|
|
9342
9459
|
if (!found?.mount.caps.ranges) {
|
|
9343
9460
|
return this.writeFile(real, resized(await this.readFileBuffer(real), size));
|
|
9344
9461
|
}
|
|
@@ -9354,8 +9471,15 @@ var MountFs = class {
|
|
|
9354
9471
|
this.table.forget(mount, real);
|
|
9355
9472
|
}
|
|
9356
9473
|
}
|
|
9357
|
-
async exists(path) {
|
|
9358
|
-
if (!this.at(path))
|
|
9474
|
+
async exists(path, redirects = 0) {
|
|
9475
|
+
if (!this.at(path)) {
|
|
9476
|
+
return this.based(
|
|
9477
|
+
[path],
|
|
9478
|
+
redirects,
|
|
9479
|
+
() => this.base.exists(path),
|
|
9480
|
+
([to], n) => this.exists(to, n)
|
|
9481
|
+
);
|
|
9482
|
+
}
|
|
9359
9483
|
try {
|
|
9360
9484
|
await this.stat(path);
|
|
9361
9485
|
return true;
|
|
@@ -9365,9 +9489,16 @@ var MountFs = class {
|
|
|
9365
9489
|
throw err;
|
|
9366
9490
|
}
|
|
9367
9491
|
}
|
|
9368
|
-
async lstat(path) {
|
|
9492
|
+
async lstat(path, redirects = 0) {
|
|
9369
9493
|
const found = this.at(path);
|
|
9370
|
-
if (!found)
|
|
9494
|
+
if (!found) {
|
|
9495
|
+
return this.based(
|
|
9496
|
+
[path],
|
|
9497
|
+
redirects,
|
|
9498
|
+
() => this.base.lstat(path),
|
|
9499
|
+
([to], n) => this.lstat(to, n)
|
|
9500
|
+
);
|
|
9501
|
+
}
|
|
9371
9502
|
const real = normalizePath(path);
|
|
9372
9503
|
if (this.table.writing(real)?.truncated) await this.table.commit(real);
|
|
9373
9504
|
return this.statWriting(
|
|
@@ -9380,9 +9511,15 @@ var MountFs = class {
|
|
|
9380
9511
|
const ends = (this.table.writing(real)?.extents ?? []).map(([, end]) => end);
|
|
9381
9512
|
return statOf({ ...attr2, size: Math.max(attr2.size, ...ends) }, real, mount);
|
|
9382
9513
|
}
|
|
9383
|
-
async stat(path) {
|
|
9514
|
+
async stat(path, redirects = 0) {
|
|
9384
9515
|
const real = await this.follow(path);
|
|
9385
|
-
|
|
9516
|
+
if (this.at(real)) return this.lstat(real);
|
|
9517
|
+
return this.based(
|
|
9518
|
+
[real],
|
|
9519
|
+
redirects,
|
|
9520
|
+
() => this.base.stat(real),
|
|
9521
|
+
([to], n) => this.stat(to, n)
|
|
9522
|
+
);
|
|
9386
9523
|
}
|
|
9387
9524
|
async entries(path) {
|
|
9388
9525
|
const real = await this.follow(path);
|
|
@@ -9394,12 +9531,26 @@ var MountFs = class {
|
|
|
9394
9531
|
list: await this.table.readdir(found.mount, real, found.rel)
|
|
9395
9532
|
};
|
|
9396
9533
|
}
|
|
9397
|
-
async readdir(path) {
|
|
9398
|
-
if (!this.at(path))
|
|
9534
|
+
async readdir(path, redirects = 0) {
|
|
9535
|
+
if (!this.at(path)) {
|
|
9536
|
+
return this.based(
|
|
9537
|
+
[path],
|
|
9538
|
+
redirects,
|
|
9539
|
+
() => this.base.readdir(path),
|
|
9540
|
+
([to], n) => this.readdir(to, n)
|
|
9541
|
+
);
|
|
9542
|
+
}
|
|
9399
9543
|
return (await this.entries(path)).list.map((e) => e.name);
|
|
9400
9544
|
}
|
|
9401
|
-
async readdirStat(path) {
|
|
9402
|
-
if (!this.at(path))
|
|
9545
|
+
async readdirStat(path, redirects = 0) {
|
|
9546
|
+
if (!this.at(path)) {
|
|
9547
|
+
return this.based(
|
|
9548
|
+
[path],
|
|
9549
|
+
redirects,
|
|
9550
|
+
() => this.base.readdirStat(path),
|
|
9551
|
+
([to], n) => this.readdirStat(to, n)
|
|
9552
|
+
);
|
|
9553
|
+
}
|
|
9403
9554
|
const { real, mount, list } = await this.entries(path);
|
|
9404
9555
|
return Promise.all(
|
|
9405
9556
|
list.map(async (entry) => {
|
|
@@ -9411,9 +9562,16 @@ var MountFs = class {
|
|
|
9411
9562
|
})
|
|
9412
9563
|
);
|
|
9413
9564
|
}
|
|
9414
|
-
async mkdir(path, options = {}) {
|
|
9565
|
+
async mkdir(path, options = {}, redirects = 0) {
|
|
9415
9566
|
const found = this.at(path);
|
|
9416
|
-
if (!found)
|
|
9567
|
+
if (!found) {
|
|
9568
|
+
return this.based(
|
|
9569
|
+
[path],
|
|
9570
|
+
redirects,
|
|
9571
|
+
() => this.base.mkdir(path, options),
|
|
9572
|
+
([to], n) => this.mkdir(to, options, n)
|
|
9573
|
+
);
|
|
9574
|
+
}
|
|
9417
9575
|
const { mount, rel: rel2 } = found;
|
|
9418
9576
|
const real = normalizePath(path);
|
|
9419
9577
|
this.writable(mount, real);
|
|
@@ -9438,11 +9596,18 @@ var MountFs = class {
|
|
|
9438
9596
|
await mount.conn.call({ op: "mkdir", path: sub, ...made2 });
|
|
9439
9597
|
}
|
|
9440
9598
|
}
|
|
9441
|
-
async rm(path, options = {}) {
|
|
9599
|
+
async rm(path, options = {}, redirects = 0) {
|
|
9442
9600
|
const found = this.at(path);
|
|
9443
9601
|
if (!found && options.recursive && this.table.under(normalizePath(path)))
|
|
9444
9602
|
return this.rmAround(normalizePath(path), options);
|
|
9445
|
-
if (!found)
|
|
9603
|
+
if (!found) {
|
|
9604
|
+
return this.based(
|
|
9605
|
+
[path],
|
|
9606
|
+
redirects,
|
|
9607
|
+
() => this.base.rm(path, options),
|
|
9608
|
+
([to], n) => this.rm(to, options, n)
|
|
9609
|
+
);
|
|
9610
|
+
}
|
|
9446
9611
|
const { mount, rel: rel2 } = found;
|
|
9447
9612
|
const real = normalizePath(path);
|
|
9448
9613
|
if (rel2 === "/" && options.recursive) await this.rmEach(real, mount, rel2, options);
|
|
@@ -9483,11 +9648,22 @@ var MountFs = class {
|
|
|
9483
9648
|
}
|
|
9484
9649
|
throw first ?? errnoError("EBUSY", `${path} holds a mount point`);
|
|
9485
9650
|
}
|
|
9486
|
-
async rename(from, to) {
|
|
9651
|
+
async rename(from, to, redirects = 0) {
|
|
9487
9652
|
const a = this.at(from);
|
|
9488
9653
|
const b = this.at(to);
|
|
9489
|
-
if (!a && !b)
|
|
9490
|
-
|
|
9654
|
+
if (!a && !b) {
|
|
9655
|
+
return this.based(
|
|
9656
|
+
[from, to],
|
|
9657
|
+
redirects,
|
|
9658
|
+
() => this.base.rename(from, to),
|
|
9659
|
+
([f, t], n) => this.rename(f, t, n)
|
|
9660
|
+
);
|
|
9661
|
+
}
|
|
9662
|
+
if (!a || !b) {
|
|
9663
|
+
const [f, t] = await this.across(from, to, redirects);
|
|
9664
|
+
return this.rename(f, t, redirects + 1);
|
|
9665
|
+
}
|
|
9666
|
+
if (a.mount !== b.mount) throw errnoError("EXDEV", `${from} -> ${to}`);
|
|
9491
9667
|
this.writable(a.mount, normalizePath(to));
|
|
9492
9668
|
await this.table.commitUnder(from);
|
|
9493
9669
|
await this.table.commitUnder(to);
|
|
@@ -9528,9 +9704,17 @@ var MountFs = class {
|
|
|
9528
9704
|
this.table.forget(a.mount, normalizePath(to));
|
|
9529
9705
|
}
|
|
9530
9706
|
}
|
|
9531
|
-
async symlink(target, path, owner) {
|
|
9707
|
+
async symlink(target, path, owner, redirects = 0) {
|
|
9532
9708
|
const found = this.at(path);
|
|
9533
|
-
if (!found)
|
|
9709
|
+
if (!found) {
|
|
9710
|
+
const make = () => this.base.symlink(target, path, owner);
|
|
9711
|
+
return this.based(
|
|
9712
|
+
[path],
|
|
9713
|
+
redirects,
|
|
9714
|
+
make,
|
|
9715
|
+
([to], n) => this.symlink(target, to, owner, n)
|
|
9716
|
+
);
|
|
9717
|
+
}
|
|
9534
9718
|
this.writable(found.mount, normalizePath(path));
|
|
9535
9719
|
if (!found.mount.caps.symlinks)
|
|
9536
9720
|
throw errnoError("EPERM", `${path}: this file system has no symlinks`);
|
|
@@ -9540,8 +9724,11 @@ var MountFs = class {
|
|
|
9540
9724
|
await found.mount.conn.call({ op: "symlink", target, path: found.rel, ...made2 });
|
|
9541
9725
|
}
|
|
9542
9726
|
async realpath(path, follow2) {
|
|
9543
|
-
|
|
9544
|
-
|
|
9727
|
+
const { realpath: realpath2 } = this.base;
|
|
9728
|
+
if (this.at(path) || !realpath2) throw errnoError("ENOSYS", path);
|
|
9729
|
+
const real = await realpath2.call(this.base, path, follow2).catch((err) => {
|
|
9730
|
+
throw redirectOf(err) ? errnoError("ENOSYS", path) : err;
|
|
9731
|
+
});
|
|
9545
9732
|
if (this.at(real)) throw errnoError("ENOSYS", path);
|
|
9546
9733
|
return real;
|
|
9547
9734
|
}
|
|
@@ -9563,17 +9750,30 @@ var MountFs = class {
|
|
|
9563
9750
|
}
|
|
9564
9751
|
return out;
|
|
9565
9752
|
}
|
|
9566
|
-
async readlink(path) {
|
|
9753
|
+
async readlink(path, redirects = 0) {
|
|
9567
9754
|
const found = this.at(path);
|
|
9568
|
-
if (!found)
|
|
9755
|
+
if (!found) {
|
|
9756
|
+
return this.based(
|
|
9757
|
+
[path],
|
|
9758
|
+
redirects,
|
|
9759
|
+
() => this.base.readlink(path),
|
|
9760
|
+
([to], n) => this.readlink(to, n)
|
|
9761
|
+
);
|
|
9762
|
+
}
|
|
9569
9763
|
return await found.mount.conn.call({ op: "readlink", path: found.rel });
|
|
9570
9764
|
}
|
|
9571
|
-
async chown(path, change) {
|
|
9765
|
+
async chown(path, change, redirects = 0) {
|
|
9572
9766
|
const real = change.follow === false || change.kind === "new" ? path : await this.follow(path);
|
|
9573
9767
|
const found = this.at(real);
|
|
9574
9768
|
if (found) return this.chownMounted(found, normalizePath(real), change);
|
|
9575
|
-
|
|
9576
|
-
|
|
9769
|
+
const { chown: chown2 } = this.base;
|
|
9770
|
+
if (!chown2) throw errnoError("EPERM", path);
|
|
9771
|
+
return this.based(
|
|
9772
|
+
[real],
|
|
9773
|
+
redirects,
|
|
9774
|
+
() => chown2.call(this.base, real, change),
|
|
9775
|
+
([to], n) => this.chown(to, change, n)
|
|
9776
|
+
);
|
|
9577
9777
|
}
|
|
9578
9778
|
async chownMounted(found, real, change) {
|
|
9579
9779
|
const { mount, rel: rel2 } = found;
|
|
@@ -9593,24 +9793,47 @@ var MountFs = class {
|
|
|
9593
9793
|
...Object.fromEntries(attrs.filter(([, value]) => value !== void 0))
|
|
9594
9794
|
});
|
|
9595
9795
|
}
|
|
9596
|
-
async chmod(path, mode) {
|
|
9796
|
+
async chmod(path, mode, redirects = 0) {
|
|
9597
9797
|
const real = await this.follow(path);
|
|
9598
9798
|
const found = this.at(real);
|
|
9599
|
-
if (!found)
|
|
9799
|
+
if (!found) {
|
|
9800
|
+
return this.based(
|
|
9801
|
+
[real],
|
|
9802
|
+
redirects,
|
|
9803
|
+
() => this.base.chmod(real, mode),
|
|
9804
|
+
([to], n) => this.chmod(to, mode, n)
|
|
9805
|
+
);
|
|
9806
|
+
}
|
|
9600
9807
|
this.writable(found.mount, real);
|
|
9601
9808
|
if (!found.mount.caps.chmod) return;
|
|
9602
9809
|
this.table.forget(found.mount, real);
|
|
9603
9810
|
await found.mount.conn.call({ op: "setattr", path: found.rel, mode });
|
|
9604
9811
|
}
|
|
9605
|
-
async utimes(path, atime, mtime) {
|
|
9812
|
+
async utimes(path, atime, mtime, redirects = 0) {
|
|
9606
9813
|
const real = await this.follow(path);
|
|
9607
9814
|
const found = this.at(real);
|
|
9608
|
-
if (!found)
|
|
9815
|
+
if (!found) {
|
|
9816
|
+
const set2 = () => this.base.utimes(real, atime, mtime);
|
|
9817
|
+
return this.based(
|
|
9818
|
+
[real],
|
|
9819
|
+
redirects,
|
|
9820
|
+
set2,
|
|
9821
|
+
([to], n) => this.utimes(to, atime, mtime, n)
|
|
9822
|
+
);
|
|
9823
|
+
}
|
|
9609
9824
|
await this.setMtime(found, real, mtime);
|
|
9610
9825
|
}
|
|
9611
|
-
async lutimes(path, atime, mtime) {
|
|
9826
|
+
async lutimes(path, atime, mtime, redirects = 0) {
|
|
9612
9827
|
const found = this.at(path);
|
|
9613
|
-
if (!found)
|
|
9828
|
+
if (!found) {
|
|
9829
|
+
const set2 = () => lutimesOf(this.base, path, atime, mtime);
|
|
9830
|
+
return this.based(
|
|
9831
|
+
[path],
|
|
9832
|
+
redirects,
|
|
9833
|
+
set2,
|
|
9834
|
+
([to], n) => this.lutimes(to, atime, mtime, n)
|
|
9835
|
+
);
|
|
9836
|
+
}
|
|
9614
9837
|
const real = normalizePath(path);
|
|
9615
9838
|
if (!found.mount.caps.linkTimes && (await this.lstat(real)).isSymbolicLink) {
|
|
9616
9839
|
throw errnoError("EOPNOTSUPP", path);
|
|
@@ -9829,7 +10052,8 @@ async function run(entry, path, req) {
|
|
|
9829
10052
|
function guardOf(entry) {
|
|
9830
10053
|
const cred = entry.dac && entry.cred?.();
|
|
9831
10054
|
if (!cred || !entry.dac) return void 0;
|
|
9832
|
-
|
|
10055
|
+
const links = entry.links === void 0 ? {} : { links: entry.links };
|
|
10056
|
+
return { fs: entry.fs, cred, pid: entry.pid ?? 0, dac: entry.dac, ...links };
|
|
9833
10057
|
}
|
|
9834
10058
|
var FOLLOWING = /* @__PURE__ */ new Set(["exists", "stat", "chown", "statfs"]);
|
|
9835
10059
|
var LOOKS = /* @__PURE__ */ new Set(["exists", "stat", "lstat"]);
|
|
@@ -9890,9 +10114,15 @@ async function holdOp(entry, path, req) {
|
|
|
9890
10114
|
entry.hold?.(path, on, open, void 0, req.handle);
|
|
9891
10115
|
return done;
|
|
9892
10116
|
}
|
|
10117
|
+
async function followed(g, path) {
|
|
10118
|
+
const st = await g.fs.lstat(path).catch(() => void 0);
|
|
10119
|
+
if (st?.isSymbolicLink && !trustedLink(permOf(st), g.links)) deny(g, "follow", path);
|
|
10120
|
+
return done;
|
|
10121
|
+
}
|
|
9893
10122
|
async function accessOp(entry, path, req) {
|
|
9894
10123
|
const g = guardOf(entry);
|
|
9895
10124
|
if (!g) return done;
|
|
10125
|
+
if (req.arg2 === "follow") return followed(g, path);
|
|
9896
10126
|
const open = req.arg2 === "open";
|
|
9897
10127
|
const cred = open || req.arg2 === "eaccess" ? g.cred : realIds(g.cred);
|
|
9898
10128
|
const options = { follow: req.nofollow !== true, ...open ? { directory: false } : {} };
|
|
@@ -9915,15 +10145,18 @@ var CHANGING = /* @__PURE__ */ new Set([
|
|
|
9915
10145
|
"lchown"
|
|
9916
10146
|
]);
|
|
9917
10147
|
var CONTENT = /* @__PURE__ */ new Set(["write", "pwrite", "truncate"]);
|
|
10148
|
+
var REMOVING = /* @__PURE__ */ new Set(["unlink", "rmdir", "rm", "rename"]);
|
|
9918
10149
|
async function mayChange(entry, path, req) {
|
|
9919
10150
|
const { mayChange: mayChange2 } = entry.fs;
|
|
9920
10151
|
if (!mayChange2) return;
|
|
9921
10152
|
const { op } = req;
|
|
9922
10153
|
if (CONTENT.has(op) && req.handle === void 0) return mayChange2.call(entry.fs, path, true);
|
|
9923
10154
|
if (!CHANGING.has(op)) return;
|
|
9924
|
-
|
|
10155
|
+
const follow2 = op === "utimes" || op === "chmod" || op === "chown";
|
|
10156
|
+
await mayChange2.call(entry.fs, path, follow2, REMOVING.has(op));
|
|
9925
10157
|
if (op === "rename" || op === "link") {
|
|
9926
|
-
|
|
10158
|
+
const to = entry.fs.resolvePath(entry.cwd, req.arg2 ?? "");
|
|
10159
|
+
await mayChange2.call(entry.fs, to, false, op === "rename");
|
|
9927
10160
|
}
|
|
9928
10161
|
}
|
|
9929
10162
|
async function guarded(entry, path, req) {
|
|
@@ -10616,7 +10849,7 @@ function mountTable(mounts = []) {
|
|
|
10616
10849
|
}
|
|
10617
10850
|
|
|
10618
10851
|
// src/version.ts
|
|
10619
|
-
var KERNEL_VERSION = true ? "1.
|
|
10852
|
+
var KERNEL_VERSION = true ? "1.89.0" : "0.0.0-dev";
|
|
10620
10853
|
var OS_RELEASE = "6.0.0-slicc";
|
|
10621
10854
|
function procVersion() {
|
|
10622
10855
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -13387,7 +13620,7 @@ var WasmProcess = class {
|
|
|
13387
13620
|
const { guard: guard2 } = this.options;
|
|
13388
13621
|
const inherited2 = req.orphan || req.contents !== void 0 || req.handle !== void 0;
|
|
13389
13622
|
if (!guard2 || inherited2 || req.pin !== void 0) return;
|
|
13390
|
-
const g = { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
|
|
13623
|
+
const g = { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid, links: guard2.links };
|
|
13391
13624
|
if (req.exclusive) return inParent(g, "open", req.path);
|
|
13392
13625
|
if (req.created && guard2.created?.take(req.path)) return;
|
|
13393
13626
|
const access2 = req.flags & WRITE_ACCESS;
|
|
@@ -13443,7 +13676,7 @@ var WasmProcess = class {
|
|
|
13443
13676
|
}
|
|
13444
13677
|
guarded() {
|
|
13445
13678
|
const { guard: guard2 } = this.options;
|
|
13446
|
-
return guard2 && { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
|
|
13679
|
+
return guard2 && { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid, links: guard2.links };
|
|
13447
13680
|
}
|
|
13448
13681
|
ttyOwner() {
|
|
13449
13682
|
return { uid: this.cred.euid, gid: this.cred.egid, mode: TTY_MODE };
|
|
@@ -14169,6 +14402,7 @@ function processInit(opts, sab, umask, cred, lane) {
|
|
|
14169
14402
|
umask,
|
|
14170
14403
|
cred,
|
|
14171
14404
|
...opts.owners ? { owners: true } : {},
|
|
14405
|
+
...opts.links !== void 0 ? { links: true } : {},
|
|
14172
14406
|
...opts.ppid !== void 0 ? { ppid: opts.ppid } : {}
|
|
14173
14407
|
};
|
|
14174
14408
|
if (opts.program.abi === "js") {
|
|
@@ -14196,6 +14430,7 @@ function holdingToken(opts, holds, caller) {
|
|
|
14196
14430
|
return mintSyncFsToken({
|
|
14197
14431
|
...opts.owners ? caller : {},
|
|
14198
14432
|
...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
|
|
14433
|
+
...opts.links !== void 0 ? { links: opts.links } : {},
|
|
14199
14434
|
...opts.fresh ? { fresh: (path) => opts.fresh?.(path, caller.umask()) } : {},
|
|
14200
14435
|
fs: opts.fs,
|
|
14201
14436
|
cwd: opts.cwd,
|
|
@@ -14209,6 +14444,9 @@ function holdingToken(opts, holds, caller) {
|
|
|
14209
14444
|
renamed: (from, to) => holds.renamed(from, to)
|
|
14210
14445
|
});
|
|
14211
14446
|
}
|
|
14447
|
+
function linksOf(opts) {
|
|
14448
|
+
return opts.links === void 0 ? {} : { links: opts.links };
|
|
14449
|
+
}
|
|
14212
14450
|
function clipboardName(opts) {
|
|
14213
14451
|
return opts.program.abi === "js" ? {} : { clipboardName: opts.argv0 };
|
|
14214
14452
|
}
|
|
@@ -14220,7 +14458,7 @@ function processOptions(opts, header3, hooks, created3) {
|
|
|
14220
14458
|
...opts.outputFilter ? { outputFilter: opts.outputFilter } : {},
|
|
14221
14459
|
...opts.clipboard ? { clipboard: opts.clipboard, ...clipboardName(opts) } : {},
|
|
14222
14460
|
...opts.readonlyAt ? { readonlyAt: opts.readonlyAt } : {},
|
|
14223
|
-
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
|
|
14461
|
+
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3, ...linksOf(opts) } } : {},
|
|
14224
14462
|
...opts.identity ? { identity: opts.identity } : {},
|
|
14225
14463
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
14226
14464
|
...opts.settling ? { settling: opts.settling } : {},
|
|
@@ -14266,6 +14504,7 @@ function threadInit(opts, program, sab, cred, thread, main) {
|
|
|
14266
14504
|
sab,
|
|
14267
14505
|
cred: copyCred(cred),
|
|
14268
14506
|
owners: opts.owners === true,
|
|
14507
|
+
...opts.links !== void 0 ? { links: true } : {},
|
|
14269
14508
|
...opts.ppid !== void 0 ? { ppid: opts.ppid } : {},
|
|
14270
14509
|
thread,
|
|
14271
14510
|
signals: main
|
|
@@ -17566,6 +17805,9 @@ var SUDO_SOURCE = [
|
|
|
17566
17805
|
].join("\n");
|
|
17567
17806
|
|
|
17568
17807
|
// src/launcher.ts
|
|
17808
|
+
function linksOf2(req) {
|
|
17809
|
+
return req.links === void 0 ? {} : { links: req.links };
|
|
17810
|
+
}
|
|
17569
17811
|
var COMMAND2 = /^\/(?:usr\/)?bin\/([^/]+)$/;
|
|
17570
17812
|
var PACKAGE_ROOT = /^(.*\/node_modules\/(?:@[^/]+\/)?[^/]+)\//;
|
|
17571
17813
|
var ENV_REFERENCE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
|
|
@@ -17741,6 +17983,7 @@ var Launcher = class {
|
|
|
17741
17983
|
warned = /* @__PURE__ */ new Set();
|
|
17742
17984
|
compiled = /* @__PURE__ */ new Map();
|
|
17743
17985
|
texts = /* @__PURE__ */ new Map();
|
|
17986
|
+
revocations = 0;
|
|
17744
17987
|
integrity;
|
|
17745
17988
|
scannedFs;
|
|
17746
17989
|
get scanned() {
|
|
@@ -17753,6 +17996,7 @@ var Launcher = class {
|
|
|
17753
17996
|
described = /* @__PURE__ */ new Map();
|
|
17754
17997
|
creds = /* @__PURE__ */ new Map();
|
|
17755
17998
|
tags = /* @__PURE__ */ new Map();
|
|
17999
|
+
links = /* @__PURE__ */ new Map();
|
|
17756
18000
|
freshModules = new FreshModules();
|
|
17757
18001
|
granted = /* @__PURE__ */ new Map();
|
|
17758
18002
|
users;
|
|
@@ -18055,14 +18299,16 @@ var Launcher = class {
|
|
|
18055
18299
|
}
|
|
18056
18300
|
const path = this.fs.resolvePath(cwd, file);
|
|
18057
18301
|
const glue = await followLinks(this.base, path);
|
|
18058
|
-
const
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
const
|
|
18302
|
+
const asked = glue === path ? {} : { asked: path };
|
|
18303
|
+
const linked2 = COMMAND2.exec(glue)?.[1];
|
|
18304
|
+
if (linked2 !== void 0) {
|
|
18305
|
+
const found = await this.resolve(`/bin/${linked2}`, argv0, cwd);
|
|
18306
|
+
const target = found && { ...found, ...asked };
|
|
18307
|
+
const byPath = !COMMAND2.test(path) && (await this.commands()).get(linked2)?.argv0Path === true;
|
|
18062
18308
|
return target && byPath ? { ...target, argv0: path } : target;
|
|
18063
18309
|
}
|
|
18064
18310
|
const own = await this.commandAt(glue, scope);
|
|
18065
|
-
if (own) return own.script ? void 0 : targetOf(own);
|
|
18311
|
+
if (own) return own.script ? void 0 : { ...targetOf(own), ...asked };
|
|
18066
18312
|
const head = await this.head(glue);
|
|
18067
18313
|
if (!head) return void 0;
|
|
18068
18314
|
if (isWasm(head)) {
|
|
@@ -18070,13 +18316,14 @@ var Launcher = class {
|
|
|
18070
18316
|
abi: "wasi",
|
|
18071
18317
|
glue,
|
|
18072
18318
|
wasm: glue,
|
|
18073
|
-
argv0: baseName(argv0 || file).replace(/\.wasm$/, "")
|
|
18319
|
+
argv0: baseName(argv0 || file).replace(/\.wasm$/, ""),
|
|
18320
|
+
...asked
|
|
18074
18321
|
};
|
|
18075
18322
|
}
|
|
18076
18323
|
if (interpreter(head) !== "node") return void 0;
|
|
18077
18324
|
const wasm = modulePath(glue);
|
|
18078
18325
|
if (!await this.base.exists(wasm)) return void 0;
|
|
18079
|
-
return { abi: "emscripten", glue, wasm, argv0: baseName(argv0 || file) };
|
|
18326
|
+
return { abi: "emscripten", glue, wasm, argv0: baseName(argv0 || file), ...asked };
|
|
18080
18327
|
}
|
|
18081
18328
|
async head(path) {
|
|
18082
18329
|
try {
|
|
@@ -18094,6 +18341,8 @@ var Launcher = class {
|
|
|
18094
18341
|
async interpreted(file, argv, cwd, scope, depth = 0) {
|
|
18095
18342
|
const command = await this.scriptCommand(file, cwd, scope);
|
|
18096
18343
|
const script = command?.script ?? this.fs.resolvePath(cwd, file);
|
|
18344
|
+
const byPath = command && file.includes("/") && !COMMAND2.test(file);
|
|
18345
|
+
const named = byPath ? { [script]: this.fs.resolvePath(cwd, file) } : {};
|
|
18097
18346
|
const head = await this.head(script);
|
|
18098
18347
|
if (!head) return void 0;
|
|
18099
18348
|
const binfmt = isWasm(head) ? void 0 : binfmtOf(await this.interpreters(scope), script);
|
|
@@ -18116,7 +18365,8 @@ var Launcher = class {
|
|
|
18116
18365
|
target: withScriptEnv(inner.target, command),
|
|
18117
18366
|
via,
|
|
18118
18367
|
sources,
|
|
18119
|
-
...bins.length > 0 ? { bins } : {}
|
|
18368
|
+
...bins.length > 0 ? { bins } : {},
|
|
18369
|
+
asked: { ...inner.asked, ...named }
|
|
18120
18370
|
};
|
|
18121
18371
|
}
|
|
18122
18372
|
const target = withScriptEnv(found, command);
|
|
@@ -18125,7 +18375,8 @@ var Launcher = class {
|
|
|
18125
18375
|
args: [...target.prefix ?? [], ...passed],
|
|
18126
18376
|
via: [interp],
|
|
18127
18377
|
sources: [script],
|
|
18128
|
-
...command?.bin ? { bins: [script] } : {}
|
|
18378
|
+
...command?.bin ? { bins: [script] } : {},
|
|
18379
|
+
asked: named
|
|
18129
18380
|
};
|
|
18130
18381
|
}
|
|
18131
18382
|
async plan(file, argv, cwd, scope, argv0) {
|
|
@@ -18139,7 +18390,14 @@ var Launcher = class {
|
|
|
18139
18390
|
async mayExec(cred, req, planned) {
|
|
18140
18391
|
const { dac } = this;
|
|
18141
18392
|
if (!dac) return;
|
|
18142
|
-
const g = {
|
|
18393
|
+
const g = {
|
|
18394
|
+
fs: this.fs,
|
|
18395
|
+
cred,
|
|
18396
|
+
pid: req.pid,
|
|
18397
|
+
dac,
|
|
18398
|
+
tag: req.tag,
|
|
18399
|
+
links: this.links.get(req.pid)
|
|
18400
|
+
};
|
|
18143
18401
|
const byPath = (file) => file.includes("/") && !COMMAND2.test(file);
|
|
18144
18402
|
if (byPath(req.file)) {
|
|
18145
18403
|
const path = this.fs.resolvePath(req.cwd, req.file);
|
|
@@ -18296,8 +18554,8 @@ var Launcher = class {
|
|
|
18296
18554
|
readFile: (path) => this.integrity ? this.text(path, KERNEL_CALLER) : fs.readFile(path)
|
|
18297
18555
|
});
|
|
18298
18556
|
}
|
|
18299
|
-
async cacheKey(path) {
|
|
18300
|
-
const verified = await this.integrity?.key(path);
|
|
18557
|
+
async cacheKey(path, asked) {
|
|
18558
|
+
const verified = await this.integrity?.key(path, asked);
|
|
18301
18559
|
if (verified !== void 0) return verified;
|
|
18302
18560
|
const st = await this.base.stat(path);
|
|
18303
18561
|
return `${path}:${st.size}:${st.mtime.getTime()}`;
|
|
@@ -18306,30 +18564,31 @@ var Launcher = class {
|
|
|
18306
18564
|
const plain = () => fs.readFileBuffer(path);
|
|
18307
18565
|
return this.integrity ? this.integrity.read(path, caller, plain) : plain();
|
|
18308
18566
|
}
|
|
18309
|
-
keyed(path, caller) {
|
|
18567
|
+
keyed(path, caller, asked) {
|
|
18310
18568
|
const plain = async () => this.base.readFileBuffer(path);
|
|
18311
|
-
return this.integrity ? this.integrity.readKeyed(path, caller, plain) : plain().then((bytes) => ({ bytes }));
|
|
18569
|
+
return this.integrity ? this.integrity.readKeyed(path, caller, plain, asked) : plain().then((bytes) => ({ bytes }));
|
|
18312
18570
|
}
|
|
18313
18571
|
cached(cache, key, load) {
|
|
18314
18572
|
const hit = cache.get(key);
|
|
18315
18573
|
if (hit !== void 0) return hit;
|
|
18574
|
+
const revocations = this.revocations;
|
|
18316
18575
|
const loading2 = load();
|
|
18317
18576
|
const found = loading2.then(({ value }) => value);
|
|
18318
18577
|
cache.set(key, found);
|
|
18319
|
-
|
|
18320
|
-
(
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
()
|
|
18326
|
-
);
|
|
18578
|
+
const drop = () => {
|
|
18579
|
+
if (cache.get(key) === found) cache.delete(key);
|
|
18580
|
+
};
|
|
18581
|
+
loading2.then((done4) => {
|
|
18582
|
+
if (done4.key === key || done4.key === void 0 && !key.includes("\0")) return;
|
|
18583
|
+
drop();
|
|
18584
|
+
if (done4.key !== void 0 && revocations === this.revocations) cache.set(done4.key, found);
|
|
18585
|
+
}, drop);
|
|
18327
18586
|
return found;
|
|
18328
18587
|
}
|
|
18329
|
-
async module(path, caller) {
|
|
18330
|
-
const key = await this.cacheKey(path);
|
|
18588
|
+
async module(path, caller, asked) {
|
|
18589
|
+
const key = await this.cacheKey(path, asked);
|
|
18331
18590
|
return this.cached(this.compiled, key, async () => {
|
|
18332
|
-
const { bytes, key: read } = await this.keyed(path, caller);
|
|
18591
|
+
const { bytes, key: read } = await this.keyed(path, caller, asked);
|
|
18333
18592
|
const memory = importedMemory(bytes);
|
|
18334
18593
|
const foreign = foreignImports(bytes);
|
|
18335
18594
|
const compiled = await WebAssembly.compile(bytes);
|
|
@@ -18338,22 +18597,30 @@ var Launcher = class {
|
|
|
18338
18597
|
}
|
|
18339
18598
|
async checkedSources(planned, caller) {
|
|
18340
18599
|
const { target } = planned;
|
|
18341
|
-
const files = [
|
|
18600
|
+
const files = [
|
|
18601
|
+
target.wasm,
|
|
18602
|
+
target.glue,
|
|
18603
|
+
target.imports,
|
|
18604
|
+
target.asked,
|
|
18605
|
+
...planned.sources ?? []
|
|
18606
|
+
];
|
|
18342
18607
|
const manifests = /* @__PURE__ */ new Set();
|
|
18343
18608
|
for (const file of files) {
|
|
18344
18609
|
const root = file === void 0 ? void 0 : PACKAGE_ROOT.exec(file)?.[1];
|
|
18345
18610
|
if (root !== void 0) manifests.add(`${root}/package.json`);
|
|
18346
18611
|
}
|
|
18347
|
-
for (const source of planned.sources ?? [])
|
|
18612
|
+
for (const source of planned.sources ?? []) {
|
|
18613
|
+
await this.text(source, caller, planned.asked?.[source]);
|
|
18614
|
+
}
|
|
18348
18615
|
for (const manifest of manifests) {
|
|
18349
18616
|
if (await this.base.exists(manifest)) await this.text(manifest, caller);
|
|
18350
18617
|
}
|
|
18351
18618
|
}
|
|
18352
|
-
async text(path, caller) {
|
|
18619
|
+
async text(path, caller, asked) {
|
|
18353
18620
|
if (!this.integrity) return this.base.readFile(path);
|
|
18354
|
-
const key = await this.cacheKey(path);
|
|
18621
|
+
const key = await this.cacheKey(path, asked);
|
|
18355
18622
|
return this.cached(this.texts, key, async () => {
|
|
18356
|
-
const { bytes, key: read } = await this.keyed(path, caller);
|
|
18623
|
+
const { bytes, key: read } = await this.keyed(path, caller, asked);
|
|
18357
18624
|
return { value: new TextDecoder().decode(bytes), key: read };
|
|
18358
18625
|
});
|
|
18359
18626
|
}
|
|
@@ -18370,17 +18637,18 @@ var Launcher = class {
|
|
|
18370
18637
|
if (target.abi === "js" && target.wasm === SUDO_PATH) {
|
|
18371
18638
|
return { abi: "js", glue: SUDO_SOURCE, path: SUDO_PATH };
|
|
18372
18639
|
}
|
|
18640
|
+
const { asked } = target;
|
|
18373
18641
|
if (target.abi === "js") {
|
|
18374
|
-
return { abi: "js", glue: await this.text(target.wasm, caller), path: target.wasm };
|
|
18642
|
+
return { abi: "js", glue: await this.text(target.wasm, caller, asked), path: target.wasm };
|
|
18375
18643
|
}
|
|
18376
18644
|
if (target.abi !== "wasi") {
|
|
18377
18645
|
const [glue, { module: module2 }] = await Promise.all([
|
|
18378
|
-
this.text(target.glue, caller),
|
|
18379
|
-
this.module(target.wasm, caller)
|
|
18646
|
+
this.text(target.glue, caller, asked),
|
|
18647
|
+
this.module(target.wasm, caller, asked && modulePath(asked))
|
|
18380
18648
|
]);
|
|
18381
18649
|
return { glue, module: module2 };
|
|
18382
18650
|
}
|
|
18383
|
-
const { module, memory, foreign } = await this.module(target.wasm, caller);
|
|
18651
|
+
const { module, memory, foreign } = await this.module(target.wasm, caller, asked);
|
|
18384
18652
|
const names = env.SLICC_WASM_BACKTRACE === "1" ? await this.names(target.wasm, module) : void 0;
|
|
18385
18653
|
const imports = target.imports ? await this.text(target.imports, caller) : void 0;
|
|
18386
18654
|
return {
|
|
@@ -18421,6 +18689,10 @@ var Launcher = class {
|
|
|
18421
18689
|
const inherited2 = req.ppid !== void 0 ? this.scrubs.get(req.ppid) : void 0;
|
|
18422
18690
|
return req.scrub ? [...inherited2 ?? [], req.scrub] : inherited2;
|
|
18423
18691
|
}
|
|
18692
|
+
marks(pid, req) {
|
|
18693
|
+
if (req.tag !== void 0) this.tags.set(pid, req.tag);
|
|
18694
|
+
if (req.links !== void 0) this.links.set(pid, req.links);
|
|
18695
|
+
}
|
|
18424
18696
|
start(req) {
|
|
18425
18697
|
this.sampling();
|
|
18426
18698
|
if (req.pgid !== void 0 && this.jobs.sessionOf(req.pgid) === void 0) {
|
|
@@ -18453,6 +18725,7 @@ var Launcher = class {
|
|
|
18453
18725
|
cred: req.cred,
|
|
18454
18726
|
...this.owners && req.program.abi === "wasi" ? { fresh: (path, umask) => this.freshModules.add(path, umask, pid) } : {},
|
|
18455
18727
|
...this.owners ? { owners: true } : {},
|
|
18728
|
+
...linksOf2(req),
|
|
18456
18729
|
sealed: this.sealed,
|
|
18457
18730
|
...scrubs ? { outputFilter: (file) => scrubbedAll(file, scrubs) } : {},
|
|
18458
18731
|
clipboard: this.clipboard,
|
|
@@ -18500,7 +18773,7 @@ var Launcher = class {
|
|
|
18500
18773
|
if (scrubs) this.scrubs.set(pid, scrubs);
|
|
18501
18774
|
const { cred } = req;
|
|
18502
18775
|
this.creds.set(pid, () => handle.cred?.() ?? copyCred(cred));
|
|
18503
|
-
|
|
18776
|
+
this.marks(pid, req);
|
|
18504
18777
|
if (req.ppid !== void 0 && this.controlsJobs(req.ppid)) this.settling.started(pid, req.ppid);
|
|
18505
18778
|
this.jobs.add(pid, req.ppid, (sig) => handle.signal(sig), terminal);
|
|
18506
18779
|
if (req.exec && req.ppid !== void 0) this.jobs.exec(req.ppid, pid, true);
|
|
@@ -18553,6 +18826,7 @@ var Launcher = class {
|
|
|
18553
18826
|
this.childTimes.delete(pid);
|
|
18554
18827
|
this.creds.delete(pid);
|
|
18555
18828
|
this.tags.delete(pid);
|
|
18829
|
+
this.links.delete(pid);
|
|
18556
18830
|
this.granted.delete(pid);
|
|
18557
18831
|
}
|
|
18558
18832
|
reaped(pid, parent) {
|
|
@@ -18728,6 +19002,7 @@ var Launcher = class {
|
|
|
18728
19002
|
umask: this.umaskOf(ppid),
|
|
18729
19003
|
cred,
|
|
18730
19004
|
tag: this.tagOf(ppid),
|
|
19005
|
+
links: grant ? grant.cred.euid : this.links.get(ppid),
|
|
18731
19006
|
...group,
|
|
18732
19007
|
...exec
|
|
18733
19008
|
});
|
|
@@ -18789,7 +19064,8 @@ var Launcher = class {
|
|
|
18789
19064
|
blocked: this.blockedBy(ppid),
|
|
18790
19065
|
umask: this.umaskOf(ppid),
|
|
18791
19066
|
cred: this.credOf(ppid),
|
|
18792
|
-
tag: this.tagOf(ppid)
|
|
19067
|
+
tag: this.tagOf(ppid),
|
|
19068
|
+
links: this.links.get(ppid)
|
|
18793
19069
|
})
|
|
18794
19070
|
);
|
|
18795
19071
|
}
|
|
@@ -18969,6 +19245,23 @@ var Launcher = class {
|
|
|
18969
19245
|
}
|
|
18970
19246
|
};
|
|
18971
19247
|
}
|
|
19248
|
+
async revokeIntegrity(path) {
|
|
19249
|
+
if (path !== void 0 && (typeof path !== "string" || !path.startsWith("/"))) {
|
|
19250
|
+
throw new TypeError("integrity.revoke takes an absolute path");
|
|
19251
|
+
}
|
|
19252
|
+
if (!this.integrity) return;
|
|
19253
|
+
const at = path === void 0 ? void 0 : normalizePath(path);
|
|
19254
|
+
const real = at && await this.base.realpath?.(at, true).catch(() => void 0);
|
|
19255
|
+
const roots = [at, real].filter((p) => p !== void 0);
|
|
19256
|
+
this.revocations++;
|
|
19257
|
+
const hit = (key) => key.includes("\0") && (at === void 0 || key.split("\0").slice(0, 2).some((part) => isProtected(roots, part)));
|
|
19258
|
+
for (const cache of [this.compiled, this.texts]) {
|
|
19259
|
+
for (const key of [...cache.keys()]) if (hit(key)) cache.delete(key);
|
|
19260
|
+
}
|
|
19261
|
+
if (at === void 0) this.integrity.forget();
|
|
19262
|
+
for (const root of roots) this.integrity.forget(root);
|
|
19263
|
+
this.resetCatalogs();
|
|
19264
|
+
}
|
|
18972
19265
|
attest(path) {
|
|
18973
19266
|
return attest(this.rootFs, path, {
|
|
18974
19267
|
users: this.usersMode,
|
|
@@ -19466,7 +19759,8 @@ var ATTEST_OPS = /* @__PURE__ */ new Set([
|
|
|
19466
19759
|
"attest",
|
|
19467
19760
|
"watch-files",
|
|
19468
19761
|
"unwatch-files",
|
|
19469
|
-
"chmod"
|
|
19762
|
+
"chmod",
|
|
19763
|
+
"integrity-revoke"
|
|
19470
19764
|
]);
|
|
19471
19765
|
function isAttestRequest(req) {
|
|
19472
19766
|
return ATTEST_OPS.has(req.op);
|
|
@@ -19484,6 +19778,7 @@ function attestOps(port) {
|
|
|
19484
19778
|
return async (l, req) => {
|
|
19485
19779
|
if (req.op === "attest") return l.attest(req.path);
|
|
19486
19780
|
if (req.op === "chmod") return l.fs.chmod(req.path, modeOption(req.mode)).then(() => true);
|
|
19781
|
+
if (req.op === "integrity-revoke") return l.revokeIntegrity(req.path).then(() => true);
|
|
19487
19782
|
if (req.op === "unwatch-files") {
|
|
19488
19783
|
watches.get(req.watch)?.();
|
|
19489
19784
|
return watches.delete(req.watch);
|