@ai-ecoverse/slicc-kernel 1.141.1 → 1.141.3
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 +3 -8
- package/dist/kernel-worker.js +41 -10
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +106 -59
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +41 -10
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +106 -59
- package/dist/process-worker.js.map +3 -3
- package/dist/types/kernel/proc-info.d.ts +2 -0
- package/dist/types/launcher.d.ts +2 -1
- package/dist/types/process/wasi/wasi-procfs.d.ts +9 -0
- package/dist/types/realm/sync-fs-wire.d.ts +1 -0
- package/package.json +7 -7
package/dist/process-worker.js
CHANGED
|
@@ -1555,6 +1555,9 @@ function refusal(err) {
|
|
|
1555
1555
|
const code2 = err?.code;
|
|
1556
1556
|
return code2 === "EACCES" || code2 === "EPERM";
|
|
1557
1557
|
}
|
|
1558
|
+
function gone(err) {
|
|
1559
|
+
return err?.code === "ENOENT";
|
|
1560
|
+
}
|
|
1558
1561
|
function young(s) {
|
|
1559
1562
|
return performance.now() - (s.filledAt ?? Number.NEGATIVE_INFINITY) < SHARED_TTL_MS;
|
|
1560
1563
|
}
|
|
@@ -2072,7 +2075,9 @@ function createStreamOps(h) {
|
|
|
2072
2075
|
if (s.handle === void 0) h.handled.delete(node);
|
|
2073
2076
|
else h.handled.add(node);
|
|
2074
2077
|
} catch (err) {
|
|
2075
|
-
if (refusal(err)
|
|
2078
|
+
if (refusal(err) || gone(err)) {
|
|
2079
|
+
throw new Fs.ErrnoError(wasiErrno(err.code));
|
|
2080
|
+
}
|
|
2076
2081
|
}
|
|
2077
2082
|
};
|
|
2078
2083
|
const permitted = (stream, created) => {
|
|
@@ -2778,7 +2783,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
2778
2783
|
var init_version = __esm({
|
|
2779
2784
|
"src/version.ts"() {
|
|
2780
2785
|
"use strict";
|
|
2781
|
-
KERNEL_VERSION = true ? "1.141.
|
|
2786
|
+
KERNEL_VERSION = true ? "1.141.3" : "0.0.0-dev";
|
|
2782
2787
|
OS_RELEASE = "6.0.0-slicc";
|
|
2783
2788
|
}
|
|
2784
2789
|
});
|
|
@@ -5264,8 +5269,8 @@ var init_process_signals = __esm({
|
|
|
5264
5269
|
const { caught, ignored, defaults = 0 } = masks;
|
|
5265
5270
|
const nocldwait = masks.nocldwait === true;
|
|
5266
5271
|
const was = this.reported;
|
|
5267
|
-
const
|
|
5268
|
-
if (
|
|
5272
|
+
const same2 = caught === was.caught && ignored === was.ignored && nocldwait === was.nocldwait;
|
|
5273
|
+
if (same2 && defaults === 0) return;
|
|
5269
5274
|
this.reported = { caught, ignored, nocldwait };
|
|
5270
5275
|
const req = {
|
|
5271
5276
|
op: "sig-mask",
|
|
@@ -5350,7 +5355,7 @@ function createSocketKernel(deps) {
|
|
|
5350
5355
|
call2(req);
|
|
5351
5356
|
return 0;
|
|
5352
5357
|
};
|
|
5353
|
-
const
|
|
5358
|
+
const guard2 = (op) => {
|
|
5354
5359
|
for (; ; ) {
|
|
5355
5360
|
try {
|
|
5356
5361
|
return op();
|
|
@@ -5382,8 +5387,8 @@ function createSocketKernel(deps) {
|
|
|
5382
5387
|
return stream.fd;
|
|
5383
5388
|
};
|
|
5384
5389
|
return {
|
|
5385
|
-
socket: (domain, nonblock, cloexec) =>
|
|
5386
|
-
socketpair: (domain, nonblock, cloexec) =>
|
|
5390
|
+
socket: (domain, nonblock, cloexec) => guard2(() => install(json2({ op: "sock-open", domain }), nonblock, cloexec)),
|
|
5391
|
+
socketpair: (domain, nonblock, cloexec) => guard2(() => {
|
|
5387
5392
|
const [a, b] = json2({ op: "sock-pair", domain });
|
|
5388
5393
|
let first;
|
|
5389
5394
|
try {
|
|
@@ -5401,9 +5406,9 @@ function createSocketKernel(deps) {
|
|
|
5401
5406
|
throw e;
|
|
5402
5407
|
}
|
|
5403
5408
|
}),
|
|
5404
|
-
bind: (fd, given) =>
|
|
5405
|
-
listen: (fd, backlog) =>
|
|
5406
|
-
accept: (fd, nonblock, cloexec) =>
|
|
5409
|
+
bind: (fd, given) => guard2(() => done({ op: "sock-bind", fd: kfd(fd), addr: resolved(Fs, given) })),
|
|
5410
|
+
listen: (fd, backlog) => guard2(() => done({ op: "sock-listen", fd: kfd(fd), backlog })),
|
|
5411
|
+
accept: (fd, nonblock, cloexec) => guard2(() => {
|
|
5407
5412
|
const listener = socketAt(fd);
|
|
5408
5413
|
const req = {
|
|
5409
5414
|
op: "sock-accept",
|
|
@@ -5413,7 +5418,7 @@ function createSocketKernel(deps) {
|
|
|
5413
5418
|
const got = json2(req);
|
|
5414
5419
|
return { fd: install(got.fd, nonblock, cloexec), peer: got.peer };
|
|
5415
5420
|
}),
|
|
5416
|
-
connect: (fd, addr) =>
|
|
5421
|
+
connect: (fd, addr) => guard2(() => {
|
|
5417
5422
|
const stream = socketAt(fd);
|
|
5418
5423
|
const nonblock = (stream.flags & O_NONBLOCK) !== 0;
|
|
5419
5424
|
return done({
|
|
@@ -5423,12 +5428,12 @@ function createSocketKernel(deps) {
|
|
|
5423
5428
|
nonblock
|
|
5424
5429
|
});
|
|
5425
5430
|
}),
|
|
5426
|
-
shutdown: (fd, how) =>
|
|
5427
|
-
name: (fd, peer) =>
|
|
5428
|
-
getopt: (fd, level, name2) =>
|
|
5429
|
-
setopt: (fd, level, name2, value2) =>
|
|
5430
|
-
resolve: (name2, family = 4) =>
|
|
5431
|
-
send: (fd, bytes, flags) =>
|
|
5431
|
+
shutdown: (fd, how) => guard2(() => done({ op: "sock-shutdown", fd: kfd(fd), how })),
|
|
5432
|
+
name: (fd, peer) => guard2(() => json2({ op: "sock-name", fd: kfd(fd), peer })),
|
|
5433
|
+
getopt: (fd, level, name2) => guard2(() => ({ value: json2({ op: "sock-getopt", fd: kfd(fd), level, name: name2 }) })),
|
|
5434
|
+
setopt: (fd, level, name2, value2) => guard2(() => done({ op: "sock-setopt", fd: kfd(fd), level, name: name2, value: value2 })),
|
|
5435
|
+
resolve: (name2, family = 4) => guard2(() => json2({ op: "sock-resolve", name: name2, family })),
|
|
5436
|
+
send: (fd, bytes, flags) => guard2(() => {
|
|
5432
5437
|
const stream = socketAt(fd);
|
|
5433
5438
|
const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
|
|
5434
5439
|
try {
|
|
@@ -5440,7 +5445,7 @@ function createSocketKernel(deps) {
|
|
|
5440
5445
|
throw e;
|
|
5441
5446
|
}
|
|
5442
5447
|
}),
|
|
5443
|
-
recv: (fd, max, flags) =>
|
|
5448
|
+
recv: (fd, max, flags) => guard2(() => {
|
|
5444
5449
|
const stream = socketAt(fd);
|
|
5445
5450
|
const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
|
|
5446
5451
|
return sys.read(stream.sliccKernelFd, max, { nonblock, peek: flags.peek === true });
|
|
@@ -5487,6 +5492,10 @@ function mayTrace(viewer, target) {
|
|
|
5487
5492
|
const uid = of.ruid === by.euid && of.euid === by.euid && of.suid === by.euid;
|
|
5488
5493
|
return uid && of.rgid === by.egid && of.egid === by.egid && of.sgid === by.egid;
|
|
5489
5494
|
}
|
|
5495
|
+
function fileIdentity(ino, mtimeMs) {
|
|
5496
|
+
if (ino === void 0 || mtimeMs === void 0 || !Number.isFinite(mtimeMs)) return void 0;
|
|
5497
|
+
return `${ino}:${Math.trunc(mtimeMs)}`;
|
|
5498
|
+
}
|
|
5490
5499
|
var init_proc_info = __esm({
|
|
5491
5500
|
"src/kernel/proc-info.ts"() {
|
|
5492
5501
|
"use strict";
|
|
@@ -5833,15 +5842,15 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
|
|
|
5833
5842
|
readdir: (node) => listAll(node)
|
|
5834
5843
|
};
|
|
5835
5844
|
const track = (stream, names) => {
|
|
5836
|
-
let
|
|
5845
|
+
let current2 = names;
|
|
5837
5846
|
const remember2 = (list) => scans.set(stream, new Set(list.filter((n) => /^[1-9]\d*$/.test(n)).map(Number)));
|
|
5838
|
-
remember2(
|
|
5847
|
+
remember2(current2 ?? []);
|
|
5839
5848
|
Object.defineProperty(stream, "getdents", {
|
|
5840
5849
|
configurable: true,
|
|
5841
5850
|
enumerable: true,
|
|
5842
|
-
get: () =>
|
|
5851
|
+
get: () => current2,
|
|
5843
5852
|
set: (next2) => {
|
|
5844
|
-
|
|
5853
|
+
current2 = next2;
|
|
5845
5854
|
if (next2) remember2(next2);
|
|
5846
5855
|
}
|
|
5847
5856
|
});
|
|
@@ -6972,7 +6981,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
6972
6981
|
const live = (miss, path) => miss.until > now() && young2(miss) && (view === void 0 || miss.gen === void 0 || !view.changedSince(miss.gen, path).changed);
|
|
6973
6982
|
const seen = new SeenAt(view, lstats);
|
|
6974
6983
|
const kept = remember(cache, seen, blind, (entry2) => filled2.set(entry2));
|
|
6975
|
-
const
|
|
6984
|
+
const gone2 = (path) => goneAbove([lstats, stats], live, path);
|
|
6976
6985
|
const usable = (map, path) => {
|
|
6977
6986
|
const hit = map.get(path);
|
|
6978
6987
|
if (hit === void 0) return void 0;
|
|
@@ -6984,7 +6993,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
6984
6993
|
cache.fresh();
|
|
6985
6994
|
let hit = usable(map, path);
|
|
6986
6995
|
if (hit === void 0) {
|
|
6987
|
-
const missing2 =
|
|
6996
|
+
const missing2 = gone2(path);
|
|
6988
6997
|
if (missing2) throw missing2.error;
|
|
6989
6998
|
hit = fetched({ view, now, seen, filled: filled2, cache }, map, path, get);
|
|
6990
6999
|
}
|
|
@@ -7051,8 +7060,8 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
7051
7060
|
readlink: (p) => {
|
|
7052
7061
|
const known = blind ? void 0 : (cache.fresh(), lstats.get(p));
|
|
7053
7062
|
const gen = seen.lstat(p);
|
|
7054
|
-
const
|
|
7055
|
-
if (known &&
|
|
7063
|
+
const current2 = view !== void 0 && gen !== void 0 && !view.changedSince(gen, p).changed;
|
|
7064
|
+
if (known && current2 && !("until" in known) && young2(known) && !known.isSymbolicLink) {
|
|
7056
7065
|
throw syncError("EINVAL", `'${p}' is not a symbolic link`);
|
|
7057
7066
|
}
|
|
7058
7067
|
return bridge.readlink(p);
|
|
@@ -7843,8 +7852,8 @@ var init_js_kernel = __esm({
|
|
|
7843
7852
|
}
|
|
7844
7853
|
async report(handlers, ignored, defaults) {
|
|
7845
7854
|
const caught = caughtOf(handlers);
|
|
7846
|
-
const
|
|
7847
|
-
if (
|
|
7855
|
+
const same2 = caught === this.reported.caught && ignored === this.reported.ignored;
|
|
7856
|
+
if (same2 && defaults === 0) return;
|
|
7848
7857
|
this.reported = { caught, ignored };
|
|
7849
7858
|
await this.call({ op: "sig-mask", caught, ignored, ...defaults ? { defaults } : {} });
|
|
7850
7859
|
}
|
|
@@ -9318,6 +9327,10 @@ var init_wasi_fds = __esm({
|
|
|
9318
9327
|
if (exclusive && this.isLink(path)) throw new WasiError("EEXIST");
|
|
9319
9328
|
const s = this.statOrMissing(path);
|
|
9320
9329
|
if (exclusive && s) throw new WasiError("EEXIST");
|
|
9330
|
+
if (s?.escape !== void 0) {
|
|
9331
|
+
refuseWrite({ readonly: true }, oflags, rights);
|
|
9332
|
+
return this.open(s.escape, oflags, rights, fdflags, mode);
|
|
9333
|
+
}
|
|
9321
9334
|
if (oflags & OFLAGS.DIRECTORY && !s?.isDirectory) {
|
|
9322
9335
|
throw new WasiError(s ? "ENOTDIR" : "ENOENT");
|
|
9323
9336
|
}
|
|
@@ -11494,7 +11507,7 @@ var init_wasi_host = __esm({
|
|
|
11494
11507
|
size: BigInt(size)
|
|
11495
11508
|
};
|
|
11496
11509
|
}
|
|
11497
|
-
statOrphanable(path, size, orphan = false,
|
|
11510
|
+
statOrphanable(path, size, orphan = false, gone2 = false) {
|
|
11498
11511
|
let s;
|
|
11499
11512
|
if (!orphan) {
|
|
11500
11513
|
try {
|
|
@@ -11503,7 +11516,7 @@ var init_wasi_host = __esm({
|
|
|
11503
11516
|
}
|
|
11504
11517
|
}
|
|
11505
11518
|
const out = this.sized(path, s, size);
|
|
11506
|
-
return
|
|
11519
|
+
return gone2 ? { ...out, nlink: 0n } : out;
|
|
11507
11520
|
}
|
|
11508
11521
|
synthetic(path) {
|
|
11509
11522
|
return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH2 && !!this.o.kernel.sys.openClipboard;
|
|
@@ -11657,11 +11670,11 @@ var init_wasi_host = __esm({
|
|
|
11657
11670
|
const asked = FSTFLAGS.ATIM | FSTFLAGS.ATIM_NOW | FSTFLAGS.MTIM | FSTFLAGS.MTIM_NOW;
|
|
11658
11671
|
if (this.o.fs.owners && (flags & asked) === 0) return;
|
|
11659
11672
|
const now = Date.now();
|
|
11660
|
-
let
|
|
11673
|
+
let current2;
|
|
11661
11674
|
const statOf = follow3 ? this.o.fs.stat.bind(this.o.fs) : this.o.fs.lstat.bind(this.o.fs);
|
|
11662
11675
|
const kept = (field2) => {
|
|
11663
|
-
|
|
11664
|
-
return
|
|
11676
|
+
current2 ??= statOf(path);
|
|
11677
|
+
return current2[field2] ?? current2.mtimeMs ?? now;
|
|
11665
11678
|
};
|
|
11666
11679
|
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS4) : kept(field2);
|
|
11667
11680
|
(follow3 ? this.o.fs.utimes : this.o.fs.lutimes).call(
|
|
@@ -12407,10 +12420,40 @@ function directMiss(err, path) {
|
|
|
12407
12420
|
if (err?.direct !== true) return false;
|
|
12408
12421
|
return !path.split("/").some((part) => part === "." || part === "..");
|
|
12409
12422
|
}
|
|
12410
|
-
function
|
|
12423
|
+
function same(fs, path, id) {
|
|
12424
|
+
try {
|
|
12425
|
+
const st = fs.stat(path);
|
|
12426
|
+
const now = fileIdentity(st.ino, st.mtimeMs);
|
|
12427
|
+
return now === void 0 || now === id;
|
|
12428
|
+
} catch {
|
|
12429
|
+
return false;
|
|
12430
|
+
}
|
|
12431
|
+
}
|
|
12432
|
+
function current(fs, tree, q) {
|
|
12433
|
+
const to = tree.escapeTo(q);
|
|
12434
|
+
if (!to || to.id === void 0) return to?.target;
|
|
12435
|
+
if (!same(fs, to.target, to.id)) throw syncError("ENOENT", q);
|
|
12436
|
+
return to.target;
|
|
12437
|
+
}
|
|
12438
|
+
function guard(toProc, shadowing) {
|
|
12439
|
+
return (paths, run) => {
|
|
12440
|
+
const physical2 = shadowing();
|
|
12441
|
+
for (const [p, follow3] of paths) {
|
|
12442
|
+
if (inProc(p) || physical2 && toProc(p, follow3) !== void 0) throw syncError("EROFS", p);
|
|
12443
|
+
}
|
|
12444
|
+
return run();
|
|
12445
|
+
};
|
|
12446
|
+
}
|
|
12447
|
+
function shownLink(fs, tree, q) {
|
|
12448
|
+
const target = tree.readlink(q);
|
|
12449
|
+
const to = tree.linkTo(q);
|
|
12450
|
+
if (!to) return target;
|
|
12451
|
+
return same(fs, to.target, to.id) ? target : `${target} (deleted)`;
|
|
12452
|
+
}
|
|
12453
|
+
function routing(fs, tree, toProc, shadowing) {
|
|
12411
12454
|
return (p, inner, own, follow3 = true, outside) => {
|
|
12412
12455
|
const proc = (q) => {
|
|
12413
|
-
const target = outside ? tree
|
|
12456
|
+
const target = outside ? current(fs, tree, q) : void 0;
|
|
12414
12457
|
return target === void 0 ? inner(q) : outside(target);
|
|
12415
12458
|
};
|
|
12416
12459
|
if (inProc(p)) return proc(p);
|
|
@@ -12431,14 +12474,8 @@ function routing(tree, toProc, shadowing) {
|
|
|
12431
12474
|
function procfsBridge(fs, tree) {
|
|
12432
12475
|
const toProc = (path, follow3) => procPath(fs, path, follow3);
|
|
12433
12476
|
const shadowing = physicalProc(fs);
|
|
12434
|
-
const via = routing(tree, toProc, shadowing);
|
|
12435
|
-
const readOnly2 = (
|
|
12436
|
-
const physical2 = shadowing();
|
|
12437
|
-
for (const [p, follow3] of paths) {
|
|
12438
|
-
if (inProc(p) || physical2 && toProc(p, follow3) !== void 0) throw syncError("EROFS", p);
|
|
12439
|
-
}
|
|
12440
|
-
return run();
|
|
12441
|
-
};
|
|
12477
|
+
const via = routing(fs, tree, toProc, shadowing);
|
|
12478
|
+
const readOnly2 = guard(toProc, shadowing);
|
|
12442
12479
|
const snapshots = /* @__PURE__ */ new Map();
|
|
12443
12480
|
let lastSnapshot = 0;
|
|
12444
12481
|
const snapshot = (q) => {
|
|
@@ -12463,7 +12500,7 @@ function procfsBridge(fs, tree) {
|
|
|
12463
12500
|
(q) => tree.stat(q),
|
|
12464
12501
|
() => fs.stat(p),
|
|
12465
12502
|
true,
|
|
12466
|
-
(t) => fs.stat(t)
|
|
12503
|
+
(t) => ({ ...fs.stat(t), escape: t })
|
|
12467
12504
|
),
|
|
12468
12505
|
lstat: (p) => via(
|
|
12469
12506
|
p,
|
|
@@ -12502,7 +12539,7 @@ function procfsBridge(fs, tree) {
|
|
|
12502
12539
|
},
|
|
12503
12540
|
readlink: (p) => via(
|
|
12504
12541
|
p,
|
|
12505
|
-
(q) => tree
|
|
12542
|
+
(q) => shownLink(fs, tree, q),
|
|
12506
12543
|
() => fs.readlink(p),
|
|
12507
12544
|
false
|
|
12508
12545
|
),
|
|
@@ -12542,7 +12579,7 @@ function procfsBridge(fs, tree) {
|
|
|
12542
12579
|
return via(p, snapshot, () => fs.hold?.(p, held2, open, void 0, want, seen) ?? late(p));
|
|
12543
12580
|
},
|
|
12544
12581
|
kept: (handle) => snapshots.has(handle) || fs.kept?.(handle) === true,
|
|
12545
|
-
escape: (p) => inProc(p) ? tree
|
|
12582
|
+
escape: (p) => inProc(p) ? current(fs, tree, p) : void 0,
|
|
12546
12583
|
pinned: (handle) => {
|
|
12547
12584
|
const bytes = snapshots.get(handle);
|
|
12548
12585
|
return bytes ? frozen(bytes) : fs.pinned?.(handle) ?? fs;
|
|
@@ -12642,12 +12679,7 @@ var init_wasi_procfs = __esm({
|
|
|
12642
12679
|
const exe = () => this.info(Number(top))?.exe === void 0 ? [] : ["exe"];
|
|
12643
12680
|
return { kind: "dir", names: () => [...PID_NAMES, ...exe(), "task"] };
|
|
12644
12681
|
}
|
|
12645
|
-
if (leaf === "exe")
|
|
12646
|
-
const info = this.info(Number(top));
|
|
12647
|
-
if (info?.exe === void 0) return void 0;
|
|
12648
|
-
const denied = !mayTrace(this.ownInfo(), info);
|
|
12649
|
-
return { kind: "link", target: info.exe, ...denied ? { denied } : {} };
|
|
12650
|
-
}
|
|
12682
|
+
if (leaf === "exe") return this.exe(Number(top));
|
|
12651
12683
|
if (!PID_NAMES.includes(leaf)) return void 0;
|
|
12652
12684
|
return {
|
|
12653
12685
|
kind: "file",
|
|
@@ -12659,6 +12691,13 @@ var init_wasi_procfs = __esm({
|
|
|
12659
12691
|
}
|
|
12660
12692
|
};
|
|
12661
12693
|
}
|
|
12694
|
+
exe(pid) {
|
|
12695
|
+
const info = this.info(pid);
|
|
12696
|
+
if (info?.exe === void 0) return void 0;
|
|
12697
|
+
const denied = !mayTrace(this.ownInfo(), info);
|
|
12698
|
+
const id = info.exeId === void 0 ? {} : { id: info.exeId };
|
|
12699
|
+
return { kind: "link", target: info.exe, ...denied ? { denied } : {}, ...id };
|
|
12700
|
+
}
|
|
12662
12701
|
ownInfo() {
|
|
12663
12702
|
const processes2 = this.listing().processes;
|
|
12664
12703
|
return processes2.find((p) => p.tid === this.pid) ?? processes2.find((p) => p.pid === this.pid);
|
|
@@ -12724,10 +12763,18 @@ var init_wasi_procfs = __esm({
|
|
|
12724
12763
|
return node.names();
|
|
12725
12764
|
}
|
|
12726
12765
|
escape(path) {
|
|
12766
|
+
return this.escapeTo(path)?.target;
|
|
12767
|
+
}
|
|
12768
|
+
escapeTo(path) {
|
|
12727
12769
|
const node = this.node(this.parts(path, true));
|
|
12728
12770
|
if (node?.kind !== "link" || !node.target.startsWith("/")) return void 0;
|
|
12729
12771
|
if (node.denied) throw syncError("EACCES", path);
|
|
12730
|
-
return node.target;
|
|
12772
|
+
return node.id === void 0 ? { target: node.target } : { target: node.target, id: node.id };
|
|
12773
|
+
}
|
|
12774
|
+
linkTo(path) {
|
|
12775
|
+
const node = this.node(this.parts(path, false));
|
|
12776
|
+
if (node?.kind !== "link" || node.id === void 0 || node.denied) return void 0;
|
|
12777
|
+
return { target: node.target, id: node.id };
|
|
12731
12778
|
}
|
|
12732
12779
|
readlink(path) {
|
|
12733
12780
|
const node = this.find(path, false);
|
|
@@ -17052,9 +17099,9 @@ function ttyOps(kernel, syncKernel) {
|
|
|
17052
17099
|
if (original) await setAttr(fd, original.termios);
|
|
17053
17100
|
return;
|
|
17054
17101
|
}
|
|
17055
|
-
const
|
|
17056
|
-
if (!saved.has(terminal)) saved.set(terminal, { fd, termios:
|
|
17057
|
-
await setAttr(fd, rawOf(
|
|
17102
|
+
const current2 = await getAttr(fd);
|
|
17103
|
+
if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current2 });
|
|
17104
|
+
await setAttr(fd, rawOf(current2));
|
|
17058
17105
|
},
|
|
17059
17106
|
async size(fd) {
|
|
17060
17107
|
const [rows, columns] = await kernel.json({ op: "tty-winsz", fd });
|
|
@@ -17100,9 +17147,9 @@ function ttyOps(kernel, syncKernel) {
|
|
|
17100
17147
|
if (original) syncSet(fd, original.termios);
|
|
17101
17148
|
return;
|
|
17102
17149
|
}
|
|
17103
|
-
const
|
|
17104
|
-
if (!saved.has(terminal)) saved.set(terminal, { fd, termios:
|
|
17105
|
-
syncSet(fd, rawOf(
|
|
17150
|
+
const current2 = syncGet(fd);
|
|
17151
|
+
if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current2 });
|
|
17152
|
+
syncSet(fd, rawOf(current2));
|
|
17106
17153
|
}
|
|
17107
17154
|
};
|
|
17108
17155
|
const modes = () => [...saved].reverse().map(([terminal, { fd, termios }]) => ({ terminal, fd, termios }));
|