@ai-ecoverse/slicc-kernel 1.143.4 → 1.143.6
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 +11 -4
- package/dist/index.js.map +1 -1
- package/dist/kernel-worker.js +193 -26
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js +1 -1
- package/dist/meta.js.map +2 -2
- package/dist/node-process-worker.js +218 -36
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +192 -25
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +218 -36
- package/dist/process-worker.js.map +3 -3
- package/dist/types/fs/changes.d.ts +4 -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/host.d.ts +5 -0
- package/dist/types/kernel/rename-log.d.ts +14 -0
- package/dist/types/kernel/vfs-file.d.ts +1 -0
- package/dist/types/launcher.d.ts +2 -0
- 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/process/wasi/wasi-host.d.ts +1 -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/package.json +10 -10
|
@@ -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);
|
|
@@ -4976,6 +5033,7 @@ var init_wasi_host = __esm({
|
|
|
4976
5033
|
startCwd;
|
|
4977
5034
|
interruptWakes = false;
|
|
4978
5035
|
strictEpoll = false;
|
|
5036
|
+
cwdFd = false;
|
|
4979
5037
|
entered = false;
|
|
4980
5038
|
enteredSignals = 0;
|
|
4981
5039
|
raisedOnEntry;
|
|
@@ -5606,8 +5664,9 @@ var init_wasi_host = __esm({
|
|
|
5606
5664
|
const to = at(fd2, p2, l2);
|
|
5607
5665
|
fds.flushPath(from);
|
|
5608
5666
|
const replaced = fds.holdsUnder(to) ? linkedElsewhere(o.fs, to) : void 0;
|
|
5609
|
-
o.fs.rename(from, to);
|
|
5667
|
+
const seq = o.fs.rename(from, to);
|
|
5610
5668
|
fds.renamed(from, to, replaced);
|
|
5669
|
+
fds.ownRename(typeof seq === "number" ? seq : void 0);
|
|
5611
5670
|
},
|
|
5612
5671
|
path_symlink: (tp, tl, dirfd, p, l) => {
|
|
5613
5672
|
const path = at(dirfd, p, l);
|
|
@@ -6725,7 +6784,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
6725
6784
|
var init_version = __esm({
|
|
6726
6785
|
"src/version.ts"() {
|
|
6727
6786
|
"use strict";
|
|
6728
|
-
KERNEL_VERSION = true ? "1.143.
|
|
6787
|
+
KERNEL_VERSION = true ? "1.143.6" : "0.0.0-dev";
|
|
6729
6788
|
OS_RELEASE = "6.0.0-slicc";
|
|
6730
6789
|
}
|
|
6731
6790
|
});
|
|
@@ -8075,7 +8134,9 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
8075
8134
|
run({ op: "rm", path }, path);
|
|
8076
8135
|
},
|
|
8077
8136
|
rename: (from, to) => {
|
|
8078
|
-
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;
|
|
8079
8140
|
},
|
|
8080
8141
|
link: (from, to, follow3) => {
|
|
8081
8142
|
run({ op: "link", path: from, arg2: to, ...follow3 ? { mode: 1 } : {} }, from);
|
|
@@ -8156,7 +8217,11 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
8156
8217
|
run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
|
|
8157
8218
|
return void 0;
|
|
8158
8219
|
},
|
|
8159
|
-
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
|
+
)
|
|
8160
8225
|
};
|
|
8161
8226
|
}
|
|
8162
8227
|
var UNCOUNTED_OPS, calls, looks, SPIN_MS, SPIN_STRIDE, SPIN_STRIDES, SPIN_CORES, spinning, SPIN_CAP_MS;
|
|
@@ -8353,12 +8418,130 @@ function freshState(stat) {
|
|
|
8353
8418
|
const base = { len: 0, loaded: false, dirty: false, openCount: 0 };
|
|
8354
8419
|
return stat ? { stat, statAt: syncCallCount(), filledAt: performance.now(), seenAt: syncEpoch(), ...base } : base;
|
|
8355
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
|
+
}
|
|
8356
8538
|
function createHelpers(Fs, ops) {
|
|
8357
8539
|
const bridgeOf = (node) => node.mount.opts.bridge;
|
|
8358
8540
|
const fileIo = (node) => pinnedIo2(bridgeOf(node), node.live.handle);
|
|
8359
8541
|
const dirty = /* @__PURE__ */ new Set();
|
|
8360
8542
|
const handled = /* @__PURE__ */ new Set();
|
|
8361
8543
|
const linked = linkedStates(bridgeOf);
|
|
8544
|
+
const renames = renameFollower(Fs, bridgeOf, (fn) => call2(fn));
|
|
8362
8545
|
function markDirty(node) {
|
|
8363
8546
|
node.live.dirty = true;
|
|
8364
8547
|
dirty.add(node);
|
|
@@ -8451,11 +8634,9 @@ function createHelpers(Fs, ops) {
|
|
|
8451
8634
|
function flushNode(node) {
|
|
8452
8635
|
const s = node.live;
|
|
8453
8636
|
if (!s.dirty || stale(s) || !(s.data || s.ranged)) return;
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
call2(() => fileIo(node).writeFile(liveNodePath(linked.holder(node)), bytes, true));
|
|
8458
|
-
}
|
|
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));
|
|
8459
8640
|
s.dirty = false;
|
|
8460
8641
|
s.stat = void 0;
|
|
8461
8642
|
}
|
|
@@ -8503,6 +8684,7 @@ function createHelpers(Fs, ops) {
|
|
|
8503
8684
|
bridgeOf,
|
|
8504
8685
|
handled,
|
|
8505
8686
|
linked,
|
|
8687
|
+
...renames,
|
|
8506
8688
|
call: call2,
|
|
8507
8689
|
metadataCall,
|
|
8508
8690
|
makeNode,
|
|
@@ -8662,7 +8844,7 @@ function createNodeOps(h) {
|
|
|
8662
8844
|
const from = liveNodePath(oldNode);
|
|
8663
8845
|
const to = childPath(newDir, newName);
|
|
8664
8846
|
flushNode(oldNode);
|
|
8665
|
-
|
|
8847
|
+
renameThrough(h, oldNode, from, to);
|
|
8666
8848
|
try {
|
|
8667
8849
|
const existing = Fs.lookupNode?.(newDir, newName);
|
|
8668
8850
|
if (existing && existing !== oldNode) Fs.hashRemoveNode?.(existing);
|
|
@@ -8757,21 +8939,11 @@ function dropOpen(s) {
|
|
|
8757
8939
|
}
|
|
8758
8940
|
function createStreamOps(h) {
|
|
8759
8941
|
const { Fs, statOf, ensureLoaded, ensureCapacity, flushNode, bridgeOf, rangedOf } = h;
|
|
8760
|
-
const held2 = (stream, change) =>
|
|
8761
|
-
const s = stream.node.live;
|
|
8762
|
-
if ((stream.flags & 3) === 0 || s.orphan) return;
|
|
8763
|
-
const before = s.writers ?? 0;
|
|
8764
|
-
s.writers = Math.max(0, before + change);
|
|
8765
|
-
if (before === 0 !== (s.writers === 0)) {
|
|
8766
|
-
try {
|
|
8767
|
-
bridgeOf(stream.node).hold?.(liveNodePath(stream.node), s.writers > 0);
|
|
8768
|
-
} catch {
|
|
8769
|
-
}
|
|
8770
|
-
}
|
|
8771
|
-
};
|
|
8942
|
+
const held2 = (stream, change) => heldStream(h, stream, change);
|
|
8772
8943
|
const opened2 = (node, on, want = 0) => {
|
|
8773
8944
|
const s = node.live;
|
|
8774
8945
|
try {
|
|
8946
|
+
h.track(node, on);
|
|
8775
8947
|
const handle = holdLive(bridgeOf(node), node, on, want);
|
|
8776
8948
|
s.handle = on ? handle : void 0;
|
|
8777
8949
|
h.linked.opening(node, on);
|
|
@@ -8867,6 +9039,7 @@ function createStreamOps(h) {
|
|
|
8867
9039
|
if (!Fs.isFile(node.mode)) return;
|
|
8868
9040
|
const s = node.live;
|
|
8869
9041
|
if (!dropOpen(s)) return;
|
|
9042
|
+
h.follow(node);
|
|
8870
9043
|
if (s.openCount > 0) {
|
|
8871
9044
|
held2(stream, -1);
|
|
8872
9045
|
return;
|
|
@@ -8880,12 +9053,14 @@ function createStreamOps(h) {
|
|
|
8880
9053
|
s.len = 0;
|
|
8881
9054
|
s.loaded = false;
|
|
8882
9055
|
held2(stream, -1);
|
|
9056
|
+
h.track(node, false);
|
|
8883
9057
|
if (s.handle !== void 0) opened2(node, false);
|
|
8884
9058
|
}
|
|
8885
9059
|
},
|
|
8886
9060
|
read(stream, buffer, offset, length, position) {
|
|
8887
9061
|
const node = stream.node;
|
|
8888
9062
|
if (Fs.isDir(node.mode)) throw new Fs.ErrnoError(wasiErrno("EISDIR"));
|
|
9063
|
+
h.follow(node);
|
|
8889
9064
|
const ranged = rangedOf(node);
|
|
8890
9065
|
if (ranged) {
|
|
8891
9066
|
const out2 = new Uint8Array(buffer.buffer, buffer.byteOffset + offset, Math.max(0, length));
|
|
@@ -8903,6 +9078,7 @@ function createStreamOps(h) {
|
|
|
8903
9078
|
const node = stream.node;
|
|
8904
9079
|
if (Fs.isDir(node.mode)) throw new Fs.ErrnoError(wasiErrno("EISDIR"));
|
|
8905
9080
|
if (length <= 0) return 0;
|
|
9081
|
+
h.follow(node);
|
|
8906
9082
|
const s = node.live;
|
|
8907
9083
|
const end = position + length;
|
|
8908
9084
|
if (s.maxFile !== void 0 && end > s.maxFile) throw new Fs.ErrnoError(wasiErrno("EFBIG"));
|
|
@@ -8934,6 +9110,7 @@ function createStreamOps(h) {
|
|
|
8934
9110
|
return pos;
|
|
8935
9111
|
},
|
|
8936
9112
|
fsync(stream) {
|
|
9113
|
+
h.follow(stream.node);
|
|
8937
9114
|
flushNode(stream.node);
|
|
8938
9115
|
}
|
|
8939
9116
|
};
|
|
@@ -8968,6 +9145,7 @@ function createLiveVfsPlugin(Fs) {
|
|
|
8968
9145
|
flushDirty: () => h.flushDirty(),
|
|
8969
9146
|
mount(mount) {
|
|
8970
9147
|
const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
|
|
9148
|
+
h.watchRenames(mount.opts.bridge);
|
|
8971
9149
|
if (!st.isDirectory) throw new Fs.ErrnoError(wasiErrno("ENOTDIR"));
|
|
8972
9150
|
const root = h.makeNode(null, "/", st);
|
|
8973
9151
|
root.mode = modeFromStat(st, mount.opts.bridge.owners === true);
|
|
@@ -17317,7 +17495,7 @@ function posixSignal(sig) {
|
|
|
17317
17495
|
function nsToMs(ns) {
|
|
17318
17496
|
return Math.ceil(Number(ns) / 1e6);
|
|
17319
17497
|
}
|
|
17320
|
-
var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON2, ECHO2, FUTEX_SLICE_MS, EINTR_LIBC, STRICT_EPOLL_LIBC, MAIN_HANDLE, WasixHost;
|
|
17498
|
+
var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON2, ECHO2, FUTEX_SLICE_MS, EINTR_LIBC, STRICT_EPOLL_LIBC, CWD_FD_LIBC, MAIN_HANDLE, WasixHost;
|
|
17321
17499
|
var init_wasix_host = __esm({
|
|
17322
17500
|
"src/process/wasi/wasix-host.ts"() {
|
|
17323
17501
|
"use strict";
|
|
@@ -17342,6 +17520,7 @@ var init_wasix_host = __esm({
|
|
|
17342
17520
|
FUTEX_SLICE_MS = 50;
|
|
17343
17521
|
EINTR_LIBC = 22;
|
|
17344
17522
|
STRICT_EPOLL_LIBC = 29;
|
|
17523
|
+
CWD_FD_LIBC = 41;
|
|
17345
17524
|
MAIN_HANDLE = 2147483647;
|
|
17346
17525
|
WasixHost = class _WasixHost {
|
|
17347
17526
|
process;
|
|
@@ -17360,7 +17539,9 @@ var init_wasix_host = __esm({
|
|
|
17360
17539
|
driver,
|
|
17361
17540
|
() => (this.threads?.tid ?? MAIN_TID) !== MAIN_TID
|
|
17362
17541
|
);
|
|
17363
|
-
|
|
17542
|
+
const libc = module ? libcVersion(module) ?? 0 : void 0;
|
|
17543
|
+
if (libc !== void 0) host.strictEpoll = libc >= STRICT_EPOLL_LIBC;
|
|
17544
|
+
if (libc !== void 0) host.cwdFd = libc >= CWD_FD_LIBC;
|
|
17364
17545
|
if (module && !WebAssembly.Module.imports(module).some((i) => i.name === "fd_fdflags_set")) {
|
|
17365
17546
|
host.fds.implicitCloexec = true;
|
|
17366
17547
|
host.interruptWakes = (libcVersion(module) ?? 0) < EINTR_LIBC;
|
|
@@ -17500,6 +17681,7 @@ var init_wasix_host = __esm({
|
|
|
17500
17681
|
mem.view().setUint32(out, host.o.parent?.() ?? host.o.ppid ?? 1, true);
|
|
17501
17682
|
},
|
|
17502
17683
|
getcwd: (buf, lenPtr) => {
|
|
17684
|
+
if (host.cwdFd && host.fds.held && !host.fds.held.alive()) return E.NOENT;
|
|
17503
17685
|
const bytes = new TextEncoder().encode(host.cwd);
|
|
17504
17686
|
const max = mem.view().getUint32(lenPtr, true);
|
|
17505
17687
|
mem.view().setUint32(lenPtr, bytes.length, true);
|