@ai-ecoverse/slicc-kernel 1.58.0 → 1.59.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 +18 -10
- package/dist/driver-worker.js +30 -11
- package/dist/driver-worker.js.map +2 -2
- package/dist/driver.js +30 -11
- package/dist/driver.js.map +2 -2
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +264 -109
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-driver-worker.js +30 -11
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +134 -21
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +264 -109
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +132 -19
- package/dist/process-worker.js.map +3 -3
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -794,12 +794,12 @@ var OpfsFs = class {
|
|
|
794
794
|
const base = dir === "/" ? "" : dir;
|
|
795
795
|
const metas = await this.meta.get(children2.map(([name2]) => `${base}/${name2}`));
|
|
796
796
|
const handed2 = this.owners ? await this.handedTo(dir) : void 0;
|
|
797
|
-
const
|
|
797
|
+
const owned3 = (stat, entry) => handed2 ? { ...stat, ...ownOf(entry) ?? handed2 } : stat;
|
|
798
798
|
return Promise.all(
|
|
799
799
|
children2.map(async ([name2, child], i) => {
|
|
800
|
-
if (!isHandle(child)) return [name2,
|
|
800
|
+
if (!isHandle(child)) return [name2, owned3(this.linkStat(child), child)];
|
|
801
801
|
const stat = await this.statOf(`${base}/${name2}`, child, metas[i]).catch(() => null);
|
|
802
|
-
return [name2, stat &&
|
|
802
|
+
return [name2, stat && owned3(stat, metas[i])];
|
|
803
803
|
})
|
|
804
804
|
);
|
|
805
805
|
}
|
|
@@ -830,9 +830,9 @@ var OpfsFs = class {
|
|
|
830
830
|
const parent = await this.locate(parentOf2(path), true);
|
|
831
831
|
if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
|
|
832
832
|
await parent.handle.getDirectoryHandle(baseOf(path), { create: true });
|
|
833
|
-
const
|
|
834
|
-
await this.stampNew(
|
|
835
|
-
this.touch(parent.path,
|
|
833
|
+
const made2 = `${parent.path === "/" ? "" : parent.path}/${baseOf(path)}`;
|
|
834
|
+
await this.stampNew(made2, owner, true);
|
|
835
|
+
this.touch(parent.path, made2);
|
|
836
836
|
}
|
|
837
837
|
async rm(path, options = {}) {
|
|
838
838
|
let found;
|
|
@@ -2644,12 +2644,22 @@ var UserDb = class {
|
|
|
2644
2644
|
async stampHome(row, shared) {
|
|
2645
2645
|
const home = this.fs.resolvePath("/", row.home);
|
|
2646
2646
|
if (!this.owners || !this.fs.chown || !HOME_DIR.test(home)) return;
|
|
2647
|
-
if (await this.
|
|
2648
|
-
if (!(await this.fs.lstat(home)).isDirectory) return;
|
|
2647
|
+
if (!await this.realDir(home)) return;
|
|
2649
2648
|
const gid = shared?.gid ?? row.gid;
|
|
2650
2649
|
await this.fs.chown(home, { uid: row.uid, gid, follow: false, kind: "adopt" });
|
|
2651
|
-
const
|
|
2652
|
-
await this.fs.chmod(home,
|
|
2650
|
+
const scoop = row.name.startsWith("scoop-");
|
|
2651
|
+
await this.fs.chmod(home, shared ? 1512 : scoop ? 488 : 448);
|
|
2652
|
+
const pnpm = `${home}/.local/share/pnpm`;
|
|
2653
|
+
if (await this.realDir(pnpm)) await this.fs.chmod(pnpm, scoop ? 488 : 448);
|
|
2654
|
+
}
|
|
2655
|
+
async realDir(path) {
|
|
2656
|
+
const parts = path.split("/").filter(Boolean);
|
|
2657
|
+
for (let n = 1; n <= parts.length; n++) {
|
|
2658
|
+
const at = `/${parts.slice(0, n).join("/")}`;
|
|
2659
|
+
const st = await this.fs.lstat(at).catch(() => void 0);
|
|
2660
|
+
if (!st?.isDirectory) return false;
|
|
2661
|
+
}
|
|
2662
|
+
return true;
|
|
2653
2663
|
}
|
|
2654
2664
|
async read(path, fallback) {
|
|
2655
2665
|
try {
|
|
@@ -2666,15 +2676,17 @@ var UserDb = class {
|
|
|
2666
2676
|
};
|
|
2667
2677
|
}
|
|
2668
2678
|
async provision(row) {
|
|
2679
|
+
const owner = this.owners ? { uid: row.uid, gid: row.gid } : void 0;
|
|
2680
|
+
const made2 = owner ? { recursive: true, owner } : { recursive: true };
|
|
2669
2681
|
const pnpm = `${row.home}/.local/share/pnpm`;
|
|
2670
2682
|
if (!await this.fs.exists(pnpm)) {
|
|
2671
|
-
await this.fs.mkdir(pnpm,
|
|
2683
|
+
await this.fs.mkdir(pnpm, made2);
|
|
2672
2684
|
await this.fs.chmod(pnpm, row.name.startsWith("scoop-") ? 488 : 448);
|
|
2673
2685
|
}
|
|
2674
2686
|
const config = `${row.home}/.config/pnpm/config.yaml`;
|
|
2675
2687
|
if (!await this.fs.exists(config)) {
|
|
2676
|
-
await this.fs.mkdir(`${row.home}/.config/pnpm`,
|
|
2677
|
-
await this.fs.writeFile(config, PNPM_CONFIG);
|
|
2688
|
+
await this.fs.mkdir(`${row.home}/.config/pnpm`, made2);
|
|
2689
|
+
await this.fs.writeFile(config, PNPM_CONFIG, owner);
|
|
2678
2690
|
}
|
|
2679
2691
|
}
|
|
2680
2692
|
async commit(passwd, group, then) {
|
|
@@ -2851,7 +2863,7 @@ async function fsCall(fs, method, args, owner) {
|
|
|
2851
2863
|
return { result: bytes, transfer: [bytes.buffer] };
|
|
2852
2864
|
}
|
|
2853
2865
|
case "writeFile":
|
|
2854
|
-
await fs.writeFile(path(0), args[1], owner);
|
|
2866
|
+
await fs.writeFile(path(0), args[1], created(owner, 438));
|
|
2855
2867
|
return { result: true };
|
|
2856
2868
|
case "stat":
|
|
2857
2869
|
return { result: await fs.stat(path(0)) };
|
|
@@ -2860,7 +2872,10 @@ async function fsCall(fs, method, args, owner) {
|
|
|
2860
2872
|
case "readdir":
|
|
2861
2873
|
return { result: await fs.readdir(path(0)) };
|
|
2862
2874
|
case "mkdir":
|
|
2863
|
-
await fs.mkdir(
|
|
2875
|
+
await fs.mkdir(
|
|
2876
|
+
path(0),
|
|
2877
|
+
owner ? { recursive: true, owner: made(owner) } : { recursive: true }
|
|
2878
|
+
);
|
|
2864
2879
|
return { result: true };
|
|
2865
2880
|
case "rm":
|
|
2866
2881
|
await fs.rm(path(0), { recursive: true, force: args[1] === true });
|
|
@@ -2871,7 +2886,7 @@ async function fsCall(fs, method, args, owner) {
|
|
|
2871
2886
|
case "realpath":
|
|
2872
2887
|
return { result: await realpath(fs, String(args[0])) };
|
|
2873
2888
|
case "symlink":
|
|
2874
|
-
await fs.symlink(String(args[0]), path(1), owner);
|
|
2889
|
+
await fs.symlink(String(args[0]), path(1), owner && { uid: owner.uid, gid: owner.gid });
|
|
2875
2890
|
return { result: true };
|
|
2876
2891
|
case "readlink":
|
|
2877
2892
|
return { result: await fs.readlink(path(0)) };
|
|
@@ -2893,8 +2908,16 @@ function dialFor(l, req, open) {
|
|
|
2893
2908
|
);
|
|
2894
2909
|
return { result: port2, transfer: [port2] };
|
|
2895
2910
|
}
|
|
2911
|
+
function created(owner, mode) {
|
|
2912
|
+
return owner && { uid: owner.uid, gid: owner.gid, mode: mode & ~owner.umask };
|
|
2913
|
+
}
|
|
2914
|
+
function made(owner) {
|
|
2915
|
+
const mode = 511 & ~owner.umask;
|
|
2916
|
+
return { uid: owner.uid, gid: owner.gid, mode, parents: mode | 192 };
|
|
2917
|
+
}
|
|
2896
2918
|
function ownerFor(l, self) {
|
|
2897
|
-
|
|
2919
|
+
if (!l.owners || !self) return void 0;
|
|
2920
|
+
return { uid: self.uid, gid: self.gid, umask: self.umask ?? 18 };
|
|
2898
2921
|
}
|
|
2899
2922
|
async function accountOf(l, user) {
|
|
2900
2923
|
const found = await l.users.lookup(user);
|
|
@@ -5782,7 +5805,17 @@ async function followLinks(fs, path) {
|
|
|
5782
5805
|
}
|
|
5783
5806
|
return current;
|
|
5784
5807
|
}
|
|
5785
|
-
function withCommandDirs(fs, names, userDir = async () => void 0) {
|
|
5808
|
+
function withCommandDirs(fs, names, userDir = async () => void 0, owners = false) {
|
|
5809
|
+
async function nearest(path) {
|
|
5810
|
+
const st = await fs.stat(path).catch(() => void 0);
|
|
5811
|
+
if (st || path === "/") return st ?? {};
|
|
5812
|
+
return nearest(path.slice(0, path.lastIndexOf("/")) || "/");
|
|
5813
|
+
}
|
|
5814
|
+
async function owned3(stat2, dir) {
|
|
5815
|
+
if (!owners) return stat2;
|
|
5816
|
+
const { uid = 0, gid = 0 } = dir === void 0 ? {} : await nearest(dir);
|
|
5817
|
+
return { ...stat2, uid, gid };
|
|
5818
|
+
}
|
|
5786
5819
|
async function children2(path) {
|
|
5787
5820
|
if (path === "/") return ["bin", "usr"];
|
|
5788
5821
|
if (path === "/usr") return ["bin"];
|
|
@@ -5791,13 +5824,18 @@ function withCommandDirs(fs, names, userDir = async () => void 0) {
|
|
|
5791
5824
|
return own?.size ? [...own] : void 0;
|
|
5792
5825
|
}
|
|
5793
5826
|
async function virtual(path) {
|
|
5794
|
-
if (path === "/usr" || path === "/bin" || path === "/usr/bin")
|
|
5827
|
+
if (path === "/usr" || path === "/bin" || path === "/usr/bin") {
|
|
5828
|
+
return owned3(synthetic(true, path));
|
|
5829
|
+
}
|
|
5795
5830
|
const name2 = COMMAND.exec(path)?.[1];
|
|
5796
|
-
if (name2 !== void 0)
|
|
5797
|
-
|
|
5831
|
+
if (name2 !== void 0) {
|
|
5832
|
+
return (await names()).has(name2) ? owned3(synthetic(false, path)) : void 0;
|
|
5833
|
+
}
|
|
5834
|
+
if ((await userDir(path))?.size) return owned3(synthetic(true, path), path);
|
|
5798
5835
|
const slash = path.lastIndexOf("/");
|
|
5799
|
-
const
|
|
5800
|
-
|
|
5836
|
+
const dir = path.slice(0, slash);
|
|
5837
|
+
const own = await userDir(dir);
|
|
5838
|
+
return own?.has(path.slice(slash + 1)) ? owned3(synthetic(false, path), dir) : void 0;
|
|
5801
5839
|
}
|
|
5802
5840
|
async function linked(path) {
|
|
5803
5841
|
return await virtual(path) ?? virtual(await followLinks(fs, path));
|
|
@@ -6192,18 +6230,18 @@ var FsWatchers = class {
|
|
|
6192
6230
|
const overrides = {
|
|
6193
6231
|
writeFile: after(fs.writeFile.bind(fs), (path) => [path]),
|
|
6194
6232
|
mkdir: async (path, options) => {
|
|
6195
|
-
const
|
|
6233
|
+
const created3 = [];
|
|
6196
6234
|
if (options?.recursive) {
|
|
6197
6235
|
const parts = normalizePath(path).split("/").filter(Boolean);
|
|
6198
6236
|
for (let at = 1; at < parts.length; at++) {
|
|
6199
6237
|
const ancestor = `/${parts.slice(0, at).join("/")}`;
|
|
6200
|
-
if (
|
|
6238
|
+
if (created3.length > 0 || !await fs.exists(ancestor)) created3.push(ancestor);
|
|
6201
6239
|
}
|
|
6202
6240
|
}
|
|
6203
6241
|
try {
|
|
6204
6242
|
await fs.mkdir(path, options);
|
|
6205
6243
|
} finally {
|
|
6206
|
-
this.changed(...
|
|
6244
|
+
this.changed(...created3, path);
|
|
6207
6245
|
}
|
|
6208
6246
|
},
|
|
6209
6247
|
rm: after(fs.rm.bind(fs), (path) => [path]),
|
|
@@ -6482,7 +6520,7 @@ async function realTarget(fs, path) {
|
|
|
6482
6520
|
}
|
|
6483
6521
|
|
|
6484
6522
|
// src/mount/protocol.ts
|
|
6485
|
-
var DRIVER_PROTOCOL = [1,
|
|
6523
|
+
var DRIVER_PROTOCOL = [1, 2];
|
|
6486
6524
|
function driverVersionError(theirs) {
|
|
6487
6525
|
const major = Array.isArray(theirs) ? theirs[0] : void 0;
|
|
6488
6526
|
if (major === DRIVER_PROTOCOL[0]) return void 0;
|
|
@@ -6584,6 +6622,19 @@ var DriverConnection = class _DriverConnection {
|
|
|
6584
6622
|
};
|
|
6585
6623
|
|
|
6586
6624
|
// src/mount/mount-fs.ts
|
|
6625
|
+
var S_ISGID3 = 1024;
|
|
6626
|
+
var ID = /^\d{1,10}$/;
|
|
6627
|
+
var MAX_ID2 = 4294967294;
|
|
6628
|
+
function idOption(value) {
|
|
6629
|
+
return value === void 0 ? 0 : Number(value);
|
|
6630
|
+
}
|
|
6631
|
+
function checkIds(options) {
|
|
6632
|
+
for (const key of ["uid", "gid"]) {
|
|
6633
|
+
const value = options[key];
|
|
6634
|
+
if (value === void 0) continue;
|
|
6635
|
+
if (!ID.test(value) || Number(value) > MAX_ID2) throw errnoError("EINVAL", `${key}=${value}`);
|
|
6636
|
+
}
|
|
6637
|
+
}
|
|
6587
6638
|
var MAX_LINKS5 = 40;
|
|
6588
6639
|
var STALE_RETRIES = 3;
|
|
6589
6640
|
var SETTLE_ROUNDS = 4;
|
|
@@ -6750,31 +6801,35 @@ var HeldPaths = class extends Map {
|
|
|
6750
6801
|
};
|
|
6751
6802
|
var parentOf6 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
|
|
6752
6803
|
var readonly = (mount) => mount.caps.readonly === true || mount.options.ro !== void 0;
|
|
6753
|
-
function inodeless(mount,
|
|
6754
|
-
if (
|
|
6804
|
+
function inodeless(mount, attr2) {
|
|
6805
|
+
if (attr2.ino !== void 0) return false;
|
|
6755
6806
|
if (mount.caps.links) mount.caps = { ...mount.caps, links: false };
|
|
6756
6807
|
return true;
|
|
6757
6808
|
}
|
|
6758
|
-
function statOf(
|
|
6759
|
-
const mtime = new Date(
|
|
6760
|
-
const fallback =
|
|
6809
|
+
function statOf(attr2, path, mount) {
|
|
6810
|
+
const mtime = new Date(attr2.mtime);
|
|
6811
|
+
const fallback = attr2.kind === "directory" ? 16877 : attr2.kind === "symlink" ? 41471 : 33188;
|
|
6761
6812
|
return {
|
|
6762
|
-
isFile:
|
|
6763
|
-
isDirectory:
|
|
6764
|
-
isSymbolicLink:
|
|
6765
|
-
size:
|
|
6766
|
-
mode:
|
|
6813
|
+
isFile: attr2.kind === "file",
|
|
6814
|
+
isDirectory: attr2.kind === "directory",
|
|
6815
|
+
isSymbolicLink: attr2.kind === "symlink",
|
|
6816
|
+
size: attr2.size,
|
|
6817
|
+
mode: attr2.mode ?? fallback,
|
|
6767
6818
|
mtime,
|
|
6768
6819
|
atime: mtime,
|
|
6769
6820
|
ctime: mtime,
|
|
6770
|
-
ino:
|
|
6771
|
-
...!inodeless(mount,
|
|
6821
|
+
ino: attr2.ino ?? inodeOf(path),
|
|
6822
|
+
...!inodeless(mount, attr2) && attr2.nlink !== void 0 ? { nlink: attr2.nlink } : {},
|
|
6772
6823
|
dev: mount.dev,
|
|
6773
6824
|
...readonly(mount) ? { readonly: true } : {},
|
|
6774
6825
|
...mount.maxFile > 0 ? { maxFile: mount.maxFile } : {},
|
|
6775
6826
|
...mount.caps.ranges ? { ranged: true } : {},
|
|
6776
6827
|
...mount.caps.links ? { linkable: true } : {},
|
|
6777
|
-
...
|
|
6828
|
+
...attr2.etag !== void 0 ? { version: attr2.etag } : {},
|
|
6829
|
+
...mount.owners ? {
|
|
6830
|
+
uid: (mount.caps.owners ? attr2.uid : void 0) ?? idOption(mount.options.uid),
|
|
6831
|
+
gid: (mount.caps.owners ? attr2.gid : void 0) ?? idOption(mount.options.gid)
|
|
6832
|
+
} : {}
|
|
6778
6833
|
};
|
|
6779
6834
|
}
|
|
6780
6835
|
function concat4(chunks, total) {
|
|
@@ -6867,6 +6922,7 @@ var MountTable = class {
|
|
|
6867
6922
|
const st = await fs.stat(target);
|
|
6868
6923
|
if (!st.isDirectory) throw errnoError("ENOTDIR", target);
|
|
6869
6924
|
const options = { ...spec.options };
|
|
6925
|
+
if (this.deps.owners) checkIds(options);
|
|
6870
6926
|
const maxFile = options.maxfile !== void 0 ? parseSize(options.maxfile) : void 0;
|
|
6871
6927
|
const opened2 = await this.deps.open(spec.type, { ...spec, target, options });
|
|
6872
6928
|
let mounted;
|
|
@@ -6912,6 +6968,7 @@ var MountTable = class {
|
|
|
6912
6968
|
attrs: /* @__PURE__ */ new Map(),
|
|
6913
6969
|
lists: /* @__PURE__ */ new Map(),
|
|
6914
6970
|
epoch: 0,
|
|
6971
|
+
owners: this.deps.owners === true,
|
|
6915
6972
|
dispose: () => opened2.dispose(),
|
|
6916
6973
|
...opened2.present ? { present: opened2.present } : {}
|
|
6917
6974
|
};
|
|
@@ -7033,15 +7090,15 @@ var MountTable = class {
|
|
|
7033
7090
|
if (cached && cached.expires > Date.now()) return cached.value;
|
|
7034
7091
|
const seen = mount.epoch;
|
|
7035
7092
|
const session = this.sessions.get(path);
|
|
7036
|
-
const
|
|
7093
|
+
const attr2 = await mount.conn.call({ op: "getattr", path: rel2 });
|
|
7037
7094
|
if (mount.epoch !== seen) {
|
|
7038
7095
|
const moved2 = this.sessions.get(path) !== session || this.committing.has(path);
|
|
7039
7096
|
if (settled && moved2 && round < SETTLE_ROUNDS) continue;
|
|
7040
|
-
return
|
|
7097
|
+
return attr2;
|
|
7041
7098
|
}
|
|
7042
7099
|
const ttl = mount.caps.attrTtl ?? 1e3;
|
|
7043
|
-
if (ttl > 0) mount.attrs.set(path, { value:
|
|
7044
|
-
return
|
|
7100
|
+
if (ttl > 0) mount.attrs.set(path, { value: attr2, expires: Date.now() + ttl });
|
|
7101
|
+
return attr2;
|
|
7045
7102
|
}
|
|
7046
7103
|
}
|
|
7047
7104
|
async readdir(mount, path, rel2) {
|
|
@@ -7088,28 +7145,43 @@ var MountFs = class {
|
|
|
7088
7145
|
const found = this.at(path);
|
|
7089
7146
|
if (!found) return path;
|
|
7090
7147
|
const real = normalizePath(path);
|
|
7091
|
-
let
|
|
7148
|
+
let attr2;
|
|
7092
7149
|
try {
|
|
7093
|
-
|
|
7150
|
+
attr2 = await this.table.getattr(found.mount, real, found.rel);
|
|
7094
7151
|
} catch (err) {
|
|
7095
7152
|
if (create && err.code === "ENOENT") return real;
|
|
7096
7153
|
throw err;
|
|
7097
7154
|
}
|
|
7098
|
-
if (
|
|
7155
|
+
if (attr2.kind !== "symlink") return real;
|
|
7099
7156
|
if (hops >= MAX_LINKS5) throw errnoError("ELOOP", path);
|
|
7100
7157
|
const target = await found.mount.conn.call({ op: "readlink", path: found.rel });
|
|
7101
7158
|
return this.follow(this.base.resolvePath(parentOf6(real), target), hops + 1, create);
|
|
7102
7159
|
}
|
|
7103
|
-
async open(mount, rel2, write) {
|
|
7160
|
+
async open(mount, rel2, write, owner) {
|
|
7104
7161
|
return await mount.conn.call({
|
|
7105
7162
|
op: "open",
|
|
7106
7163
|
path: rel2,
|
|
7107
7164
|
write,
|
|
7108
7165
|
create: write,
|
|
7109
7166
|
truncate: write,
|
|
7110
|
-
exclusive: false
|
|
7167
|
+
exclusive: false,
|
|
7168
|
+
...owner
|
|
7111
7169
|
});
|
|
7112
7170
|
}
|
|
7171
|
+
async driverOwner(found, real, owner, directory) {
|
|
7172
|
+
const { mount, rel: rel2 } = found;
|
|
7173
|
+
if (!owner || !mount.owners || !mount.caps.owners) return void 0;
|
|
7174
|
+
const dir = parentOf6(real);
|
|
7175
|
+
const above = statOf(await this.table.getattr(mount, dir, parentOf6(rel2)), dir, mount);
|
|
7176
|
+
const setgid = (above.mode & S_ISGID3) !== 0;
|
|
7177
|
+
let mode = owner.mode;
|
|
7178
|
+
if (directory && setgid) mode = (mode ?? 493) | S_ISGID3;
|
|
7179
|
+
return {
|
|
7180
|
+
uid: owner.uid,
|
|
7181
|
+
gid: setgid ? above.gid : owner.gid,
|
|
7182
|
+
...mode !== void 0 ? { mode } : {}
|
|
7183
|
+
};
|
|
7184
|
+
}
|
|
7113
7185
|
resolvePath(base, path) {
|
|
7114
7186
|
return this.base.resolvePath(base, path);
|
|
7115
7187
|
}
|
|
@@ -7131,9 +7203,9 @@ var MountFs = class {
|
|
|
7131
7203
|
}
|
|
7132
7204
|
async readWhole(mount, real, rel2) {
|
|
7133
7205
|
await this.table.commit(real);
|
|
7134
|
-
const
|
|
7135
|
-
if (
|
|
7136
|
-
if (mount.maxFile > 0 &&
|
|
7206
|
+
const attr2 = await this.table.getattr(mount, real, rel2);
|
|
7207
|
+
if (attr2.kind === "directory") throw errnoError("EISDIR", real);
|
|
7208
|
+
if (mount.maxFile > 0 && attr2.size > mount.maxFile) {
|
|
7137
7209
|
throw errnoError("EFBIG", `${real} is larger than this mount's maxfile (${mount.maxFile})`);
|
|
7138
7210
|
}
|
|
7139
7211
|
const fh = await this.open(mount, rel2, false);
|
|
@@ -7151,7 +7223,7 @@ var MountFs = class {
|
|
|
7151
7223
|
if (bytes.length === 0) break;
|
|
7152
7224
|
chunks.push(bytes);
|
|
7153
7225
|
total += bytes.length;
|
|
7154
|
-
if (bytes.length < chunk2 && total >=
|
|
7226
|
+
if (bytes.length < chunk2 && total >= attr2.size) break;
|
|
7155
7227
|
}
|
|
7156
7228
|
} finally {
|
|
7157
7229
|
await mount.conn.call({ op: "release", fh });
|
|
@@ -7171,18 +7243,19 @@ var MountFs = class {
|
|
|
7171
7243
|
`${real} would be larger than this mount's maxfile (${mount.maxFile})`
|
|
7172
7244
|
);
|
|
7173
7245
|
}
|
|
7246
|
+
const made2 = await this.driverOwner(found, real, owner, false);
|
|
7174
7247
|
for (let attempt = 1; ; attempt++) {
|
|
7175
7248
|
try {
|
|
7176
|
-
return await this.writeWhole(mount, real, rel2, bytes);
|
|
7249
|
+
return await this.writeWhole(mount, real, rel2, bytes, made2);
|
|
7177
7250
|
} catch (err) {
|
|
7178
7251
|
if (err.code !== "ESTALE" || attempt >= STALE_RETRIES) throw err;
|
|
7179
7252
|
}
|
|
7180
7253
|
}
|
|
7181
7254
|
}
|
|
7182
|
-
async writeWhole(mount, real, rel2, bytes) {
|
|
7255
|
+
async writeWhole(mount, real, rel2, bytes, owner) {
|
|
7183
7256
|
await this.table.commit(real);
|
|
7184
7257
|
this.table.forget(mount, real);
|
|
7185
|
-
const fh = await this.open(mount, rel2, true);
|
|
7258
|
+
const fh = await this.open(mount, rel2, true, owner);
|
|
7186
7259
|
const chunk2 = mount.caps.maxIo ?? DEFAULT_IO;
|
|
7187
7260
|
try {
|
|
7188
7261
|
for (let offset = 0; offset < bytes.length; offset += chunk2) {
|
|
@@ -7328,9 +7401,9 @@ var MountFs = class {
|
|
|
7328
7401
|
found.mount
|
|
7329
7402
|
);
|
|
7330
7403
|
}
|
|
7331
|
-
statWriting(
|
|
7404
|
+
statWriting(attr2, real, mount) {
|
|
7332
7405
|
const ends = (this.table.writing(real)?.extents ?? []).map(([, end]) => end);
|
|
7333
|
-
return statOf({ ...
|
|
7406
|
+
return statOf({ ...attr2, size: Math.max(attr2.size, ...ends) }, real, mount);
|
|
7334
7407
|
}
|
|
7335
7408
|
async stat(path) {
|
|
7336
7409
|
const real = await this.follow(path);
|
|
@@ -7369,10 +7442,12 @@ var MountFs = class {
|
|
|
7369
7442
|
const { mount, rel: rel2 } = found;
|
|
7370
7443
|
const real = normalizePath(path);
|
|
7371
7444
|
this.writable(mount, real);
|
|
7445
|
+
const { owner } = options;
|
|
7372
7446
|
if (!options.recursive) {
|
|
7373
7447
|
if (rel2 === "/") throw errnoError("EEXIST", real);
|
|
7448
|
+
const made2 = await this.driverOwner(found, real, owner, true);
|
|
7374
7449
|
this.table.forget(mount, real);
|
|
7375
|
-
await mount.conn.call({ op: "mkdir", path: rel2 });
|
|
7450
|
+
await mount.conn.call({ op: "mkdir", path: rel2, ...made2 });
|
|
7376
7451
|
return;
|
|
7377
7452
|
}
|
|
7378
7453
|
const parts = rel2.split("/").filter(Boolean);
|
|
@@ -7382,8 +7457,10 @@ var MountFs = class {
|
|
|
7382
7457
|
const exists = await this.table.getattr(mount, full, sub).catch(() => void 0);
|
|
7383
7458
|
if (exists?.kind === "directory") continue;
|
|
7384
7459
|
if (exists) throw errnoError("ENOTDIR", full);
|
|
7460
|
+
const own = n === parts.length ? owner : owner && { ...owner, mode: owner.parents };
|
|
7461
|
+
const made2 = await this.driverOwner({ mount, rel: sub }, full, own, true);
|
|
7385
7462
|
this.table.forget(mount, full);
|
|
7386
|
-
await mount.conn.call({ op: "mkdir", path: sub });
|
|
7463
|
+
await mount.conn.call({ op: "mkdir", path: sub, ...made2 });
|
|
7387
7464
|
}
|
|
7388
7465
|
}
|
|
7389
7466
|
async rm(path, options = {}) {
|
|
@@ -7394,21 +7471,21 @@ var MountFs = class {
|
|
|
7394
7471
|
if (rel2 === "/") throw errnoError("EBUSY", `${real} is a mount point`);
|
|
7395
7472
|
this.writable(mount, real);
|
|
7396
7473
|
await this.table.commitUnder(real);
|
|
7397
|
-
let
|
|
7474
|
+
let attr2;
|
|
7398
7475
|
try {
|
|
7399
|
-
|
|
7476
|
+
attr2 = await this.table.getattr(mount, real, rel2);
|
|
7400
7477
|
} catch (err) {
|
|
7401
7478
|
if (options.force && err.code === "ENOENT") return;
|
|
7402
7479
|
throw err;
|
|
7403
7480
|
}
|
|
7404
7481
|
this.table.forget(mount, real);
|
|
7405
|
-
if (
|
|
7482
|
+
if (attr2.kind === "directory" && options.recursive) {
|
|
7406
7483
|
for (const entry of await this.table.readdir(mount, real, rel2)) {
|
|
7407
7484
|
await this.rm(`${real}/${entry.name}`, { recursive: true, force: options.force ?? false });
|
|
7408
7485
|
}
|
|
7409
7486
|
this.table.forget(mount, real);
|
|
7410
7487
|
}
|
|
7411
|
-
await mount.conn.call({ op:
|
|
7488
|
+
await mount.conn.call({ op: attr2.kind === "directory" ? "rmdir" : "unlink", path: rel2 });
|
|
7412
7489
|
this.table.forget(mount, real);
|
|
7413
7490
|
}
|
|
7414
7491
|
async rename(from, to) {
|
|
@@ -7462,8 +7539,10 @@ var MountFs = class {
|
|
|
7462
7539
|
this.writable(found.mount, normalizePath(path));
|
|
7463
7540
|
if (!found.mount.caps.symlinks)
|
|
7464
7541
|
throw errnoError("EPERM", `${path}: this file system has no symlinks`);
|
|
7542
|
+
const link2 = owner && { uid: owner.uid, gid: owner.gid };
|
|
7543
|
+
const made2 = await this.driverOwner(found, normalizePath(path), link2, false);
|
|
7465
7544
|
this.table.forget(found.mount, normalizePath(path));
|
|
7466
|
-
await found.mount.conn.call({ op: "symlink", target, path: found.rel });
|
|
7545
|
+
await found.mount.conn.call({ op: "symlink", target, path: found.rel, ...made2 });
|
|
7467
7546
|
}
|
|
7468
7547
|
async realpath(path, follow2) {
|
|
7469
7548
|
if (this.at(path) || !this.base.realpath) throw errnoError("ENOSYS", path);
|
|
@@ -7478,13 +7557,29 @@ var MountFs = class {
|
|
|
7478
7557
|
}
|
|
7479
7558
|
async chown(path, change) {
|
|
7480
7559
|
const real = change.follow === false || change.kind === "new" ? path : await this.follow(path);
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
throw errnoError("EPERM", `${path}: this file system keeps no owners`);
|
|
7484
|
-
}
|
|
7560
|
+
const found = this.at(real);
|
|
7561
|
+
if (found) return this.chownMounted(found, normalizePath(real), change);
|
|
7485
7562
|
if (!this.base.chown) throw errnoError("EPERM", path);
|
|
7486
7563
|
return this.base.chown(real, change);
|
|
7487
7564
|
}
|
|
7565
|
+
async chownMounted(found, real, change) {
|
|
7566
|
+
const { mount, rel: rel2 } = found;
|
|
7567
|
+
if (!mount.owners || !mount.caps.owners) {
|
|
7568
|
+
if (change.kind === "new") return;
|
|
7569
|
+
throw errnoError("EPERM", `${real}: this file system keeps no owners`);
|
|
7570
|
+
}
|
|
7571
|
+
this.writable(mount, real);
|
|
7572
|
+
const { uid, gid, mode } = change;
|
|
7573
|
+
const fresh = change.kind === "new" && { uid, gid, mode };
|
|
7574
|
+
const set2 = fresh ? await this.driverOwner(found, real, fresh, false) : change;
|
|
7575
|
+
this.table.forget(mount, real);
|
|
7576
|
+
const attrs = Object.entries({ uid: set2.uid, gid: set2.gid, mode: set2.mode });
|
|
7577
|
+
await mount.conn.call({
|
|
7578
|
+
op: "setattr",
|
|
7579
|
+
path: rel2,
|
|
7580
|
+
...Object.fromEntries(attrs.filter(([, value]) => value !== void 0))
|
|
7581
|
+
});
|
|
7582
|
+
}
|
|
7488
7583
|
async chmod(path, mode) {
|
|
7489
7584
|
const found = this.at(path);
|
|
7490
7585
|
if (!found) return this.base.chmod(path, mode);
|
|
@@ -7591,7 +7686,10 @@ function mkdirOptions(entry, mode = 511) {
|
|
|
7591
7686
|
}
|
|
7592
7687
|
async function chown(entry, path, req) {
|
|
7593
7688
|
const cred = entry.cred?.();
|
|
7594
|
-
if (!cred)
|
|
7689
|
+
if (!cred) {
|
|
7690
|
+
await (req.op === "chown" ? entry.fs.stat(path) : entry.fs.lstat(path));
|
|
7691
|
+
return done;
|
|
7692
|
+
}
|
|
7595
7693
|
await chownAs(entry.fs, cred, path, {
|
|
7596
7694
|
...req.uid !== void 0 ? { uid: req.uid } : {},
|
|
7597
7695
|
...req.gid !== void 0 ? { gid: req.gid } : {},
|
|
@@ -11415,6 +11513,7 @@ function spawnWasmProcess(opts) {
|
|
|
11415
11513
|
cwd: opts.cwd,
|
|
11416
11514
|
sab: tsab,
|
|
11417
11515
|
cred: copyCred(process.cred),
|
|
11516
|
+
owners: opts.owners === true,
|
|
11418
11517
|
...opts.ppid !== void 0 ? { ppid: opts.ppid } : {},
|
|
11419
11518
|
thread
|
|
11420
11519
|
};
|
|
@@ -11808,6 +11907,17 @@ var SettlingChildren = class {
|
|
|
11808
11907
|
};
|
|
11809
11908
|
|
|
11810
11909
|
// src/mount/driver.ts
|
|
11910
|
+
function ownerOf2(req) {
|
|
11911
|
+
const owner = {
|
|
11912
|
+
...req.uid !== void 0 ? { uid: req.uid } : {},
|
|
11913
|
+
...req.gid !== void 0 ? { gid: req.gid } : {},
|
|
11914
|
+
...req.mode !== void 0 ? { mode: req.mode } : {}
|
|
11915
|
+
};
|
|
11916
|
+
return Object.keys(owner).length > 0 ? owner : void 0;
|
|
11917
|
+
}
|
|
11918
|
+
function withOwner(base, owner) {
|
|
11919
|
+
return owner ? { ...base, owner } : base;
|
|
11920
|
+
}
|
|
11811
11921
|
function fsError2(code, message3 = code) {
|
|
11812
11922
|
return Object.assign(new Error(message3), { code });
|
|
11813
11923
|
}
|
|
@@ -11818,13 +11928,19 @@ async function dispatch(h, req) {
|
|
|
11818
11928
|
case "readdir":
|
|
11819
11929
|
return h.readdir(req.path);
|
|
11820
11930
|
case "open":
|
|
11821
|
-
return h.open(
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11931
|
+
return h.open(
|
|
11932
|
+
req.path,
|
|
11933
|
+
withOwner(
|
|
11934
|
+
{
|
|
11935
|
+
write: req.write,
|
|
11936
|
+
create: req.create,
|
|
11937
|
+
truncate: req.truncate,
|
|
11938
|
+
exclusive: req.exclusive,
|
|
11939
|
+
...req.ifMatch !== void 0 ? { ifMatch: req.ifMatch } : {}
|
|
11940
|
+
},
|
|
11941
|
+
ownerOf2(req)
|
|
11942
|
+
)
|
|
11943
|
+
);
|
|
11828
11944
|
case "read":
|
|
11829
11945
|
return h.read(req.fh, req.offset, req.size);
|
|
11830
11946
|
case "write":
|
|
@@ -11832,7 +11948,7 @@ async function dispatch(h, req) {
|
|
|
11832
11948
|
case "release":
|
|
11833
11949
|
return h.release(req.fh);
|
|
11834
11950
|
case "mkdir":
|
|
11835
|
-
return h.mkdir(req.path);
|
|
11951
|
+
return ownerOf2(req) ? h.mkdir(req.path, ownerOf2(req)) : h.mkdir(req.path);
|
|
11836
11952
|
case "rmdir":
|
|
11837
11953
|
return h.rmdir(req.path);
|
|
11838
11954
|
case "unlink":
|
|
@@ -11844,7 +11960,7 @@ async function dispatch(h, req) {
|
|
|
11844
11960
|
return h.link(req.from, req.to);
|
|
11845
11961
|
case "symlink":
|
|
11846
11962
|
if (!h.symlink) throw fsError2("EPERM", "this file system has no symlinks");
|
|
11847
|
-
return h.symlink(req.target, req.path);
|
|
11963
|
+
return ownerOf2(req) ? h.symlink(req.target, req.path, ownerOf2(req)) : h.symlink(req.target, req.path);
|
|
11848
11964
|
case "readlink":
|
|
11849
11965
|
if (!h.readlink) throw fsError2("EINVAL", `${req.path} is not a symlink`);
|
|
11850
11966
|
return h.readlink(req.path);
|
|
@@ -11852,7 +11968,9 @@ async function dispatch(h, req) {
|
|
|
11852
11968
|
return h.setattr?.(req.path, {
|
|
11853
11969
|
...req.mode !== void 0 ? { mode: req.mode } : {},
|
|
11854
11970
|
...req.mtime !== void 0 ? { mtime: req.mtime } : {},
|
|
11855
|
-
...req.size !== void 0 ? { size: req.size } : {}
|
|
11971
|
+
...req.size !== void 0 ? { size: req.size } : {},
|
|
11972
|
+
...req.uid !== void 0 ? { uid: req.uid } : {},
|
|
11973
|
+
...req.gid !== void 0 ? { gid: req.gid } : {}
|
|
11856
11974
|
});
|
|
11857
11975
|
case "statfs":
|
|
11858
11976
|
return h.statfs?.() ?? null;
|
|
@@ -12003,8 +12121,8 @@ function kernelFsHandlers(fs) {
|
|
|
12003
12121
|
getattr: async (path) => attrOf(await fs.lstat(path)),
|
|
12004
12122
|
readdir: async (path) => (await fs.readdirStat(path)).flatMap(([name2, st]) => {
|
|
12005
12123
|
if (!st) return [];
|
|
12006
|
-
const
|
|
12007
|
-
return [{ name: name2, kind:
|
|
12124
|
+
const attr2 = attrOf(st);
|
|
12125
|
+
return [{ name: name2, kind: attr2.kind, attr: attr2 }];
|
|
12008
12126
|
}),
|
|
12009
12127
|
async open(path, flags) {
|
|
12010
12128
|
const st = await existing(path);
|
|
@@ -12434,7 +12552,7 @@ function hostfsHandlers(current, againMs = RESTORE_AGAIN_MS) {
|
|
|
12434
12552
|
"list",
|
|
12435
12553
|
{ path: rel(path) }
|
|
12436
12554
|
);
|
|
12437
|
-
return entries.map(({ name: name2, attr }) => ({ name: name2, kind:
|
|
12555
|
+
return entries.map(({ name: name2, attr: attr2 }) => ({ name: name2, kind: attr2.kind, attr: attr2 }));
|
|
12438
12556
|
},
|
|
12439
12557
|
async open(path, flags) {
|
|
12440
12558
|
const client = current();
|
|
@@ -12924,8 +13042,8 @@ var ChunkedBytes = class {
|
|
|
12924
13042
|
}
|
|
12925
13043
|
return out;
|
|
12926
13044
|
}
|
|
12927
|
-
write(offset, bytes,
|
|
12928
|
-
const whole =
|
|
13045
|
+
write(offset, bytes, owned3 = false) {
|
|
13046
|
+
const whole = owned3 && bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength;
|
|
12929
13047
|
for (let done4 = 0; done4 < bytes.length; ) {
|
|
12930
13048
|
const at = offset + done4;
|
|
12931
13049
|
const index = Math.floor(at / CHUNK3);
|
|
@@ -12958,18 +13076,42 @@ var ChunkedBytes = class {
|
|
|
12958
13076
|
};
|
|
12959
13077
|
|
|
12960
13078
|
// src/mount/tmpfs.ts
|
|
12961
|
-
function
|
|
12962
|
-
|
|
12963
|
-
|
|
13079
|
+
function idOption2(value) {
|
|
13080
|
+
return value !== void 0 && /^\d+$/.test(value) ? Number(value) : 0;
|
|
13081
|
+
}
|
|
13082
|
+
function created2(ino, kind, mode, from, owner) {
|
|
13083
|
+
return {
|
|
12964
13084
|
kind,
|
|
12965
|
-
ino
|
|
12966
|
-
mode,
|
|
13085
|
+
ino,
|
|
13086
|
+
mode: owner?.mode === void 0 ? mode : mode & ~4095 | owner.mode & 4095,
|
|
12967
13087
|
mtime: Date.now(),
|
|
12968
13088
|
data: new ChunkedBytes(),
|
|
12969
13089
|
target: "",
|
|
12970
13090
|
children: /* @__PURE__ */ new Map(),
|
|
12971
|
-
links: 1
|
|
12972
|
-
|
|
13091
|
+
links: 1,
|
|
13092
|
+
uid: owner?.uid ?? from?.uid ?? 0,
|
|
13093
|
+
gid: owner?.gid ?? from?.gid ?? 0
|
|
13094
|
+
};
|
|
13095
|
+
}
|
|
13096
|
+
function owned2(node, change) {
|
|
13097
|
+
if (change.uid !== void 0) node.uid = change.uid;
|
|
13098
|
+
if (change.gid !== void 0) node.gid = change.gid;
|
|
13099
|
+
}
|
|
13100
|
+
function attr(node) {
|
|
13101
|
+
return {
|
|
13102
|
+
kind: node.kind,
|
|
13103
|
+
size: node.kind === "file" ? node.data.size : node.kind === "symlink" ? node.target.length : 4096,
|
|
13104
|
+
mtime: node.mtime,
|
|
13105
|
+
mode: node.mode,
|
|
13106
|
+
ino: node.ino,
|
|
13107
|
+
...node.kind === "directory" ? {} : { nlink: node.links },
|
|
13108
|
+
uid: node.uid,
|
|
13109
|
+
gid: node.gid
|
|
13110
|
+
};
|
|
13111
|
+
}
|
|
13112
|
+
function tmpfs() {
|
|
13113
|
+
let inodes = 0;
|
|
13114
|
+
const make = (kind, mode, from, owner) => created2(++inodes, kind, mode, from, owner);
|
|
12973
13115
|
const root = make("directory", 16877);
|
|
12974
13116
|
const handles = /* @__PURE__ */ new Map();
|
|
12975
13117
|
let nextFh = 0;
|
|
@@ -12996,14 +13138,6 @@ function tmpfs() {
|
|
|
12996
13138
|
if (dir.kind !== "directory") throw fsError2("ENOTDIR", path);
|
|
12997
13139
|
return { dir, name: name2 };
|
|
12998
13140
|
}
|
|
12999
|
-
const attr = (node) => ({
|
|
13000
|
-
kind: node.kind,
|
|
13001
|
-
size: node.kind === "file" ? node.data.size : node.kind === "symlink" ? node.target.length : 4096,
|
|
13002
|
-
mtime: node.mtime,
|
|
13003
|
-
mode: node.mode,
|
|
13004
|
-
ino: node.ino,
|
|
13005
|
-
...node.kind === "directory" ? {} : { nlink: node.links }
|
|
13006
|
-
});
|
|
13007
13141
|
const handle = (fh) => {
|
|
13008
13142
|
const found = handles.get(fh);
|
|
13009
13143
|
if (!found) throw fsError2("EBADF", `handle ${fh}`);
|
|
@@ -13016,11 +13150,16 @@ function tmpfs() {
|
|
|
13016
13150
|
if (existing?.kind === "directory" && flags.write) throw fsError2("EISDIR", path);
|
|
13017
13151
|
if (existing) return existing;
|
|
13018
13152
|
if (!flags.create) throw fsError2("ENOENT", path);
|
|
13019
|
-
const node = make("file", 33188);
|
|
13153
|
+
const node = make("file", 33188, dir, flags.owner);
|
|
13020
13154
|
place(dir, name2, node);
|
|
13021
13155
|
return node;
|
|
13022
13156
|
}
|
|
13023
13157
|
return {
|
|
13158
|
+
mount(info) {
|
|
13159
|
+
root.uid = idOption2(info.options.uid);
|
|
13160
|
+
root.gid = idOption2(info.options.gid);
|
|
13161
|
+
return void 0;
|
|
13162
|
+
},
|
|
13024
13163
|
async getattr(path) {
|
|
13025
13164
|
return attr(find(path));
|
|
13026
13165
|
},
|
|
@@ -13053,10 +13192,10 @@ function tmpfs() {
|
|
|
13053
13192
|
handle(fh);
|
|
13054
13193
|
handles.delete(fh);
|
|
13055
13194
|
},
|
|
13056
|
-
async mkdir(path) {
|
|
13195
|
+
async mkdir(path, owner) {
|
|
13057
13196
|
const { dir, name: name2 } = parent(path);
|
|
13058
13197
|
if (dir.children.has(name2)) throw fsError2("EEXIST", path);
|
|
13059
|
-
place(dir, name2, make("directory", 16877));
|
|
13198
|
+
place(dir, name2, make("directory", 16877, dir, owner));
|
|
13060
13199
|
},
|
|
13061
13200
|
async rmdir(path) {
|
|
13062
13201
|
const { dir, name: name2 } = parent(path);
|
|
@@ -13103,10 +13242,10 @@ function tmpfs() {
|
|
|
13103
13242
|
place(dir, name2, node);
|
|
13104
13243
|
node.links++;
|
|
13105
13244
|
},
|
|
13106
|
-
async symlink(target, path) {
|
|
13245
|
+
async symlink(target, path, owner) {
|
|
13107
13246
|
const { dir, name: name2 } = parent(path);
|
|
13108
13247
|
if (dir.children.has(name2)) throw fsError2("EEXIST", path);
|
|
13109
|
-
const node = make("symlink", 41471);
|
|
13248
|
+
const node = make("symlink", 41471, dir, owner && { ...owner, mode: 511 });
|
|
13110
13249
|
node.target = target;
|
|
13111
13250
|
place(dir, name2, node);
|
|
13112
13251
|
},
|
|
@@ -13125,6 +13264,7 @@ function tmpfs() {
|
|
|
13125
13264
|
node.mtime = Date.now();
|
|
13126
13265
|
}
|
|
13127
13266
|
if (change.mtime !== void 0) node.mtime = change.mtime;
|
|
13267
|
+
owned2(node, change);
|
|
13128
13268
|
},
|
|
13129
13269
|
async statfs() {
|
|
13130
13270
|
return { bsize: 4096, blocks: 262144, bfree: 262144 };
|
|
@@ -13445,7 +13585,8 @@ var Launcher = class {
|
|
|
13445
13585
|
this.mounts = new MountTable({
|
|
13446
13586
|
open: (type, spec) => this.driver(type, spec),
|
|
13447
13587
|
busy: (target) => [...this.openFiles].some((nodes) => nodes.holds(target)) || heldUnder(this.held, target),
|
|
13448
|
-
changed: this.watchers.changed.bind(this.watchers)
|
|
13588
|
+
changed: this.watchers.changed.bind(this.watchers),
|
|
13589
|
+
owners: this.owners
|
|
13449
13590
|
});
|
|
13450
13591
|
this.base = this.watchers.wrap(this.mounts.wrap(options.fs));
|
|
13451
13592
|
this.createWorker = options.createWorker;
|
|
@@ -13478,7 +13619,8 @@ var Launcher = class {
|
|
|
13478
13619
|
const fs = withCommandDirs(
|
|
13479
13620
|
this.base,
|
|
13480
13621
|
async () => new Set((await this.commands()).keys()),
|
|
13481
|
-
(dir) => this.userCommandDir(dir)
|
|
13622
|
+
(dir) => this.userCommandDir(dir),
|
|
13623
|
+
this.owners
|
|
13482
13624
|
);
|
|
13483
13625
|
this.nodes = new VfsNodes(fs, (path) => this.released(path));
|
|
13484
13626
|
this.nodes.keepsOnDisk = true;
|
|
@@ -14008,7 +14150,15 @@ var Launcher = class {
|
|
|
14008
14150
|
serveFilesystem(
|
|
14009
14151
|
port2,
|
|
14010
14152
|
tmpfs(),
|
|
14011
|
-
{
|
|
14153
|
+
{
|
|
14154
|
+
symlinks: true,
|
|
14155
|
+
links: true,
|
|
14156
|
+
chmod: true,
|
|
14157
|
+
owners: true,
|
|
14158
|
+
linkTimes: true,
|
|
14159
|
+
ranges: true,
|
|
14160
|
+
attrTtl: 0
|
|
14161
|
+
},
|
|
14012
14162
|
{ owned: true }
|
|
14013
14163
|
);
|
|
14014
14164
|
return {
|
|
@@ -14081,6 +14231,11 @@ var Launcher = class {
|
|
|
14081
14231
|
void this.unlinked.sweep(entry.target);
|
|
14082
14232
|
return entry;
|
|
14083
14233
|
}
|
|
14234
|
+
mountedBy(spec, cred) {
|
|
14235
|
+
if (!this.owners || cred.euid === 0 && cred.egid === 0) return spec;
|
|
14236
|
+
const ids = { uid: String(cred.euid), gid: String(cred.egid) };
|
|
14237
|
+
return { ...spec, options: { ...ids, ...spec.options } };
|
|
14238
|
+
}
|
|
14084
14239
|
mountRoot(path) {
|
|
14085
14240
|
let root = "/";
|
|
14086
14241
|
for (const { target } of this.mounts.list()) {
|
|
@@ -14124,7 +14279,7 @@ var Launcher = class {
|
|
|
14124
14279
|
async processMount(pid, call, signal) {
|
|
14125
14280
|
const spec = mountCall(call);
|
|
14126
14281
|
await this.permit({ op: "mount", pid, ...spec, options: { ...spec.options } });
|
|
14127
|
-
const entry = await this.mount(spec);
|
|
14282
|
+
const entry = await this.mount(this.mountedBy(spec, this.credOf(pid)));
|
|
14128
14283
|
if (signal.aborted) this.umount(entry.target, true);
|
|
14129
14284
|
}
|
|
14130
14285
|
async processUmount(pid, target, flags) {
|