@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/node.js
CHANGED
|
@@ -1774,12 +1774,22 @@ var UserDb = class {
|
|
|
1774
1774
|
async stampHome(row, shared) {
|
|
1775
1775
|
const home = this.fs.resolvePath("/", row.home);
|
|
1776
1776
|
if (!this.owners || !this.fs.chown || !HOME_DIR.test(home)) return;
|
|
1777
|
-
if (await this.
|
|
1778
|
-
if (!(await this.fs.lstat(home)).isDirectory) return;
|
|
1777
|
+
if (!await this.realDir(home)) return;
|
|
1779
1778
|
const gid = shared?.gid ?? row.gid;
|
|
1780
1779
|
await this.fs.chown(home, { uid: row.uid, gid, follow: false, kind: "adopt" });
|
|
1781
|
-
const
|
|
1782
|
-
await this.fs.chmod(home,
|
|
1780
|
+
const scoop = row.name.startsWith("scoop-");
|
|
1781
|
+
await this.fs.chmod(home, shared ? 1512 : scoop ? 488 : 448);
|
|
1782
|
+
const pnpm = `${home}/.local/share/pnpm`;
|
|
1783
|
+
if (await this.realDir(pnpm)) await this.fs.chmod(pnpm, scoop ? 488 : 448);
|
|
1784
|
+
}
|
|
1785
|
+
async realDir(path) {
|
|
1786
|
+
const parts = path.split("/").filter(Boolean);
|
|
1787
|
+
for (let n = 1; n <= parts.length; n++) {
|
|
1788
|
+
const at = `/${parts.slice(0, n).join("/")}`;
|
|
1789
|
+
const st = await this.fs.lstat(at).catch(() => void 0);
|
|
1790
|
+
if (!st?.isDirectory) return false;
|
|
1791
|
+
}
|
|
1792
|
+
return true;
|
|
1783
1793
|
}
|
|
1784
1794
|
async read(path, fallback) {
|
|
1785
1795
|
try {
|
|
@@ -1796,15 +1806,17 @@ var UserDb = class {
|
|
|
1796
1806
|
};
|
|
1797
1807
|
}
|
|
1798
1808
|
async provision(row) {
|
|
1809
|
+
const owner = this.owners ? { uid: row.uid, gid: row.gid } : void 0;
|
|
1810
|
+
const made2 = owner ? { recursive: true, owner } : { recursive: true };
|
|
1799
1811
|
const pnpm = `${row.home}/.local/share/pnpm`;
|
|
1800
1812
|
if (!await this.fs.exists(pnpm)) {
|
|
1801
|
-
await this.fs.mkdir(pnpm,
|
|
1813
|
+
await this.fs.mkdir(pnpm, made2);
|
|
1802
1814
|
await this.fs.chmod(pnpm, row.name.startsWith("scoop-") ? 488 : 448);
|
|
1803
1815
|
}
|
|
1804
1816
|
const config = `${row.home}/.config/pnpm/config.yaml`;
|
|
1805
1817
|
if (!await this.fs.exists(config)) {
|
|
1806
|
-
await this.fs.mkdir(`${row.home}/.config/pnpm`,
|
|
1807
|
-
await this.fs.writeFile(config, PNPM_CONFIG);
|
|
1818
|
+
await this.fs.mkdir(`${row.home}/.config/pnpm`, made2);
|
|
1819
|
+
await this.fs.writeFile(config, PNPM_CONFIG, owner);
|
|
1808
1820
|
}
|
|
1809
1821
|
}
|
|
1810
1822
|
async commit(passwd, group, then) {
|
|
@@ -2008,7 +2020,7 @@ async function fsCall(fs, method, args, owner) {
|
|
|
2008
2020
|
return { result: bytes, transfer: [bytes.buffer] };
|
|
2009
2021
|
}
|
|
2010
2022
|
case "writeFile":
|
|
2011
|
-
await fs.writeFile(path(0), args[1], owner);
|
|
2023
|
+
await fs.writeFile(path(0), args[1], created(owner, 438));
|
|
2012
2024
|
return { result: true };
|
|
2013
2025
|
case "stat":
|
|
2014
2026
|
return { result: await fs.stat(path(0)) };
|
|
@@ -2017,7 +2029,10 @@ async function fsCall(fs, method, args, owner) {
|
|
|
2017
2029
|
case "readdir":
|
|
2018
2030
|
return { result: await fs.readdir(path(0)) };
|
|
2019
2031
|
case "mkdir":
|
|
2020
|
-
await fs.mkdir(
|
|
2032
|
+
await fs.mkdir(
|
|
2033
|
+
path(0),
|
|
2034
|
+
owner ? { recursive: true, owner: made(owner) } : { recursive: true }
|
|
2035
|
+
);
|
|
2021
2036
|
return { result: true };
|
|
2022
2037
|
case "rm":
|
|
2023
2038
|
await fs.rm(path(0), { recursive: true, force: args[1] === true });
|
|
@@ -2028,7 +2043,7 @@ async function fsCall(fs, method, args, owner) {
|
|
|
2028
2043
|
case "realpath":
|
|
2029
2044
|
return { result: await realpath(fs, String(args[0])) };
|
|
2030
2045
|
case "symlink":
|
|
2031
|
-
await fs.symlink(String(args[0]), path(1), owner);
|
|
2046
|
+
await fs.symlink(String(args[0]), path(1), owner && { uid: owner.uid, gid: owner.gid });
|
|
2032
2047
|
return { result: true };
|
|
2033
2048
|
case "readlink":
|
|
2034
2049
|
return { result: await fs.readlink(path(0)) };
|
|
@@ -2050,8 +2065,16 @@ function dialFor(l, req, open) {
|
|
|
2050
2065
|
);
|
|
2051
2066
|
return { result: port2, transfer: [port2] };
|
|
2052
2067
|
}
|
|
2068
|
+
function created(owner, mode) {
|
|
2069
|
+
return owner && { uid: owner.uid, gid: owner.gid, mode: mode & ~owner.umask };
|
|
2070
|
+
}
|
|
2071
|
+
function made(owner) {
|
|
2072
|
+
const mode = 511 & ~owner.umask;
|
|
2073
|
+
return { uid: owner.uid, gid: owner.gid, mode, parents: mode | 192 };
|
|
2074
|
+
}
|
|
2053
2075
|
function ownerFor(l, self) {
|
|
2054
|
-
|
|
2076
|
+
if (!l.owners || !self) return void 0;
|
|
2077
|
+
return { uid: self.uid, gid: self.gid, umask: self.umask ?? 18 };
|
|
2055
2078
|
}
|
|
2056
2079
|
async function accountOf(l, user) {
|
|
2057
2080
|
const found = await l.users.lookup(user);
|
|
@@ -2925,12 +2948,12 @@ var OpfsFs = class {
|
|
|
2925
2948
|
const base = dir === "/" ? "" : dir;
|
|
2926
2949
|
const metas = await this.meta.get(children2.map(([name2]) => `${base}/${name2}`));
|
|
2927
2950
|
const handed2 = this.owners ? await this.handedTo(dir) : void 0;
|
|
2928
|
-
const
|
|
2951
|
+
const owned3 = (stat, entry) => handed2 ? { ...stat, ...ownOf(entry) ?? handed2 } : stat;
|
|
2929
2952
|
return Promise.all(
|
|
2930
2953
|
children2.map(async ([name2, child], i) => {
|
|
2931
|
-
if (!isHandle(child)) return [name2,
|
|
2954
|
+
if (!isHandle(child)) return [name2, owned3(this.linkStat(child), child)];
|
|
2932
2955
|
const stat = await this.statOf(`${base}/${name2}`, child, metas[i]).catch(() => null);
|
|
2933
|
-
return [name2, stat &&
|
|
2956
|
+
return [name2, stat && owned3(stat, metas[i])];
|
|
2934
2957
|
})
|
|
2935
2958
|
);
|
|
2936
2959
|
}
|
|
@@ -2961,9 +2984,9 @@ var OpfsFs = class {
|
|
|
2961
2984
|
const parent = await this.locate(parentOf2(path), true);
|
|
2962
2985
|
if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
|
|
2963
2986
|
await parent.handle.getDirectoryHandle(baseOf(path), { create: true });
|
|
2964
|
-
const
|
|
2965
|
-
await this.stampNew(
|
|
2966
|
-
this.touch(parent.path,
|
|
2987
|
+
const made2 = `${parent.path === "/" ? "" : parent.path}/${baseOf(path)}`;
|
|
2988
|
+
await this.stampNew(made2, owner, true);
|
|
2989
|
+
this.touch(parent.path, made2);
|
|
2967
2990
|
}
|
|
2968
2991
|
async rm(path, options = {}) {
|
|
2969
2992
|
let found;
|
|
@@ -4408,7 +4431,17 @@ async function followLinks(fs, path) {
|
|
|
4408
4431
|
}
|
|
4409
4432
|
return current;
|
|
4410
4433
|
}
|
|
4411
|
-
function withCommandDirs(fs, names, userDir = async () => void 0) {
|
|
4434
|
+
function withCommandDirs(fs, names, userDir = async () => void 0, owners = false) {
|
|
4435
|
+
async function nearest(path) {
|
|
4436
|
+
const st = await fs.stat(path).catch(() => void 0);
|
|
4437
|
+
if (st || path === "/") return st ?? {};
|
|
4438
|
+
return nearest(path.slice(0, path.lastIndexOf("/")) || "/");
|
|
4439
|
+
}
|
|
4440
|
+
async function owned3(stat2, dir) {
|
|
4441
|
+
if (!owners) return stat2;
|
|
4442
|
+
const { uid = 0, gid = 0 } = dir === void 0 ? {} : await nearest(dir);
|
|
4443
|
+
return { ...stat2, uid, gid };
|
|
4444
|
+
}
|
|
4412
4445
|
async function children2(path) {
|
|
4413
4446
|
if (path === "/") return ["bin", "usr"];
|
|
4414
4447
|
if (path === "/usr") return ["bin"];
|
|
@@ -4417,13 +4450,18 @@ function withCommandDirs(fs, names, userDir = async () => void 0) {
|
|
|
4417
4450
|
return own?.size ? [...own] : void 0;
|
|
4418
4451
|
}
|
|
4419
4452
|
async function virtual(path) {
|
|
4420
|
-
if (path === "/usr" || path === "/bin" || path === "/usr/bin")
|
|
4453
|
+
if (path === "/usr" || path === "/bin" || path === "/usr/bin") {
|
|
4454
|
+
return owned3(synthetic(true, path));
|
|
4455
|
+
}
|
|
4421
4456
|
const name2 = COMMAND.exec(path)?.[1];
|
|
4422
|
-
if (name2 !== void 0)
|
|
4423
|
-
|
|
4457
|
+
if (name2 !== void 0) {
|
|
4458
|
+
return (await names()).has(name2) ? owned3(synthetic(false, path)) : void 0;
|
|
4459
|
+
}
|
|
4460
|
+
if ((await userDir(path))?.size) return owned3(synthetic(true, path), path);
|
|
4424
4461
|
const slash = path.lastIndexOf("/");
|
|
4425
|
-
const
|
|
4426
|
-
|
|
4462
|
+
const dir = path.slice(0, slash);
|
|
4463
|
+
const own = await userDir(dir);
|
|
4464
|
+
return own?.has(path.slice(slash + 1)) ? owned3(synthetic(false, path), dir) : void 0;
|
|
4427
4465
|
}
|
|
4428
4466
|
async function linked(path) {
|
|
4429
4467
|
return await virtual(path) ?? virtual(await followLinks(fs, path));
|
|
@@ -4599,18 +4637,18 @@ var FsWatchers = class {
|
|
|
4599
4637
|
const overrides = {
|
|
4600
4638
|
writeFile: after(fs.writeFile.bind(fs), (path) => [path]),
|
|
4601
4639
|
mkdir: async (path, options) => {
|
|
4602
|
-
const
|
|
4640
|
+
const created3 = [];
|
|
4603
4641
|
if (options?.recursive) {
|
|
4604
4642
|
const parts = normalizePath(path).split("/").filter(Boolean);
|
|
4605
4643
|
for (let at = 1; at < parts.length; at++) {
|
|
4606
4644
|
const ancestor = `/${parts.slice(0, at).join("/")}`;
|
|
4607
|
-
if (
|
|
4645
|
+
if (created3.length > 0 || !await fs.exists(ancestor)) created3.push(ancestor);
|
|
4608
4646
|
}
|
|
4609
4647
|
}
|
|
4610
4648
|
try {
|
|
4611
4649
|
await fs.mkdir(path, options);
|
|
4612
4650
|
} finally {
|
|
4613
|
-
this.changed(...
|
|
4651
|
+
this.changed(...created3, path);
|
|
4614
4652
|
}
|
|
4615
4653
|
},
|
|
4616
4654
|
rm: after(fs.rm.bind(fs), (path) => [path]),
|
|
@@ -4889,7 +4927,7 @@ async function realTarget(fs, path) {
|
|
|
4889
4927
|
}
|
|
4890
4928
|
|
|
4891
4929
|
// src/mount/protocol.ts
|
|
4892
|
-
var DRIVER_PROTOCOL = [1,
|
|
4930
|
+
var DRIVER_PROTOCOL = [1, 2];
|
|
4893
4931
|
function driverVersionError(theirs) {
|
|
4894
4932
|
const major = Array.isArray(theirs) ? theirs[0] : void 0;
|
|
4895
4933
|
if (major === DRIVER_PROTOCOL[0]) return void 0;
|
|
@@ -4991,6 +5029,19 @@ var DriverConnection = class _DriverConnection {
|
|
|
4991
5029
|
};
|
|
4992
5030
|
|
|
4993
5031
|
// src/mount/mount-fs.ts
|
|
5032
|
+
var S_ISGID3 = 1024;
|
|
5033
|
+
var ID = /^\d{1,10}$/;
|
|
5034
|
+
var MAX_ID2 = 4294967294;
|
|
5035
|
+
function idOption(value) {
|
|
5036
|
+
return value === void 0 ? 0 : Number(value);
|
|
5037
|
+
}
|
|
5038
|
+
function checkIds(options) {
|
|
5039
|
+
for (const key of ["uid", "gid"]) {
|
|
5040
|
+
const value = options[key];
|
|
5041
|
+
if (value === void 0) continue;
|
|
5042
|
+
if (!ID.test(value) || Number(value) > MAX_ID2) throw errnoError("EINVAL", `${key}=${value}`);
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
4994
5045
|
var MAX_LINKS5 = 40;
|
|
4995
5046
|
var STALE_RETRIES = 3;
|
|
4996
5047
|
var SETTLE_ROUNDS = 4;
|
|
@@ -5157,31 +5208,35 @@ var HeldPaths = class extends Map {
|
|
|
5157
5208
|
};
|
|
5158
5209
|
var parentOf6 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
|
|
5159
5210
|
var readonly = (mount) => mount.caps.readonly === true || mount.options.ro !== void 0;
|
|
5160
|
-
function inodeless(mount,
|
|
5161
|
-
if (
|
|
5211
|
+
function inodeless(mount, attr2) {
|
|
5212
|
+
if (attr2.ino !== void 0) return false;
|
|
5162
5213
|
if (mount.caps.links) mount.caps = { ...mount.caps, links: false };
|
|
5163
5214
|
return true;
|
|
5164
5215
|
}
|
|
5165
|
-
function statOf(
|
|
5166
|
-
const mtime = new Date(
|
|
5167
|
-
const fallback =
|
|
5216
|
+
function statOf(attr2, path, mount) {
|
|
5217
|
+
const mtime = new Date(attr2.mtime);
|
|
5218
|
+
const fallback = attr2.kind === "directory" ? 16877 : attr2.kind === "symlink" ? 41471 : 33188;
|
|
5168
5219
|
return {
|
|
5169
|
-
isFile:
|
|
5170
|
-
isDirectory:
|
|
5171
|
-
isSymbolicLink:
|
|
5172
|
-
size:
|
|
5173
|
-
mode:
|
|
5220
|
+
isFile: attr2.kind === "file",
|
|
5221
|
+
isDirectory: attr2.kind === "directory",
|
|
5222
|
+
isSymbolicLink: attr2.kind === "symlink",
|
|
5223
|
+
size: attr2.size,
|
|
5224
|
+
mode: attr2.mode ?? fallback,
|
|
5174
5225
|
mtime,
|
|
5175
5226
|
atime: mtime,
|
|
5176
5227
|
ctime: mtime,
|
|
5177
|
-
ino:
|
|
5178
|
-
...!inodeless(mount,
|
|
5228
|
+
ino: attr2.ino ?? inodeOf(path),
|
|
5229
|
+
...!inodeless(mount, attr2) && attr2.nlink !== void 0 ? { nlink: attr2.nlink } : {},
|
|
5179
5230
|
dev: mount.dev,
|
|
5180
5231
|
...readonly(mount) ? { readonly: true } : {},
|
|
5181
5232
|
...mount.maxFile > 0 ? { maxFile: mount.maxFile } : {},
|
|
5182
5233
|
...mount.caps.ranges ? { ranged: true } : {},
|
|
5183
5234
|
...mount.caps.links ? { linkable: true } : {},
|
|
5184
|
-
...
|
|
5235
|
+
...attr2.etag !== void 0 ? { version: attr2.etag } : {},
|
|
5236
|
+
...mount.owners ? {
|
|
5237
|
+
uid: (mount.caps.owners ? attr2.uid : void 0) ?? idOption(mount.options.uid),
|
|
5238
|
+
gid: (mount.caps.owners ? attr2.gid : void 0) ?? idOption(mount.options.gid)
|
|
5239
|
+
} : {}
|
|
5185
5240
|
};
|
|
5186
5241
|
}
|
|
5187
5242
|
function concat3(chunks2, total) {
|
|
@@ -5274,6 +5329,7 @@ var MountTable = class {
|
|
|
5274
5329
|
const st = await fs.stat(target);
|
|
5275
5330
|
if (!st.isDirectory) throw errnoError("ENOTDIR", target);
|
|
5276
5331
|
const options = { ...spec.options };
|
|
5332
|
+
if (this.deps.owners) checkIds(options);
|
|
5277
5333
|
const maxFile = options.maxfile !== void 0 ? parseSize(options.maxfile) : void 0;
|
|
5278
5334
|
const opened2 = await this.deps.open(spec.type, { ...spec, target, options });
|
|
5279
5335
|
let mounted;
|
|
@@ -5319,6 +5375,7 @@ var MountTable = class {
|
|
|
5319
5375
|
attrs: /* @__PURE__ */ new Map(),
|
|
5320
5376
|
lists: /* @__PURE__ */ new Map(),
|
|
5321
5377
|
epoch: 0,
|
|
5378
|
+
owners: this.deps.owners === true,
|
|
5322
5379
|
dispose: () => opened2.dispose(),
|
|
5323
5380
|
...opened2.present ? { present: opened2.present } : {}
|
|
5324
5381
|
};
|
|
@@ -5440,15 +5497,15 @@ var MountTable = class {
|
|
|
5440
5497
|
if (cached && cached.expires > Date.now()) return cached.value;
|
|
5441
5498
|
const seen = mount.epoch;
|
|
5442
5499
|
const session = this.sessions.get(path);
|
|
5443
|
-
const
|
|
5500
|
+
const attr2 = await mount.conn.call({ op: "getattr", path: rel2 });
|
|
5444
5501
|
if (mount.epoch !== seen) {
|
|
5445
5502
|
const moved2 = this.sessions.get(path) !== session || this.committing.has(path);
|
|
5446
5503
|
if (settled && moved2 && round < SETTLE_ROUNDS) continue;
|
|
5447
|
-
return
|
|
5504
|
+
return attr2;
|
|
5448
5505
|
}
|
|
5449
5506
|
const ttl = mount.caps.attrTtl ?? 1e3;
|
|
5450
|
-
if (ttl > 0) mount.attrs.set(path, { value:
|
|
5451
|
-
return
|
|
5507
|
+
if (ttl > 0) mount.attrs.set(path, { value: attr2, expires: Date.now() + ttl });
|
|
5508
|
+
return attr2;
|
|
5452
5509
|
}
|
|
5453
5510
|
}
|
|
5454
5511
|
async readdir(mount, path, rel2) {
|
|
@@ -5495,28 +5552,43 @@ var MountFs = class {
|
|
|
5495
5552
|
const found = this.at(path);
|
|
5496
5553
|
if (!found) return path;
|
|
5497
5554
|
const real = normalizePath(path);
|
|
5498
|
-
let
|
|
5555
|
+
let attr2;
|
|
5499
5556
|
try {
|
|
5500
|
-
|
|
5557
|
+
attr2 = await this.table.getattr(found.mount, real, found.rel);
|
|
5501
5558
|
} catch (err) {
|
|
5502
5559
|
if (create && err.code === "ENOENT") return real;
|
|
5503
5560
|
throw err;
|
|
5504
5561
|
}
|
|
5505
|
-
if (
|
|
5562
|
+
if (attr2.kind !== "symlink") return real;
|
|
5506
5563
|
if (hops >= MAX_LINKS5) throw errnoError("ELOOP", path);
|
|
5507
5564
|
const target = await found.mount.conn.call({ op: "readlink", path: found.rel });
|
|
5508
5565
|
return this.follow(this.base.resolvePath(parentOf6(real), target), hops + 1, create);
|
|
5509
5566
|
}
|
|
5510
|
-
async open(mount, rel2, write) {
|
|
5567
|
+
async open(mount, rel2, write, owner) {
|
|
5511
5568
|
return await mount.conn.call({
|
|
5512
5569
|
op: "open",
|
|
5513
5570
|
path: rel2,
|
|
5514
5571
|
write,
|
|
5515
5572
|
create: write,
|
|
5516
5573
|
truncate: write,
|
|
5517
|
-
exclusive: false
|
|
5574
|
+
exclusive: false,
|
|
5575
|
+
...owner
|
|
5518
5576
|
});
|
|
5519
5577
|
}
|
|
5578
|
+
async driverOwner(found, real, owner, directory) {
|
|
5579
|
+
const { mount, rel: rel2 } = found;
|
|
5580
|
+
if (!owner || !mount.owners || !mount.caps.owners) return void 0;
|
|
5581
|
+
const dir = parentOf6(real);
|
|
5582
|
+
const above = statOf(await this.table.getattr(mount, dir, parentOf6(rel2)), dir, mount);
|
|
5583
|
+
const setgid = (above.mode & S_ISGID3) !== 0;
|
|
5584
|
+
let mode = owner.mode;
|
|
5585
|
+
if (directory && setgid) mode = (mode ?? 493) | S_ISGID3;
|
|
5586
|
+
return {
|
|
5587
|
+
uid: owner.uid,
|
|
5588
|
+
gid: setgid ? above.gid : owner.gid,
|
|
5589
|
+
...mode !== void 0 ? { mode } : {}
|
|
5590
|
+
};
|
|
5591
|
+
}
|
|
5520
5592
|
resolvePath(base, path) {
|
|
5521
5593
|
return this.base.resolvePath(base, path);
|
|
5522
5594
|
}
|
|
@@ -5538,9 +5610,9 @@ var MountFs = class {
|
|
|
5538
5610
|
}
|
|
5539
5611
|
async readWhole(mount, real, rel2) {
|
|
5540
5612
|
await this.table.commit(real);
|
|
5541
|
-
const
|
|
5542
|
-
if (
|
|
5543
|
-
if (mount.maxFile > 0 &&
|
|
5613
|
+
const attr2 = await this.table.getattr(mount, real, rel2);
|
|
5614
|
+
if (attr2.kind === "directory") throw errnoError("EISDIR", real);
|
|
5615
|
+
if (mount.maxFile > 0 && attr2.size > mount.maxFile) {
|
|
5544
5616
|
throw errnoError("EFBIG", `${real} is larger than this mount's maxfile (${mount.maxFile})`);
|
|
5545
5617
|
}
|
|
5546
5618
|
const fh = await this.open(mount, rel2, false);
|
|
@@ -5558,7 +5630,7 @@ var MountFs = class {
|
|
|
5558
5630
|
if (bytes.length === 0) break;
|
|
5559
5631
|
chunks2.push(bytes);
|
|
5560
5632
|
total += bytes.length;
|
|
5561
|
-
if (bytes.length < chunk2 && total >=
|
|
5633
|
+
if (bytes.length < chunk2 && total >= attr2.size) break;
|
|
5562
5634
|
}
|
|
5563
5635
|
} finally {
|
|
5564
5636
|
await mount.conn.call({ op: "release", fh });
|
|
@@ -5578,18 +5650,19 @@ var MountFs = class {
|
|
|
5578
5650
|
`${real} would be larger than this mount's maxfile (${mount.maxFile})`
|
|
5579
5651
|
);
|
|
5580
5652
|
}
|
|
5653
|
+
const made2 = await this.driverOwner(found, real, owner, false);
|
|
5581
5654
|
for (let attempt = 1; ; attempt++) {
|
|
5582
5655
|
try {
|
|
5583
|
-
return await this.writeWhole(mount, real, rel2, bytes);
|
|
5656
|
+
return await this.writeWhole(mount, real, rel2, bytes, made2);
|
|
5584
5657
|
} catch (err) {
|
|
5585
5658
|
if (err.code !== "ESTALE" || attempt >= STALE_RETRIES) throw err;
|
|
5586
5659
|
}
|
|
5587
5660
|
}
|
|
5588
5661
|
}
|
|
5589
|
-
async writeWhole(mount, real, rel2, bytes) {
|
|
5662
|
+
async writeWhole(mount, real, rel2, bytes, owner) {
|
|
5590
5663
|
await this.table.commit(real);
|
|
5591
5664
|
this.table.forget(mount, real);
|
|
5592
|
-
const fh = await this.open(mount, rel2, true);
|
|
5665
|
+
const fh = await this.open(mount, rel2, true, owner);
|
|
5593
5666
|
const chunk2 = mount.caps.maxIo ?? DEFAULT_IO;
|
|
5594
5667
|
try {
|
|
5595
5668
|
for (let offset = 0; offset < bytes.length; offset += chunk2) {
|
|
@@ -5735,9 +5808,9 @@ var MountFs = class {
|
|
|
5735
5808
|
found.mount
|
|
5736
5809
|
);
|
|
5737
5810
|
}
|
|
5738
|
-
statWriting(
|
|
5811
|
+
statWriting(attr2, real, mount) {
|
|
5739
5812
|
const ends = (this.table.writing(real)?.extents ?? []).map(([, end]) => end);
|
|
5740
|
-
return statOf({ ...
|
|
5813
|
+
return statOf({ ...attr2, size: Math.max(attr2.size, ...ends) }, real, mount);
|
|
5741
5814
|
}
|
|
5742
5815
|
async stat(path) {
|
|
5743
5816
|
const real = await this.follow(path);
|
|
@@ -5776,10 +5849,12 @@ var MountFs = class {
|
|
|
5776
5849
|
const { mount, rel: rel2 } = found;
|
|
5777
5850
|
const real = normalizePath(path);
|
|
5778
5851
|
this.writable(mount, real);
|
|
5852
|
+
const { owner } = options;
|
|
5779
5853
|
if (!options.recursive) {
|
|
5780
5854
|
if (rel2 === "/") throw errnoError("EEXIST", real);
|
|
5855
|
+
const made2 = await this.driverOwner(found, real, owner, true);
|
|
5781
5856
|
this.table.forget(mount, real);
|
|
5782
|
-
await mount.conn.call({ op: "mkdir", path: rel2 });
|
|
5857
|
+
await mount.conn.call({ op: "mkdir", path: rel2, ...made2 });
|
|
5783
5858
|
return;
|
|
5784
5859
|
}
|
|
5785
5860
|
const parts = rel2.split("/").filter(Boolean);
|
|
@@ -5789,8 +5864,10 @@ var MountFs = class {
|
|
|
5789
5864
|
const exists = await this.table.getattr(mount, full, sub).catch(() => void 0);
|
|
5790
5865
|
if (exists?.kind === "directory") continue;
|
|
5791
5866
|
if (exists) throw errnoError("ENOTDIR", full);
|
|
5867
|
+
const own = n === parts.length ? owner : owner && { ...owner, mode: owner.parents };
|
|
5868
|
+
const made2 = await this.driverOwner({ mount, rel: sub }, full, own, true);
|
|
5792
5869
|
this.table.forget(mount, full);
|
|
5793
|
-
await mount.conn.call({ op: "mkdir", path: sub });
|
|
5870
|
+
await mount.conn.call({ op: "mkdir", path: sub, ...made2 });
|
|
5794
5871
|
}
|
|
5795
5872
|
}
|
|
5796
5873
|
async rm(path, options = {}) {
|
|
@@ -5801,21 +5878,21 @@ var MountFs = class {
|
|
|
5801
5878
|
if (rel2 === "/") throw errnoError("EBUSY", `${real} is a mount point`);
|
|
5802
5879
|
this.writable(mount, real);
|
|
5803
5880
|
await this.table.commitUnder(real);
|
|
5804
|
-
let
|
|
5881
|
+
let attr2;
|
|
5805
5882
|
try {
|
|
5806
|
-
|
|
5883
|
+
attr2 = await this.table.getattr(mount, real, rel2);
|
|
5807
5884
|
} catch (err) {
|
|
5808
5885
|
if (options.force && err.code === "ENOENT") return;
|
|
5809
5886
|
throw err;
|
|
5810
5887
|
}
|
|
5811
5888
|
this.table.forget(mount, real);
|
|
5812
|
-
if (
|
|
5889
|
+
if (attr2.kind === "directory" && options.recursive) {
|
|
5813
5890
|
for (const entry of await this.table.readdir(mount, real, rel2)) {
|
|
5814
5891
|
await this.rm(`${real}/${entry.name}`, { recursive: true, force: options.force ?? false });
|
|
5815
5892
|
}
|
|
5816
5893
|
this.table.forget(mount, real);
|
|
5817
5894
|
}
|
|
5818
|
-
await mount.conn.call({ op:
|
|
5895
|
+
await mount.conn.call({ op: attr2.kind === "directory" ? "rmdir" : "unlink", path: rel2 });
|
|
5819
5896
|
this.table.forget(mount, real);
|
|
5820
5897
|
}
|
|
5821
5898
|
async rename(from, to) {
|
|
@@ -5869,8 +5946,10 @@ var MountFs = class {
|
|
|
5869
5946
|
this.writable(found.mount, normalizePath(path));
|
|
5870
5947
|
if (!found.mount.caps.symlinks)
|
|
5871
5948
|
throw errnoError("EPERM", `${path}: this file system has no symlinks`);
|
|
5949
|
+
const link2 = owner && { uid: owner.uid, gid: owner.gid };
|
|
5950
|
+
const made2 = await this.driverOwner(found, normalizePath(path), link2, false);
|
|
5872
5951
|
this.table.forget(found.mount, normalizePath(path));
|
|
5873
|
-
await found.mount.conn.call({ op: "symlink", target, path: found.rel });
|
|
5952
|
+
await found.mount.conn.call({ op: "symlink", target, path: found.rel, ...made2 });
|
|
5874
5953
|
}
|
|
5875
5954
|
async realpath(path, follow2) {
|
|
5876
5955
|
if (this.at(path) || !this.base.realpath) throw errnoError("ENOSYS", path);
|
|
@@ -5885,13 +5964,29 @@ var MountFs = class {
|
|
|
5885
5964
|
}
|
|
5886
5965
|
async chown(path, change) {
|
|
5887
5966
|
const real = change.follow === false || change.kind === "new" ? path : await this.follow(path);
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
throw errnoError("EPERM", `${path}: this file system keeps no owners`);
|
|
5891
|
-
}
|
|
5967
|
+
const found = this.at(real);
|
|
5968
|
+
if (found) return this.chownMounted(found, normalizePath(real), change);
|
|
5892
5969
|
if (!this.base.chown) throw errnoError("EPERM", path);
|
|
5893
5970
|
return this.base.chown(real, change);
|
|
5894
5971
|
}
|
|
5972
|
+
async chownMounted(found, real, change) {
|
|
5973
|
+
const { mount, rel: rel2 } = found;
|
|
5974
|
+
if (!mount.owners || !mount.caps.owners) {
|
|
5975
|
+
if (change.kind === "new") return;
|
|
5976
|
+
throw errnoError("EPERM", `${real}: this file system keeps no owners`);
|
|
5977
|
+
}
|
|
5978
|
+
this.writable(mount, real);
|
|
5979
|
+
const { uid, gid, mode } = change;
|
|
5980
|
+
const fresh = change.kind === "new" && { uid, gid, mode };
|
|
5981
|
+
const set2 = fresh ? await this.driverOwner(found, real, fresh, false) : change;
|
|
5982
|
+
this.table.forget(mount, real);
|
|
5983
|
+
const attrs = Object.entries({ uid: set2.uid, gid: set2.gid, mode: set2.mode });
|
|
5984
|
+
await mount.conn.call({
|
|
5985
|
+
op: "setattr",
|
|
5986
|
+
path: rel2,
|
|
5987
|
+
...Object.fromEntries(attrs.filter(([, value]) => value !== void 0))
|
|
5988
|
+
});
|
|
5989
|
+
}
|
|
5895
5990
|
async chmod(path, mode) {
|
|
5896
5991
|
const found = this.at(path);
|
|
5897
5992
|
if (!found) return this.base.chmod(path, mode);
|
|
@@ -5998,7 +6093,10 @@ function mkdirOptions(entry, mode = 511) {
|
|
|
5998
6093
|
}
|
|
5999
6094
|
async function chown(entry, path, req) {
|
|
6000
6095
|
const cred = entry.cred?.();
|
|
6001
|
-
if (!cred)
|
|
6096
|
+
if (!cred) {
|
|
6097
|
+
await (req.op === "chown" ? entry.fs.stat(path) : entry.fs.lstat(path));
|
|
6098
|
+
return done;
|
|
6099
|
+
}
|
|
6002
6100
|
await chownAs(entry.fs, cred, path, {
|
|
6003
6101
|
...req.uid !== void 0 ? { uid: req.uid } : {},
|
|
6004
6102
|
...req.gid !== void 0 ? { gid: req.gid } : {},
|
|
@@ -11170,6 +11268,7 @@ function spawnWasmProcess(opts) {
|
|
|
11170
11268
|
cwd: opts.cwd,
|
|
11171
11269
|
sab: tsab,
|
|
11172
11270
|
cred: copyCred(process2.cred),
|
|
11271
|
+
owners: opts.owners === true,
|
|
11173
11272
|
...opts.ppid !== void 0 ? { ppid: opts.ppid } : {},
|
|
11174
11273
|
thread
|
|
11175
11274
|
};
|
|
@@ -11563,6 +11662,17 @@ var SettlingChildren = class {
|
|
|
11563
11662
|
};
|
|
11564
11663
|
|
|
11565
11664
|
// src/mount/driver.ts
|
|
11665
|
+
function ownerOf2(req) {
|
|
11666
|
+
const owner = {
|
|
11667
|
+
...req.uid !== void 0 ? { uid: req.uid } : {},
|
|
11668
|
+
...req.gid !== void 0 ? { gid: req.gid } : {},
|
|
11669
|
+
...req.mode !== void 0 ? { mode: req.mode } : {}
|
|
11670
|
+
};
|
|
11671
|
+
return Object.keys(owner).length > 0 ? owner : void 0;
|
|
11672
|
+
}
|
|
11673
|
+
function withOwner(base, owner) {
|
|
11674
|
+
return owner ? { ...base, owner } : base;
|
|
11675
|
+
}
|
|
11566
11676
|
function fsError2(code, message3 = code) {
|
|
11567
11677
|
return Object.assign(new Error(message3), { code });
|
|
11568
11678
|
}
|
|
@@ -11573,13 +11683,19 @@ async function dispatch(h, req) {
|
|
|
11573
11683
|
case "readdir":
|
|
11574
11684
|
return h.readdir(req.path);
|
|
11575
11685
|
case "open":
|
|
11576
|
-
return h.open(
|
|
11577
|
-
|
|
11578
|
-
|
|
11579
|
-
|
|
11580
|
-
|
|
11581
|
-
|
|
11582
|
-
|
|
11686
|
+
return h.open(
|
|
11687
|
+
req.path,
|
|
11688
|
+
withOwner(
|
|
11689
|
+
{
|
|
11690
|
+
write: req.write,
|
|
11691
|
+
create: req.create,
|
|
11692
|
+
truncate: req.truncate,
|
|
11693
|
+
exclusive: req.exclusive,
|
|
11694
|
+
...req.ifMatch !== void 0 ? { ifMatch: req.ifMatch } : {}
|
|
11695
|
+
},
|
|
11696
|
+
ownerOf2(req)
|
|
11697
|
+
)
|
|
11698
|
+
);
|
|
11583
11699
|
case "read":
|
|
11584
11700
|
return h.read(req.fh, req.offset, req.size);
|
|
11585
11701
|
case "write":
|
|
@@ -11587,7 +11703,7 @@ async function dispatch(h, req) {
|
|
|
11587
11703
|
case "release":
|
|
11588
11704
|
return h.release(req.fh);
|
|
11589
11705
|
case "mkdir":
|
|
11590
|
-
return h.mkdir(req.path);
|
|
11706
|
+
return ownerOf2(req) ? h.mkdir(req.path, ownerOf2(req)) : h.mkdir(req.path);
|
|
11591
11707
|
case "rmdir":
|
|
11592
11708
|
return h.rmdir(req.path);
|
|
11593
11709
|
case "unlink":
|
|
@@ -11599,7 +11715,7 @@ async function dispatch(h, req) {
|
|
|
11599
11715
|
return h.link(req.from, req.to);
|
|
11600
11716
|
case "symlink":
|
|
11601
11717
|
if (!h.symlink) throw fsError2("EPERM", "this file system has no symlinks");
|
|
11602
|
-
return h.symlink(req.target, req.path);
|
|
11718
|
+
return ownerOf2(req) ? h.symlink(req.target, req.path, ownerOf2(req)) : h.symlink(req.target, req.path);
|
|
11603
11719
|
case "readlink":
|
|
11604
11720
|
if (!h.readlink) throw fsError2("EINVAL", `${req.path} is not a symlink`);
|
|
11605
11721
|
return h.readlink(req.path);
|
|
@@ -11607,7 +11723,9 @@ async function dispatch(h, req) {
|
|
|
11607
11723
|
return h.setattr?.(req.path, {
|
|
11608
11724
|
...req.mode !== void 0 ? { mode: req.mode } : {},
|
|
11609
11725
|
...req.mtime !== void 0 ? { mtime: req.mtime } : {},
|
|
11610
|
-
...req.size !== void 0 ? { size: req.size } : {}
|
|
11726
|
+
...req.size !== void 0 ? { size: req.size } : {},
|
|
11727
|
+
...req.uid !== void 0 ? { uid: req.uid } : {},
|
|
11728
|
+
...req.gid !== void 0 ? { gid: req.gid } : {}
|
|
11611
11729
|
});
|
|
11612
11730
|
case "statfs":
|
|
11613
11731
|
return h.statfs?.() ?? null;
|
|
@@ -11758,8 +11876,8 @@ function kernelFsHandlers(fs) {
|
|
|
11758
11876
|
getattr: async (path) => attrOf(await fs.lstat(path)),
|
|
11759
11877
|
readdir: async (path) => (await fs.readdirStat(path)).flatMap(([name2, st]) => {
|
|
11760
11878
|
if (!st) return [];
|
|
11761
|
-
const
|
|
11762
|
-
return [{ name: name2, kind:
|
|
11879
|
+
const attr2 = attrOf(st);
|
|
11880
|
+
return [{ name: name2, kind: attr2.kind, attr: attr2 }];
|
|
11763
11881
|
}),
|
|
11764
11882
|
async open(path, flags) {
|
|
11765
11883
|
const st = await existing(path);
|
|
@@ -12189,7 +12307,7 @@ function hostfsHandlers(current, againMs = RESTORE_AGAIN_MS) {
|
|
|
12189
12307
|
"list",
|
|
12190
12308
|
{ path: rel(path) }
|
|
12191
12309
|
);
|
|
12192
|
-
return entries.map(({ name: name2, attr }) => ({ name: name2, kind:
|
|
12310
|
+
return entries.map(({ name: name2, attr: attr2 }) => ({ name: name2, kind: attr2.kind, attr: attr2 }));
|
|
12193
12311
|
},
|
|
12194
12312
|
async open(path, flags) {
|
|
12195
12313
|
const client = current();
|
|
@@ -12782,8 +12900,8 @@ var ChunkedBytes = class {
|
|
|
12782
12900
|
}
|
|
12783
12901
|
return out;
|
|
12784
12902
|
}
|
|
12785
|
-
write(offset, bytes,
|
|
12786
|
-
const whole =
|
|
12903
|
+
write(offset, bytes, owned3 = false) {
|
|
12904
|
+
const whole = owned3 && bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength;
|
|
12787
12905
|
for (let done4 = 0; done4 < bytes.length; ) {
|
|
12788
12906
|
const at = offset + done4;
|
|
12789
12907
|
const index = Math.floor(at / CHUNK3);
|
|
@@ -12816,18 +12934,42 @@ var ChunkedBytes = class {
|
|
|
12816
12934
|
};
|
|
12817
12935
|
|
|
12818
12936
|
// src/mount/tmpfs.ts
|
|
12819
|
-
function
|
|
12820
|
-
|
|
12821
|
-
|
|
12937
|
+
function idOption2(value) {
|
|
12938
|
+
return value !== void 0 && /^\d+$/.test(value) ? Number(value) : 0;
|
|
12939
|
+
}
|
|
12940
|
+
function created2(ino, kind, mode, from, owner) {
|
|
12941
|
+
return {
|
|
12822
12942
|
kind,
|
|
12823
|
-
ino
|
|
12824
|
-
mode,
|
|
12943
|
+
ino,
|
|
12944
|
+
mode: owner?.mode === void 0 ? mode : mode & ~4095 | owner.mode & 4095,
|
|
12825
12945
|
mtime: Date.now(),
|
|
12826
12946
|
data: new ChunkedBytes(),
|
|
12827
12947
|
target: "",
|
|
12828
12948
|
children: /* @__PURE__ */ new Map(),
|
|
12829
|
-
links: 1
|
|
12830
|
-
|
|
12949
|
+
links: 1,
|
|
12950
|
+
uid: owner?.uid ?? from?.uid ?? 0,
|
|
12951
|
+
gid: owner?.gid ?? from?.gid ?? 0
|
|
12952
|
+
};
|
|
12953
|
+
}
|
|
12954
|
+
function owned2(node, change) {
|
|
12955
|
+
if (change.uid !== void 0) node.uid = change.uid;
|
|
12956
|
+
if (change.gid !== void 0) node.gid = change.gid;
|
|
12957
|
+
}
|
|
12958
|
+
function attr(node) {
|
|
12959
|
+
return {
|
|
12960
|
+
kind: node.kind,
|
|
12961
|
+
size: node.kind === "file" ? node.data.size : node.kind === "symlink" ? node.target.length : 4096,
|
|
12962
|
+
mtime: node.mtime,
|
|
12963
|
+
mode: node.mode,
|
|
12964
|
+
ino: node.ino,
|
|
12965
|
+
...node.kind === "directory" ? {} : { nlink: node.links },
|
|
12966
|
+
uid: node.uid,
|
|
12967
|
+
gid: node.gid
|
|
12968
|
+
};
|
|
12969
|
+
}
|
|
12970
|
+
function tmpfs() {
|
|
12971
|
+
let inodes = 0;
|
|
12972
|
+
const make = (kind, mode, from, owner) => created2(++inodes, kind, mode, from, owner);
|
|
12831
12973
|
const root = make("directory", 16877);
|
|
12832
12974
|
const handles = /* @__PURE__ */ new Map();
|
|
12833
12975
|
let nextFh = 0;
|
|
@@ -12854,14 +12996,6 @@ function tmpfs() {
|
|
|
12854
12996
|
if (dir.kind !== "directory") throw fsError2("ENOTDIR", path);
|
|
12855
12997
|
return { dir, name: name2 };
|
|
12856
12998
|
}
|
|
12857
|
-
const attr = (node) => ({
|
|
12858
|
-
kind: node.kind,
|
|
12859
|
-
size: node.kind === "file" ? node.data.size : node.kind === "symlink" ? node.target.length : 4096,
|
|
12860
|
-
mtime: node.mtime,
|
|
12861
|
-
mode: node.mode,
|
|
12862
|
-
ino: node.ino,
|
|
12863
|
-
...node.kind === "directory" ? {} : { nlink: node.links }
|
|
12864
|
-
});
|
|
12865
12999
|
const handle = (fh) => {
|
|
12866
13000
|
const found = handles.get(fh);
|
|
12867
13001
|
if (!found) throw fsError2("EBADF", `handle ${fh}`);
|
|
@@ -12874,11 +13008,16 @@ function tmpfs() {
|
|
|
12874
13008
|
if (existing?.kind === "directory" && flags.write) throw fsError2("EISDIR", path);
|
|
12875
13009
|
if (existing) return existing;
|
|
12876
13010
|
if (!flags.create) throw fsError2("ENOENT", path);
|
|
12877
|
-
const node = make("file", 33188);
|
|
13011
|
+
const node = make("file", 33188, dir, flags.owner);
|
|
12878
13012
|
place(dir, name2, node);
|
|
12879
13013
|
return node;
|
|
12880
13014
|
}
|
|
12881
13015
|
return {
|
|
13016
|
+
mount(info) {
|
|
13017
|
+
root.uid = idOption2(info.options.uid);
|
|
13018
|
+
root.gid = idOption2(info.options.gid);
|
|
13019
|
+
return void 0;
|
|
13020
|
+
},
|
|
12882
13021
|
async getattr(path) {
|
|
12883
13022
|
return attr(find(path));
|
|
12884
13023
|
},
|
|
@@ -12911,10 +13050,10 @@ function tmpfs() {
|
|
|
12911
13050
|
handle(fh);
|
|
12912
13051
|
handles.delete(fh);
|
|
12913
13052
|
},
|
|
12914
|
-
async mkdir(path) {
|
|
13053
|
+
async mkdir(path, owner) {
|
|
12915
13054
|
const { dir, name: name2 } = parent(path);
|
|
12916
13055
|
if (dir.children.has(name2)) throw fsError2("EEXIST", path);
|
|
12917
|
-
place(dir, name2, make("directory", 16877));
|
|
13056
|
+
place(dir, name2, make("directory", 16877, dir, owner));
|
|
12918
13057
|
},
|
|
12919
13058
|
async rmdir(path) {
|
|
12920
13059
|
const { dir, name: name2 } = parent(path);
|
|
@@ -12961,10 +13100,10 @@ function tmpfs() {
|
|
|
12961
13100
|
place(dir, name2, node);
|
|
12962
13101
|
node.links++;
|
|
12963
13102
|
},
|
|
12964
|
-
async symlink(target, path) {
|
|
13103
|
+
async symlink(target, path, owner) {
|
|
12965
13104
|
const { dir, name: name2 } = parent(path);
|
|
12966
13105
|
if (dir.children.has(name2)) throw fsError2("EEXIST", path);
|
|
12967
|
-
const node = make("symlink", 41471);
|
|
13106
|
+
const node = make("symlink", 41471, dir, owner && { ...owner, mode: 511 });
|
|
12968
13107
|
node.target = target;
|
|
12969
13108
|
place(dir, name2, node);
|
|
12970
13109
|
},
|
|
@@ -12983,6 +13122,7 @@ function tmpfs() {
|
|
|
12983
13122
|
node.mtime = Date.now();
|
|
12984
13123
|
}
|
|
12985
13124
|
if (change.mtime !== void 0) node.mtime = change.mtime;
|
|
13125
|
+
owned2(node, change);
|
|
12986
13126
|
},
|
|
12987
13127
|
async statfs() {
|
|
12988
13128
|
return { bsize: 4096, blocks: 262144, bfree: 262144 };
|
|
@@ -13303,7 +13443,8 @@ var Launcher = class {
|
|
|
13303
13443
|
this.mounts = new MountTable({
|
|
13304
13444
|
open: (type, spec) => this.driver(type, spec),
|
|
13305
13445
|
busy: (target) => [...this.openFiles].some((nodes) => nodes.holds(target)) || heldUnder(this.held, target),
|
|
13306
|
-
changed: this.watchers.changed.bind(this.watchers)
|
|
13446
|
+
changed: this.watchers.changed.bind(this.watchers),
|
|
13447
|
+
owners: this.owners
|
|
13307
13448
|
});
|
|
13308
13449
|
this.base = this.watchers.wrap(this.mounts.wrap(options.fs));
|
|
13309
13450
|
this.createWorker = options.createWorker;
|
|
@@ -13336,7 +13477,8 @@ var Launcher = class {
|
|
|
13336
13477
|
const fs = withCommandDirs(
|
|
13337
13478
|
this.base,
|
|
13338
13479
|
async () => new Set((await this.commands()).keys()),
|
|
13339
|
-
(dir) => this.userCommandDir(dir)
|
|
13480
|
+
(dir) => this.userCommandDir(dir),
|
|
13481
|
+
this.owners
|
|
13340
13482
|
);
|
|
13341
13483
|
this.nodes = new VfsNodes(fs, (path) => this.released(path));
|
|
13342
13484
|
this.nodes.keepsOnDisk = true;
|
|
@@ -13866,7 +14008,15 @@ var Launcher = class {
|
|
|
13866
14008
|
serveFilesystem(
|
|
13867
14009
|
port2,
|
|
13868
14010
|
tmpfs(),
|
|
13869
|
-
{
|
|
14011
|
+
{
|
|
14012
|
+
symlinks: true,
|
|
14013
|
+
links: true,
|
|
14014
|
+
chmod: true,
|
|
14015
|
+
owners: true,
|
|
14016
|
+
linkTimes: true,
|
|
14017
|
+
ranges: true,
|
|
14018
|
+
attrTtl: 0
|
|
14019
|
+
},
|
|
13870
14020
|
{ owned: true }
|
|
13871
14021
|
);
|
|
13872
14022
|
return {
|
|
@@ -13939,6 +14089,11 @@ var Launcher = class {
|
|
|
13939
14089
|
void this.unlinked.sweep(entry.target);
|
|
13940
14090
|
return entry;
|
|
13941
14091
|
}
|
|
14092
|
+
mountedBy(spec, cred) {
|
|
14093
|
+
if (!this.owners || cred.euid === 0 && cred.egid === 0) return spec;
|
|
14094
|
+
const ids = { uid: String(cred.euid), gid: String(cred.egid) };
|
|
14095
|
+
return { ...spec, options: { ...ids, ...spec.options } };
|
|
14096
|
+
}
|
|
13942
14097
|
mountRoot(path) {
|
|
13943
14098
|
let root = "/";
|
|
13944
14099
|
for (const { target } of this.mounts.list()) {
|
|
@@ -13982,7 +14137,7 @@ var Launcher = class {
|
|
|
13982
14137
|
async processMount(pid, call, signal) {
|
|
13983
14138
|
const spec = mountCall(call);
|
|
13984
14139
|
await this.permit({ op: "mount", pid, ...spec, options: { ...spec.options } });
|
|
13985
|
-
const entry = await this.mount(spec);
|
|
14140
|
+
const entry = await this.mount(this.mountedBy(spec, this.credOf(pid)));
|
|
13986
14141
|
if (signal.aborted) this.umount(entry.target, true);
|
|
13987
14142
|
}
|
|
13988
14143
|
async processUmount(pid, target, flags) {
|