@ai-ecoverse/slicc-kernel 1.62.4 → 1.64.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 +8 -2
- package/dist/kernel-worker.js +409 -233
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +290 -128
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +409 -233
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +290 -128
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -427,13 +427,21 @@ var OpfsFs = class {
|
|
|
427
427
|
trackOwners() {
|
|
428
428
|
this.owners = true;
|
|
429
429
|
}
|
|
430
|
+
async hasOwner(path) {
|
|
431
|
+
return ownOf((await this.meta.get([path]))[0]) !== void 0;
|
|
432
|
+
}
|
|
430
433
|
async ancestry(path) {
|
|
431
434
|
const entries = await this.meta.get(chain(path));
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
435
|
+
const out = [];
|
|
436
|
+
for (const [i, entry] of entries.entries()) {
|
|
437
|
+
const link2 = entry?.link !== void 0 && !await this.real(entry.path);
|
|
438
|
+
out.push({
|
|
439
|
+
...ownOf(entry) ?? (i === 0 ? ROOT_OWNER : inherit(entries.slice(0, i))),
|
|
440
|
+
...entry?.mode !== void 0 ? { mode: entry.mode } : {},
|
|
441
|
+
...link2 ? { link: entry.link } : {}
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
return out;
|
|
437
445
|
}
|
|
438
446
|
async handedTo(dir) {
|
|
439
447
|
return inherit(await this.meta.get(chain(dir)));
|
|
@@ -1397,15 +1405,24 @@ async function present(fs, path, directory) {
|
|
|
1397
1405
|
const st = await fs.lstat(path).catch(() => void 0);
|
|
1398
1406
|
return st !== void 0 && (!directory || st.isDirectory);
|
|
1399
1407
|
}
|
|
1408
|
+
async function finalOf(fs, walked, want, options) {
|
|
1409
|
+
const perm = walked.perm;
|
|
1410
|
+
if ((want & X_OK) === 0 || options.directory !== void 0) {
|
|
1411
|
+
return [perm, options.directory !== false];
|
|
1412
|
+
}
|
|
1413
|
+
const look = options.follow === false ? fs.lstat : fs.stat;
|
|
1414
|
+
const st = await look.call(fs, walked.path).catch(() => void 0);
|
|
1415
|
+
return st ? [permOf(st), st.isDirectory] : [perm, false];
|
|
1416
|
+
}
|
|
1400
1417
|
async function access(fs, cred, path, want, options = {}) {
|
|
1401
1418
|
const walked = await walk(fs, cred, path, options.follow !== false);
|
|
1402
1419
|
if (walked.denied !== void 0) {
|
|
1403
1420
|
if (await present(fs, walked.denied, true)) return walked;
|
|
1404
1421
|
return { path, perm: void 0, missing: true };
|
|
1405
1422
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
if (want === 0 || permits(cred, perm, want,
|
|
1423
|
+
if (!walked.perm) return { ...walked, missing: true };
|
|
1424
|
+
const [perm, directory] = await finalOf(fs, walked, want, options);
|
|
1425
|
+
if (want === 0 || permits(cred, perm, want, directory)) return walked;
|
|
1409
1426
|
if (await present(fs, walked.path, false)) return { ...walked, denied: walked.path };
|
|
1410
1427
|
return { ...walked, missing: true };
|
|
1411
1428
|
}
|
|
@@ -1416,6 +1433,7 @@ function refused(path, errno = "EACCES") {
|
|
|
1416
1433
|
// src/fs/dac.ts
|
|
1417
1434
|
var MAX_DENIAL_KEYS = 1e4;
|
|
1418
1435
|
var S_ISGID3 = 1024;
|
|
1436
|
+
var DIR = { directory: true };
|
|
1419
1437
|
var Dac = class {
|
|
1420
1438
|
mode;
|
|
1421
1439
|
hook;
|
|
@@ -1452,6 +1470,17 @@ var Dac = class {
|
|
|
1452
1470
|
);
|
|
1453
1471
|
}
|
|
1454
1472
|
};
|
|
1473
|
+
var MAX_CREATED = 1024;
|
|
1474
|
+
var Created = class {
|
|
1475
|
+
paths = /* @__PURE__ */ new Set();
|
|
1476
|
+
add(path) {
|
|
1477
|
+
if (this.paths.size >= MAX_CREATED) this.paths.clear();
|
|
1478
|
+
this.paths.add(normalizePath(path));
|
|
1479
|
+
}
|
|
1480
|
+
take(path) {
|
|
1481
|
+
return this.paths.delete(normalizePath(path));
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1455
1484
|
function deny(g, op, path, errno = "EACCES") {
|
|
1456
1485
|
g.dac.denied({ pid: g.pid, uid: g.cred.euid, op, path, errno });
|
|
1457
1486
|
}
|
|
@@ -1460,20 +1489,30 @@ async function need(g, op, path, want, options = {}, shown = path) {
|
|
|
1460
1489
|
if (walked.denied !== void 0) deny(g, op, shown);
|
|
1461
1490
|
return walked;
|
|
1462
1491
|
}
|
|
1492
|
+
function entryIn(dir, path) {
|
|
1493
|
+
return joinName(dir.path, path.slice(path.lastIndexOf("/") + 1));
|
|
1494
|
+
}
|
|
1463
1495
|
async function stickyEntry(g, op, path, dir) {
|
|
1464
1496
|
const perm = dir.perm;
|
|
1465
1497
|
if (!perm || sticky(g.cred, perm, perm)) return;
|
|
1466
|
-
const entry =
|
|
1498
|
+
const entry = entryIn(dir, path);
|
|
1467
1499
|
if (sticky(g.cred, perm, (await ancestryOf(g.fs, entry)).at(-1))) return;
|
|
1468
1500
|
if (await present(g.fs, entry, false)) deny(g, op, path, "EPERM");
|
|
1469
1501
|
}
|
|
1470
1502
|
async function inParent(g, op, path, old = false) {
|
|
1471
|
-
|
|
1472
|
-
|
|
1503
|
+
if (old === "replaced") {
|
|
1504
|
+
const dir2 = await need(g, op, parentOf3(path), W_OK | X_OK, DIR, path);
|
|
1505
|
+
return dir2.denied === void 0 ? stickyEntry(g, op, path, dir2) : void 0;
|
|
1506
|
+
}
|
|
1507
|
+
if (!old) return void await need(g, op, parentOf3(path), W_OK | X_OK, DIR, path);
|
|
1508
|
+
const dir = await access(g.fs, g.cred, parentOf3(path), W_OK | X_OK, DIR);
|
|
1509
|
+
if (dir.denied === void 0) return stickyEntry(g, op, path, dir);
|
|
1510
|
+
const lookup = dir.denied === dir.path && dir.perm && permits(g.cred, dir.perm, X_OK);
|
|
1511
|
+
if (!lookup || await present(g.fs, entryIn(dir, path), false)) deny(g, op, path);
|
|
1473
1512
|
}
|
|
1474
1513
|
async function makeIn(g, op, path) {
|
|
1475
1514
|
for (let dir = parentOf3(path); ; dir = parentOf3(dir)) {
|
|
1476
|
-
const walked = await access(g.fs, g.cred, dir, W_OK | X_OK);
|
|
1515
|
+
const walked = await access(g.fs, g.cred, dir, W_OK | X_OK, DIR);
|
|
1477
1516
|
if (walked.denied !== void 0) {
|
|
1478
1517
|
if (!await present(g.fs, path, true)) deny(g, op, path);
|
|
1479
1518
|
return;
|
|
@@ -1499,7 +1538,7 @@ async function removable(g, op, path) {
|
|
|
1499
1538
|
async function renamable(g, from, to) {
|
|
1500
1539
|
if (from === to) return void await need(g, "rename", from, 0, { follow: false });
|
|
1501
1540
|
await inParent(g, "rename", from, true);
|
|
1502
|
-
await inParent(g, "rename", to,
|
|
1541
|
+
await inParent(g, "rename", to, "replaced");
|
|
1503
1542
|
if (g.cred.euid === 0 || parentOf3(from) === parentOf3(to)) return;
|
|
1504
1543
|
const st = await g.fs.lstat(from).catch(() => void 0);
|
|
1505
1544
|
if (st?.isDirectory && !permits(g.cred, permOf(st), W_OK)) deny(g, "rename", from);
|
|
@@ -1525,8 +1564,20 @@ async function chmodMode(g, path, mode) {
|
|
|
1525
1564
|
if (!g.dac.enforcing || !perm || g.cred.euid === 0 || inGroup(g.cred, perm.gid)) return mode;
|
|
1526
1565
|
return mode & ~S_ISGID3;
|
|
1527
1566
|
}
|
|
1528
|
-
async function retimable(g, op, path) {
|
|
1529
|
-
|
|
1567
|
+
async function retimable(g, op, path, now = false) {
|
|
1568
|
+
const follow2 = op !== "lutimes";
|
|
1569
|
+
if (!now) return void await ownerOnly(g, op, path, follow2);
|
|
1570
|
+
const walked = await need(g, op, path, 0, { follow: follow2 });
|
|
1571
|
+
const perm = walked.perm;
|
|
1572
|
+
if (!perm || g.cred.euid === 0 || perm.uid === g.cred.euid) return;
|
|
1573
|
+
if (permits(g.cred, perm, W_OK, false)) return;
|
|
1574
|
+
if (await present(g.fs, walked.path, false)) deny(g, op, path);
|
|
1575
|
+
}
|
|
1576
|
+
async function fileWritable(g, op, path) {
|
|
1577
|
+
await need(g, op, path, W_OK, { directory: false });
|
|
1578
|
+
}
|
|
1579
|
+
function realIds(cred) {
|
|
1580
|
+
return { ...cred, groups: [...cred.groups], euid: cred.ruid, egid: cred.rgid };
|
|
1530
1581
|
}
|
|
1531
1582
|
async function listable(g, op, path) {
|
|
1532
1583
|
await need(g, op, path, R_OK | X_OK, { directory: true });
|
|
@@ -1538,10 +1589,16 @@ async function readable(g, op, path) {
|
|
|
1538
1589
|
await need(g, op, path, R_OK, { directory: false });
|
|
1539
1590
|
}
|
|
1540
1591
|
async function writable(g, op, path) {
|
|
1541
|
-
|
|
1542
|
-
|
|
1592
|
+
await openable(g, op, path, W_OK, true);
|
|
1593
|
+
}
|
|
1594
|
+
async function creatable(g, op, path) {
|
|
1543
1595
|
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,
|
|
1596
|
+
if (target.denied === void 0) await need(g, op, parentOf3(target.path), W_OK | X_OK, DIR, path);
|
|
1597
|
+
}
|
|
1598
|
+
async function openable(g, op, path, want, create) {
|
|
1599
|
+
const st = create ? await g.fs.stat(path).catch(() => void 0) : void 0;
|
|
1600
|
+
if (create && !st) return creatable(g, op, path);
|
|
1601
|
+
await need(g, op, path, want, { directory: st?.isDirectory ?? false });
|
|
1545
1602
|
}
|
|
1546
1603
|
|
|
1547
1604
|
// src/kernel/pipe.ts
|
|
@@ -4980,11 +5037,11 @@ function realmCa(owner, store) {
|
|
|
4980
5037
|
opened.set(store, cas);
|
|
4981
5038
|
let ca = cas.get(owner);
|
|
4982
5039
|
if (!ca) {
|
|
4983
|
-
const
|
|
4984
|
-
ca =
|
|
4985
|
-
cas.set(owner,
|
|
4986
|
-
|
|
4987
|
-
if (cas.get(owner) ===
|
|
5040
|
+
const opening2 = RealmCa.open(owner, store);
|
|
5041
|
+
ca = opening2;
|
|
5042
|
+
cas.set(owner, opening2);
|
|
5043
|
+
opening2.catch(() => {
|
|
5044
|
+
if (cas.get(owner) === opening2) cas.delete(owner);
|
|
4988
5045
|
});
|
|
4989
5046
|
}
|
|
4990
5047
|
return ca;
|
|
@@ -6373,6 +6430,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
6373
6430
|
...fs.realpath ? { realpath: fs.realpath.bind(fs) } : {},
|
|
6374
6431
|
...fs.chown ? { chown: fs.chown.bind(fs) } : {},
|
|
6375
6432
|
...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
|
|
6433
|
+
...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
|
|
6376
6434
|
chmod: (path, mode) => fs.chmod(path, mode),
|
|
6377
6435
|
utimes: (path, atime, mtime) => fs.utimes(path, atime, mtime),
|
|
6378
6436
|
lutimes: (path, atime, mtime) => lutimesOf(fs, path, atime, mtime),
|
|
@@ -6472,8 +6530,10 @@ var UnlinkedKeeper = class {
|
|
|
6472
6530
|
count = 0;
|
|
6473
6531
|
links = /* @__PURE__ */ new Map();
|
|
6474
6532
|
linked = /* @__PURE__ */ new Map();
|
|
6533
|
+
dirOwner;
|
|
6475
6534
|
constructor(fs, holders, rootOf, options = {}) {
|
|
6476
6535
|
const { locks, owner } = options;
|
|
6536
|
+
this.dirOwner = options.dirOwner;
|
|
6477
6537
|
this.fs = fs;
|
|
6478
6538
|
this.holders = holders;
|
|
6479
6539
|
this.rootOf = rootOf;
|
|
@@ -6584,7 +6644,8 @@ var UnlinkedKeeper = class {
|
|
|
6584
6644
|
const dir = dirOf(this.rootOf(path));
|
|
6585
6645
|
const hidden = `${dir}/${this.instance}.${++this.count}`;
|
|
6586
6646
|
try {
|
|
6587
|
-
|
|
6647
|
+
const owner = this.dirOwner;
|
|
6648
|
+
await this.fs.mkdir(dir, { recursive: true, ...owner ? { owner } : {} });
|
|
6588
6649
|
await this.fs.rename(path, hidden);
|
|
6589
6650
|
await this.linkedName(hidden);
|
|
6590
6651
|
return hidden;
|
|
@@ -7963,6 +8024,10 @@ var MountFs = class {
|
|
|
7963
8024
|
if (this.at(real)) throw errnoError("ENOSYS", path);
|
|
7964
8025
|
return real;
|
|
7965
8026
|
}
|
|
8027
|
+
async hasOwner(path) {
|
|
8028
|
+
if (this.at(path)) return true;
|
|
8029
|
+
return await this.base.hasOwner?.(path) ?? true;
|
|
8030
|
+
}
|
|
7966
8031
|
async ancestry(path) {
|
|
7967
8032
|
const names = chain(normalizePath(path));
|
|
7968
8033
|
const first = names.findIndex((name2) => this.at(name2));
|
|
@@ -8052,6 +8117,9 @@ function revokeSyncFsToken(token) {
|
|
|
8052
8117
|
}
|
|
8053
8118
|
|
|
8054
8119
|
// src/realm/sync-fs-wire.ts
|
|
8120
|
+
var HOLD_READ = 4;
|
|
8121
|
+
var HOLD_WRITE = 8;
|
|
8122
|
+
var HOLD_CREATED = 16;
|
|
8055
8123
|
var SYNC_FS_REQUEST_TIMEOUT_MS = 25e3;
|
|
8056
8124
|
function syncError(code, label) {
|
|
8057
8125
|
return Object.assign(new Error(`${code}: ${label}`), { code });
|
|
@@ -8175,6 +8243,7 @@ async function run(entry, path, req) {
|
|
|
8175
8243
|
return done;
|
|
8176
8244
|
case "create":
|
|
8177
8245
|
await createExclusive(fs, path, ownerFor2(entry, req.mode ?? 438));
|
|
8246
|
+
entry.created?.add(path);
|
|
8178
8247
|
return done;
|
|
8179
8248
|
case "readlink":
|
|
8180
8249
|
return json2(await fs.readlink(path));
|
|
@@ -8231,11 +8300,47 @@ async function guard(g, path, req, cwd) {
|
|
|
8231
8300
|
return linkable(g, path, other(), req.mode === 1);
|
|
8232
8301
|
case "utimes":
|
|
8233
8302
|
case "lutimes":
|
|
8234
|
-
return retimable(g, op, path);
|
|
8303
|
+
return retimable(g, op, path, req.now === true);
|
|
8304
|
+
case "read":
|
|
8305
|
+
case "pread":
|
|
8306
|
+
return req.handle === void 0 ? readable(g, op, path) : void 0;
|
|
8307
|
+
case "pwrite":
|
|
8308
|
+
case "truncate":
|
|
8309
|
+
return req.handle === void 0 ? fileWritable(g, op, path) : void 0;
|
|
8310
|
+
case "write":
|
|
8311
|
+
return req.handle === void 0 && req.mode !== 1 ? writable(g, op, path) : void 0;
|
|
8235
8312
|
default:
|
|
8236
8313
|
return void 0;
|
|
8237
8314
|
}
|
|
8238
8315
|
}
|
|
8316
|
+
async function opening(entry, path, mode) {
|
|
8317
|
+
const g = guardOf(entry);
|
|
8318
|
+
const want = (mode & HOLD_READ ? R_OK : 0) | (mode & HOLD_WRITE ? W_OK : 0);
|
|
8319
|
+
const created3 = (mode & HOLD_CREATED) !== 0 && entry.created?.take(path) === true;
|
|
8320
|
+
if (g && want !== 0 && !created3) {
|
|
8321
|
+
await need(g, "open", path, want, { directory: false });
|
|
8322
|
+
}
|
|
8323
|
+
}
|
|
8324
|
+
async function holdOp(entry, path, req) {
|
|
8325
|
+
const mode = req.mode ?? 0;
|
|
8326
|
+
const [on, open] = [(mode & 1) === 1, (mode & 2) === 2];
|
|
8327
|
+
if (on && open) {
|
|
8328
|
+
await opening(entry, path, mode);
|
|
8329
|
+
const real = await entry.fs.realpath?.(path, true).catch(() => path);
|
|
8330
|
+
return json2(entry.hold?.(path, on, open, real) ?? null);
|
|
8331
|
+
}
|
|
8332
|
+
entry.hold?.(path, on, open, void 0, req.handle);
|
|
8333
|
+
return done;
|
|
8334
|
+
}
|
|
8335
|
+
async function accessOp(entry, path, req) {
|
|
8336
|
+
const g = guardOf(entry);
|
|
8337
|
+
if (!g) return done;
|
|
8338
|
+
const open = req.arg2 === "open";
|
|
8339
|
+
const cred = open || req.arg2 === "eaccess" ? g.cred : realIds(g.cred);
|
|
8340
|
+
const options = { follow: req.nofollow !== true, ...open ? { directory: false } : {} };
|
|
8341
|
+
await need({ ...g, cred }, open ? "open" : "access", path, req.mode ?? 0, options);
|
|
8342
|
+
return done;
|
|
8343
|
+
}
|
|
8239
8344
|
async function guarded(entry, path, req) {
|
|
8240
8345
|
const g = guardOf(entry);
|
|
8241
8346
|
if (!g) return void 0;
|
|
@@ -8299,16 +8404,6 @@ async function owned(entry, own, req, path, target) {
|
|
|
8299
8404
|
}
|
|
8300
8405
|
return own(target, () => run(entry, path, req));
|
|
8301
8406
|
}
|
|
8302
|
-
async function holdOp(entry, path, req) {
|
|
8303
|
-
const mode = req.mode ?? 0;
|
|
8304
|
-
const [on, open] = [(mode & 1) === 1, (mode & 2) === 2];
|
|
8305
|
-
if (on && open) {
|
|
8306
|
-
const real = await entry.fs.realpath?.(path, true).catch(() => path);
|
|
8307
|
-
return json2(entry.hold?.(path, on, open, real) ?? null);
|
|
8308
|
-
}
|
|
8309
|
-
entry.hold?.(path, on, open, void 0, req.handle);
|
|
8310
|
-
return done;
|
|
8311
|
-
}
|
|
8312
8407
|
var IDENTITY_OPS = /* @__PURE__ */ new Set([
|
|
8313
8408
|
"write",
|
|
8314
8409
|
"pwrite",
|
|
@@ -8345,7 +8440,8 @@ async function dispatchOne(entry, req) {
|
|
|
8345
8440
|
const path = fs.resolvePath(cwd, req.path);
|
|
8346
8441
|
if (req.op === "kept") return json2(entry.keptFor?.(req.handle ?? -1) !== void 0);
|
|
8347
8442
|
if (req.op === "stat" && req.handle !== void 0) return await keptStat(entry, req);
|
|
8348
|
-
if (req.op === "
|
|
8443
|
+
if (req.op === "access") return await accessOp(entry, path, req);
|
|
8444
|
+
if (req.op === "hold") return await holdOp(entry, path, req);
|
|
8349
8445
|
const refused2 = await guarded(entry, path, req);
|
|
8350
8446
|
if (refused2) return refused2;
|
|
8351
8447
|
if (req.op === "statfs") return json2(await entry.statfs?.(path) ?? await storageUsage());
|
|
@@ -8514,188 +8610,6 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
8514
8610
|
};
|
|
8515
8611
|
}
|
|
8516
8612
|
|
|
8517
|
-
// src/process/process-fds.ts
|
|
8518
|
-
var field2 = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
8519
|
-
function mountTable(mounts = []) {
|
|
8520
|
-
const root = globalThis.navigator?.storage ? "opfs" : "memory";
|
|
8521
|
-
const lines2 = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
8522
|
-
for (const m of mounts) {
|
|
8523
|
-
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
8524
|
-
if (m.state !== "ok") options.push(m.state);
|
|
8525
|
-
const access2 = options.includes("ro") ? [] : ["rw"];
|
|
8526
|
-
lines2.push(
|
|
8527
|
-
`${field2(m.source)} ${field2(m.target)} ${m.type} ${[...access2, ...options].join(",")} 0 0`
|
|
8528
|
-
);
|
|
8529
|
-
}
|
|
8530
|
-
return `${lines2.join("\n")}
|
|
8531
|
-
`;
|
|
8532
|
-
}
|
|
8533
|
-
|
|
8534
|
-
// src/process/procfs.ts
|
|
8535
|
-
var HZ = 100;
|
|
8536
|
-
var KIB = 1024;
|
|
8537
|
-
var FALLBACK_MEMORY = 4 * KIB * KIB * KIB;
|
|
8538
|
-
var PID_FILES = ["cmdline", "comm", "stat", "statm", "status"];
|
|
8539
|
-
var SYSTEM_FILES = ["loadavg", "meminfo", "stat", "uptime"];
|
|
8540
|
-
function commOf(info) {
|
|
8541
|
-
const name2 = info.argv[0] ?? "";
|
|
8542
|
-
return name2.slice(name2.lastIndexOf("/") + 1).slice(0, 15);
|
|
8543
|
-
}
|
|
8544
|
-
function ttyNumber(tty) {
|
|
8545
|
-
const pts = tty && /^\/dev\/pts\/(\d+)$/.exec(tty);
|
|
8546
|
-
if (pts) return 136 << 8 | Number(pts[1]);
|
|
8547
|
-
const vt = tty && /^\/dev\/tty(\d+)$/.exec(tty);
|
|
8548
|
-
return vt ? 4 << 8 | Number(vt[1]) : 0;
|
|
8549
|
-
}
|
|
8550
|
-
function pages(bytes) {
|
|
8551
|
-
return Math.ceil(bytes / 4096);
|
|
8552
|
-
}
|
|
8553
|
-
function ticks(ms) {
|
|
8554
|
-
return Math.max(0, Math.floor(ms * HZ / 1e3));
|
|
8555
|
-
}
|
|
8556
|
-
function pidStat(info, boot) {
|
|
8557
|
-
const fields = [
|
|
8558
|
-
info.pid,
|
|
8559
|
-
`(${commOf(info)})`,
|
|
8560
|
-
info.state,
|
|
8561
|
-
info.ppid,
|
|
8562
|
-
info.pgid,
|
|
8563
|
-
info.sid,
|
|
8564
|
-
ttyNumber(info.tty),
|
|
8565
|
-
info.tty ? info.pgid : -1,
|
|
8566
|
-
4194304,
|
|
8567
|
-
0,
|
|
8568
|
-
0,
|
|
8569
|
-
0,
|
|
8570
|
-
0,
|
|
8571
|
-
0,
|
|
8572
|
-
0,
|
|
8573
|
-
0,
|
|
8574
|
-
0,
|
|
8575
|
-
20,
|
|
8576
|
-
0,
|
|
8577
|
-
1,
|
|
8578
|
-
0,
|
|
8579
|
-
ticks(info.started - boot),
|
|
8580
|
-
info.memory,
|
|
8581
|
-
pages(info.memory),
|
|
8582
|
-
"18446744073709551615",
|
|
8583
|
-
...Array(12).fill(0),
|
|
8584
|
-
17,
|
|
8585
|
-
0,
|
|
8586
|
-
0,
|
|
8587
|
-
0,
|
|
8588
|
-
0,
|
|
8589
|
-
0,
|
|
8590
|
-
0,
|
|
8591
|
-
...Array(7).fill(0),
|
|
8592
|
-
0
|
|
8593
|
-
];
|
|
8594
|
-
return `${fields.join(" ")}
|
|
8595
|
-
`;
|
|
8596
|
-
}
|
|
8597
|
-
var sigMask = (mask = 0) => (mask >>> 1).toString(16).padStart(16, "0");
|
|
8598
|
-
function pidStatus(info) {
|
|
8599
|
-
const state = info.state === "Z" ? "Z (zombie)" : "S (sleeping)";
|
|
8600
|
-
const c = info.cred ?? ROOT;
|
|
8601
|
-
const ids = (r, e, s) => `${r} ${e} ${s} ${e}`;
|
|
8602
|
-
return [
|
|
8603
|
-
`Name: ${commOf(info)}`,
|
|
8604
|
-
`Umask: ${(info.umask ?? 18).toString(8).padStart(4, "0")}`,
|
|
8605
|
-
`State: ${state}`,
|
|
8606
|
-
`Tgid: ${info.pid}`,
|
|
8607
|
-
"Ngid: 0",
|
|
8608
|
-
`Pid: ${info.pid}`,
|
|
8609
|
-
`PPid: ${info.ppid}`,
|
|
8610
|
-
"TracerPid: 0",
|
|
8611
|
-
`Uid: ${ids(c.ruid, c.euid, c.suid)}`,
|
|
8612
|
-
`Gid: ${ids(c.rgid, c.egid, c.sgid)}`,
|
|
8613
|
-
"FDSize: 64",
|
|
8614
|
-
`VmSize: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8615
|
-
`VmRSS: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8616
|
-
`Groups: ${c.groups.join(" ")}`,
|
|
8617
|
-
`NSpid: ${info.pid}`,
|
|
8618
|
-
`NSpgid: ${info.pgid}`,
|
|
8619
|
-
`NSsid: ${info.sid}`,
|
|
8620
|
-
"Threads: 1",
|
|
8621
|
-
"SigQ: 0/0",
|
|
8622
|
-
"SigPnd: 0000000000000000",
|
|
8623
|
-
"ShdPnd: 0000000000000000",
|
|
8624
|
-
"SigBlk: 0000000000000000",
|
|
8625
|
-
`SigIgn: ${sigMask(info.sigIgn)}`,
|
|
8626
|
-
`SigCgt: ${sigMask(info.sigCgt)}`,
|
|
8627
|
-
""
|
|
8628
|
-
].join("\n");
|
|
8629
|
-
}
|
|
8630
|
-
function pidFile(name2, info, boot) {
|
|
8631
|
-
if (name2 === "cmdline") return info.state === "Z" ? "" : `${info.argv.join("\0")}\0`;
|
|
8632
|
-
if (name2 === "comm") return `${commOf(info)}
|
|
8633
|
-
`;
|
|
8634
|
-
if (name2 === "stat") return pidStat(info, boot);
|
|
8635
|
-
if (name2 === "statm") {
|
|
8636
|
-
const p = pages(info.memory);
|
|
8637
|
-
return `${p} ${p} 0 0 0 ${p} 0
|
|
8638
|
-
`;
|
|
8639
|
-
}
|
|
8640
|
-
return pidStatus(info);
|
|
8641
|
-
}
|
|
8642
|
-
function memoryInfo(source, used = 0) {
|
|
8643
|
-
const total = source.deviceMemory ? source.deviceMemory * KIB * KIB * KIB : FALLBACK_MEMORY;
|
|
8644
|
-
const free = Math.max(0, total - used - (source.usedHeap ?? 0));
|
|
8645
|
-
const kb = (bytes) => `${Math.floor(bytes / KIB)} kB`;
|
|
8646
|
-
return [
|
|
8647
|
-
["MemTotal", kb(total)],
|
|
8648
|
-
["MemFree", kb(free)],
|
|
8649
|
-
["MemAvailable", kb(free)],
|
|
8650
|
-
["Buffers", kb(0)],
|
|
8651
|
-
["Cached", kb(0)],
|
|
8652
|
-
["SwapCached", kb(0)],
|
|
8653
|
-
["Shmem", kb(0)],
|
|
8654
|
-
["SReclaimable", kb(0)],
|
|
8655
|
-
["SwapTotal", kb(0)],
|
|
8656
|
-
["SwapFree", kb(0)]
|
|
8657
|
-
].map(([key, value]) => `${`${key}:`.padEnd(16)}${value.padStart(12)}`).concat("").join("\n");
|
|
8658
|
-
}
|
|
8659
|
-
function systemFile(name2, listing, now, memory) {
|
|
8660
|
-
const up = Math.max(0, now - listing.boot) / 1e3;
|
|
8661
|
-
if (name2 === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
|
|
8662
|
-
`;
|
|
8663
|
-
if (name2 === "meminfo") {
|
|
8664
|
-
return memoryInfo(
|
|
8665
|
-
memory,
|
|
8666
|
-
listing.processes.reduce((sum, p) => sum + p.memory, 0)
|
|
8667
|
-
);
|
|
8668
|
-
}
|
|
8669
|
-
const live = listing.processes.filter((p) => p.state !== "Z");
|
|
8670
|
-
if (name2 === "loadavg") {
|
|
8671
|
-
const last = Math.max(0, ...listing.processes.map((p) => p.pid));
|
|
8672
|
-
return `0.00 0.00 0.00 1/${live.length} ${last}
|
|
8673
|
-
`;
|
|
8674
|
-
}
|
|
8675
|
-
const idle = ticks(now - listing.boot);
|
|
8676
|
-
return [
|
|
8677
|
-
`cpu 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
8678
|
-
`cpu0 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
8679
|
-
"intr 0",
|
|
8680
|
-
"ctxt 0",
|
|
8681
|
-
`btime ${Math.floor(listing.boot / 1e3)}`,
|
|
8682
|
-
`processes ${listing.processes.length}`,
|
|
8683
|
-
"procs_running 1",
|
|
8684
|
-
"procs_blocked 0",
|
|
8685
|
-
""
|
|
8686
|
-
].join("\n");
|
|
8687
|
-
}
|
|
8688
|
-
function memorySource(scope = globalThis) {
|
|
8689
|
-
const nav = scope.navigator;
|
|
8690
|
-
const perf = scope.performance;
|
|
8691
|
-
const deviceMemory = nav?.deviceMemory;
|
|
8692
|
-
const used = perf?.memory?.usedJSHeapSize;
|
|
8693
|
-
return {
|
|
8694
|
-
...typeof deviceMemory === "number" && deviceMemory > 0 ? { deviceMemory } : {},
|
|
8695
|
-
...typeof used === "number" ? { usedHeap: used } : {}
|
|
8696
|
-
};
|
|
8697
|
-
}
|
|
8698
|
-
|
|
8699
8613
|
// src/fs/pages.ts
|
|
8700
8614
|
var PAGE = 64 * 1024;
|
|
8701
8615
|
var READAHEAD = 1024 * 1024;
|
|
@@ -8921,6 +8835,191 @@ var AsyncRangedFile = class {
|
|
|
8921
8835
|
}
|
|
8922
8836
|
};
|
|
8923
8837
|
|
|
8838
|
+
// src/realm/live-vfs-fs.ts
|
|
8839
|
+
var EARLY_WHOLE_FILE = 64 * 1024;
|
|
8840
|
+
|
|
8841
|
+
// src/process/process-fds.ts
|
|
8842
|
+
var field2 = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
8843
|
+
function mountTable(mounts = []) {
|
|
8844
|
+
const root = globalThis.navigator?.storage ? "opfs" : "memory";
|
|
8845
|
+
const lines2 = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
8846
|
+
for (const m of mounts) {
|
|
8847
|
+
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
8848
|
+
if (m.state !== "ok") options.push(m.state);
|
|
8849
|
+
const access2 = options.includes("ro") ? [] : ["rw"];
|
|
8850
|
+
lines2.push(
|
|
8851
|
+
`${field2(m.source)} ${field2(m.target)} ${m.type} ${[...access2, ...options].join(",")} 0 0`
|
|
8852
|
+
);
|
|
8853
|
+
}
|
|
8854
|
+
return `${lines2.join("\n")}
|
|
8855
|
+
`;
|
|
8856
|
+
}
|
|
8857
|
+
|
|
8858
|
+
// src/process/procfs.ts
|
|
8859
|
+
var HZ = 100;
|
|
8860
|
+
var KIB = 1024;
|
|
8861
|
+
var FALLBACK_MEMORY = 4 * KIB * KIB * KIB;
|
|
8862
|
+
var PID_FILES = ["cmdline", "comm", "stat", "statm", "status"];
|
|
8863
|
+
var SYSTEM_FILES = ["loadavg", "meminfo", "stat", "uptime"];
|
|
8864
|
+
function commOf(info) {
|
|
8865
|
+
const name2 = info.argv[0] ?? "";
|
|
8866
|
+
return name2.slice(name2.lastIndexOf("/") + 1).slice(0, 15);
|
|
8867
|
+
}
|
|
8868
|
+
function ttyNumber(tty) {
|
|
8869
|
+
const pts = tty && /^\/dev\/pts\/(\d+)$/.exec(tty);
|
|
8870
|
+
if (pts) return 136 << 8 | Number(pts[1]);
|
|
8871
|
+
const vt = tty && /^\/dev\/tty(\d+)$/.exec(tty);
|
|
8872
|
+
return vt ? 4 << 8 | Number(vt[1]) : 0;
|
|
8873
|
+
}
|
|
8874
|
+
function pages(bytes) {
|
|
8875
|
+
return Math.ceil(bytes / 4096);
|
|
8876
|
+
}
|
|
8877
|
+
function ticks(ms) {
|
|
8878
|
+
return Math.max(0, Math.floor(ms * HZ / 1e3));
|
|
8879
|
+
}
|
|
8880
|
+
function pidStat(info, boot) {
|
|
8881
|
+
const fields = [
|
|
8882
|
+
info.pid,
|
|
8883
|
+
`(${commOf(info)})`,
|
|
8884
|
+
info.state,
|
|
8885
|
+
info.ppid,
|
|
8886
|
+
info.pgid,
|
|
8887
|
+
info.sid,
|
|
8888
|
+
ttyNumber(info.tty),
|
|
8889
|
+
info.tty ? info.pgid : -1,
|
|
8890
|
+
4194304,
|
|
8891
|
+
0,
|
|
8892
|
+
0,
|
|
8893
|
+
0,
|
|
8894
|
+
0,
|
|
8895
|
+
0,
|
|
8896
|
+
0,
|
|
8897
|
+
0,
|
|
8898
|
+
0,
|
|
8899
|
+
20,
|
|
8900
|
+
0,
|
|
8901
|
+
1,
|
|
8902
|
+
0,
|
|
8903
|
+
ticks(info.started - boot),
|
|
8904
|
+
info.memory,
|
|
8905
|
+
pages(info.memory),
|
|
8906
|
+
"18446744073709551615",
|
|
8907
|
+
...Array(12).fill(0),
|
|
8908
|
+
17,
|
|
8909
|
+
0,
|
|
8910
|
+
0,
|
|
8911
|
+
0,
|
|
8912
|
+
0,
|
|
8913
|
+
0,
|
|
8914
|
+
0,
|
|
8915
|
+
...Array(7).fill(0),
|
|
8916
|
+
0
|
|
8917
|
+
];
|
|
8918
|
+
return `${fields.join(" ")}
|
|
8919
|
+
`;
|
|
8920
|
+
}
|
|
8921
|
+
var sigMask = (mask = 0) => (mask >>> 1).toString(16).padStart(16, "0");
|
|
8922
|
+
function pidStatus(info) {
|
|
8923
|
+
const state = info.state === "Z" ? "Z (zombie)" : "S (sleeping)";
|
|
8924
|
+
const c = info.cred ?? ROOT;
|
|
8925
|
+
const ids = (r, e, s) => `${r} ${e} ${s} ${e}`;
|
|
8926
|
+
return [
|
|
8927
|
+
`Name: ${commOf(info)}`,
|
|
8928
|
+
`Umask: ${(info.umask ?? 18).toString(8).padStart(4, "0")}`,
|
|
8929
|
+
`State: ${state}`,
|
|
8930
|
+
`Tgid: ${info.pid}`,
|
|
8931
|
+
"Ngid: 0",
|
|
8932
|
+
`Pid: ${info.pid}`,
|
|
8933
|
+
`PPid: ${info.ppid}`,
|
|
8934
|
+
"TracerPid: 0",
|
|
8935
|
+
`Uid: ${ids(c.ruid, c.euid, c.suid)}`,
|
|
8936
|
+
`Gid: ${ids(c.rgid, c.egid, c.sgid)}`,
|
|
8937
|
+
"FDSize: 64",
|
|
8938
|
+
`VmSize: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8939
|
+
`VmRSS: ${Math.ceil(info.memory / KIB)} kB`,
|
|
8940
|
+
`Groups: ${c.groups.join(" ")}`,
|
|
8941
|
+
`NSpid: ${info.pid}`,
|
|
8942
|
+
`NSpgid: ${info.pgid}`,
|
|
8943
|
+
`NSsid: ${info.sid}`,
|
|
8944
|
+
"Threads: 1",
|
|
8945
|
+
"SigQ: 0/0",
|
|
8946
|
+
"SigPnd: 0000000000000000",
|
|
8947
|
+
"ShdPnd: 0000000000000000",
|
|
8948
|
+
"SigBlk: 0000000000000000",
|
|
8949
|
+
`SigIgn: ${sigMask(info.sigIgn)}`,
|
|
8950
|
+
`SigCgt: ${sigMask(info.sigCgt)}`,
|
|
8951
|
+
""
|
|
8952
|
+
].join("\n");
|
|
8953
|
+
}
|
|
8954
|
+
function pidFile(name2, info, boot) {
|
|
8955
|
+
if (name2 === "cmdline") return info.state === "Z" ? "" : `${info.argv.join("\0")}\0`;
|
|
8956
|
+
if (name2 === "comm") return `${commOf(info)}
|
|
8957
|
+
`;
|
|
8958
|
+
if (name2 === "stat") return pidStat(info, boot);
|
|
8959
|
+
if (name2 === "statm") {
|
|
8960
|
+
const p = pages(info.memory);
|
|
8961
|
+
return `${p} ${p} 0 0 0 ${p} 0
|
|
8962
|
+
`;
|
|
8963
|
+
}
|
|
8964
|
+
return pidStatus(info);
|
|
8965
|
+
}
|
|
8966
|
+
function memoryInfo(source, used = 0) {
|
|
8967
|
+
const total = source.deviceMemory ? source.deviceMemory * KIB * KIB * KIB : FALLBACK_MEMORY;
|
|
8968
|
+
const free = Math.max(0, total - used - (source.usedHeap ?? 0));
|
|
8969
|
+
const kb = (bytes) => `${Math.floor(bytes / KIB)} kB`;
|
|
8970
|
+
return [
|
|
8971
|
+
["MemTotal", kb(total)],
|
|
8972
|
+
["MemFree", kb(free)],
|
|
8973
|
+
["MemAvailable", kb(free)],
|
|
8974
|
+
["Buffers", kb(0)],
|
|
8975
|
+
["Cached", kb(0)],
|
|
8976
|
+
["SwapCached", kb(0)],
|
|
8977
|
+
["Shmem", kb(0)],
|
|
8978
|
+
["SReclaimable", kb(0)],
|
|
8979
|
+
["SwapTotal", kb(0)],
|
|
8980
|
+
["SwapFree", kb(0)]
|
|
8981
|
+
].map(([key, value]) => `${`${key}:`.padEnd(16)}${value.padStart(12)}`).concat("").join("\n");
|
|
8982
|
+
}
|
|
8983
|
+
function systemFile(name2, listing, now, memory) {
|
|
8984
|
+
const up = Math.max(0, now - listing.boot) / 1e3;
|
|
8985
|
+
if (name2 === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
|
|
8986
|
+
`;
|
|
8987
|
+
if (name2 === "meminfo") {
|
|
8988
|
+
return memoryInfo(
|
|
8989
|
+
memory,
|
|
8990
|
+
listing.processes.reduce((sum, p) => sum + p.memory, 0)
|
|
8991
|
+
);
|
|
8992
|
+
}
|
|
8993
|
+
const live = listing.processes.filter((p) => p.state !== "Z");
|
|
8994
|
+
if (name2 === "loadavg") {
|
|
8995
|
+
const last = Math.max(0, ...listing.processes.map((p) => p.pid));
|
|
8996
|
+
return `0.00 0.00 0.00 1/${live.length} ${last}
|
|
8997
|
+
`;
|
|
8998
|
+
}
|
|
8999
|
+
const idle = ticks(now - listing.boot);
|
|
9000
|
+
return [
|
|
9001
|
+
`cpu 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
9002
|
+
`cpu0 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
9003
|
+
"intr 0",
|
|
9004
|
+
"ctxt 0",
|
|
9005
|
+
`btime ${Math.floor(listing.boot / 1e3)}`,
|
|
9006
|
+
`processes ${listing.processes.length}`,
|
|
9007
|
+
"procs_running 1",
|
|
9008
|
+
"procs_blocked 0",
|
|
9009
|
+
""
|
|
9010
|
+
].join("\n");
|
|
9011
|
+
}
|
|
9012
|
+
function memorySource(scope = globalThis) {
|
|
9013
|
+
const nav = scope.navigator;
|
|
9014
|
+
const perf = scope.performance;
|
|
9015
|
+
const deviceMemory = nav?.deviceMemory;
|
|
9016
|
+
const used = perf?.memory?.usedJSHeapSize;
|
|
9017
|
+
return {
|
|
9018
|
+
...typeof deviceMemory === "number" && deviceMemory > 0 ? { deviceMemory } : {},
|
|
9019
|
+
...typeof used === "number" ? { usedHeap: used } : {}
|
|
9020
|
+
};
|
|
9021
|
+
}
|
|
9022
|
+
|
|
8924
9023
|
// src/process/wasi/wasi-files.ts
|
|
8925
9024
|
function normalize(path) {
|
|
8926
9025
|
const out = [];
|
|
@@ -11199,6 +11298,7 @@ var WasmProcess = class {
|
|
|
11199
11298
|
throw Object.assign(new Error(alias.refused), { code: alias.refused });
|
|
11200
11299
|
if (alias !== void 0) return this.openProc(req, alias);
|
|
11201
11300
|
await refuseReadonly(this.options.fs, req.path, req.flags, req);
|
|
11301
|
+
await this.mayOpen(req);
|
|
11202
11302
|
const fd = this.fds.install(heldFile(), 3);
|
|
11203
11303
|
try {
|
|
11204
11304
|
const nodes = this.nodes;
|
|
@@ -11244,6 +11344,17 @@ var WasmProcess = class {
|
|
|
11244
11344
|
};
|
|
11245
11345
|
return fs.exclusive ? fs.exclusive(first.path, look) : look();
|
|
11246
11346
|
}
|
|
11347
|
+
async mayOpen(req) {
|
|
11348
|
+
const { guard: guard2 } = this.options;
|
|
11349
|
+
const inherited2 = req.orphan || req.contents !== void 0 || req.handle !== void 0;
|
|
11350
|
+
if (!guard2 || inherited2 || req.pin !== void 0) return;
|
|
11351
|
+
const g = { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
|
|
11352
|
+
if (req.exclusive) return inParent(g, "open", req.path);
|
|
11353
|
+
if (req.created && guard2.created?.take(req.path)) return;
|
|
11354
|
+
const access2 = req.flags & WRITE_ACCESS;
|
|
11355
|
+
const want = (access2 === 1 ? 0 : R_OK) | (access2 !== 0 || req.truncate ? W_OK : 0);
|
|
11356
|
+
await openable(g, "open", req.path, want, req.create === true);
|
|
11357
|
+
}
|
|
11247
11358
|
newOwner() {
|
|
11248
11359
|
if (!this.options.owners) return void 0;
|
|
11249
11360
|
return { uid: this.cred.euid, gid: this.cred.egid, mode: 438 & ~this.umask };
|
|
@@ -11928,7 +12039,7 @@ function inherited(opts) {
|
|
|
11928
12039
|
function holdingToken(opts, holds, caller) {
|
|
11929
12040
|
return mintSyncFsToken({
|
|
11930
12041
|
...opts.owners ? caller : {},
|
|
11931
|
-
...opts.dac ? { dac: opts.dac, pid: opts.pid } : {},
|
|
12042
|
+
...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
|
|
11932
12043
|
fs: opts.fs,
|
|
11933
12044
|
cwd: opts.cwd,
|
|
11934
12045
|
...opts.statfs ? { statfs: opts.statfs } : {},
|
|
@@ -11941,10 +12052,11 @@ function holdingToken(opts, holds, caller) {
|
|
|
11941
12052
|
renamed: (from, to) => holds.renamed(from, to)
|
|
11942
12053
|
});
|
|
11943
12054
|
}
|
|
11944
|
-
function processOptions(opts, header3, hooks) {
|
|
12055
|
+
function processOptions(opts, header3, hooks, created3) {
|
|
11945
12056
|
return {
|
|
11946
12057
|
...inherited(opts),
|
|
11947
12058
|
...opts.owners ? { owners: true } : {},
|
|
12059
|
+
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
|
|
11948
12060
|
...opts.identity ? { identity: opts.identity } : {},
|
|
11949
12061
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
11950
12062
|
...opts.settling ? { settling: opts.settling } : {},
|
|
@@ -11978,20 +12090,27 @@ function spawnWasmProcess(opts) {
|
|
|
11978
12090
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
11979
12091
|
const header3 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
11980
12092
|
const threadSignals = /* @__PURE__ */ new Map();
|
|
12093
|
+
const created3 = new Created();
|
|
11981
12094
|
const process = new WasmProcess(
|
|
11982
12095
|
opts.pid,
|
|
11983
12096
|
opts.fds,
|
|
11984
|
-
processOptions(
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
12097
|
+
processOptions(
|
|
12098
|
+
opts,
|
|
12099
|
+
header3,
|
|
12100
|
+
{
|
|
12101
|
+
raise: (sig) => signal(sig),
|
|
12102
|
+
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process.signalMasks().caught, sig)
|
|
12103
|
+
},
|
|
12104
|
+
created3
|
|
12105
|
+
)
|
|
11988
12106
|
);
|
|
11989
12107
|
publishStops(process, header3);
|
|
11990
12108
|
const holds = new HeldPaths();
|
|
11991
12109
|
opts.held?.add(holds);
|
|
11992
12110
|
const token = holdingToken(opts, holds, {
|
|
11993
12111
|
cred: () => process.cred,
|
|
11994
|
-
umask: () => process.umask
|
|
12112
|
+
umask: () => process.umask,
|
|
12113
|
+
created: created3
|
|
11995
12114
|
});
|
|
11996
12115
|
process.keptPath = (path) => holds.keptAt(path)?.hidden;
|
|
11997
12116
|
process.keptHandle = (handle2) => holds.keptFor(handle2)?.hidden;
|
|
@@ -13104,16 +13223,16 @@ function hostfsHandlers(current, againMs = RESTORE_AGAIN_MS) {
|
|
|
13104
13223
|
});
|
|
13105
13224
|
async function writable2(client, path, flags) {
|
|
13106
13225
|
const { ifMatch: _, ...asked } = flags;
|
|
13107
|
-
const
|
|
13226
|
+
const opening2 = () => client.call("open", { path: rel(path), ...asked });
|
|
13108
13227
|
try {
|
|
13109
|
-
return { opened: await
|
|
13228
|
+
return { opened: await opening2(), restore: void 0 };
|
|
13110
13229
|
} catch (err) {
|
|
13111
13230
|
if (!flags.write || codeOf4(err) !== "EACCES") throw err;
|
|
13112
13231
|
const was = await client.call("stat", { path: rel(path) });
|
|
13113
13232
|
const mode = was.mode ?? 0;
|
|
13114
13233
|
if (mode & 128) throw err;
|
|
13115
13234
|
const restore = { path: rel(path), mode, was };
|
|
13116
|
-
const opened2 = await client.call("setattr", { path: rel(path), mode: mode | 128 }).then(
|
|
13235
|
+
const opened2 = await client.call("setattr", { path: rel(path), mode: mode | 128 }).then(opening2).catch(async (again) => {
|
|
13117
13236
|
await settle3(client, restore).catch(() => {
|
|
13118
13237
|
});
|
|
13119
13238
|
throw again;
|
|
@@ -14018,6 +14137,16 @@ var NOT_FOUND = 127;
|
|
|
14018
14137
|
var DECIDE_MS = 100;
|
|
14019
14138
|
var INIT_PID = 1;
|
|
14020
14139
|
var SHARED_DIRS = ["/tmp", "/home"];
|
|
14140
|
+
var LAYOUT = [
|
|
14141
|
+
["/", 493],
|
|
14142
|
+
["/root", 448],
|
|
14143
|
+
["/home", 493],
|
|
14144
|
+
["/etc", 493],
|
|
14145
|
+
[PASSWD, 420],
|
|
14146
|
+
[GROUP, 420],
|
|
14147
|
+
["/usr", 493],
|
|
14148
|
+
["/usr/local", 493]
|
|
14149
|
+
];
|
|
14021
14150
|
var encoder3 = new TextEncoder();
|
|
14022
14151
|
var USERS_MODES = ["off", "report", "enforce"];
|
|
14023
14152
|
function usersMode(mode = "off") {
|
|
@@ -14211,7 +14340,8 @@ var Launcher = class {
|
|
|
14211
14340
|
{
|
|
14212
14341
|
locks: webLocks(),
|
|
14213
14342
|
busy: (path) => [...this.openFiles].some((nodes) => nodes.holds(path)),
|
|
14214
|
-
owner: options.unlinkOwner
|
|
14343
|
+
owner: options.unlinkOwner,
|
|
14344
|
+
...this.owners ? { dirOwner: { uid: 0, gid: 0, mode: 448 } } : {}
|
|
14215
14345
|
}
|
|
14216
14346
|
);
|
|
14217
14347
|
this.fs = this.unlinked.wrap(keepingOpen(fs, this.nodes));
|
|
@@ -14371,15 +14501,33 @@ var Launcher = class {
|
|
|
14371
14501
|
return void 0;
|
|
14372
14502
|
}
|
|
14373
14503
|
const inner = await this.interpreted(interp, [interp, ...passed], cwd, scope, depth + 1);
|
|
14374
|
-
|
|
14504
|
+
const via = [interp, ...inner?.via ?? []];
|
|
14505
|
+
return inner && { ...inner, target: withScriptEnv(inner.target, command), via };
|
|
14375
14506
|
}
|
|
14376
14507
|
const target = withScriptEnv(found, command);
|
|
14377
|
-
return { target, args: [...target.prefix ?? [], ...passed] };
|
|
14508
|
+
return { target, args: [...target.prefix ?? [], ...passed], via: [interp] };
|
|
14378
14509
|
}
|
|
14379
14510
|
async plan(file, argv, cwd, scope) {
|
|
14380
14511
|
const direct = await this.resolve(file, argv[0] ?? file, cwd, scope);
|
|
14381
14512
|
if (direct) return { target: direct, args: [...direct.prefix ?? [], ...argv.slice(1)] };
|
|
14382
|
-
|
|
14513
|
+
const script = await this.interpreted(file, argv, cwd, scope);
|
|
14514
|
+
return script && { ...script, script: true };
|
|
14515
|
+
}
|
|
14516
|
+
async mayExec(cred, req, planned) {
|
|
14517
|
+
const { dac } = this;
|
|
14518
|
+
if (!dac) return;
|
|
14519
|
+
const g = { fs: this.fs, cred, pid: req.pid, dac };
|
|
14520
|
+
const byPath = (file) => file.includes("/") && !COMMAND2.test(file);
|
|
14521
|
+
if (byPath(req.file)) {
|
|
14522
|
+
const path = this.fs.resolvePath(req.cwd, req.file);
|
|
14523
|
+
await need(g, "exec", path, planned?.script ? R_OK | X_OK : X_OK);
|
|
14524
|
+
}
|
|
14525
|
+
const via = planned?.via ?? [];
|
|
14526
|
+
for (const [i, file] of via.entries()) {
|
|
14527
|
+
if (!byPath(file)) continue;
|
|
14528
|
+
const want = i < via.length - 1 ? R_OK | X_OK : X_OK;
|
|
14529
|
+
await need(g, "exec", this.fs.resolvePath(req.cwd, file), want);
|
|
14530
|
+
}
|
|
14383
14531
|
}
|
|
14384
14532
|
async unrunnable(file, cwd, scope) {
|
|
14385
14533
|
const path = this.fs.resolvePath(cwd, file);
|
|
@@ -14599,6 +14747,12 @@ var Launcher = class {
|
|
|
14599
14747
|
return async (req, fds) => {
|
|
14600
14748
|
const scope = await this.scopeOf(this.credOf(ppid).euid);
|
|
14601
14749
|
const planned = await this.plan(req.file, req.argv, req.cwd, scope);
|
|
14750
|
+
try {
|
|
14751
|
+
await this.mayExec(this.credOf(ppid), { ...req, pid: ppid }, planned);
|
|
14752
|
+
} catch (err) {
|
|
14753
|
+
await fds.closeAll();
|
|
14754
|
+
throw err.code === "EACCES" ? new SpawnError("EACCES") : err;
|
|
14755
|
+
}
|
|
14602
14756
|
if (!planned) {
|
|
14603
14757
|
await fds.closeAll();
|
|
14604
14758
|
throw new SpawnError(await this.unrunnable(req.file, req.cwd, scope));
|
|
@@ -14812,6 +14966,24 @@ var Launcher = class {
|
|
|
14812
14966
|
await this.provisionPnpmHome();
|
|
14813
14967
|
return entry;
|
|
14814
14968
|
}
|
|
14969
|
+
async stampLayout() {
|
|
14970
|
+
const layout = [
|
|
14971
|
+
...LAYOUT,
|
|
14972
|
+
[this.modulesDir, 493],
|
|
14973
|
+
[this.pnpmHome, 493],
|
|
14974
|
+
[`/${UNLINKED_DIR}`, 448]
|
|
14975
|
+
];
|
|
14976
|
+
for (const [path, mode] of layout) {
|
|
14977
|
+
const real = await this.realLayoutPath(path);
|
|
14978
|
+
const fresh = real !== void 0 && !await this.base.hasOwner?.(real);
|
|
14979
|
+
if (fresh) await this.base.chown?.(real, { uid: 0, gid: 0, mode, follow: false });
|
|
14980
|
+
}
|
|
14981
|
+
}
|
|
14982
|
+
async realLayoutPath(path) {
|
|
14983
|
+
if (!await this.base.exists(path)) return void 0;
|
|
14984
|
+
if (path === "/") return path;
|
|
14985
|
+
return joinName(await realDir(this.base, parentOf3(path)), baseName(path));
|
|
14986
|
+
}
|
|
14815
14987
|
async provisionPnpmHome() {
|
|
14816
14988
|
await this.base.mkdir(this.pnpmHome, { recursive: true }).catch(() => void 0);
|
|
14817
14989
|
}
|
|
@@ -14882,8 +15054,10 @@ var Launcher = class {
|
|
|
14882
15054
|
}
|
|
14883
15055
|
async prepare() {
|
|
14884
15056
|
for (const dir of SHARED_DIRS) await this.base.mkdir(dir, { recursive: true });
|
|
15057
|
+
if (this.owners) await this.base.chmod("/tmp", 1023);
|
|
14885
15058
|
await this.provisionPnpmHome();
|
|
14886
15059
|
await this.users.ensure();
|
|
15060
|
+
if (this.owners) await this.stampLayout();
|
|
14887
15061
|
await writeCaFile(this.base, this.ca).catch(() => void 0);
|
|
14888
15062
|
this.fstab = this.mountFstab();
|
|
14889
15063
|
}
|
|
@@ -14929,7 +15103,9 @@ var Launcher = class {
|
|
|
14929
15103
|
const cwd = await physicalPathAsync(this.base, start2.startsWith("/") ? start2 : `/${start2}`);
|
|
14930
15104
|
const [file = ""] = argv;
|
|
14931
15105
|
await this.base.mkdir(cwd, { recursive: true });
|
|
14932
|
-
|
|
15106
|
+
const planned = await this.plan(file, argv, cwd, scope);
|
|
15107
|
+
await this.mayExec(credOf(account), { file, cwd, pid: 0 }, planned);
|
|
15108
|
+
return { cwd, file, planned };
|
|
14933
15109
|
}
|
|
14934
15110
|
async openTerminal(argv, options) {
|
|
14935
15111
|
const account = await this.account(options.user);
|