@ai-ecoverse/slicc-kernel 1.62.3 → 1.63.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 +9 -3
- package/dist/kernel-worker.js +374 -242
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +289 -128
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +374 -242
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +289 -128
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -429,11 +429,16 @@ var OpfsFs = class {
|
|
|
429
429
|
}
|
|
430
430
|
async ancestry(path) {
|
|
431
431
|
const entries = await this.meta.get(chain(path));
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
432
|
+
const out = [];
|
|
433
|
+
for (const [i, entry] of entries.entries()) {
|
|
434
|
+
const link2 = entry?.link !== void 0 && !await this.real(entry.path);
|
|
435
|
+
out.push({
|
|
436
|
+
...ownOf(entry) ?? (i === 0 ? ROOT_OWNER : inherit(entries.slice(0, i))),
|
|
437
|
+
...entry?.mode !== void 0 ? { mode: entry.mode } : {},
|
|
438
|
+
...link2 ? { link: entry.link } : {}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
return out;
|
|
437
442
|
}
|
|
438
443
|
async handedTo(dir) {
|
|
439
444
|
return inherit(await this.meta.get(chain(dir)));
|
|
@@ -1397,15 +1402,24 @@ async function present(fs, path, directory) {
|
|
|
1397
1402
|
const st = await fs.lstat(path).catch(() => void 0);
|
|
1398
1403
|
return st !== void 0 && (!directory || st.isDirectory);
|
|
1399
1404
|
}
|
|
1405
|
+
async function finalOf(fs, walked, want, options) {
|
|
1406
|
+
const perm = walked.perm;
|
|
1407
|
+
if ((want & X_OK) === 0 || options.directory !== void 0) {
|
|
1408
|
+
return [perm, options.directory !== false];
|
|
1409
|
+
}
|
|
1410
|
+
const look = options.follow === false ? fs.lstat : fs.stat;
|
|
1411
|
+
const st = await look.call(fs, walked.path).catch(() => void 0);
|
|
1412
|
+
return st ? [permOf(st), st.isDirectory] : [perm, false];
|
|
1413
|
+
}
|
|
1400
1414
|
async function access(fs, cred, path, want, options = {}) {
|
|
1401
1415
|
const walked = await walk(fs, cred, path, options.follow !== false);
|
|
1402
1416
|
if (walked.denied !== void 0) {
|
|
1403
1417
|
if (await present(fs, walked.denied, true)) return walked;
|
|
1404
1418
|
return { path, perm: void 0, missing: true };
|
|
1405
1419
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
if (want === 0 || permits(cred, perm, want,
|
|
1420
|
+
if (!walked.perm) return { ...walked, missing: true };
|
|
1421
|
+
const [perm, directory] = await finalOf(fs, walked, want, options);
|
|
1422
|
+
if (want === 0 || permits(cred, perm, want, directory)) return walked;
|
|
1409
1423
|
if (await present(fs, walked.path, false)) return { ...walked, denied: walked.path };
|
|
1410
1424
|
return { ...walked, missing: true };
|
|
1411
1425
|
}
|
|
@@ -1416,6 +1430,7 @@ function refused(path, errno = "EACCES") {
|
|
|
1416
1430
|
// src/fs/dac.ts
|
|
1417
1431
|
var MAX_DENIAL_KEYS = 1e4;
|
|
1418
1432
|
var S_ISGID3 = 1024;
|
|
1433
|
+
var DIR = { directory: true };
|
|
1419
1434
|
var Dac = class {
|
|
1420
1435
|
mode;
|
|
1421
1436
|
hook;
|
|
@@ -1452,6 +1467,17 @@ var Dac = class {
|
|
|
1452
1467
|
);
|
|
1453
1468
|
}
|
|
1454
1469
|
};
|
|
1470
|
+
var MAX_CREATED = 1024;
|
|
1471
|
+
var Created = class {
|
|
1472
|
+
paths = /* @__PURE__ */ new Set();
|
|
1473
|
+
add(path) {
|
|
1474
|
+
if (this.paths.size >= MAX_CREATED) this.paths.clear();
|
|
1475
|
+
this.paths.add(normalizePath(path));
|
|
1476
|
+
}
|
|
1477
|
+
take(path) {
|
|
1478
|
+
return this.paths.delete(normalizePath(path));
|
|
1479
|
+
}
|
|
1480
|
+
};
|
|
1455
1481
|
function deny(g, op, path, errno = "EACCES") {
|
|
1456
1482
|
g.dac.denied({ pid: g.pid, uid: g.cred.euid, op, path, errno });
|
|
1457
1483
|
}
|
|
@@ -1460,20 +1486,30 @@ async function need(g, op, path, want, options = {}, shown = path) {
|
|
|
1460
1486
|
if (walked.denied !== void 0) deny(g, op, shown);
|
|
1461
1487
|
return walked;
|
|
1462
1488
|
}
|
|
1489
|
+
function entryIn(dir, path) {
|
|
1490
|
+
return joinName(dir.path, path.slice(path.lastIndexOf("/") + 1));
|
|
1491
|
+
}
|
|
1463
1492
|
async function stickyEntry(g, op, path, dir) {
|
|
1464
1493
|
const perm = dir.perm;
|
|
1465
1494
|
if (!perm || sticky(g.cred, perm, perm)) return;
|
|
1466
|
-
const entry =
|
|
1495
|
+
const entry = entryIn(dir, path);
|
|
1467
1496
|
if (sticky(g.cred, perm, (await ancestryOf(g.fs, entry)).at(-1))) return;
|
|
1468
1497
|
if (await present(g.fs, entry, false)) deny(g, op, path, "EPERM");
|
|
1469
1498
|
}
|
|
1470
1499
|
async function inParent(g, op, path, old = false) {
|
|
1471
|
-
|
|
1472
|
-
|
|
1500
|
+
if (old === "replaced") {
|
|
1501
|
+
const dir2 = await need(g, op, parentOf3(path), W_OK | X_OK, DIR, path);
|
|
1502
|
+
return dir2.denied === void 0 ? stickyEntry(g, op, path, dir2) : void 0;
|
|
1503
|
+
}
|
|
1504
|
+
if (!old) return void await need(g, op, parentOf3(path), W_OK | X_OK, DIR, path);
|
|
1505
|
+
const dir = await access(g.fs, g.cred, parentOf3(path), W_OK | X_OK, DIR);
|
|
1506
|
+
if (dir.denied === void 0) return stickyEntry(g, op, path, dir);
|
|
1507
|
+
const lookup = dir.denied === dir.path && dir.perm && permits(g.cred, dir.perm, X_OK);
|
|
1508
|
+
if (!lookup || await present(g.fs, entryIn(dir, path), false)) deny(g, op, path);
|
|
1473
1509
|
}
|
|
1474
1510
|
async function makeIn(g, op, path) {
|
|
1475
1511
|
for (let dir = parentOf3(path); ; dir = parentOf3(dir)) {
|
|
1476
|
-
const walked = await access(g.fs, g.cred, dir, W_OK | X_OK);
|
|
1512
|
+
const walked = await access(g.fs, g.cred, dir, W_OK | X_OK, DIR);
|
|
1477
1513
|
if (walked.denied !== void 0) {
|
|
1478
1514
|
if (!await present(g.fs, path, true)) deny(g, op, path);
|
|
1479
1515
|
return;
|
|
@@ -1499,7 +1535,7 @@ async function removable(g, op, path) {
|
|
|
1499
1535
|
async function renamable(g, from, to) {
|
|
1500
1536
|
if (from === to) return void await need(g, "rename", from, 0, { follow: false });
|
|
1501
1537
|
await inParent(g, "rename", from, true);
|
|
1502
|
-
await inParent(g, "rename", to,
|
|
1538
|
+
await inParent(g, "rename", to, "replaced");
|
|
1503
1539
|
if (g.cred.euid === 0 || parentOf3(from) === parentOf3(to)) return;
|
|
1504
1540
|
const st = await g.fs.lstat(from).catch(() => void 0);
|
|
1505
1541
|
if (st?.isDirectory && !permits(g.cred, permOf(st), W_OK)) deny(g, "rename", from);
|
|
@@ -1525,8 +1561,20 @@ async function chmodMode(g, path, mode) {
|
|
|
1525
1561
|
if (!g.dac.enforcing || !perm || g.cred.euid === 0 || inGroup(g.cred, perm.gid)) return mode;
|
|
1526
1562
|
return mode & ~S_ISGID3;
|
|
1527
1563
|
}
|
|
1528
|
-
async function retimable(g, op, path) {
|
|
1529
|
-
|
|
1564
|
+
async function retimable(g, op, path, now = false) {
|
|
1565
|
+
const follow2 = op !== "lutimes";
|
|
1566
|
+
if (!now) return void await ownerOnly(g, op, path, follow2);
|
|
1567
|
+
const walked = await need(g, op, path, 0, { follow: follow2 });
|
|
1568
|
+
const perm = walked.perm;
|
|
1569
|
+
if (!perm || g.cred.euid === 0 || perm.uid === g.cred.euid) return;
|
|
1570
|
+
if (permits(g.cred, perm, W_OK, false)) return;
|
|
1571
|
+
if (await present(g.fs, walked.path, false)) deny(g, op, path);
|
|
1572
|
+
}
|
|
1573
|
+
async function fileWritable(g, op, path) {
|
|
1574
|
+
await need(g, op, path, W_OK, { directory: false });
|
|
1575
|
+
}
|
|
1576
|
+
function realIds(cred) {
|
|
1577
|
+
return { ...cred, groups: [...cred.groups], euid: cred.ruid, egid: cred.rgid };
|
|
1530
1578
|
}
|
|
1531
1579
|
async function listable(g, op, path) {
|
|
1532
1580
|
await need(g, op, path, R_OK | X_OK, { directory: true });
|
|
@@ -1538,10 +1586,16 @@ async function readable(g, op, path) {
|
|
|
1538
1586
|
await need(g, op, path, R_OK, { directory: false });
|
|
1539
1587
|
}
|
|
1540
1588
|
async function writable(g, op, path) {
|
|
1541
|
-
|
|
1542
|
-
|
|
1589
|
+
await openable(g, op, path, W_OK, true);
|
|
1590
|
+
}
|
|
1591
|
+
async function creatable(g, op, path) {
|
|
1543
1592
|
const target = await need(g, op, path, 0);
|
|
1544
|
-
if (target.denied === void 0) await need(g, op, parentOf3(target.path), W_OK | X_OK,
|
|
1593
|
+
if (target.denied === void 0) await need(g, op, parentOf3(target.path), W_OK | X_OK, DIR, path);
|
|
1594
|
+
}
|
|
1595
|
+
async function openable(g, op, path, want, create) {
|
|
1596
|
+
const st = create ? await g.fs.stat(path).catch(() => void 0) : void 0;
|
|
1597
|
+
if (create && !st) return creatable(g, op, path);
|
|
1598
|
+
await need(g, op, path, want, { directory: st?.isDirectory ?? false });
|
|
1545
1599
|
}
|
|
1546
1600
|
|
|
1547
1601
|
// src/kernel/pipe.ts
|
|
@@ -4980,11 +5034,11 @@ function realmCa(owner, store) {
|
|
|
4980
5034
|
opened.set(store, cas);
|
|
4981
5035
|
let ca = cas.get(owner);
|
|
4982
5036
|
if (!ca) {
|
|
4983
|
-
const
|
|
4984
|
-
ca =
|
|
4985
|
-
cas.set(owner,
|
|
4986
|
-
|
|
4987
|
-
if (cas.get(owner) ===
|
|
5037
|
+
const opening2 = RealmCa.open(owner, store);
|
|
5038
|
+
ca = opening2;
|
|
5039
|
+
cas.set(owner, opening2);
|
|
5040
|
+
opening2.catch(() => {
|
|
5041
|
+
if (cas.get(owner) === opening2) cas.delete(owner);
|
|
4988
5042
|
});
|
|
4989
5043
|
}
|
|
4990
5044
|
return ca;
|
|
@@ -8052,6 +8106,9 @@ function revokeSyncFsToken(token) {
|
|
|
8052
8106
|
}
|
|
8053
8107
|
|
|
8054
8108
|
// src/realm/sync-fs-wire.ts
|
|
8109
|
+
var HOLD_READ = 4;
|
|
8110
|
+
var HOLD_WRITE = 8;
|
|
8111
|
+
var HOLD_CREATED = 16;
|
|
8055
8112
|
var SYNC_FS_REQUEST_TIMEOUT_MS = 25e3;
|
|
8056
8113
|
function syncError(code, label) {
|
|
8057
8114
|
return Object.assign(new Error(`${code}: ${label}`), { code });
|
|
@@ -8112,17 +8169,8 @@ function mkdirOptions(entry, mode = 511) {
|
|
|
8112
8169
|
return { recursive: true, owner: { ...owner, parents } };
|
|
8113
8170
|
}
|
|
8114
8171
|
async function mkdirExclusive(entry, path, mode) {
|
|
8115
|
-
const
|
|
8116
|
-
|
|
8117
|
-
const own = owner ? { owner } : {};
|
|
8118
|
-
try {
|
|
8119
|
-
await fs.mkdir(path, own);
|
|
8120
|
-
} catch (err) {
|
|
8121
|
-
if (err?.code !== "ENOENT") throw err;
|
|
8122
|
-
const above = owner ? { owner: { ...owner, mode: owner.parents } } : {};
|
|
8123
|
-
await fs.mkdir(path.slice(0, path.lastIndexOf("/")) || "/", { recursive: true, ...above });
|
|
8124
|
-
await fs.mkdir(path, own);
|
|
8125
|
-
}
|
|
8172
|
+
const owner = ownerFor2(entry, mode ?? 511);
|
|
8173
|
+
await entry.fs.mkdir(path, owner ? { owner } : {});
|
|
8126
8174
|
}
|
|
8127
8175
|
async function chown(entry, path, req) {
|
|
8128
8176
|
const cred = entry.cred?.();
|
|
@@ -8184,6 +8232,7 @@ async function run(entry, path, req) {
|
|
|
8184
8232
|
return done;
|
|
8185
8233
|
case "create":
|
|
8186
8234
|
await createExclusive(fs, path, ownerFor2(entry, req.mode ?? 438));
|
|
8235
|
+
entry.created?.add(path);
|
|
8187
8236
|
return done;
|
|
8188
8237
|
case "readlink":
|
|
8189
8238
|
return json2(await fs.readlink(path));
|
|
@@ -8240,11 +8289,47 @@ async function guard(g, path, req, cwd) {
|
|
|
8240
8289
|
return linkable(g, path, other(), req.mode === 1);
|
|
8241
8290
|
case "utimes":
|
|
8242
8291
|
case "lutimes":
|
|
8243
|
-
return retimable(g, op, path);
|
|
8292
|
+
return retimable(g, op, path, req.now === true);
|
|
8293
|
+
case "read":
|
|
8294
|
+
case "pread":
|
|
8295
|
+
return req.handle === void 0 ? readable(g, op, path) : void 0;
|
|
8296
|
+
case "pwrite":
|
|
8297
|
+
case "truncate":
|
|
8298
|
+
return req.handle === void 0 ? fileWritable(g, op, path) : void 0;
|
|
8299
|
+
case "write":
|
|
8300
|
+
return req.handle === void 0 && req.mode !== 1 ? writable(g, op, path) : void 0;
|
|
8244
8301
|
default:
|
|
8245
8302
|
return void 0;
|
|
8246
8303
|
}
|
|
8247
8304
|
}
|
|
8305
|
+
async function opening(entry, path, mode) {
|
|
8306
|
+
const g = guardOf(entry);
|
|
8307
|
+
const want = (mode & HOLD_READ ? R_OK : 0) | (mode & HOLD_WRITE ? W_OK : 0);
|
|
8308
|
+
const created3 = (mode & HOLD_CREATED) !== 0 && entry.created?.take(path) === true;
|
|
8309
|
+
if (g && want !== 0 && !created3) {
|
|
8310
|
+
await need(g, "open", path, want, { directory: false });
|
|
8311
|
+
}
|
|
8312
|
+
}
|
|
8313
|
+
async function holdOp(entry, path, req) {
|
|
8314
|
+
const mode = req.mode ?? 0;
|
|
8315
|
+
const [on, open] = [(mode & 1) === 1, (mode & 2) === 2];
|
|
8316
|
+
if (on && open) {
|
|
8317
|
+
await opening(entry, path, mode);
|
|
8318
|
+
const real = await entry.fs.realpath?.(path, true).catch(() => path);
|
|
8319
|
+
return json2(entry.hold?.(path, on, open, real) ?? null);
|
|
8320
|
+
}
|
|
8321
|
+
entry.hold?.(path, on, open, void 0, req.handle);
|
|
8322
|
+
return done;
|
|
8323
|
+
}
|
|
8324
|
+
async function accessOp(entry, path, req) {
|
|
8325
|
+
const g = guardOf(entry);
|
|
8326
|
+
if (!g) return done;
|
|
8327
|
+
const open = req.arg2 === "open";
|
|
8328
|
+
const cred = open || req.arg2 === "eaccess" ? g.cred : realIds(g.cred);
|
|
8329
|
+
const options = { follow: req.nofollow !== true, ...open ? { directory: false } : {} };
|
|
8330
|
+
await need({ ...g, cred }, open ? "open" : "access", path, req.mode ?? 0, options);
|
|
8331
|
+
return done;
|
|
8332
|
+
}
|
|
8248
8333
|
async function guarded(entry, path, req) {
|
|
8249
8334
|
const g = guardOf(entry);
|
|
8250
8335
|
if (!g) return void 0;
|
|
@@ -8308,16 +8393,6 @@ async function owned(entry, own, req, path, target) {
|
|
|
8308
8393
|
}
|
|
8309
8394
|
return own(target, () => run(entry, path, req));
|
|
8310
8395
|
}
|
|
8311
|
-
async function holdOp(entry, path, req) {
|
|
8312
|
-
const mode = req.mode ?? 0;
|
|
8313
|
-
const [on, open] = [(mode & 1) === 1, (mode & 2) === 2];
|
|
8314
|
-
if (on && open) {
|
|
8315
|
-
const real = await entry.fs.realpath?.(path, true).catch(() => path);
|
|
8316
|
-
return json2(entry.hold?.(path, on, open, real) ?? null);
|
|
8317
|
-
}
|
|
8318
|
-
entry.hold?.(path, on, open, void 0, req.handle);
|
|
8319
|
-
return done;
|
|
8320
|
-
}
|
|
8321
8396
|
var IDENTITY_OPS = /* @__PURE__ */ new Set([
|
|
8322
8397
|
"write",
|
|
8323
8398
|
"pwrite",
|
|
@@ -8354,7 +8429,8 @@ async function dispatchOne(entry, req) {
|
|
|
8354
8429
|
const path = fs.resolvePath(cwd, req.path);
|
|
8355
8430
|
if (req.op === "kept") return json2(entry.keptFor?.(req.handle ?? -1) !== void 0);
|
|
8356
8431
|
if (req.op === "stat" && req.handle !== void 0) return await keptStat(entry, req);
|
|
8357
|
-
if (req.op === "
|
|
8432
|
+
if (req.op === "access") return await accessOp(entry, path, req);
|
|
8433
|
+
if (req.op === "hold") return await holdOp(entry, path, req);
|
|
8358
8434
|
const refused2 = await guarded(entry, path, req);
|
|
8359
8435
|
if (refused2) return refused2;
|
|
8360
8436
|
if (req.op === "statfs") return json2(await entry.statfs?.(path) ?? await storageUsage());
|
|
@@ -8523,188 +8599,6 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
8523
8599
|
};
|
|
8524
8600
|
}
|
|
8525
8601
|
|
|
8526
|
-
// src/process/process-fds.ts
|
|
8527
|
-
var field2 = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
8528
|
-
function mountTable(mounts = []) {
|
|
8529
|
-
const root = globalThis.navigator?.storage ? "opfs" : "memory";
|
|
8530
|
-
const lines2 = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
8531
|
-
for (const m of mounts) {
|
|
8532
|
-
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
8533
|
-
if (m.state !== "ok") options.push(m.state);
|
|
8534
|
-
const access2 = options.includes("ro") ? [] : ["rw"];
|
|
8535
|
-
lines2.push(
|
|
8536
|
-
`${field2(m.source)} ${field2(m.target)} ${m.type} ${[...access2, ...options].join(",")} 0 0`
|
|
8537
|
-
);
|
|
8538
|
-
}
|
|
8539
|
-
return `${lines2.join("\n")}
|
|
8540
|
-
`;
|
|
8541
|
-
}
|
|
8542
|
-
|
|
8543
|
-
// src/process/procfs.ts
|
|
8544
|
-
var HZ = 100;
|
|
8545
|
-
var KIB = 1024;
|
|
8546
|
-
var FALLBACK_MEMORY = 4 * KIB * KIB * KIB;
|
|
8547
|
-
var PID_FILES = ["cmdline", "comm", "stat", "statm", "status"];
|
|
8548
|
-
var SYSTEM_FILES = ["loadavg", "meminfo", "stat", "uptime"];
|
|
8549
|
-
function commOf(info) {
|
|
8550
|
-
const name2 = info.argv[0] ?? "";
|
|
8551
|
-
return name2.slice(name2.lastIndexOf("/") + 1).slice(0, 15);
|
|
8552
|
-
}
|
|
8553
|
-
function ttyNumber(tty) {
|
|
8554
|
-
const pts = tty && /^\/dev\/pts\/(\d+)$/.exec(tty);
|
|
8555
|
-
if (pts) return 136 << 8 | Number(pts[1]);
|
|
8556
|
-
const vt = tty && /^\/dev\/tty(\d+)$/.exec(tty);
|
|
8557
|
-
return vt ? 4 << 8 | Number(vt[1]) : 0;
|
|
8558
|
-
}
|
|
8559
|
-
function pages(bytes) {
|
|
8560
|
-
return Math.ceil(bytes / 4096);
|
|
8561
|
-
}
|
|
8562
|
-
function ticks(ms) {
|
|
8563
|
-
return Math.max(0, Math.floor(ms * HZ / 1e3));
|
|
8564
|
-
}
|
|
8565
|
-
function pidStat(info, boot) {
|
|
8566
|
-
const fields = [
|
|
8567
|
-
info.pid,
|
|
8568
|
-
`(${commOf(info)})`,
|
|
8569
|
-
info.state,
|
|
8570
|
-
info.ppid,
|
|
8571
|
-
info.pgid,
|
|
8572
|
-
info.sid,
|
|
8573
|
-
ttyNumber(info.tty),
|
|
8574
|
-
info.tty ? info.pgid : -1,
|
|
8575
|
-
4194304,
|
|
8576
|
-
0,
|
|
8577
|
-
0,
|
|
8578
|
-
0,
|
|
8579
|
-
0,
|
|
8580
|
-
0,
|
|
8581
|
-
0,
|
|
8582
|
-
0,
|
|
8583
|
-
0,
|
|
8584
|
-
20,
|
|
8585
|
-
0,
|
|
8586
|
-
1,
|
|
8587
|
-
0,
|
|
8588
|
-
ticks(info.started - boot),
|
|
8589
|
-
info.memory,
|
|
8590
|
-
pages(info.memory),
|
|
8591
|
-
"18446744073709551615",
|
|
8592
|
-
...Array(12).fill(0),
|
|
8593
|
-
17,
|
|
8594
|
-
0,
|
|
8595
|
-
0,
|
|
8596
|
-
0,
|
|
8597
|
-
0,
|
|
8598
|
-
0,
|
|
8599
|
-
0,
|
|
8600
|
-
...Array(7).fill(0),
|
|
8601
|
-
0
|
|
8602
|
-
];
|
|
8603
|
-
return `${fields.join(" ")}
|
|
8604
|
-
`;
|
|
8605
|
-
}
|
|
8606
|
-
var sigMask = (mask = 0) => (mask >>> 1).toString(16).padStart(16, "0");
|
|
8607
|
-
function pidStatus(info) {
|
|
8608
|
-
const state = info.state === "Z" ? "Z (zombie)" : "S (sleeping)";
|
|
8609
|
-
const c = info.cred ?? ROOT;
|
|
8610
|
-
const ids = (r, e, s) => `${r} ${e} ${s} ${e}`;
|
|
8611
|
-
return [
|
|
8612
|
-
`Name: ${commOf(info)}`,
|
|
8613
|
-
`Umask: ${(info.umask ?? 18).toString(8).padStart(4, "0")}`,
|
|
8614
|
-
`State: ${state}`,
|
|
8615
|
-
`Tgid: ${info.pid}`,
|
|
8616
|
-
"Ngid: 0",
|
|
8617
|
-
`Pid: ${info.pid}`,
|
|
8618
|
-
`PPid: ${info.ppid}`,
|
|
8619
|
-
"TracerPid: 0",
|
|
8620
|
-
`Uid: ${ids(c.ruid, c.euid, c.suid)}`,
|
|
8621
|
-
`Gid: ${ids(c.rgid, c.egid, c.sgid)}`,
|
|
8622
|
-
"FDSize: 64",
|
|
8623
|
-
`VmSize: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8624
|
-
`VmRSS: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8625
|
-
`Groups: ${c.groups.join(" ")}`,
|
|
8626
|
-
`NSpid: ${info.pid}`,
|
|
8627
|
-
`NSpgid: ${info.pgid}`,
|
|
8628
|
-
`NSsid: ${info.sid}`,
|
|
8629
|
-
"Threads: 1",
|
|
8630
|
-
"SigQ: 0/0",
|
|
8631
|
-
"SigPnd: 0000000000000000",
|
|
8632
|
-
"ShdPnd: 0000000000000000",
|
|
8633
|
-
"SigBlk: 0000000000000000",
|
|
8634
|
-
`SigIgn: ${sigMask(info.sigIgn)}`,
|
|
8635
|
-
`SigCgt: ${sigMask(info.sigCgt)}`,
|
|
8636
|
-
""
|
|
8637
|
-
].join("\n");
|
|
8638
|
-
}
|
|
8639
|
-
function pidFile(name2, info, boot) {
|
|
8640
|
-
if (name2 === "cmdline") return info.state === "Z" ? "" : `${info.argv.join("\0")}\0`;
|
|
8641
|
-
if (name2 === "comm") return `${commOf(info)}
|
|
8642
|
-
`;
|
|
8643
|
-
if (name2 === "stat") return pidStat(info, boot);
|
|
8644
|
-
if (name2 === "statm") {
|
|
8645
|
-
const p = pages(info.memory);
|
|
8646
|
-
return `${p} ${p} 0 0 0 ${p} 0
|
|
8647
|
-
`;
|
|
8648
|
-
}
|
|
8649
|
-
return pidStatus(info);
|
|
8650
|
-
}
|
|
8651
|
-
function memoryInfo(source, used = 0) {
|
|
8652
|
-
const total = source.deviceMemory ? source.deviceMemory * KIB * KIB * KIB : FALLBACK_MEMORY;
|
|
8653
|
-
const free = Math.max(0, total - used - (source.usedHeap ?? 0));
|
|
8654
|
-
const kb = (bytes) => `${Math.floor(bytes / KIB)} kB`;
|
|
8655
|
-
return [
|
|
8656
|
-
["MemTotal", kb(total)],
|
|
8657
|
-
["MemFree", kb(free)],
|
|
8658
|
-
["MemAvailable", kb(free)],
|
|
8659
|
-
["Buffers", kb(0)],
|
|
8660
|
-
["Cached", kb(0)],
|
|
8661
|
-
["SwapCached", kb(0)],
|
|
8662
|
-
["Shmem", kb(0)],
|
|
8663
|
-
["SReclaimable", kb(0)],
|
|
8664
|
-
["SwapTotal", kb(0)],
|
|
8665
|
-
["SwapFree", kb(0)]
|
|
8666
|
-
].map(([key, value]) => `${`${key}:`.padEnd(16)}${value.padStart(12)}`).concat("").join("\n");
|
|
8667
|
-
}
|
|
8668
|
-
function systemFile(name2, listing, now, memory) {
|
|
8669
|
-
const up = Math.max(0, now - listing.boot) / 1e3;
|
|
8670
|
-
if (name2 === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
|
|
8671
|
-
`;
|
|
8672
|
-
if (name2 === "meminfo") {
|
|
8673
|
-
return memoryInfo(
|
|
8674
|
-
memory,
|
|
8675
|
-
listing.processes.reduce((sum, p) => sum + p.memory, 0)
|
|
8676
|
-
);
|
|
8677
|
-
}
|
|
8678
|
-
const live = listing.processes.filter((p) => p.state !== "Z");
|
|
8679
|
-
if (name2 === "loadavg") {
|
|
8680
|
-
const last = Math.max(0, ...listing.processes.map((p) => p.pid));
|
|
8681
|
-
return `0.00 0.00 0.00 1/${live.length} ${last}
|
|
8682
|
-
`;
|
|
8683
|
-
}
|
|
8684
|
-
const idle = ticks(now - listing.boot);
|
|
8685
|
-
return [
|
|
8686
|
-
`cpu 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
8687
|
-
`cpu0 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
8688
|
-
"intr 0",
|
|
8689
|
-
"ctxt 0",
|
|
8690
|
-
`btime ${Math.floor(listing.boot / 1e3)}`,
|
|
8691
|
-
`processes ${listing.processes.length}`,
|
|
8692
|
-
"procs_running 1",
|
|
8693
|
-
"procs_blocked 0",
|
|
8694
|
-
""
|
|
8695
|
-
].join("\n");
|
|
8696
|
-
}
|
|
8697
|
-
function memorySource(scope = globalThis) {
|
|
8698
|
-
const nav = scope.navigator;
|
|
8699
|
-
const perf = scope.performance;
|
|
8700
|
-
const deviceMemory = nav?.deviceMemory;
|
|
8701
|
-
const used = perf?.memory?.usedJSHeapSize;
|
|
8702
|
-
return {
|
|
8703
|
-
...typeof deviceMemory === "number" && deviceMemory > 0 ? { deviceMemory } : {},
|
|
8704
|
-
...typeof used === "number" ? { usedHeap: used } : {}
|
|
8705
|
-
};
|
|
8706
|
-
}
|
|
8707
|
-
|
|
8708
8602
|
// src/fs/pages.ts
|
|
8709
8603
|
var PAGE = 64 * 1024;
|
|
8710
8604
|
var READAHEAD = 1024 * 1024;
|
|
@@ -8930,6 +8824,191 @@ var AsyncRangedFile = class {
|
|
|
8930
8824
|
}
|
|
8931
8825
|
};
|
|
8932
8826
|
|
|
8827
|
+
// src/realm/live-vfs-fs.ts
|
|
8828
|
+
var EARLY_WHOLE_FILE = 64 * 1024;
|
|
8829
|
+
|
|
8830
|
+
// src/process/process-fds.ts
|
|
8831
|
+
var field2 = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
8832
|
+
function mountTable(mounts = []) {
|
|
8833
|
+
const root = globalThis.navigator?.storage ? "opfs" : "memory";
|
|
8834
|
+
const lines2 = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
8835
|
+
for (const m of mounts) {
|
|
8836
|
+
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
8837
|
+
if (m.state !== "ok") options.push(m.state);
|
|
8838
|
+
const access2 = options.includes("ro") ? [] : ["rw"];
|
|
8839
|
+
lines2.push(
|
|
8840
|
+
`${field2(m.source)} ${field2(m.target)} ${m.type} ${[...access2, ...options].join(",")} 0 0`
|
|
8841
|
+
);
|
|
8842
|
+
}
|
|
8843
|
+
return `${lines2.join("\n")}
|
|
8844
|
+
`;
|
|
8845
|
+
}
|
|
8846
|
+
|
|
8847
|
+
// src/process/procfs.ts
|
|
8848
|
+
var HZ = 100;
|
|
8849
|
+
var KIB = 1024;
|
|
8850
|
+
var FALLBACK_MEMORY = 4 * KIB * KIB * KIB;
|
|
8851
|
+
var PID_FILES = ["cmdline", "comm", "stat", "statm", "status"];
|
|
8852
|
+
var SYSTEM_FILES = ["loadavg", "meminfo", "stat", "uptime"];
|
|
8853
|
+
function commOf(info) {
|
|
8854
|
+
const name2 = info.argv[0] ?? "";
|
|
8855
|
+
return name2.slice(name2.lastIndexOf("/") + 1).slice(0, 15);
|
|
8856
|
+
}
|
|
8857
|
+
function ttyNumber(tty) {
|
|
8858
|
+
const pts = tty && /^\/dev\/pts\/(\d+)$/.exec(tty);
|
|
8859
|
+
if (pts) return 136 << 8 | Number(pts[1]);
|
|
8860
|
+
const vt = tty && /^\/dev\/tty(\d+)$/.exec(tty);
|
|
8861
|
+
return vt ? 4 << 8 | Number(vt[1]) : 0;
|
|
8862
|
+
}
|
|
8863
|
+
function pages(bytes) {
|
|
8864
|
+
return Math.ceil(bytes / 4096);
|
|
8865
|
+
}
|
|
8866
|
+
function ticks(ms) {
|
|
8867
|
+
return Math.max(0, Math.floor(ms * HZ / 1e3));
|
|
8868
|
+
}
|
|
8869
|
+
function pidStat(info, boot) {
|
|
8870
|
+
const fields = [
|
|
8871
|
+
info.pid,
|
|
8872
|
+
`(${commOf(info)})`,
|
|
8873
|
+
info.state,
|
|
8874
|
+
info.ppid,
|
|
8875
|
+
info.pgid,
|
|
8876
|
+
info.sid,
|
|
8877
|
+
ttyNumber(info.tty),
|
|
8878
|
+
info.tty ? info.pgid : -1,
|
|
8879
|
+
4194304,
|
|
8880
|
+
0,
|
|
8881
|
+
0,
|
|
8882
|
+
0,
|
|
8883
|
+
0,
|
|
8884
|
+
0,
|
|
8885
|
+
0,
|
|
8886
|
+
0,
|
|
8887
|
+
0,
|
|
8888
|
+
20,
|
|
8889
|
+
0,
|
|
8890
|
+
1,
|
|
8891
|
+
0,
|
|
8892
|
+
ticks(info.started - boot),
|
|
8893
|
+
info.memory,
|
|
8894
|
+
pages(info.memory),
|
|
8895
|
+
"18446744073709551615",
|
|
8896
|
+
...Array(12).fill(0),
|
|
8897
|
+
17,
|
|
8898
|
+
0,
|
|
8899
|
+
0,
|
|
8900
|
+
0,
|
|
8901
|
+
0,
|
|
8902
|
+
0,
|
|
8903
|
+
0,
|
|
8904
|
+
...Array(7).fill(0),
|
|
8905
|
+
0
|
|
8906
|
+
];
|
|
8907
|
+
return `${fields.join(" ")}
|
|
8908
|
+
`;
|
|
8909
|
+
}
|
|
8910
|
+
var sigMask = (mask = 0) => (mask >>> 1).toString(16).padStart(16, "0");
|
|
8911
|
+
function pidStatus(info) {
|
|
8912
|
+
const state = info.state === "Z" ? "Z (zombie)" : "S (sleeping)";
|
|
8913
|
+
const c = info.cred ?? ROOT;
|
|
8914
|
+
const ids = (r, e, s) => `${r} ${e} ${s} ${e}`;
|
|
8915
|
+
return [
|
|
8916
|
+
`Name: ${commOf(info)}`,
|
|
8917
|
+
`Umask: ${(info.umask ?? 18).toString(8).padStart(4, "0")}`,
|
|
8918
|
+
`State: ${state}`,
|
|
8919
|
+
`Tgid: ${info.pid}`,
|
|
8920
|
+
"Ngid: 0",
|
|
8921
|
+
`Pid: ${info.pid}`,
|
|
8922
|
+
`PPid: ${info.ppid}`,
|
|
8923
|
+
"TracerPid: 0",
|
|
8924
|
+
`Uid: ${ids(c.ruid, c.euid, c.suid)}`,
|
|
8925
|
+
`Gid: ${ids(c.rgid, c.egid, c.sgid)}`,
|
|
8926
|
+
"FDSize: 64",
|
|
8927
|
+
`VmSize: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8928
|
+
`VmRSS: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8929
|
+
`Groups: ${c.groups.join(" ")}`,
|
|
8930
|
+
`NSpid: ${info.pid}`,
|
|
8931
|
+
`NSpgid: ${info.pgid}`,
|
|
8932
|
+
`NSsid: ${info.sid}`,
|
|
8933
|
+
"Threads: 1",
|
|
8934
|
+
"SigQ: 0/0",
|
|
8935
|
+
"SigPnd: 0000000000000000",
|
|
8936
|
+
"ShdPnd: 0000000000000000",
|
|
8937
|
+
"SigBlk: 0000000000000000",
|
|
8938
|
+
`SigIgn: ${sigMask(info.sigIgn)}`,
|
|
8939
|
+
`SigCgt: ${sigMask(info.sigCgt)}`,
|
|
8940
|
+
""
|
|
8941
|
+
].join("\n");
|
|
8942
|
+
}
|
|
8943
|
+
function pidFile(name2, info, boot) {
|
|
8944
|
+
if (name2 === "cmdline") return info.state === "Z" ? "" : `${info.argv.join("\0")}\0`;
|
|
8945
|
+
if (name2 === "comm") return `${commOf(info)}
|
|
8946
|
+
`;
|
|
8947
|
+
if (name2 === "stat") return pidStat(info, boot);
|
|
8948
|
+
if (name2 === "statm") {
|
|
8949
|
+
const p = pages(info.memory);
|
|
8950
|
+
return `${p} ${p} 0 0 0 ${p} 0
|
|
8951
|
+
`;
|
|
8952
|
+
}
|
|
8953
|
+
return pidStatus(info);
|
|
8954
|
+
}
|
|
8955
|
+
function memoryInfo(source, used = 0) {
|
|
8956
|
+
const total = source.deviceMemory ? source.deviceMemory * KIB * KIB * KIB : FALLBACK_MEMORY;
|
|
8957
|
+
const free = Math.max(0, total - used - (source.usedHeap ?? 0));
|
|
8958
|
+
const kb = (bytes) => `${Math.floor(bytes / KIB)} kB`;
|
|
8959
|
+
return [
|
|
8960
|
+
["MemTotal", kb(total)],
|
|
8961
|
+
["MemFree", kb(free)],
|
|
8962
|
+
["MemAvailable", kb(free)],
|
|
8963
|
+
["Buffers", kb(0)],
|
|
8964
|
+
["Cached", kb(0)],
|
|
8965
|
+
["SwapCached", kb(0)],
|
|
8966
|
+
["Shmem", kb(0)],
|
|
8967
|
+
["SReclaimable", kb(0)],
|
|
8968
|
+
["SwapTotal", kb(0)],
|
|
8969
|
+
["SwapFree", kb(0)]
|
|
8970
|
+
].map(([key, value]) => `${`${key}:`.padEnd(16)}${value.padStart(12)}`).concat("").join("\n");
|
|
8971
|
+
}
|
|
8972
|
+
function systemFile(name2, listing, now, memory) {
|
|
8973
|
+
const up = Math.max(0, now - listing.boot) / 1e3;
|
|
8974
|
+
if (name2 === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
|
|
8975
|
+
`;
|
|
8976
|
+
if (name2 === "meminfo") {
|
|
8977
|
+
return memoryInfo(
|
|
8978
|
+
memory,
|
|
8979
|
+
listing.processes.reduce((sum, p) => sum + p.memory, 0)
|
|
8980
|
+
);
|
|
8981
|
+
}
|
|
8982
|
+
const live = listing.processes.filter((p) => p.state !== "Z");
|
|
8983
|
+
if (name2 === "loadavg") {
|
|
8984
|
+
const last = Math.max(0, ...listing.processes.map((p) => p.pid));
|
|
8985
|
+
return `0.00 0.00 0.00 1/${live.length} ${last}
|
|
8986
|
+
`;
|
|
8987
|
+
}
|
|
8988
|
+
const idle = ticks(now - listing.boot);
|
|
8989
|
+
return [
|
|
8990
|
+
`cpu 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
8991
|
+
`cpu0 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
8992
|
+
"intr 0",
|
|
8993
|
+
"ctxt 0",
|
|
8994
|
+
`btime ${Math.floor(listing.boot / 1e3)}`,
|
|
8995
|
+
`processes ${listing.processes.length}`,
|
|
8996
|
+
"procs_running 1",
|
|
8997
|
+
"procs_blocked 0",
|
|
8998
|
+
""
|
|
8999
|
+
].join("\n");
|
|
9000
|
+
}
|
|
9001
|
+
function memorySource(scope = globalThis) {
|
|
9002
|
+
const nav = scope.navigator;
|
|
9003
|
+
const perf = scope.performance;
|
|
9004
|
+
const deviceMemory = nav?.deviceMemory;
|
|
9005
|
+
const used = perf?.memory?.usedJSHeapSize;
|
|
9006
|
+
return {
|
|
9007
|
+
...typeof deviceMemory === "number" && deviceMemory > 0 ? { deviceMemory } : {},
|
|
9008
|
+
...typeof used === "number" ? { usedHeap: used } : {}
|
|
9009
|
+
};
|
|
9010
|
+
}
|
|
9011
|
+
|
|
8933
9012
|
// src/process/wasi/wasi-files.ts
|
|
8934
9013
|
function normalize(path) {
|
|
8935
9014
|
const out = [];
|
|
@@ -11208,6 +11287,7 @@ var WasmProcess = class {
|
|
|
11208
11287
|
throw Object.assign(new Error(alias.refused), { code: alias.refused });
|
|
11209
11288
|
if (alias !== void 0) return this.openProc(req, alias);
|
|
11210
11289
|
await refuseReadonly(this.options.fs, req.path, req.flags, req);
|
|
11290
|
+
await this.mayOpen(req);
|
|
11211
11291
|
const fd = this.fds.install(heldFile(), 3);
|
|
11212
11292
|
try {
|
|
11213
11293
|
const nodes = this.nodes;
|
|
@@ -11253,6 +11333,17 @@ var WasmProcess = class {
|
|
|
11253
11333
|
};
|
|
11254
11334
|
return fs.exclusive ? fs.exclusive(first.path, look) : look();
|
|
11255
11335
|
}
|
|
11336
|
+
async mayOpen(req) {
|
|
11337
|
+
const { guard: guard2 } = this.options;
|
|
11338
|
+
const inherited2 = req.orphan || req.contents !== void 0 || req.handle !== void 0;
|
|
11339
|
+
if (!guard2 || inherited2 || req.pin !== void 0) return;
|
|
11340
|
+
const g = { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
|
|
11341
|
+
if (req.exclusive) return inParent(g, "open", req.path);
|
|
11342
|
+
if (req.created && guard2.created?.take(req.path)) return;
|
|
11343
|
+
const access2 = req.flags & WRITE_ACCESS;
|
|
11344
|
+
const want = (access2 === 1 ? 0 : R_OK) | (access2 !== 0 || req.truncate ? W_OK : 0);
|
|
11345
|
+
await openable(g, "open", req.path, want, req.create === true);
|
|
11346
|
+
}
|
|
11256
11347
|
newOwner() {
|
|
11257
11348
|
if (!this.options.owners) return void 0;
|
|
11258
11349
|
return { uid: this.cred.euid, gid: this.cred.egid, mode: 438 & ~this.umask };
|
|
@@ -11937,7 +12028,7 @@ function inherited(opts) {
|
|
|
11937
12028
|
function holdingToken(opts, holds, caller) {
|
|
11938
12029
|
return mintSyncFsToken({
|
|
11939
12030
|
...opts.owners ? caller : {},
|
|
11940
|
-
...opts.dac ? { dac: opts.dac, pid: opts.pid } : {},
|
|
12031
|
+
...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
|
|
11941
12032
|
fs: opts.fs,
|
|
11942
12033
|
cwd: opts.cwd,
|
|
11943
12034
|
...opts.statfs ? { statfs: opts.statfs } : {},
|
|
@@ -11950,10 +12041,11 @@ function holdingToken(opts, holds, caller) {
|
|
|
11950
12041
|
renamed: (from, to) => holds.renamed(from, to)
|
|
11951
12042
|
});
|
|
11952
12043
|
}
|
|
11953
|
-
function processOptions(opts, header3, hooks) {
|
|
12044
|
+
function processOptions(opts, header3, hooks, created3) {
|
|
11954
12045
|
return {
|
|
11955
12046
|
...inherited(opts),
|
|
11956
12047
|
...opts.owners ? { owners: true } : {},
|
|
12048
|
+
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
|
|
11957
12049
|
...opts.identity ? { identity: opts.identity } : {},
|
|
11958
12050
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
11959
12051
|
...opts.settling ? { settling: opts.settling } : {},
|
|
@@ -11987,20 +12079,27 @@ function spawnWasmProcess(opts) {
|
|
|
11987
12079
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
11988
12080
|
const header3 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
11989
12081
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
12082
|
+
const created3 = new Created();
|
|
11990
12083
|
const process = new WasmProcess(
|
|
11991
12084
|
opts.pid,
|
|
11992
12085
|
opts.fds,
|
|
11993
|
-
processOptions(
|
|
11994
|
-
|
|
11995
|
-
|
|
11996
|
-
|
|
12086
|
+
processOptions(
|
|
12087
|
+
opts,
|
|
12088
|
+
header3,
|
|
12089
|
+
{
|
|
12090
|
+
raise: (sig) => signal(sig),
|
|
12091
|
+
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process.signalMasks().caught, sig)
|
|
12092
|
+
},
|
|
12093
|
+
created3
|
|
12094
|
+
)
|
|
11997
12095
|
);
|
|
11998
12096
|
publishStops(process, header3);
|
|
11999
12097
|
const holds = new HeldPaths();
|
|
12000
12098
|
opts.held?.add(holds);
|
|
12001
12099
|
const token = holdingToken(opts, holds, {
|
|
12002
12100
|
cred: () => process.cred,
|
|
12003
|
-
umask: () => process.umask
|
|
12101
|
+
umask: () => process.umask,
|
|
12102
|
+
created: created3
|
|
12004
12103
|
});
|
|
12005
12104
|
process.keptPath = (path) => holds.keptAt(path)?.hidden;
|
|
12006
12105
|
process.keptHandle = (handle2) => holds.keptFor(handle2)?.hidden;
|
|
@@ -13113,16 +13212,16 @@ function hostfsHandlers(current, againMs = RESTORE_AGAIN_MS) {
|
|
|
13113
13212
|
});
|
|
13114
13213
|
async function writable2(client, path, flags) {
|
|
13115
13214
|
const { ifMatch: _, ...asked } = flags;
|
|
13116
|
-
const
|
|
13215
|
+
const opening2 = () => client.call("open", { path: rel(path), ...asked });
|
|
13117
13216
|
try {
|
|
13118
|
-
return { opened: await
|
|
13217
|
+
return { opened: await opening2(), restore: void 0 };
|
|
13119
13218
|
} catch (err) {
|
|
13120
13219
|
if (!flags.write || codeOf4(err) !== "EACCES") throw err;
|
|
13121
13220
|
const was = await client.call("stat", { path: rel(path) });
|
|
13122
13221
|
const mode = was.mode ?? 0;
|
|
13123
13222
|
if (mode & 128) throw err;
|
|
13124
13223
|
const restore = { path: rel(path), mode, was };
|
|
13125
|
-
const opened2 = await client.call("setattr", { path: rel(path), mode: mode | 128 }).then(
|
|
13224
|
+
const opened2 = await client.call("setattr", { path: rel(path), mode: mode | 128 }).then(opening2).catch(async (again) => {
|
|
13126
13225
|
await settle3(client, restore).catch(() => {
|
|
13127
13226
|
});
|
|
13128
13227
|
throw again;
|
|
@@ -14380,15 +14479,33 @@ var Launcher = class {
|
|
|
14380
14479
|
return void 0;
|
|
14381
14480
|
}
|
|
14382
14481
|
const inner = await this.interpreted(interp, [interp, ...passed], cwd, scope, depth + 1);
|
|
14383
|
-
|
|
14482
|
+
const via = [interp, ...inner?.via ?? []];
|
|
14483
|
+
return inner && { ...inner, target: withScriptEnv(inner.target, command), via };
|
|
14384
14484
|
}
|
|
14385
14485
|
const target = withScriptEnv(found, command);
|
|
14386
|
-
return { target, args: [...target.prefix ?? [], ...passed] };
|
|
14486
|
+
return { target, args: [...target.prefix ?? [], ...passed], via: [interp] };
|
|
14387
14487
|
}
|
|
14388
14488
|
async plan(file, argv, cwd, scope) {
|
|
14389
14489
|
const direct = await this.resolve(file, argv[0] ?? file, cwd, scope);
|
|
14390
14490
|
if (direct) return { target: direct, args: [...direct.prefix ?? [], ...argv.slice(1)] };
|
|
14391
|
-
|
|
14491
|
+
const script = await this.interpreted(file, argv, cwd, scope);
|
|
14492
|
+
return script && { ...script, script: true };
|
|
14493
|
+
}
|
|
14494
|
+
async mayExec(cred, req, planned) {
|
|
14495
|
+
const { dac } = this;
|
|
14496
|
+
if (!dac) return;
|
|
14497
|
+
const g = { fs: this.fs, cred, pid: req.pid, dac };
|
|
14498
|
+
const byPath = (file) => file.includes("/") && !COMMAND2.test(file);
|
|
14499
|
+
if (byPath(req.file)) {
|
|
14500
|
+
const path = this.fs.resolvePath(req.cwd, req.file);
|
|
14501
|
+
await need(g, "exec", path, planned?.script ? R_OK | X_OK : X_OK);
|
|
14502
|
+
}
|
|
14503
|
+
const via = planned?.via ?? [];
|
|
14504
|
+
for (const [i, file] of via.entries()) {
|
|
14505
|
+
if (!byPath(file)) continue;
|
|
14506
|
+
const want = i < via.length - 1 ? R_OK | X_OK : X_OK;
|
|
14507
|
+
await need(g, "exec", this.fs.resolvePath(req.cwd, file), want);
|
|
14508
|
+
}
|
|
14392
14509
|
}
|
|
14393
14510
|
async unrunnable(file, cwd, scope) {
|
|
14394
14511
|
const path = this.fs.resolvePath(cwd, file);
|
|
@@ -14608,6 +14725,12 @@ var Launcher = class {
|
|
|
14608
14725
|
return async (req, fds) => {
|
|
14609
14726
|
const scope = await this.scopeOf(this.credOf(ppid).euid);
|
|
14610
14727
|
const planned = await this.plan(req.file, req.argv, req.cwd, scope);
|
|
14728
|
+
try {
|
|
14729
|
+
await this.mayExec(this.credOf(ppid), { ...req, pid: ppid }, planned);
|
|
14730
|
+
} catch (err) {
|
|
14731
|
+
await fds.closeAll();
|
|
14732
|
+
throw err.code === "EACCES" ? new SpawnError("EACCES") : err;
|
|
14733
|
+
}
|
|
14611
14734
|
if (!planned) {
|
|
14612
14735
|
await fds.closeAll();
|
|
14613
14736
|
throw new SpawnError(await this.unrunnable(req.file, req.cwd, scope));
|
|
@@ -14817,8 +14940,13 @@ var Launcher = class {
|
|
|
14817
14940
|
this.fs
|
|
14818
14941
|
);
|
|
14819
14942
|
void this.unlinked.sweep(entry.target);
|
|
14943
|
+
if (this.pnpmHome.startsWith(`${entry.target.replace(/\/$/, "")}/`))
|
|
14944
|
+
await this.provisionPnpmHome();
|
|
14820
14945
|
return entry;
|
|
14821
14946
|
}
|
|
14947
|
+
async provisionPnpmHome() {
|
|
14948
|
+
await this.base.mkdir(this.pnpmHome, { recursive: true }).catch(() => void 0);
|
|
14949
|
+
}
|
|
14822
14950
|
mountedBy(spec, cred) {
|
|
14823
14951
|
if (!this.owners || cred.euid === 0 && cred.egid === 0) return spec;
|
|
14824
14952
|
const ids = { uid: String(cred.euid), gid: String(cred.egid) };
|
|
@@ -14886,6 +15014,8 @@ var Launcher = class {
|
|
|
14886
15014
|
}
|
|
14887
15015
|
async prepare() {
|
|
14888
15016
|
for (const dir of SHARED_DIRS) await this.base.mkdir(dir, { recursive: true });
|
|
15017
|
+
if (this.owners) await this.base.chmod("/tmp", 1023);
|
|
15018
|
+
await this.provisionPnpmHome();
|
|
14889
15019
|
await this.users.ensure();
|
|
14890
15020
|
await writeCaFile(this.base, this.ca).catch(() => void 0);
|
|
14891
15021
|
this.fstab = this.mountFstab();
|
|
@@ -14932,7 +15062,9 @@ var Launcher = class {
|
|
|
14932
15062
|
const cwd = await physicalPathAsync(this.base, start2.startsWith("/") ? start2 : `/${start2}`);
|
|
14933
15063
|
const [file = ""] = argv;
|
|
14934
15064
|
await this.base.mkdir(cwd, { recursive: true });
|
|
14935
|
-
|
|
15065
|
+
const planned = await this.plan(file, argv, cwd, scope);
|
|
15066
|
+
await this.mayExec(credOf(account), { file, cwd, pid: 0 }, planned);
|
|
15067
|
+
return { cwd, file, planned };
|
|
14936
15068
|
}
|
|
14937
15069
|
async openTerminal(argv, options) {
|
|
14938
15070
|
const account = await this.account(options.user);
|