@ai-ecoverse/slicc-kernel 1.8.12 → 1.10.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 +28 -1
- package/dist/index.js +424 -2
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +581 -68
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +308 -16
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +1058 -166
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +308 -16
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
|
@@ -268,28 +268,28 @@ function createNodeOps(h) {
|
|
|
268
268
|
blocks: Math.ceil(size / 4096) * 8
|
|
269
269
|
};
|
|
270
270
|
},
|
|
271
|
-
setattr(node,
|
|
271
|
+
setattr(node, attr2) {
|
|
272
272
|
if (node.live.orphan) {
|
|
273
|
-
if (
|
|
274
|
-
node.mode = node.mode & ~PERM_MASK |
|
|
273
|
+
if (attr2.mode !== void 0 && attr2.mode !== null) {
|
|
274
|
+
node.mode = node.mode & ~PERM_MASK | attr2.mode & PERM_MASK;
|
|
275
275
|
}
|
|
276
|
-
if (
|
|
276
|
+
if (attr2.size !== void 0 && attr2.size !== null) truncate(node, attr2.size);
|
|
277
277
|
return;
|
|
278
278
|
}
|
|
279
279
|
const path = liveNodePath(node);
|
|
280
|
-
if (
|
|
281
|
-
const perm =
|
|
280
|
+
if (attr2.mode !== void 0 && attr2.mode !== null) {
|
|
281
|
+
const perm = attr2.mode & PERM_MASK;
|
|
282
282
|
if (perm !== (node.mode & PERM_MASK)) {
|
|
283
283
|
metadataCall(() => bridgeOf(node).chmod(path, perm));
|
|
284
284
|
node.mode = node.mode & ~PERM_MASK | perm;
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
|
-
if (
|
|
288
|
-
truncate(node,
|
|
287
|
+
if (attr2.size !== void 0 && attr2.size !== null && Fs.isFile(node.mode)) {
|
|
288
|
+
truncate(node, attr2.size);
|
|
289
289
|
}
|
|
290
|
-
const mtime = toMs(
|
|
290
|
+
const mtime = toMs(attr2.mtime) ?? attr2.timestamp;
|
|
291
291
|
if (mtime !== void 0) {
|
|
292
|
-
const atime = toMs(
|
|
292
|
+
const atime = toMs(attr2.atime) ?? mtime;
|
|
293
293
|
flushNode(node);
|
|
294
294
|
metadataCall(() => bridgeOf(node).utimes(path, atime, mtime));
|
|
295
295
|
}
|
|
@@ -2405,10 +2405,297 @@ var init_process_sockets = __esm({
|
|
|
2405
2405
|
}
|
|
2406
2406
|
});
|
|
2407
2407
|
|
|
2408
|
+
// src/process/procfs.ts
|
|
2409
|
+
function commOf(info) {
|
|
2410
|
+
const name = info.argv[0] ?? "";
|
|
2411
|
+
return name.slice(name.lastIndexOf("/") + 1).slice(0, 15);
|
|
2412
|
+
}
|
|
2413
|
+
function ttyNumber(tty) {
|
|
2414
|
+
const pts = tty && /^\/dev\/pts\/(\d+)$/.exec(tty);
|
|
2415
|
+
if (pts) return 136 << 8 | Number(pts[1]);
|
|
2416
|
+
const vt = tty && /^\/dev\/tty(\d+)$/.exec(tty);
|
|
2417
|
+
return vt ? 4 << 8 | Number(vt[1]) : 0;
|
|
2418
|
+
}
|
|
2419
|
+
function ticks(ms) {
|
|
2420
|
+
return Math.max(0, Math.floor(ms * HZ / 1e3));
|
|
2421
|
+
}
|
|
2422
|
+
function pidStat(info, boot) {
|
|
2423
|
+
const fields = [
|
|
2424
|
+
info.pid,
|
|
2425
|
+
`(${commOf(info)})`,
|
|
2426
|
+
info.state,
|
|
2427
|
+
info.ppid,
|
|
2428
|
+
info.pgid,
|
|
2429
|
+
info.sid,
|
|
2430
|
+
ttyNumber(info.tty),
|
|
2431
|
+
info.tty ? info.pgid : -1,
|
|
2432
|
+
4194304,
|
|
2433
|
+
0,
|
|
2434
|
+
0,
|
|
2435
|
+
0,
|
|
2436
|
+
0,
|
|
2437
|
+
0,
|
|
2438
|
+
0,
|
|
2439
|
+
0,
|
|
2440
|
+
0,
|
|
2441
|
+
20,
|
|
2442
|
+
0,
|
|
2443
|
+
1,
|
|
2444
|
+
0,
|
|
2445
|
+
ticks(info.started - boot),
|
|
2446
|
+
0,
|
|
2447
|
+
0,
|
|
2448
|
+
"18446744073709551615",
|
|
2449
|
+
...Array(12).fill(0),
|
|
2450
|
+
17,
|
|
2451
|
+
0,
|
|
2452
|
+
0,
|
|
2453
|
+
0,
|
|
2454
|
+
0,
|
|
2455
|
+
0,
|
|
2456
|
+
0,
|
|
2457
|
+
...Array(7).fill(0),
|
|
2458
|
+
0
|
|
2459
|
+
];
|
|
2460
|
+
return `${fields.join(" ")}
|
|
2461
|
+
`;
|
|
2462
|
+
}
|
|
2463
|
+
function pidStatus(info) {
|
|
2464
|
+
const state = info.state === "Z" ? "Z (zombie)" : "S (sleeping)";
|
|
2465
|
+
const ids = `${UID} ${UID} ${UID} ${UID}`;
|
|
2466
|
+
return [
|
|
2467
|
+
`Name: ${commOf(info)}`,
|
|
2468
|
+
"Umask: 0022",
|
|
2469
|
+
`State: ${state}`,
|
|
2470
|
+
`Tgid: ${info.pid}`,
|
|
2471
|
+
"Ngid: 0",
|
|
2472
|
+
`Pid: ${info.pid}`,
|
|
2473
|
+
`PPid: ${info.ppid}`,
|
|
2474
|
+
"TracerPid: 0",
|
|
2475
|
+
`Uid: ${ids}`,
|
|
2476
|
+
`Gid: ${ids}`,
|
|
2477
|
+
"FDSize: 64",
|
|
2478
|
+
"Groups: ",
|
|
2479
|
+
`NSpid: ${info.pid}`,
|
|
2480
|
+
`NSpgid: ${info.pgid}`,
|
|
2481
|
+
`NSsid: ${info.sid}`,
|
|
2482
|
+
"Threads: 1",
|
|
2483
|
+
"SigQ: 0/0",
|
|
2484
|
+
"SigPnd: 0000000000000000",
|
|
2485
|
+
"ShdPnd: 0000000000000000",
|
|
2486
|
+
"SigBlk: 0000000000000000",
|
|
2487
|
+
"SigIgn: 0000000000000000",
|
|
2488
|
+
"SigCgt: 0000000000000000",
|
|
2489
|
+
""
|
|
2490
|
+
].join("\n");
|
|
2491
|
+
}
|
|
2492
|
+
function pidFile(name, info, boot) {
|
|
2493
|
+
if (name === "cmdline") return info.state === "Z" ? "" : `${info.argv.join("\0")}\0`;
|
|
2494
|
+
if (name === "comm") return `${commOf(info)}
|
|
2495
|
+
`;
|
|
2496
|
+
if (name === "stat") return pidStat(info, boot);
|
|
2497
|
+
if (name === "statm") return "0 0 0 0 0 0 0\n";
|
|
2498
|
+
return pidStatus(info);
|
|
2499
|
+
}
|
|
2500
|
+
function memoryInfo(source) {
|
|
2501
|
+
const total = source.deviceMemory ? source.deviceMemory * KIB * KIB * KIB : FALLBACK_MEMORY;
|
|
2502
|
+
const free = Math.max(0, total - (source.usedHeap ?? 0));
|
|
2503
|
+
const kb = (bytes) => `${Math.floor(bytes / KIB)} kB`;
|
|
2504
|
+
return [
|
|
2505
|
+
["MemTotal", kb(total)],
|
|
2506
|
+
["MemFree", kb(free)],
|
|
2507
|
+
["MemAvailable", kb(free)],
|
|
2508
|
+
["Buffers", kb(0)],
|
|
2509
|
+
["Cached", kb(0)],
|
|
2510
|
+
["SwapCached", kb(0)],
|
|
2511
|
+
["Shmem", kb(0)],
|
|
2512
|
+
["SReclaimable", kb(0)],
|
|
2513
|
+
["SwapTotal", kb(0)],
|
|
2514
|
+
["SwapFree", kb(0)]
|
|
2515
|
+
].map(([key, value2]) => `${`${key}:`.padEnd(16)}${value2.padStart(12)}`).concat("").join("\n");
|
|
2516
|
+
}
|
|
2517
|
+
function systemFile(name, listing, now, memory) {
|
|
2518
|
+
const up = Math.max(0, now - listing.boot) / 1e3;
|
|
2519
|
+
if (name === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
|
|
2520
|
+
`;
|
|
2521
|
+
if (name === "meminfo") return memoryInfo(memory);
|
|
2522
|
+
const live = listing.processes.filter((p) => p.state !== "Z");
|
|
2523
|
+
if (name === "loadavg") {
|
|
2524
|
+
const last = Math.max(0, ...listing.processes.map((p) => p.pid));
|
|
2525
|
+
return `0.00 0.00 0.00 1/${live.length} ${last}
|
|
2526
|
+
`;
|
|
2527
|
+
}
|
|
2528
|
+
const idle = ticks(now - listing.boot);
|
|
2529
|
+
return [
|
|
2530
|
+
`cpu 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
2531
|
+
`cpu0 0 0 0 ${idle} 0 0 0 0 0 0`,
|
|
2532
|
+
"intr 0",
|
|
2533
|
+
"ctxt 0",
|
|
2534
|
+
`btime ${Math.floor(listing.boot / 1e3)}`,
|
|
2535
|
+
`processes ${listing.processes.length}`,
|
|
2536
|
+
"procs_running 1",
|
|
2537
|
+
"procs_blocked 0",
|
|
2538
|
+
""
|
|
2539
|
+
].join("\n");
|
|
2540
|
+
}
|
|
2541
|
+
function memorySource(scope2 = globalThis) {
|
|
2542
|
+
const nav = scope2.navigator;
|
|
2543
|
+
const perf = scope2.performance;
|
|
2544
|
+
const deviceMemory = nav?.deviceMemory;
|
|
2545
|
+
const used = perf?.memory?.usedJSHeapSize;
|
|
2546
|
+
return {
|
|
2547
|
+
...typeof deviceMemory === "number" && deviceMemory > 0 ? { deviceMemory } : {},
|
|
2548
|
+
...typeof used === "number" ? { usedHeap: used } : {}
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
function attr(node) {
|
|
2552
|
+
const now = /* @__PURE__ */ new Date();
|
|
2553
|
+
return {
|
|
2554
|
+
dev: 3,
|
|
2555
|
+
ino: node.id,
|
|
2556
|
+
mode: node.mode,
|
|
2557
|
+
nlink: 1,
|
|
2558
|
+
uid: UID,
|
|
2559
|
+
gid: UID,
|
|
2560
|
+
rdev: 0,
|
|
2561
|
+
size: 0,
|
|
2562
|
+
atime: now,
|
|
2563
|
+
mtime: now,
|
|
2564
|
+
ctime: now,
|
|
2565
|
+
blksize: 4096,
|
|
2566
|
+
blocks: 0
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2569
|
+
function useProcfs(Fs, sys, pid, memory = memorySource()) {
|
|
2570
|
+
const { lookupPath, createNode, hashRemoveNode } = Fs;
|
|
2571
|
+
const procList = sys.procList?.bind(sys);
|
|
2572
|
+
if (!lookupPath || !createNode || !hashRemoveNode || !procList) return;
|
|
2573
|
+
let proc;
|
|
2574
|
+
let self;
|
|
2575
|
+
try {
|
|
2576
|
+
proc = lookupPath.call(Fs, "/proc", { follow: true }).node;
|
|
2577
|
+
self = lookupPath.call(Fs, "/proc/self", { follow: true }).node;
|
|
2578
|
+
} catch {
|
|
2579
|
+
return;
|
|
2580
|
+
}
|
|
2581
|
+
const error = (errno2 = ENOENT) => new Fs.ErrnoError(errno2);
|
|
2582
|
+
const fresh = (parent, name, mode) => {
|
|
2583
|
+
const node = createNode.call(Fs, parent, name, mode, 0);
|
|
2584
|
+
hashRemoveNode.call(Fs, node);
|
|
2585
|
+
node.node_ops = { getattr: attr, setattr: () => {
|
|
2586
|
+
} };
|
|
2587
|
+
node.stream_ops = {
|
|
2588
|
+
llseek: (stream, offset, whence) => {
|
|
2589
|
+
const at = (whence === 1 ? stream.position : 0) + offset;
|
|
2590
|
+
if (at < 0) throw error(EINVAL);
|
|
2591
|
+
return at;
|
|
2592
|
+
}
|
|
2593
|
+
};
|
|
2594
|
+
return node;
|
|
2595
|
+
};
|
|
2596
|
+
const file = (parent, name, content) => {
|
|
2597
|
+
const node = fresh(parent, name, FILE_MODE);
|
|
2598
|
+
node.stream_ops = {
|
|
2599
|
+
open: (stream) => {
|
|
2600
|
+
stream.sliccProc = new TextEncoder().encode(content());
|
|
2601
|
+
},
|
|
2602
|
+
read: (stream, buffer, offset, length, at) => {
|
|
2603
|
+
const data = stream.sliccProc ?? new Uint8Array(0);
|
|
2604
|
+
const chunk = data.subarray(at, at + length);
|
|
2605
|
+
buffer.set(chunk, offset);
|
|
2606
|
+
return chunk.length;
|
|
2607
|
+
},
|
|
2608
|
+
llseek: (stream, offset, whence) => {
|
|
2609
|
+
const end = stream.sliccProc?.length ?? 0;
|
|
2610
|
+
const at = (whence === 1 ? stream.position : whence === 2 ? end : 0) + offset;
|
|
2611
|
+
if (at < 0) throw error(EINVAL);
|
|
2612
|
+
return at;
|
|
2613
|
+
}
|
|
2614
|
+
};
|
|
2615
|
+
return node;
|
|
2616
|
+
};
|
|
2617
|
+
const find = (processes2, target, own) => processes2.find((p) => own ? p.tid === target : p.pid === target || p.tid === target);
|
|
2618
|
+
const infoOf = (target) => find(procList().processes, target, false);
|
|
2619
|
+
const pidContent = (target, name, own = false) => () => {
|
|
2620
|
+
const listing = procList();
|
|
2621
|
+
const info = find(listing.processes, target, own);
|
|
2622
|
+
if (!info) throw error(ESRCH);
|
|
2623
|
+
return pidFile(name, info, listing.boot);
|
|
2624
|
+
};
|
|
2625
|
+
const pidNames = (names) => [.../* @__PURE__ */ new Set([...names, ...PID_FILES])];
|
|
2626
|
+
const pidDir = (name, target) => {
|
|
2627
|
+
const dir = fresh(proc, name, DIR_MODE2);
|
|
2628
|
+
dir.node_ops.lookup = (parent, child) => {
|
|
2629
|
+
if (!PID_FILES.includes(child)) throw error();
|
|
2630
|
+
return file(parent, child, pidContent(target, child));
|
|
2631
|
+
};
|
|
2632
|
+
dir.node_ops.readdir = () => [".", "..", ...PID_FILES];
|
|
2633
|
+
return dir;
|
|
2634
|
+
};
|
|
2635
|
+
const procOps = proc.node_ops;
|
|
2636
|
+
const lookup = procOps.lookup?.bind(procOps);
|
|
2637
|
+
const readdir = procOps.readdir?.bind(procOps);
|
|
2638
|
+
proc.node_ops = {
|
|
2639
|
+
...procOps,
|
|
2640
|
+
lookup: (parent, name) => {
|
|
2641
|
+
if (/^[1-9]\d*$/.test(name)) {
|
|
2642
|
+
if (!infoOf(Number(name))) throw error();
|
|
2643
|
+
return pidDir(name, Number(name));
|
|
2644
|
+
}
|
|
2645
|
+
if (SYSTEM_FILES.includes(name)) {
|
|
2646
|
+
return file(
|
|
2647
|
+
parent,
|
|
2648
|
+
name,
|
|
2649
|
+
() => systemFile(name, procList(), Date.now(), memory)
|
|
2650
|
+
);
|
|
2651
|
+
}
|
|
2652
|
+
if (!lookup) throw error();
|
|
2653
|
+
return lookup(parent, name);
|
|
2654
|
+
},
|
|
2655
|
+
readdir: (node) => {
|
|
2656
|
+
const names = new Set(readdir ? readdir(node) : [".", ".."]);
|
|
2657
|
+
for (const name of SYSTEM_FILES) names.add(name);
|
|
2658
|
+
for (const p of procList().processes) names.add(String(p.pid));
|
|
2659
|
+
return [...names];
|
|
2660
|
+
}
|
|
2661
|
+
};
|
|
2662
|
+
const selfOps = self.node_ops;
|
|
2663
|
+
const selfLookup = selfOps.lookup?.bind(selfOps);
|
|
2664
|
+
const selfReaddir = selfOps.readdir?.bind(selfOps);
|
|
2665
|
+
self.node_ops = {
|
|
2666
|
+
...selfOps,
|
|
2667
|
+
lookup: (parent, name) => {
|
|
2668
|
+
if (PID_FILES.includes(name)) {
|
|
2669
|
+
return file(parent, name, pidContent(pid, name, true));
|
|
2670
|
+
}
|
|
2671
|
+
if (!selfLookup) throw error();
|
|
2672
|
+
return selfLookup(parent, name);
|
|
2673
|
+
},
|
|
2674
|
+
readdir: (node) => pidNames(selfReaddir ? selfReaddir(node) : [".", ".."])
|
|
2675
|
+
};
|
|
2676
|
+
}
|
|
2677
|
+
var HZ, DIR_MODE2, FILE_MODE, ENOENT, ESRCH, EINVAL, UID, KIB, FALLBACK_MEMORY, PID_FILES, SYSTEM_FILES;
|
|
2678
|
+
var init_procfs = __esm({
|
|
2679
|
+
"src/process/procfs.ts"() {
|
|
2680
|
+
"use strict";
|
|
2681
|
+
HZ = 100;
|
|
2682
|
+
DIR_MODE2 = 16749;
|
|
2683
|
+
FILE_MODE = 33060;
|
|
2684
|
+
ENOENT = 44;
|
|
2685
|
+
ESRCH = 71;
|
|
2686
|
+
EINVAL = 28;
|
|
2687
|
+
UID = 1e3;
|
|
2688
|
+
KIB = 1024;
|
|
2689
|
+
FALLBACK_MEMORY = 4 * KIB * KIB * KIB;
|
|
2690
|
+
PID_FILES = ["cmdline", "comm", "stat", "statm", "status"];
|
|
2691
|
+
SYSTEM_FILES = ["loadavg", "meminfo", "stat", "uptime"];
|
|
2692
|
+
}
|
|
2693
|
+
});
|
|
2694
|
+
|
|
2408
2695
|
// src/process/realm-user.ts
|
|
2409
2696
|
function ownByRealmUser(Fs) {
|
|
2410
2697
|
const { stat, fstat } = Fs;
|
|
2411
|
-
const owned = (
|
|
2698
|
+
const owned = (attr2) => ({ ...attr2, uid: REALM_UID, gid: REALM_GID });
|
|
2412
2699
|
if (typeof stat === "function") {
|
|
2413
2700
|
Fs.stat = (path, dontFollow) => owned(stat.call(Fs, path, dontFollow));
|
|
2414
2701
|
}
|
|
@@ -2519,6 +2806,9 @@ function kernelSys(transport) {
|
|
|
2519
2806
|
ptyNumbers() {
|
|
2520
2807
|
return json(call2({ op: "pty-list" }, "pty-list"));
|
|
2521
2808
|
},
|
|
2809
|
+
procList() {
|
|
2810
|
+
return json(call2({ op: "proc-list" }, "proc-list"));
|
|
2811
|
+
},
|
|
2522
2812
|
ptyNumber(fd) {
|
|
2523
2813
|
return json(call2({ op: "pty-number", fd }, `pty-number ${fd}`));
|
|
2524
2814
|
},
|
|
@@ -2680,6 +2970,7 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
2680
2970
|
streams.useControllingTerminal();
|
|
2681
2971
|
useDevFd(running.FS);
|
|
2682
2972
|
useMounts(running.FS);
|
|
2973
|
+
useProcfs(running.FS, sys, init.pid);
|
|
2683
2974
|
ownByRealmUser(running.FS);
|
|
2684
2975
|
const livePath = (s) => liveNodePath(s.node);
|
|
2685
2976
|
running.sliccKernel = createProcessKernel({
|
|
@@ -2746,6 +3037,7 @@ var init_process_runtime = __esm({
|
|
|
2746
3037
|
init_process_http();
|
|
2747
3038
|
init_process_signals();
|
|
2748
3039
|
init_process_sockets();
|
|
3040
|
+
init_procfs();
|
|
2749
3041
|
init_realm_user();
|
|
2750
3042
|
init_kernel_streams();
|
|
2751
3043
|
O_RDONLY = 0;
|
|
@@ -4453,7 +4745,7 @@ function importsContext({
|
|
|
4453
4745
|
const path = pathOf(fd);
|
|
4454
4746
|
if (path === void 0) {
|
|
4455
4747
|
const kind = e.type === "device" ? "device" : "stream";
|
|
4456
|
-
return { kind, mode: kind === "device" ? 8630 : 4480, uid:
|
|
4748
|
+
return { kind, mode: kind === "device" ? 8630 : 4480, uid: UID2, gid: UID2, size: 0 };
|
|
4457
4749
|
}
|
|
4458
4750
|
host.fds.flushPath(path);
|
|
4459
4751
|
const s = fs.stat(path);
|
|
@@ -4461,8 +4753,8 @@ function importsContext({
|
|
|
4461
4753
|
kind: s.isDirectory ? "dir" : "file",
|
|
4462
4754
|
path,
|
|
4463
4755
|
mode: s.mode ?? (s.isDirectory ? 16877 : 33188),
|
|
4464
|
-
uid:
|
|
4465
|
-
gid:
|
|
4756
|
+
uid: UID2,
|
|
4757
|
+
gid: UID2,
|
|
4466
4758
|
size: s.size,
|
|
4467
4759
|
...s.ino !== void 0 ? { ino: s.ino } : {},
|
|
4468
4760
|
...s.mtimeMs !== void 0 ? { mtimeMs: s.mtimeMs } : {}
|
|
@@ -4580,13 +4872,13 @@ function processes(host, call2) {
|
|
|
4580
4872
|
}
|
|
4581
4873
|
};
|
|
4582
4874
|
}
|
|
4583
|
-
var
|
|
4875
|
+
var UID2, STDIO;
|
|
4584
4876
|
var init_wasi_imports = __esm({
|
|
4585
4877
|
"src/process/wasi/wasi-imports.ts"() {
|
|
4586
4878
|
"use strict";
|
|
4587
4879
|
init_wasi_abi();
|
|
4588
4880
|
init_wasi_files();
|
|
4589
|
-
|
|
4881
|
+
UID2 = 1e3;
|
|
4590
4882
|
STDIO = ["stdin", "stdout", "stderr"];
|
|
4591
4883
|
}
|
|
4592
4884
|
});
|