@ai-ecoverse/slicc-kernel 1.143.5 → 1.144.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 +15 -7
- package/dist/driver-worker.js +5 -1
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +5 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +7830 -7524
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js +1 -1
- package/dist/meta.js.map +2 -2
- package/dist/node-driver-worker.js +5 -1
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +212 -35
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +24174 -23864
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +212 -35
- package/dist/process-worker.js.map +3 -3
- package/dist/types/client/attach.d.ts +3 -0
- package/dist/types/client/protocol.d.ts +3 -0
- package/dist/types/client/serve-client.d.ts +1 -1
- package/dist/types/cron/crontab.d.ts +13 -1
- package/dist/types/cron/service.d.ts +2 -0
- package/dist/types/fs/changes.d.ts +4 -0
- package/dist/types/fs/dac.d.ts +2 -0
- package/dist/types/fs/meta.d.ts +4 -0
- package/dist/types/fs/opfs.d.ts +10 -0
- package/dist/types/fs/remote.d.ts +4 -0
- package/dist/types/fs/types.d.ts +4 -0
- package/dist/types/kernel/clipboard.d.ts +3 -2
- package/dist/types/kernel/host.d.ts +5 -0
- package/dist/types/kernel/proc-info.d.ts +1 -0
- package/dist/types/kernel/process.d.ts +1 -1
- package/dist/types/kernel/rename-log.d.ts +14 -0
- package/dist/types/kernel/sealed.d.ts +8 -3
- package/dist/types/kernel/vfs-file.d.ts +1 -0
- package/dist/types/launcher.d.ts +12 -1
- package/dist/types/process/wasi/wasi-fds.d.ts +4 -1
- package/dist/types/process/wasi/wasi-files.d.ts +2 -0
- package/dist/types/realm/live-vfs-fs.d.ts +8 -0
- package/dist/types/realm/sync-fs-token-registry.d.ts +5 -0
- package/dist/types/realm/sync-fs-wire.d.ts +7 -2
- package/dist/types/sudo.d.ts +2 -1
- package/package.json +7 -7
|
@@ -287,7 +287,7 @@ function normal(path) {
|
|
|
287
287
|
}
|
|
288
288
|
return `/${parts.join("/")}`;
|
|
289
289
|
}
|
|
290
|
-
var GEN, RING, RING_SIZE, SLOT, SHARED_TTL_MS, DIRTY, FOREIGN, CHANGES_BYTES, ChangeView;
|
|
290
|
+
var GEN, RING, RING_SIZE, SLOT, SHARED_TTL_MS, RENAME_WAIT_MS, DIRTY, FOREIGN, RENAMES, CHANGES_BYTES, ChangeView;
|
|
291
291
|
var init_changes = __esm({
|
|
292
292
|
"src/fs/changes.ts"() {
|
|
293
293
|
"use strict";
|
|
@@ -296,9 +296,11 @@ var init_changes = __esm({
|
|
|
296
296
|
RING_SIZE = 4096;
|
|
297
297
|
SLOT = 2;
|
|
298
298
|
SHARED_TTL_MS = 100;
|
|
299
|
+
RENAME_WAIT_MS = 100;
|
|
299
300
|
DIRTY = RING + RING_SIZE * SLOT;
|
|
300
301
|
FOREIGN = DIRTY + 1;
|
|
301
|
-
|
|
302
|
+
RENAMES = FOREIGN + 1;
|
|
303
|
+
CHANGES_BYTES = (RENAMES + 1) * 4;
|
|
302
304
|
ChangeView = class {
|
|
303
305
|
view;
|
|
304
306
|
constructor(sab) {
|
|
@@ -313,6 +315,13 @@ var init_changes = __esm({
|
|
|
313
315
|
foreign() {
|
|
314
316
|
return this.view.length > FOREIGN && Atomics.load(this.view, FOREIGN) === 1;
|
|
315
317
|
}
|
|
318
|
+
renames() {
|
|
319
|
+
return this.view.length > RENAMES ? Atomics.load(this.view, RENAMES) : 0;
|
|
320
|
+
}
|
|
321
|
+
awaitRename(seen, ms) {
|
|
322
|
+
if (this.view.length > RENAMES) Atomics.wait(this.view, RENAMES, seen, ms);
|
|
323
|
+
return this.renames();
|
|
324
|
+
}
|
|
316
325
|
changedSince(seen, path) {
|
|
317
326
|
const now = Atomics.load(this.view, GEN);
|
|
318
327
|
const distance = now - seen >>> 0;
|
|
@@ -730,7 +739,8 @@ var init_sync_fs_wire = __esm({
|
|
|
730
739
|
"truncate",
|
|
731
740
|
"chown",
|
|
732
741
|
"lchown",
|
|
733
|
-
"access"
|
|
742
|
+
"access",
|
|
743
|
+
"renames"
|
|
734
744
|
];
|
|
735
745
|
HOLD_READ = 4;
|
|
736
746
|
HOLD_WRITE = 8;
|
|
@@ -747,7 +757,8 @@ var init_sync_fs_wire = __esm({
|
|
|
747
757
|
"readlink",
|
|
748
758
|
"statfs",
|
|
749
759
|
"kept",
|
|
750
|
-
"access"
|
|
760
|
+
"access",
|
|
761
|
+
"renames"
|
|
751
762
|
]);
|
|
752
763
|
}
|
|
753
764
|
});
|
|
@@ -966,6 +977,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
966
977
|
const entry = (p) => [p, p.slice(0, p.lastIndexOf("/")) || "/"];
|
|
967
978
|
return {
|
|
968
979
|
...bridge.changes ? { changes: bridge.changes } : {},
|
|
980
|
+
...bridge.renames ? { renames: bridge.renames.bind(bridge) } : {},
|
|
969
981
|
readFile: (p) => bridge.readFile(p),
|
|
970
982
|
readdir: (p) => bridge.readdir(p),
|
|
971
983
|
readdirStat: (p) => {
|
|
@@ -1082,6 +1094,7 @@ var init_wasi_files = __esm({
|
|
|
1082
1094
|
seen = 0;
|
|
1083
1095
|
maxFile;
|
|
1084
1096
|
handle;
|
|
1097
|
+
moved;
|
|
1085
1098
|
constructor(fs, path, empty, maxFile, size, version, watch) {
|
|
1086
1099
|
this.fs = fs;
|
|
1087
1100
|
this.where = path;
|
|
@@ -1090,7 +1103,11 @@ var init_wasi_files = __esm({
|
|
|
1090
1103
|
this.watch = watch;
|
|
1091
1104
|
this.seen = watch?.seen ?? watch?.view.now() ?? 0;
|
|
1092
1105
|
if (size !== void 0 && pread && pwrite && truncate) {
|
|
1093
|
-
const io = {
|
|
1106
|
+
const io = {
|
|
1107
|
+
pread: (_, ...rest2) => this.retried(() => pread.call(fs, this.where, ...rest2)),
|
|
1108
|
+
pwrite: (_, ...rest2) => this.retried(() => pwrite.call(fs, this.where, ...rest2)),
|
|
1109
|
+
truncate: (_, size2) => this.retried(() => truncate.call(fs, this.where, size2))
|
|
1110
|
+
};
|
|
1094
1111
|
this.ranged = new RangedFile(io, path, size, version, watch);
|
|
1095
1112
|
if (empty) this.truncate(0);
|
|
1096
1113
|
} else if (empty) {
|
|
@@ -1102,6 +1119,14 @@ var init_wasi_files = __esm({
|
|
|
1102
1119
|
get path() {
|
|
1103
1120
|
return this.where;
|
|
1104
1121
|
}
|
|
1122
|
+
retried(op) {
|
|
1123
|
+
try {
|
|
1124
|
+
return op();
|
|
1125
|
+
} catch (err) {
|
|
1126
|
+
if (err.code !== "ENOENT" || !this.moved?.(true)) throw err;
|
|
1127
|
+
return op();
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1105
1130
|
set path(path) {
|
|
1106
1131
|
this.where = path;
|
|
1107
1132
|
if (this.ranged) this.ranged.path = path;
|
|
@@ -1125,7 +1150,7 @@ var init_wasi_files = __esm({
|
|
|
1125
1150
|
}
|
|
1126
1151
|
if (!this.data) {
|
|
1127
1152
|
this.seen = view?.now() ?? 0;
|
|
1128
|
-
this.data = this.fs.readFile(this.path);
|
|
1153
|
+
this.data = this.retried(() => this.fs.readFile(this.path));
|
|
1129
1154
|
this.length = this.data.length;
|
|
1130
1155
|
}
|
|
1131
1156
|
return this.data;
|
|
@@ -1166,8 +1191,9 @@ var init_wasi_files = __esm({
|
|
|
1166
1191
|
append(bytes) {
|
|
1167
1192
|
const { append } = this.fs;
|
|
1168
1193
|
if (!append || this.orphaned) return void 0;
|
|
1194
|
+
this.moved?.(false);
|
|
1169
1195
|
this.flush();
|
|
1170
|
-
const end = append.call(this.fs, this.path, bytes);
|
|
1196
|
+
const end = this.retried(() => append.call(this.fs, this.path, bytes));
|
|
1171
1197
|
if (!this.ranged) {
|
|
1172
1198
|
this.data = void 0;
|
|
1173
1199
|
this.length = 0;
|
|
@@ -1215,11 +1241,17 @@ var init_wasi_files = __esm({
|
|
|
1215
1241
|
}
|
|
1216
1242
|
flush() {
|
|
1217
1243
|
if (this.orphaned || !this.dirty) return;
|
|
1244
|
+
this.moved?.(false);
|
|
1218
1245
|
if (this.ranged) this.ranged.flush();
|
|
1219
1246
|
else if (!this.data) return;
|
|
1220
|
-
else if (this.whole || !this.fs.pwrite)
|
|
1221
|
-
|
|
1222
|
-
|
|
1247
|
+
else if (this.whole || !this.fs.pwrite) {
|
|
1248
|
+
const whole = this.data.slice(0, this.length);
|
|
1249
|
+
this.retried(() => this.fs.writeFile(this.path, whole, true));
|
|
1250
|
+
} else {
|
|
1251
|
+
const { pwrite } = this.fs;
|
|
1252
|
+
const run = this.data.slice(this.from, this.to);
|
|
1253
|
+
this.retried(() => pwrite.call(this.fs, this.path, this.from, run, true));
|
|
1254
|
+
}
|
|
1223
1255
|
this.dirty = false;
|
|
1224
1256
|
this.whole = false;
|
|
1225
1257
|
this.from = Infinity;
|
|
@@ -3061,6 +3093,7 @@ var SYNTHETIC_DIRS, O_NONBLOCK, O_WRONLY2, O_RDWR2, O_APPEND2, SEALED_PATH, CLIP
|
|
|
3061
3093
|
var init_wasi_fds = __esm({
|
|
3062
3094
|
"src/process/wasi/wasi-fds.ts"() {
|
|
3063
3095
|
"use strict";
|
|
3096
|
+
init_changes();
|
|
3064
3097
|
init_ranged();
|
|
3065
3098
|
init_fd_table();
|
|
3066
3099
|
init_sync_fs_wire();
|
|
@@ -3081,9 +3114,29 @@ var init_wasi_fds = __esm({
|
|
|
3081
3114
|
ids = /* @__PURE__ */ new Map();
|
|
3082
3115
|
kernel;
|
|
3083
3116
|
fs;
|
|
3117
|
+
renamesSeen;
|
|
3084
3118
|
constructor(kernel, fs) {
|
|
3085
3119
|
this.kernel = kernel;
|
|
3086
3120
|
this.fs = fs;
|
|
3121
|
+
this.renamesSeen = fs.changes?.renames() ?? 0;
|
|
3122
|
+
}
|
|
3123
|
+
ownRename(seq) {
|
|
3124
|
+
if (seq !== void 0 && seq === (this.renamesSeen + 1 | 0)) this.renamesSeen = seq;
|
|
3125
|
+
}
|
|
3126
|
+
followRenames(missing2 = false) {
|
|
3127
|
+
const view = this.fs.changes;
|
|
3128
|
+
let now = view?.renames() ?? 0;
|
|
3129
|
+
if (missing2 && view && now === this.renamesSeen) now = view.awaitRename(now, RENAME_WAIT_MS);
|
|
3130
|
+
if (now === this.renamesSeen || !this.fs.renames) return false;
|
|
3131
|
+
const held2 = [...this.buffers].filter(([, b]) => !b.isOrphan()).map(([p]) => p);
|
|
3132
|
+
if (held2.length === 0) {
|
|
3133
|
+
this.renamesSeen = now;
|
|
3134
|
+
return false;
|
|
3135
|
+
}
|
|
3136
|
+
const { now: seen, renames } = this.fs.renames(this.renamesSeen, held2);
|
|
3137
|
+
this.renamesSeen = seen;
|
|
3138
|
+
for (const [from, to] of renames) this.renamed(from, to, void 0, true);
|
|
3139
|
+
return renames.length > 0;
|
|
3087
3140
|
}
|
|
3088
3141
|
setup(cwd, inherited, root = false) {
|
|
3089
3142
|
for (const fd of [0, 1, 2]) this.table.set(fd, this.stdioEntry(fd));
|
|
@@ -3283,6 +3336,7 @@ var init_wasi_fds = __esm({
|
|
|
3283
3336
|
get(fd) {
|
|
3284
3337
|
const e = this.find(fd);
|
|
3285
3338
|
if (!e) throw new WasiError("EBADF");
|
|
3339
|
+
if (e.type === "file") this.followRenames();
|
|
3286
3340
|
return e;
|
|
3287
3341
|
}
|
|
3288
3342
|
preopen(fd) {
|
|
@@ -3603,9 +3657,9 @@ var init_wasi_fds = __esm({
|
|
|
3603
3657
|
buffer.orphan();
|
|
3604
3658
|
this.forget(buffer);
|
|
3605
3659
|
}
|
|
3606
|
-
renamed(from, to, replacedLinked) {
|
|
3660
|
+
renamed(from, to, replacedLinked, foreign = false) {
|
|
3607
3661
|
if (from === to) return;
|
|
3608
|
-
if (this.shared) this.kernel.call({ op: "fd-path-renamed", from, to });
|
|
3662
|
+
if (this.shared && !foreign) this.kernel.call({ op: "fd-path-renamed", from, to });
|
|
3609
3663
|
for (const e of this.table.values()) {
|
|
3610
3664
|
if (e.type === "kernel" && e.path !== void 0 && within(e.path, from)) {
|
|
3611
3665
|
e.path = to + e.path.slice(from.length);
|
|
@@ -3613,6 +3667,7 @@ var init_wasi_fds = __esm({
|
|
|
3613
3667
|
}
|
|
3614
3668
|
const moved = [];
|
|
3615
3669
|
for (const [p, buffer] of this.buffers) {
|
|
3670
|
+
if (foreign && buffer.isOrphan()) continue;
|
|
3616
3671
|
if (within(p, from)) moved.push([p, buffer]);
|
|
3617
3672
|
else if (within(p, to)) {
|
|
3618
3673
|
this.detach(buffer, replacedLinked);
|
|
@@ -3754,6 +3809,7 @@ var init_wasi_fds = __esm({
|
|
|
3754
3809
|
}
|
|
3755
3810
|
file(path, existing, oflags, rights, fdflags, mode, created = false) {
|
|
3756
3811
|
const { readable: readable3, writable: writable2 } = openAccess(existing, oflags, rights);
|
|
3812
|
+
this.followRenames();
|
|
3757
3813
|
let buffer = created ? void 0 : this.buffers.get(path);
|
|
3758
3814
|
if (buffer?.handle !== void 0 && this.fs.kept?.(buffer.handle)) {
|
|
3759
3815
|
this.buffers.delete(path);
|
|
@@ -3801,6 +3857,7 @@ var init_wasi_fds = __esm({
|
|
|
3801
3857
|
st
|
|
3802
3858
|
);
|
|
3803
3859
|
const buffer = new FileBuffer(io, path, empty, st.maxFile, ranged, st.version, watch);
|
|
3860
|
+
buffer.moved = (missing2) => this.followRenames(missing2);
|
|
3804
3861
|
buffer.handle = handle;
|
|
3805
3862
|
this.buffers.set(path, buffer);
|
|
3806
3863
|
const id = this.identity(st);
|
|
@@ -5607,8 +5664,9 @@ var init_wasi_host = __esm({
|
|
|
5607
5664
|
const to = at(fd2, p2, l2);
|
|
5608
5665
|
fds.flushPath(from);
|
|
5609
5666
|
const replaced = fds.holdsUnder(to) ? linkedElsewhere(o.fs, to) : void 0;
|
|
5610
|
-
o.fs.rename(from, to);
|
|
5667
|
+
const seq = o.fs.rename(from, to);
|
|
5611
5668
|
fds.renamed(from, to, replaced);
|
|
5669
|
+
fds.ownRename(typeof seq === "number" ? seq : void 0);
|
|
5612
5670
|
},
|
|
5613
5671
|
path_symlink: (tp, tl, dirfd, p, l) => {
|
|
5614
5672
|
const path = at(dirfd, p, l);
|
|
@@ -6726,7 +6784,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
6726
6784
|
var init_version = __esm({
|
|
6727
6785
|
"src/version.ts"() {
|
|
6728
6786
|
"use strict";
|
|
6729
|
-
KERNEL_VERSION = true ? "1.
|
|
6787
|
+
KERNEL_VERSION = true ? "1.144.0" : "0.0.0-dev";
|
|
6730
6788
|
OS_RELEASE = "6.0.0-slicc";
|
|
6731
6789
|
}
|
|
6732
6790
|
});
|
|
@@ -8076,7 +8134,9 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
8076
8134
|
run({ op: "rm", path }, path);
|
|
8077
8135
|
},
|
|
8078
8136
|
rename: (from, to) => {
|
|
8079
|
-
run({ op: "rename", path: from, arg2: to }, from);
|
|
8137
|
+
const r = run({ op: "rename", path: from, arg2: to }, from);
|
|
8138
|
+
const seq = r.ok && r.kind === "json" ? r.json.seq : void 0;
|
|
8139
|
+
return typeof seq === "number" ? seq : void 0;
|
|
8080
8140
|
},
|
|
8081
8141
|
link: (from, to, follow3) => {
|
|
8082
8142
|
run({ op: "link", path: from, arg2: to, ...follow3 ? { mode: 1 } : {} }, from);
|
|
@@ -8157,7 +8217,11 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
8157
8217
|
run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
|
|
8158
8218
|
return void 0;
|
|
8159
8219
|
},
|
|
8160
|
-
statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path))
|
|
8220
|
+
statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path)),
|
|
8221
|
+
renames: (since, held2) => json2(
|
|
8222
|
+
{ op: "renames", path: "/", offset: since, arg2: JSON.stringify(held2) },
|
|
8223
|
+
"/"
|
|
8224
|
+
)
|
|
8161
8225
|
};
|
|
8162
8226
|
}
|
|
8163
8227
|
var UNCOUNTED_OPS, calls, looks, SPIN_MS, SPIN_STRIDE, SPIN_STRIDES, SPIN_CORES, spinning, SPIN_CAP_MS;
|
|
@@ -8354,12 +8418,130 @@ function freshState(stat) {
|
|
|
8354
8418
|
const base = { len: 0, loaded: false, dirty: false, openCount: 0 };
|
|
8355
8419
|
return stat ? { stat, statAt: syncCallCount(), filledAt: performance.now(), seenAt: syncEpoch(), ...base } : base;
|
|
8356
8420
|
}
|
|
8421
|
+
function inCache(Fs, node) {
|
|
8422
|
+
const table = Fs.nameTable;
|
|
8423
|
+
const parent = node.parent;
|
|
8424
|
+
const hash = Fs.hashName?.(parent.id ?? 0, node.name);
|
|
8425
|
+
if (!table || hash === void 0) return true;
|
|
8426
|
+
let at = table[hash];
|
|
8427
|
+
while (at) {
|
|
8428
|
+
if (at === node) return true;
|
|
8429
|
+
at = at.name_next;
|
|
8430
|
+
}
|
|
8431
|
+
return false;
|
|
8432
|
+
}
|
|
8433
|
+
function heldUnder(held2, from) {
|
|
8434
|
+
let moving = held2;
|
|
8435
|
+
while (moving && moving !== moving.mount.root && liveNodePath(moving) !== from) {
|
|
8436
|
+
moving = moving.parent;
|
|
8437
|
+
}
|
|
8438
|
+
return moving && moving !== moving.mount.root && liveNodePath(moving) === from ? moving : void 0;
|
|
8439
|
+
}
|
|
8440
|
+
function relinked(Fs, moving, to) {
|
|
8441
|
+
const slash = to.lastIndexOf("/");
|
|
8442
|
+
let dir;
|
|
8443
|
+
try {
|
|
8444
|
+
dir = Fs.lookupPath?.(slash <= 0 ? "/" : to.slice(0, slash)).node;
|
|
8445
|
+
} catch {
|
|
8446
|
+
}
|
|
8447
|
+
if (!dir || dir.mount !== moving.mount) return;
|
|
8448
|
+
const name2 = to.slice(slash + 1);
|
|
8449
|
+
try {
|
|
8450
|
+
const existing = Fs.lookupNode?.(dir, name2);
|
|
8451
|
+
if (existing && existing !== moving) Fs.hashRemoveNode?.(existing);
|
|
8452
|
+
} catch {
|
|
8453
|
+
}
|
|
8454
|
+
moving.parent.live.listed = void 0;
|
|
8455
|
+
dir.live.listed = void 0;
|
|
8456
|
+
Fs.hashRemoveNode?.(moving);
|
|
8457
|
+
moving.name = name2;
|
|
8458
|
+
moving.parent = dir;
|
|
8459
|
+
Fs.hashAddNode?.(moving);
|
|
8460
|
+
moving.live.stat = void 0;
|
|
8461
|
+
}
|
|
8462
|
+
function renameFollower(Fs, bridgeOf, call2) {
|
|
8463
|
+
const open = /* @__PURE__ */ new Set();
|
|
8464
|
+
const seen = /* @__PURE__ */ new Map();
|
|
8465
|
+
const follow3 = (node, missing2 = false) => {
|
|
8466
|
+
const bridge = bridgeOf(node);
|
|
8467
|
+
const view = bridge.changes;
|
|
8468
|
+
const since = seen.get(bridge);
|
|
8469
|
+
let now = view?.renames() ?? 0;
|
|
8470
|
+
if (missing2 && view && now === since) now = view.awaitRename(now, RENAME_WAIT_MS);
|
|
8471
|
+
const ask = bridge.renames?.bind(bridge);
|
|
8472
|
+
if (since === void 0 || now === since || !ask) return false;
|
|
8473
|
+
const held2 = [...open].filter((n) => !n.live.orphan && bridgeOf(n) === bridge);
|
|
8474
|
+
if (held2.length === 0) {
|
|
8475
|
+
seen.set(bridge, now);
|
|
8476
|
+
return false;
|
|
8477
|
+
}
|
|
8478
|
+
const reply = call2(
|
|
8479
|
+
() => ask(
|
|
8480
|
+
since,
|
|
8481
|
+
held2.map((n) => liveNodePath(n))
|
|
8482
|
+
)
|
|
8483
|
+
);
|
|
8484
|
+
seen.set(bridge, reply.now);
|
|
8485
|
+
for (const [from, to] of reply.renames) {
|
|
8486
|
+
for (const n of held2) {
|
|
8487
|
+
const moving = heldUnder(n, from);
|
|
8488
|
+
if (moving && inCache(Fs, moving)) relinked(Fs, moving, to);
|
|
8489
|
+
}
|
|
8490
|
+
}
|
|
8491
|
+
return reply.renames.length > 0;
|
|
8492
|
+
};
|
|
8493
|
+
return {
|
|
8494
|
+
open,
|
|
8495
|
+
follow: follow3,
|
|
8496
|
+
track(node, on) {
|
|
8497
|
+
if (!on) {
|
|
8498
|
+
open.delete(node);
|
|
8499
|
+
return;
|
|
8500
|
+
}
|
|
8501
|
+
follow3(node);
|
|
8502
|
+
open.add(node);
|
|
8503
|
+
},
|
|
8504
|
+
watchRenames(bridge) {
|
|
8505
|
+
if (!seen.has(bridge)) seen.set(bridge, bridge.changes?.renames() ?? 0);
|
|
8506
|
+
},
|
|
8507
|
+
ownRename(bridge, seq) {
|
|
8508
|
+
const since = seen.get(bridge);
|
|
8509
|
+
if (seq !== void 0 && since !== void 0 && seq === (since + 1 | 0))
|
|
8510
|
+
seen.set(bridge, seq);
|
|
8511
|
+
}
|
|
8512
|
+
};
|
|
8513
|
+
}
|
|
8514
|
+
function followingOnce(write2, follow3) {
|
|
8515
|
+
try {
|
|
8516
|
+
write2();
|
|
8517
|
+
} catch (err) {
|
|
8518
|
+
if (err.errno !== wasiErrno("ENOENT") || !follow3()) throw err;
|
|
8519
|
+
write2();
|
|
8520
|
+
}
|
|
8521
|
+
}
|
|
8522
|
+
function renameThrough(h, node, from, to) {
|
|
8523
|
+
const seq = h.call(() => h.bridgeOf(node).rename(from, to));
|
|
8524
|
+
h.ownRename(h.bridgeOf(node), typeof seq === "number" ? seq : void 0);
|
|
8525
|
+
}
|
|
8526
|
+
function heldStream(h, stream, change) {
|
|
8527
|
+
const s = stream.node.live;
|
|
8528
|
+
if ((stream.flags & 3) === 0 || s.orphan) return;
|
|
8529
|
+
const before = s.writers ?? 0;
|
|
8530
|
+
s.writers = Math.max(0, before + change);
|
|
8531
|
+
if (before === 0 !== (s.writers === 0)) {
|
|
8532
|
+
try {
|
|
8533
|
+
h.bridgeOf(stream.node).hold?.(liveNodePath(stream.node), s.writers > 0);
|
|
8534
|
+
} catch {
|
|
8535
|
+
}
|
|
8536
|
+
}
|
|
8537
|
+
}
|
|
8357
8538
|
function createHelpers(Fs, ops) {
|
|
8358
8539
|
const bridgeOf = (node) => node.mount.opts.bridge;
|
|
8359
8540
|
const fileIo = (node) => pinnedIo2(bridgeOf(node), node.live.handle);
|
|
8360
8541
|
const dirty = /* @__PURE__ */ new Set();
|
|
8361
8542
|
const handled = /* @__PURE__ */ new Set();
|
|
8362
8543
|
const linked = linkedStates(bridgeOf);
|
|
8544
|
+
const renames = renameFollower(Fs, bridgeOf, (fn) => call2(fn));
|
|
8363
8545
|
function markDirty(node) {
|
|
8364
8546
|
node.live.dirty = true;
|
|
8365
8547
|
dirty.add(node);
|
|
@@ -8452,11 +8634,9 @@ function createHelpers(Fs, ops) {
|
|
|
8452
8634
|
function flushNode(node) {
|
|
8453
8635
|
const s = node.live;
|
|
8454
8636
|
if (!s.dirty || stale(s) || !(s.data || s.ranged)) return;
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
call2(() => fileIo(node).writeFile(liveNodePath(linked.holder(node)), bytes, true));
|
|
8459
|
-
}
|
|
8637
|
+
const whole = () => s.data.slice(0, s.len);
|
|
8638
|
+
const write2 = () => s.ranged ? call2(() => s.ranged?.flush()) : call2(() => fileIo(node).writeFile(liveNodePath(linked.holder(node)), whole(), true));
|
|
8639
|
+
followingOnce(write2, () => renames.follow(node, true));
|
|
8460
8640
|
s.dirty = false;
|
|
8461
8641
|
s.stat = void 0;
|
|
8462
8642
|
}
|
|
@@ -8504,6 +8684,7 @@ function createHelpers(Fs, ops) {
|
|
|
8504
8684
|
bridgeOf,
|
|
8505
8685
|
handled,
|
|
8506
8686
|
linked,
|
|
8687
|
+
...renames,
|
|
8507
8688
|
call: call2,
|
|
8508
8689
|
metadataCall,
|
|
8509
8690
|
makeNode,
|
|
@@ -8663,7 +8844,7 @@ function createNodeOps(h) {
|
|
|
8663
8844
|
const from = liveNodePath(oldNode);
|
|
8664
8845
|
const to = childPath(newDir, newName);
|
|
8665
8846
|
flushNode(oldNode);
|
|
8666
|
-
|
|
8847
|
+
renameThrough(h, oldNode, from, to);
|
|
8667
8848
|
try {
|
|
8668
8849
|
const existing = Fs.lookupNode?.(newDir, newName);
|
|
8669
8850
|
if (existing && existing !== oldNode) Fs.hashRemoveNode?.(existing);
|
|
@@ -8758,21 +8939,11 @@ function dropOpen(s) {
|
|
|
8758
8939
|
}
|
|
8759
8940
|
function createStreamOps(h) {
|
|
8760
8941
|
const { Fs, statOf, ensureLoaded, ensureCapacity, flushNode, bridgeOf, rangedOf } = h;
|
|
8761
|
-
const held2 = (stream, change) =>
|
|
8762
|
-
const s = stream.node.live;
|
|
8763
|
-
if ((stream.flags & 3) === 0 || s.orphan) return;
|
|
8764
|
-
const before = s.writers ?? 0;
|
|
8765
|
-
s.writers = Math.max(0, before + change);
|
|
8766
|
-
if (before === 0 !== (s.writers === 0)) {
|
|
8767
|
-
try {
|
|
8768
|
-
bridgeOf(stream.node).hold?.(liveNodePath(stream.node), s.writers > 0);
|
|
8769
|
-
} catch {
|
|
8770
|
-
}
|
|
8771
|
-
}
|
|
8772
|
-
};
|
|
8942
|
+
const held2 = (stream, change) => heldStream(h, stream, change);
|
|
8773
8943
|
const opened2 = (node, on, want = 0) => {
|
|
8774
8944
|
const s = node.live;
|
|
8775
8945
|
try {
|
|
8946
|
+
h.track(node, on);
|
|
8776
8947
|
const handle = holdLive(bridgeOf(node), node, on, want);
|
|
8777
8948
|
s.handle = on ? handle : void 0;
|
|
8778
8949
|
h.linked.opening(node, on);
|
|
@@ -8868,6 +9039,7 @@ function createStreamOps(h) {
|
|
|
8868
9039
|
if (!Fs.isFile(node.mode)) return;
|
|
8869
9040
|
const s = node.live;
|
|
8870
9041
|
if (!dropOpen(s)) return;
|
|
9042
|
+
h.follow(node);
|
|
8871
9043
|
if (s.openCount > 0) {
|
|
8872
9044
|
held2(stream, -1);
|
|
8873
9045
|
return;
|
|
@@ -8881,12 +9053,14 @@ function createStreamOps(h) {
|
|
|
8881
9053
|
s.len = 0;
|
|
8882
9054
|
s.loaded = false;
|
|
8883
9055
|
held2(stream, -1);
|
|
9056
|
+
h.track(node, false);
|
|
8884
9057
|
if (s.handle !== void 0) opened2(node, false);
|
|
8885
9058
|
}
|
|
8886
9059
|
},
|
|
8887
9060
|
read(stream, buffer, offset, length, position) {
|
|
8888
9061
|
const node = stream.node;
|
|
8889
9062
|
if (Fs.isDir(node.mode)) throw new Fs.ErrnoError(wasiErrno("EISDIR"));
|
|
9063
|
+
h.follow(node);
|
|
8890
9064
|
const ranged = rangedOf(node);
|
|
8891
9065
|
if (ranged) {
|
|
8892
9066
|
const out2 = new Uint8Array(buffer.buffer, buffer.byteOffset + offset, Math.max(0, length));
|
|
@@ -8904,6 +9078,7 @@ function createStreamOps(h) {
|
|
|
8904
9078
|
const node = stream.node;
|
|
8905
9079
|
if (Fs.isDir(node.mode)) throw new Fs.ErrnoError(wasiErrno("EISDIR"));
|
|
8906
9080
|
if (length <= 0) return 0;
|
|
9081
|
+
h.follow(node);
|
|
8907
9082
|
const s = node.live;
|
|
8908
9083
|
const end = position + length;
|
|
8909
9084
|
if (s.maxFile !== void 0 && end > s.maxFile) throw new Fs.ErrnoError(wasiErrno("EFBIG"));
|
|
@@ -8935,6 +9110,7 @@ function createStreamOps(h) {
|
|
|
8935
9110
|
return pos;
|
|
8936
9111
|
},
|
|
8937
9112
|
fsync(stream) {
|
|
9113
|
+
h.follow(stream.node);
|
|
8938
9114
|
flushNode(stream.node);
|
|
8939
9115
|
}
|
|
8940
9116
|
};
|
|
@@ -8969,6 +9145,7 @@ function createLiveVfsPlugin(Fs) {
|
|
|
8969
9145
|
flushDirty: () => h.flushDirty(),
|
|
8970
9146
|
mount(mount) {
|
|
8971
9147
|
const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
|
|
9148
|
+
h.watchRenames(mount.opts.bridge);
|
|
8972
9149
|
if (!st.isDirectory) throw new Fs.ErrnoError(wasiErrno("ENOTDIR"));
|
|
8973
9150
|
const root = h.makeNode(null, "/", st);
|
|
8974
9151
|
root.mode = modeFromStat(st, mount.opts.bridge.owners === true);
|
|
@@ -10562,7 +10739,7 @@ function pidStatus(info) {
|
|
|
10562
10739
|
"TracerPid: 0",
|
|
10563
10740
|
`Uid: ${ids(c.ruid, c.euid, c.suid)}`,
|
|
10564
10741
|
`Gid: ${ids(c.rgid, c.egid, c.sgid)}`,
|
|
10565
|
-
...info.tag !== void 0 ? [
|
|
10742
|
+
...(info.tags ?? (info.tag !== void 0 ? [info.tag] : [])).map(tagLine),
|
|
10566
10743
|
"FDSize: 64",
|
|
10567
10744
|
`VmSize: ${Math.ceil(info.memory / KIB)} kB`,
|
|
10568
10745
|
`VmRSS: ${Math.ceil(info.memory / KIB)} kB`,
|