@ai-ecoverse/slicc-kernel 1.72.0 → 1.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.js +13 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +79 -16
- package/dist/kernel-worker.js.map +2 -2
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +74 -15
- package/dist/node.js.map +2 -2
- package/dist/process-worker.js.map +2 -2
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -361,7 +361,17 @@ async function chownAs(fs, cred, path, change) {
|
|
|
361
361
|
}
|
|
362
362
|
|
|
363
363
|
// src/fs/protect.ts
|
|
364
|
-
|
|
364
|
+
function protectInit(protection) {
|
|
365
|
+
const writers = [...writerTags(protection)];
|
|
366
|
+
return { paths: [...protection.paths], ...writers.length > 0 ? { writers } : {} };
|
|
367
|
+
}
|
|
368
|
+
function writerTags(protection) {
|
|
369
|
+
const writers = protection?.writers ?? [];
|
|
370
|
+
if (!Array.isArray(writers) || writers.some((tag) => typeof tag !== "string" || tag === "")) {
|
|
371
|
+
throw new TypeError("protect.writers must be a list of process tags");
|
|
372
|
+
}
|
|
373
|
+
return new Set(writers);
|
|
374
|
+
}
|
|
365
375
|
function protectedPrefixes(paths) {
|
|
366
376
|
return [...new Set(paths.map((p) => normalizePath(p)))];
|
|
367
377
|
}
|
|
@@ -873,6 +883,9 @@ var OpfsFs = class {
|
|
|
873
883
|
protect(prefixes2) {
|
|
874
884
|
this.guarded = prefixes2;
|
|
875
885
|
}
|
|
886
|
+
unguarded() {
|
|
887
|
+
return Object.create(this, { guarded: { value: [] } });
|
|
888
|
+
}
|
|
876
889
|
refuse(path, holding = false) {
|
|
877
890
|
if (isProtected(this.guarded, path) || holding && holdsProtected(this.guarded, path)) {
|
|
878
891
|
throw fsError("EROFS", path);
|
|
@@ -1042,15 +1055,15 @@ var OpfsFs = class {
|
|
|
1042
1055
|
}
|
|
1043
1056
|
dirTimes = /* @__PURE__ */ new Map();
|
|
1044
1057
|
dirDirty = /* @__PURE__ */ new Set();
|
|
1045
|
-
|
|
1058
|
+
flushing = {};
|
|
1046
1059
|
touch(...dirs) {
|
|
1047
1060
|
const now = Date.now();
|
|
1048
1061
|
for (const dir of dirs) {
|
|
1049
1062
|
this.dirTimes.set(dir, now);
|
|
1050
1063
|
this.dirDirty.add(dir);
|
|
1051
1064
|
}
|
|
1052
|
-
this.
|
|
1053
|
-
this.
|
|
1065
|
+
this.flushing.dir ??= Promise.resolve().then(() => this.flushDirTimes()).catch(() => void 0).finally(() => {
|
|
1066
|
+
this.flushing.dir = void 0;
|
|
1054
1067
|
});
|
|
1055
1068
|
}
|
|
1056
1069
|
async flushDirTimes() {
|
|
@@ -3821,6 +3834,12 @@ var CLIENT_CHECKS = {
|
|
|
3821
3834
|
readlink: (g, at) => searchable(g, "readlink", at(0), false),
|
|
3822
3835
|
exists: (g, at) => searchable(g, "exists", at(0), true)
|
|
3823
3836
|
};
|
|
3837
|
+
function clientFs(l, tag, self, req) {
|
|
3838
|
+
if (!FS_METHODS.includes(req.method)) {
|
|
3839
|
+
throw new Error(`unknown file system call ${req.method}`);
|
|
3840
|
+
}
|
|
3841
|
+
return fsCall(l.fsFor(tag), req.method, req.args, ownerFor(l, self), guardFor(l, self, tag));
|
|
3842
|
+
}
|
|
3824
3843
|
async function fsCall(fs, method, args, owner, g) {
|
|
3825
3844
|
const path = (i) => fs.resolvePath("/", String(args[i]));
|
|
3826
3845
|
if (g) {
|
|
@@ -4108,10 +4127,7 @@ function serveClient(port, host) {
|
|
|
4108
4127
|
case "ps":
|
|
4109
4128
|
return { result: processes(l, self) };
|
|
4110
4129
|
case "fs":
|
|
4111
|
-
|
|
4112
|
-
throw new Error(`unknown file system call ${req.method}`);
|
|
4113
|
-
}
|
|
4114
|
-
return fsCall(l.processFs, req.method, req.args, ownerFor(l, self), guard2(l));
|
|
4130
|
+
return clientFs(l, host.tag, self, req);
|
|
4115
4131
|
case "watch":
|
|
4116
4132
|
case "unwatch":
|
|
4117
4133
|
return watchOp(l, req, watches, send, guard2(l));
|
|
@@ -15880,6 +15896,10 @@ var Launcher = class {
|
|
|
15880
15896
|
fs;
|
|
15881
15897
|
processFs;
|
|
15882
15898
|
prefixes;
|
|
15899
|
+
writerTags;
|
|
15900
|
+
unguardedRoot;
|
|
15901
|
+
writers;
|
|
15902
|
+
unlinkOwnerOption;
|
|
15883
15903
|
base;
|
|
15884
15904
|
createWorker;
|
|
15885
15905
|
modulesDir;
|
|
@@ -15997,7 +16017,7 @@ var Launcher = class {
|
|
|
15997
16017
|
this.nodes = new VfsNodes(fs, (path) => this.released(path));
|
|
15998
16018
|
this.nodes.keepsOnDisk = true;
|
|
15999
16019
|
this.openFiles.add(this.nodes);
|
|
16000
|
-
const holders = [this.held,
|
|
16020
|
+
const holders = [this.held, this.openFiles];
|
|
16001
16021
|
this.unlinked = new UnlinkedKeeper(
|
|
16002
16022
|
fs,
|
|
16003
16023
|
{ [Symbol.iterator]: () => holders.flatMap((set2) => [...set2]).values() },
|
|
@@ -16010,7 +16030,12 @@ var Launcher = class {
|
|
|
16010
16030
|
}
|
|
16011
16031
|
);
|
|
16012
16032
|
this.fs = this.unlinked.wrap(keepingOpen(fs, this.nodes));
|
|
16013
|
-
|
|
16033
|
+
this.writerTags = writerTags(options.protect);
|
|
16034
|
+
this.unlinkOwnerOption = options.unlinkOwner;
|
|
16035
|
+
if (this.writerTags.size > 0 && options.fs.protect && !options.fs.unguarded) {
|
|
16036
|
+
throw new TypeError("protect.writers needs a root file system with an unguarded view");
|
|
16037
|
+
}
|
|
16038
|
+
this.unguardedRoot = options.fs.unguarded?.() ?? options.fs;
|
|
16014
16039
|
this.prefixes = protectedPrefixes(options.protect?.paths ?? []);
|
|
16015
16040
|
this.processFs = this.prefixes.length > 0 ? new ProtectedFs(this.prefixes).view(this.fs) : this.fs;
|
|
16016
16041
|
options.fs.protect?.(this.prefixes);
|
|
@@ -16334,6 +16359,7 @@ var Launcher = class {
|
|
|
16334
16359
|
throw fsError("ESRCH", `no process group ${req.pgid}`);
|
|
16335
16360
|
}
|
|
16336
16361
|
const pid = this.nextPid++;
|
|
16362
|
+
const stack = this.stackFor(req.tag);
|
|
16337
16363
|
const terminal = req.fds.stdioTerminal();
|
|
16338
16364
|
const decided = req.decided ?? Promise.resolve(true);
|
|
16339
16365
|
const count = (byParent) => {
|
|
@@ -16364,8 +16390,8 @@ var Launcher = class {
|
|
|
16364
16390
|
env: req.env,
|
|
16365
16391
|
cwd: req.cwd,
|
|
16366
16392
|
fds: req.fds,
|
|
16367
|
-
fs:
|
|
16368
|
-
...this.prefixes.length > 0 ? { readonlyAt: (path) => isProtected(this.prefixes, path) } : {},
|
|
16393
|
+
fs: stack.fs,
|
|
16394
|
+
...this.prefixes.length > 0 && !stack.writer ? { readonlyAt: (path) => isProtected(this.prefixes, path) } : {},
|
|
16369
16395
|
createWorker: this.createWorker,
|
|
16370
16396
|
onError: req.report,
|
|
16371
16397
|
spawner: this.spawner(pid, req.report),
|
|
@@ -16380,9 +16406,9 @@ var Launcher = class {
|
|
|
16380
16406
|
}),
|
|
16381
16407
|
sudo: (call, signal) => this.sudo(pid, call, signal),
|
|
16382
16408
|
openFiles: this.openFiles,
|
|
16383
|
-
nodes:
|
|
16409
|
+
nodes: stack.nodes,
|
|
16384
16410
|
held: this.held,
|
|
16385
|
-
unlinkGate:
|
|
16411
|
+
unlinkGate: stack.unlinked.gate,
|
|
16386
16412
|
statfs: (path) => this.mounts.statfs(path),
|
|
16387
16413
|
mounts: () => this.mounts.list(),
|
|
16388
16414
|
mount: (call, signal) => this.processMount(pid, call, signal),
|
|
@@ -16683,6 +16709,7 @@ var Launcher = class {
|
|
|
16683
16709
|
released(path) {
|
|
16684
16710
|
const at = normalizePath(path);
|
|
16685
16711
|
this.unlinked.closed(at);
|
|
16712
|
+
this.writers?.unlinked.closed(at);
|
|
16686
16713
|
const open = [...this.openFiles].some((nodes) => nodes.writes(at)) || heldUnder(this.held, at);
|
|
16687
16714
|
if (!open) void this.mounts.commit(at).catch(() => void 0);
|
|
16688
16715
|
}
|
|
@@ -17001,13 +17028,49 @@ var Launcher = class {
|
|
|
17001
17028
|
...account.umask !== void 0 ? { umask: account.umask } : {}
|
|
17002
17029
|
};
|
|
17003
17030
|
}
|
|
17031
|
+
fsFor(tag) {
|
|
17032
|
+
return this.stackFor(tag).fs;
|
|
17033
|
+
}
|
|
17034
|
+
isWriter(tag) {
|
|
17035
|
+
return tag !== void 0 && this.prefixes.length > 0 && this.writerTags.has(tag);
|
|
17036
|
+
}
|
|
17037
|
+
stackFor(tag) {
|
|
17038
|
+
if (!this.isWriter(tag)) {
|
|
17039
|
+
return { fs: this.processFs, nodes: this.nodes, unlinked: this.unlinked, writer: false };
|
|
17040
|
+
}
|
|
17041
|
+
this.writers ??= this.writerStack();
|
|
17042
|
+
return this.writers;
|
|
17043
|
+
}
|
|
17044
|
+
writerStack() {
|
|
17045
|
+
const fs = withCommandDirs(
|
|
17046
|
+
this.watchers.wrap(this.mounts.wrap(this.unguardedRoot)),
|
|
17047
|
+
async () => new Set((await this.commands()).keys()),
|
|
17048
|
+
(dir) => this.userCommandDir(dir),
|
|
17049
|
+
this.owners
|
|
17050
|
+
);
|
|
17051
|
+
const nodes = new VfsNodes(fs, (path) => this.released(path));
|
|
17052
|
+
nodes.keepsOnDisk = true;
|
|
17053
|
+
this.openFiles.add(nodes);
|
|
17054
|
+
const unlinked = new UnlinkedKeeper(
|
|
17055
|
+
fs,
|
|
17056
|
+
{ [Symbol.iterator]: () => [this.held, this.openFiles].flatMap((set2) => [...set2]).values() },
|
|
17057
|
+
(path) => this.mountRoot(path),
|
|
17058
|
+
{
|
|
17059
|
+
locks: webLocks(),
|
|
17060
|
+
busy: (path) => [...this.openFiles].some((open) => open.holds(path)),
|
|
17061
|
+
owner: this.unlinkOwnerOption,
|
|
17062
|
+
...this.owners ? { dirOwner: { uid: 0, gid: 0, mode: 448 } } : {}
|
|
17063
|
+
}
|
|
17064
|
+
);
|
|
17065
|
+
return { fs: unlinked.wrap(keepingOpen(fs, nodes)), nodes, unlinked, writer: true };
|
|
17066
|
+
}
|
|
17004
17067
|
async starting(argv, dir, account, tag) {
|
|
17005
17068
|
this.resetCatalogs();
|
|
17006
17069
|
const scope = account.uid === 0 ? "" : pnpmHomeOf(account, this.pnpmHome);
|
|
17007
17070
|
const start2 = dir ?? "/";
|
|
17008
17071
|
const cwd = await physicalPathAsync(this.base, start2.startsWith("/") ? start2 : `/${start2}`);
|
|
17009
17072
|
const [file = ""] = argv;
|
|
17010
|
-
if (!await this.base.exists(cwd)) await this.
|
|
17073
|
+
if (!await this.base.exists(cwd)) await this.stackFor(tag).fs.mkdir(cwd, { recursive: true });
|
|
17011
17074
|
const planned = await this.plan(file, argv, cwd, scope);
|
|
17012
17075
|
await this.mayExec(credOf(account), { file, cwd, pid: 0, tag }, planned);
|
|
17013
17076
|
return { cwd, file, planned };
|
|
@@ -17270,7 +17333,7 @@ function hostOptions(req, port, sealed) {
|
|
|
17270
17333
|
...req.hostname !== void 0 ? { hostname: req.hostname } : {},
|
|
17271
17334
|
...req.users !== void 0 ? { users: req.users } : {},
|
|
17272
17335
|
...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {},
|
|
17273
|
-
...req.protect ? { protect:
|
|
17336
|
+
...req.protect ? { protect: protectInit(req.protect) } : {},
|
|
17274
17337
|
...req.sealed ? { sealed } : {}
|
|
17275
17338
|
};
|
|
17276
17339
|
}
|