@ai-ecoverse/slicc-kernel 1.143.5 → 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 +9 -2
- 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 +211 -34
- 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 +211 -34
- 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/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 +7 -7
package/dist/process-worker.js
CHANGED
|
@@ -561,7 +561,7 @@ function normal(path) {
|
|
|
561
561
|
}
|
|
562
562
|
return `/${parts.join("/")}`;
|
|
563
563
|
}
|
|
564
|
-
var GEN, RING, RING_SIZE, SLOT, SHARED_TTL_MS, DIRTY, FOREIGN, CHANGES_BYTES, ChangeView;
|
|
564
|
+
var GEN, RING, RING_SIZE, SLOT, SHARED_TTL_MS, RENAME_WAIT_MS, DIRTY, FOREIGN, RENAMES, CHANGES_BYTES, ChangeView;
|
|
565
565
|
var init_changes = __esm({
|
|
566
566
|
"src/fs/changes.ts"() {
|
|
567
567
|
"use strict";
|
|
@@ -570,9 +570,11 @@ var init_changes = __esm({
|
|
|
570
570
|
RING_SIZE = 4096;
|
|
571
571
|
SLOT = 2;
|
|
572
572
|
SHARED_TTL_MS = 100;
|
|
573
|
+
RENAME_WAIT_MS = 100;
|
|
573
574
|
DIRTY = RING + RING_SIZE * SLOT;
|
|
574
575
|
FOREIGN = DIRTY + 1;
|
|
575
|
-
|
|
576
|
+
RENAMES = FOREIGN + 1;
|
|
577
|
+
CHANGES_BYTES = (RENAMES + 1) * 4;
|
|
576
578
|
ChangeView = class {
|
|
577
579
|
view;
|
|
578
580
|
constructor(sab) {
|
|
@@ -587,6 +589,13 @@ var init_changes = __esm({
|
|
|
587
589
|
foreign() {
|
|
588
590
|
return this.view.length > FOREIGN && Atomics.load(this.view, FOREIGN) === 1;
|
|
589
591
|
}
|
|
592
|
+
renames() {
|
|
593
|
+
return this.view.length > RENAMES ? Atomics.load(this.view, RENAMES) : 0;
|
|
594
|
+
}
|
|
595
|
+
awaitRename(seen, ms) {
|
|
596
|
+
if (this.view.length > RENAMES) Atomics.wait(this.view, RENAMES, seen, ms);
|
|
597
|
+
return this.renames();
|
|
598
|
+
}
|
|
590
599
|
changedSince(seen, path) {
|
|
591
600
|
const now = Atomics.load(this.view, GEN);
|
|
592
601
|
const distance = now - seen >>> 0;
|
|
@@ -1163,7 +1172,8 @@ var init_sync_fs_wire = __esm({
|
|
|
1163
1172
|
"truncate",
|
|
1164
1173
|
"chown",
|
|
1165
1174
|
"lchown",
|
|
1166
|
-
"access"
|
|
1175
|
+
"access",
|
|
1176
|
+
"renames"
|
|
1167
1177
|
];
|
|
1168
1178
|
HOLD_READ = 4;
|
|
1169
1179
|
HOLD_WRITE = 8;
|
|
@@ -1180,7 +1190,8 @@ var init_sync_fs_wire = __esm({
|
|
|
1180
1190
|
"readlink",
|
|
1181
1191
|
"statfs",
|
|
1182
1192
|
"kept",
|
|
1183
|
-
"access"
|
|
1193
|
+
"access",
|
|
1194
|
+
"renames"
|
|
1184
1195
|
]);
|
|
1185
1196
|
}
|
|
1186
1197
|
});
|
|
@@ -1372,7 +1383,9 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
1372
1383
|
run({ op: "rm", path }, path);
|
|
1373
1384
|
},
|
|
1374
1385
|
rename: (from, to) => {
|
|
1375
|
-
run({ op: "rename", path: from, arg2: to }, from);
|
|
1386
|
+
const r = run({ op: "rename", path: from, arg2: to }, from);
|
|
1387
|
+
const seq = r.ok && r.kind === "json" ? r.json.seq : void 0;
|
|
1388
|
+
return typeof seq === "number" ? seq : void 0;
|
|
1376
1389
|
},
|
|
1377
1390
|
link: (from, to, follow3) => {
|
|
1378
1391
|
run({ op: "link", path: from, arg2: to, ...follow3 ? { mode: 1 } : {} }, from);
|
|
@@ -1453,7 +1466,11 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
1453
1466
|
run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
|
|
1454
1467
|
return void 0;
|
|
1455
1468
|
},
|
|
1456
|
-
statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path))
|
|
1469
|
+
statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path)),
|
|
1470
|
+
renames: (since, held2) => json2(
|
|
1471
|
+
{ op: "renames", path: "/", offset: since, arg2: JSON.stringify(held2) },
|
|
1472
|
+
"/"
|
|
1473
|
+
)
|
|
1457
1474
|
};
|
|
1458
1475
|
}
|
|
1459
1476
|
var UNCOUNTED_OPS, calls, looks, SPIN_MS, SPIN_STRIDE, SPIN_STRIDES, SPIN_CORES, spinning, SPIN_CAP_MS;
|
|
@@ -1650,12 +1667,130 @@ function freshState(stat) {
|
|
|
1650
1667
|
const base = { len: 0, loaded: false, dirty: false, openCount: 0 };
|
|
1651
1668
|
return stat ? { stat, statAt: syncCallCount(), filledAt: performance.now(), seenAt: syncEpoch(), ...base } : base;
|
|
1652
1669
|
}
|
|
1670
|
+
function inCache(Fs, node) {
|
|
1671
|
+
const table = Fs.nameTable;
|
|
1672
|
+
const parent = node.parent;
|
|
1673
|
+
const hash = Fs.hashName?.(parent.id ?? 0, node.name);
|
|
1674
|
+
if (!table || hash === void 0) return true;
|
|
1675
|
+
let at = table[hash];
|
|
1676
|
+
while (at) {
|
|
1677
|
+
if (at === node) return true;
|
|
1678
|
+
at = at.name_next;
|
|
1679
|
+
}
|
|
1680
|
+
return false;
|
|
1681
|
+
}
|
|
1682
|
+
function heldUnder(held2, from) {
|
|
1683
|
+
let moving = held2;
|
|
1684
|
+
while (moving && moving !== moving.mount.root && liveNodePath(moving) !== from) {
|
|
1685
|
+
moving = moving.parent;
|
|
1686
|
+
}
|
|
1687
|
+
return moving && moving !== moving.mount.root && liveNodePath(moving) === from ? moving : void 0;
|
|
1688
|
+
}
|
|
1689
|
+
function relinked(Fs, moving, to) {
|
|
1690
|
+
const slash = to.lastIndexOf("/");
|
|
1691
|
+
let dir;
|
|
1692
|
+
try {
|
|
1693
|
+
dir = Fs.lookupPath?.(slash <= 0 ? "/" : to.slice(0, slash)).node;
|
|
1694
|
+
} catch {
|
|
1695
|
+
}
|
|
1696
|
+
if (!dir || dir.mount !== moving.mount) return;
|
|
1697
|
+
const name2 = to.slice(slash + 1);
|
|
1698
|
+
try {
|
|
1699
|
+
const existing = Fs.lookupNode?.(dir, name2);
|
|
1700
|
+
if (existing && existing !== moving) Fs.hashRemoveNode?.(existing);
|
|
1701
|
+
} catch {
|
|
1702
|
+
}
|
|
1703
|
+
moving.parent.live.listed = void 0;
|
|
1704
|
+
dir.live.listed = void 0;
|
|
1705
|
+
Fs.hashRemoveNode?.(moving);
|
|
1706
|
+
moving.name = name2;
|
|
1707
|
+
moving.parent = dir;
|
|
1708
|
+
Fs.hashAddNode?.(moving);
|
|
1709
|
+
moving.live.stat = void 0;
|
|
1710
|
+
}
|
|
1711
|
+
function renameFollower(Fs, bridgeOf, call2) {
|
|
1712
|
+
const open = /* @__PURE__ */ new Set();
|
|
1713
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1714
|
+
const follow3 = (node, missing2 = false) => {
|
|
1715
|
+
const bridge = bridgeOf(node);
|
|
1716
|
+
const view = bridge.changes;
|
|
1717
|
+
const since = seen.get(bridge);
|
|
1718
|
+
let now = view?.renames() ?? 0;
|
|
1719
|
+
if (missing2 && view && now === since) now = view.awaitRename(now, RENAME_WAIT_MS);
|
|
1720
|
+
const ask = bridge.renames?.bind(bridge);
|
|
1721
|
+
if (since === void 0 || now === since || !ask) return false;
|
|
1722
|
+
const held2 = [...open].filter((n) => !n.live.orphan && bridgeOf(n) === bridge);
|
|
1723
|
+
if (held2.length === 0) {
|
|
1724
|
+
seen.set(bridge, now);
|
|
1725
|
+
return false;
|
|
1726
|
+
}
|
|
1727
|
+
const reply = call2(
|
|
1728
|
+
() => ask(
|
|
1729
|
+
since,
|
|
1730
|
+
held2.map((n) => liveNodePath(n))
|
|
1731
|
+
)
|
|
1732
|
+
);
|
|
1733
|
+
seen.set(bridge, reply.now);
|
|
1734
|
+
for (const [from, to] of reply.renames) {
|
|
1735
|
+
for (const n of held2) {
|
|
1736
|
+
const moving = heldUnder(n, from);
|
|
1737
|
+
if (moving && inCache(Fs, moving)) relinked(Fs, moving, to);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
return reply.renames.length > 0;
|
|
1741
|
+
};
|
|
1742
|
+
return {
|
|
1743
|
+
open,
|
|
1744
|
+
follow: follow3,
|
|
1745
|
+
track(node, on) {
|
|
1746
|
+
if (!on) {
|
|
1747
|
+
open.delete(node);
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
follow3(node);
|
|
1751
|
+
open.add(node);
|
|
1752
|
+
},
|
|
1753
|
+
watchRenames(bridge) {
|
|
1754
|
+
if (!seen.has(bridge)) seen.set(bridge, bridge.changes?.renames() ?? 0);
|
|
1755
|
+
},
|
|
1756
|
+
ownRename(bridge, seq) {
|
|
1757
|
+
const since = seen.get(bridge);
|
|
1758
|
+
if (seq !== void 0 && since !== void 0 && seq === (since + 1 | 0))
|
|
1759
|
+
seen.set(bridge, seq);
|
|
1760
|
+
}
|
|
1761
|
+
};
|
|
1762
|
+
}
|
|
1763
|
+
function followingOnce(write2, follow3) {
|
|
1764
|
+
try {
|
|
1765
|
+
write2();
|
|
1766
|
+
} catch (err) {
|
|
1767
|
+
if (err.errno !== wasiErrno("ENOENT") || !follow3()) throw err;
|
|
1768
|
+
write2();
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
function renameThrough(h, node, from, to) {
|
|
1772
|
+
const seq = h.call(() => h.bridgeOf(node).rename(from, to));
|
|
1773
|
+
h.ownRename(h.bridgeOf(node), typeof seq === "number" ? seq : void 0);
|
|
1774
|
+
}
|
|
1775
|
+
function heldStream(h, stream, change) {
|
|
1776
|
+
const s = stream.node.live;
|
|
1777
|
+
if ((stream.flags & 3) === 0 || s.orphan) return;
|
|
1778
|
+
const before = s.writers ?? 0;
|
|
1779
|
+
s.writers = Math.max(0, before + change);
|
|
1780
|
+
if (before === 0 !== (s.writers === 0)) {
|
|
1781
|
+
try {
|
|
1782
|
+
h.bridgeOf(stream.node).hold?.(liveNodePath(stream.node), s.writers > 0);
|
|
1783
|
+
} catch {
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1653
1787
|
function createHelpers(Fs, ops) {
|
|
1654
1788
|
const bridgeOf = (node) => node.mount.opts.bridge;
|
|
1655
1789
|
const fileIo = (node) => pinnedIo(bridgeOf(node), node.live.handle);
|
|
1656
1790
|
const dirty = /* @__PURE__ */ new Set();
|
|
1657
1791
|
const handled = /* @__PURE__ */ new Set();
|
|
1658
1792
|
const linked = linkedStates(bridgeOf);
|
|
1793
|
+
const renames = renameFollower(Fs, bridgeOf, (fn) => call2(fn));
|
|
1659
1794
|
function markDirty(node) {
|
|
1660
1795
|
node.live.dirty = true;
|
|
1661
1796
|
dirty.add(node);
|
|
@@ -1748,11 +1883,9 @@ function createHelpers(Fs, ops) {
|
|
|
1748
1883
|
function flushNode(node) {
|
|
1749
1884
|
const s = node.live;
|
|
1750
1885
|
if (!s.dirty || stale(s) || !(s.data || s.ranged)) return;
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
call2(() => fileIo(node).writeFile(liveNodePath(linked.holder(node)), bytes, true));
|
|
1755
|
-
}
|
|
1886
|
+
const whole = () => s.data.slice(0, s.len);
|
|
1887
|
+
const write2 = () => s.ranged ? call2(() => s.ranged?.flush()) : call2(() => fileIo(node).writeFile(liveNodePath(linked.holder(node)), whole(), true));
|
|
1888
|
+
followingOnce(write2, () => renames.follow(node, true));
|
|
1756
1889
|
s.dirty = false;
|
|
1757
1890
|
s.stat = void 0;
|
|
1758
1891
|
}
|
|
@@ -1800,6 +1933,7 @@ function createHelpers(Fs, ops) {
|
|
|
1800
1933
|
bridgeOf,
|
|
1801
1934
|
handled,
|
|
1802
1935
|
linked,
|
|
1936
|
+
...renames,
|
|
1803
1937
|
call: call2,
|
|
1804
1938
|
metadataCall,
|
|
1805
1939
|
makeNode,
|
|
@@ -1959,7 +2093,7 @@ function createNodeOps(h) {
|
|
|
1959
2093
|
const from = liveNodePath(oldNode);
|
|
1960
2094
|
const to = childPath(newDir, newName);
|
|
1961
2095
|
flushNode(oldNode);
|
|
1962
|
-
|
|
2096
|
+
renameThrough(h, oldNode, from, to);
|
|
1963
2097
|
try {
|
|
1964
2098
|
const existing = Fs.lookupNode?.(newDir, newName);
|
|
1965
2099
|
if (existing && existing !== oldNode) Fs.hashRemoveNode?.(existing);
|
|
@@ -2054,21 +2188,11 @@ function dropOpen(s) {
|
|
|
2054
2188
|
}
|
|
2055
2189
|
function createStreamOps(h) {
|
|
2056
2190
|
const { Fs, statOf, ensureLoaded, ensureCapacity, flushNode, bridgeOf, rangedOf } = h;
|
|
2057
|
-
const held2 = (stream, change) =>
|
|
2058
|
-
const s = stream.node.live;
|
|
2059
|
-
if ((stream.flags & 3) === 0 || s.orphan) return;
|
|
2060
|
-
const before = s.writers ?? 0;
|
|
2061
|
-
s.writers = Math.max(0, before + change);
|
|
2062
|
-
if (before === 0 !== (s.writers === 0)) {
|
|
2063
|
-
try {
|
|
2064
|
-
bridgeOf(stream.node).hold?.(liveNodePath(stream.node), s.writers > 0);
|
|
2065
|
-
} catch {
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
};
|
|
2191
|
+
const held2 = (stream, change) => heldStream(h, stream, change);
|
|
2069
2192
|
const opened2 = (node, on, want = 0) => {
|
|
2070
2193
|
const s = node.live;
|
|
2071
2194
|
try {
|
|
2195
|
+
h.track(node, on);
|
|
2072
2196
|
const handle = holdLive(bridgeOf(node), node, on, want);
|
|
2073
2197
|
s.handle = on ? handle : void 0;
|
|
2074
2198
|
h.linked.opening(node, on);
|
|
@@ -2164,6 +2288,7 @@ function createStreamOps(h) {
|
|
|
2164
2288
|
if (!Fs.isFile(node.mode)) return;
|
|
2165
2289
|
const s = node.live;
|
|
2166
2290
|
if (!dropOpen(s)) return;
|
|
2291
|
+
h.follow(node);
|
|
2167
2292
|
if (s.openCount > 0) {
|
|
2168
2293
|
held2(stream, -1);
|
|
2169
2294
|
return;
|
|
@@ -2177,12 +2302,14 @@ function createStreamOps(h) {
|
|
|
2177
2302
|
s.len = 0;
|
|
2178
2303
|
s.loaded = false;
|
|
2179
2304
|
held2(stream, -1);
|
|
2305
|
+
h.track(node, false);
|
|
2180
2306
|
if (s.handle !== void 0) opened2(node, false);
|
|
2181
2307
|
}
|
|
2182
2308
|
},
|
|
2183
2309
|
read(stream, buffer, offset, length, position) {
|
|
2184
2310
|
const node = stream.node;
|
|
2185
2311
|
if (Fs.isDir(node.mode)) throw new Fs.ErrnoError(wasiErrno("EISDIR"));
|
|
2312
|
+
h.follow(node);
|
|
2186
2313
|
const ranged = rangedOf(node);
|
|
2187
2314
|
if (ranged) {
|
|
2188
2315
|
const out2 = new Uint8Array(buffer.buffer, buffer.byteOffset + offset, Math.max(0, length));
|
|
@@ -2200,6 +2327,7 @@ function createStreamOps(h) {
|
|
|
2200
2327
|
const node = stream.node;
|
|
2201
2328
|
if (Fs.isDir(node.mode)) throw new Fs.ErrnoError(wasiErrno("EISDIR"));
|
|
2202
2329
|
if (length <= 0) return 0;
|
|
2330
|
+
h.follow(node);
|
|
2203
2331
|
const s = node.live;
|
|
2204
2332
|
const end = position + length;
|
|
2205
2333
|
if (s.maxFile !== void 0 && end > s.maxFile) throw new Fs.ErrnoError(wasiErrno("EFBIG"));
|
|
@@ -2231,6 +2359,7 @@ function createStreamOps(h) {
|
|
|
2231
2359
|
return pos;
|
|
2232
2360
|
},
|
|
2233
2361
|
fsync(stream) {
|
|
2362
|
+
h.follow(stream.node);
|
|
2234
2363
|
flushNode(stream.node);
|
|
2235
2364
|
}
|
|
2236
2365
|
};
|
|
@@ -2265,6 +2394,7 @@ function createLiveVfsPlugin(Fs) {
|
|
|
2265
2394
|
flushDirty: () => h.flushDirty(),
|
|
2266
2395
|
mount(mount) {
|
|
2267
2396
|
const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
|
|
2397
|
+
h.watchRenames(mount.opts.bridge);
|
|
2268
2398
|
if (!st.isDirectory) throw new Fs.ErrnoError(wasiErrno("ENOTDIR"));
|
|
2269
2399
|
const root = h.makeNode(null, "/", st);
|
|
2270
2400
|
root.mode = modeFromStat(st, mount.opts.bridge.owners === true);
|
|
@@ -2783,7 +2913,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
2783
2913
|
var init_version = __esm({
|
|
2784
2914
|
"src/version.ts"() {
|
|
2785
2915
|
"use strict";
|
|
2786
|
-
KERNEL_VERSION = true ? "1.143.
|
|
2916
|
+
KERNEL_VERSION = true ? "1.143.6" : "0.0.0-dev";
|
|
2787
2917
|
OS_RELEASE = "6.0.0-slicc";
|
|
2788
2918
|
}
|
|
2789
2919
|
});
|
|
@@ -7059,6 +7189,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
7059
7189
|
const entry = (p) => [p, p.slice(0, p.lastIndexOf("/")) || "/"];
|
|
7060
7190
|
return {
|
|
7061
7191
|
...bridge.changes ? { changes: bridge.changes } : {},
|
|
7192
|
+
...bridge.renames ? { renames: bridge.renames.bind(bridge) } : {},
|
|
7062
7193
|
readFile: (p) => bridge.readFile(p),
|
|
7063
7194
|
readdir: (p) => bridge.readdir(p),
|
|
7064
7195
|
readdirStat: (p) => {
|
|
@@ -7175,6 +7306,7 @@ var init_wasi_files = __esm({
|
|
|
7175
7306
|
seen = 0;
|
|
7176
7307
|
maxFile;
|
|
7177
7308
|
handle;
|
|
7309
|
+
moved;
|
|
7178
7310
|
constructor(fs, path, empty, maxFile, size, version, watch) {
|
|
7179
7311
|
this.fs = fs;
|
|
7180
7312
|
this.where = path;
|
|
@@ -7183,7 +7315,11 @@ var init_wasi_files = __esm({
|
|
|
7183
7315
|
this.watch = watch;
|
|
7184
7316
|
this.seen = watch?.seen ?? watch?.view.now() ?? 0;
|
|
7185
7317
|
if (size !== void 0 && pread && pwrite && truncate) {
|
|
7186
|
-
const io = {
|
|
7318
|
+
const io = {
|
|
7319
|
+
pread: (_, ...rest2) => this.retried(() => pread.call(fs, this.where, ...rest2)),
|
|
7320
|
+
pwrite: (_, ...rest2) => this.retried(() => pwrite.call(fs, this.where, ...rest2)),
|
|
7321
|
+
truncate: (_, size2) => this.retried(() => truncate.call(fs, this.where, size2))
|
|
7322
|
+
};
|
|
7187
7323
|
this.ranged = new RangedFile(io, path, size, version, watch);
|
|
7188
7324
|
if (empty) this.truncate(0);
|
|
7189
7325
|
} else if (empty) {
|
|
@@ -7195,6 +7331,14 @@ var init_wasi_files = __esm({
|
|
|
7195
7331
|
get path() {
|
|
7196
7332
|
return this.where;
|
|
7197
7333
|
}
|
|
7334
|
+
retried(op) {
|
|
7335
|
+
try {
|
|
7336
|
+
return op();
|
|
7337
|
+
} catch (err) {
|
|
7338
|
+
if (err.code !== "ENOENT" || !this.moved?.(true)) throw err;
|
|
7339
|
+
return op();
|
|
7340
|
+
}
|
|
7341
|
+
}
|
|
7198
7342
|
set path(path) {
|
|
7199
7343
|
this.where = path;
|
|
7200
7344
|
if (this.ranged) this.ranged.path = path;
|
|
@@ -7218,7 +7362,7 @@ var init_wasi_files = __esm({
|
|
|
7218
7362
|
}
|
|
7219
7363
|
if (!this.data) {
|
|
7220
7364
|
this.seen = view?.now() ?? 0;
|
|
7221
|
-
this.data = this.fs.readFile(this.path);
|
|
7365
|
+
this.data = this.retried(() => this.fs.readFile(this.path));
|
|
7222
7366
|
this.length = this.data.length;
|
|
7223
7367
|
}
|
|
7224
7368
|
return this.data;
|
|
@@ -7259,8 +7403,9 @@ var init_wasi_files = __esm({
|
|
|
7259
7403
|
append(bytes) {
|
|
7260
7404
|
const { append } = this.fs;
|
|
7261
7405
|
if (!append || this.orphaned) return void 0;
|
|
7406
|
+
this.moved?.(false);
|
|
7262
7407
|
this.flush();
|
|
7263
|
-
const end = append.call(this.fs, this.path, bytes);
|
|
7408
|
+
const end = this.retried(() => append.call(this.fs, this.path, bytes));
|
|
7264
7409
|
if (!this.ranged) {
|
|
7265
7410
|
this.data = void 0;
|
|
7266
7411
|
this.length = 0;
|
|
@@ -7308,11 +7453,17 @@ var init_wasi_files = __esm({
|
|
|
7308
7453
|
}
|
|
7309
7454
|
flush() {
|
|
7310
7455
|
if (this.orphaned || !this.dirty) return;
|
|
7456
|
+
this.moved?.(false);
|
|
7311
7457
|
if (this.ranged) this.ranged.flush();
|
|
7312
7458
|
else if (!this.data) return;
|
|
7313
|
-
else if (this.whole || !this.fs.pwrite)
|
|
7314
|
-
|
|
7315
|
-
|
|
7459
|
+
else if (this.whole || !this.fs.pwrite) {
|
|
7460
|
+
const whole = this.data.slice(0, this.length);
|
|
7461
|
+
this.retried(() => this.fs.writeFile(this.path, whole, true));
|
|
7462
|
+
} else {
|
|
7463
|
+
const { pwrite } = this.fs;
|
|
7464
|
+
const run = this.data.slice(this.from, this.to);
|
|
7465
|
+
this.retried(() => pwrite.call(this.fs, this.path, this.from, run, true));
|
|
7466
|
+
}
|
|
7316
7467
|
this.dirty = false;
|
|
7317
7468
|
this.whole = false;
|
|
7318
7469
|
this.from = Infinity;
|
|
@@ -8700,6 +8851,7 @@ var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY5, O_RDWR5, O_APPEND3, SEALED_PATH2, C
|
|
|
8700
8851
|
var init_wasi_fds = __esm({
|
|
8701
8852
|
"src/process/wasi/wasi-fds.ts"() {
|
|
8702
8853
|
"use strict";
|
|
8854
|
+
init_changes();
|
|
8703
8855
|
init_ranged();
|
|
8704
8856
|
init_fd_table();
|
|
8705
8857
|
init_sync_fs_wire();
|
|
@@ -8720,9 +8872,29 @@ var init_wasi_fds = __esm({
|
|
|
8720
8872
|
ids = /* @__PURE__ */ new Map();
|
|
8721
8873
|
kernel;
|
|
8722
8874
|
fs;
|
|
8875
|
+
renamesSeen;
|
|
8723
8876
|
constructor(kernel, fs) {
|
|
8724
8877
|
this.kernel = kernel;
|
|
8725
8878
|
this.fs = fs;
|
|
8879
|
+
this.renamesSeen = fs.changes?.renames() ?? 0;
|
|
8880
|
+
}
|
|
8881
|
+
ownRename(seq) {
|
|
8882
|
+
if (seq !== void 0 && seq === (this.renamesSeen + 1 | 0)) this.renamesSeen = seq;
|
|
8883
|
+
}
|
|
8884
|
+
followRenames(missing2 = false) {
|
|
8885
|
+
const view = this.fs.changes;
|
|
8886
|
+
let now = view?.renames() ?? 0;
|
|
8887
|
+
if (missing2 && view && now === this.renamesSeen) now = view.awaitRename(now, RENAME_WAIT_MS);
|
|
8888
|
+
if (now === this.renamesSeen || !this.fs.renames) return false;
|
|
8889
|
+
const held2 = [...this.buffers].filter(([, b]) => !b.isOrphan()).map(([p]) => p);
|
|
8890
|
+
if (held2.length === 0) {
|
|
8891
|
+
this.renamesSeen = now;
|
|
8892
|
+
return false;
|
|
8893
|
+
}
|
|
8894
|
+
const { now: seen, renames } = this.fs.renames(this.renamesSeen, held2);
|
|
8895
|
+
this.renamesSeen = seen;
|
|
8896
|
+
for (const [from, to] of renames) this.renamed(from, to, void 0, true);
|
|
8897
|
+
return renames.length > 0;
|
|
8726
8898
|
}
|
|
8727
8899
|
setup(cwd, inherited, root = false) {
|
|
8728
8900
|
for (const fd of [0, 1, 2]) this.table.set(fd, this.stdioEntry(fd));
|
|
@@ -8922,6 +9094,7 @@ var init_wasi_fds = __esm({
|
|
|
8922
9094
|
get(fd) {
|
|
8923
9095
|
const e = this.find(fd);
|
|
8924
9096
|
if (!e) throw new WasiError("EBADF");
|
|
9097
|
+
if (e.type === "file") this.followRenames();
|
|
8925
9098
|
return e;
|
|
8926
9099
|
}
|
|
8927
9100
|
preopen(fd) {
|
|
@@ -9242,9 +9415,9 @@ var init_wasi_fds = __esm({
|
|
|
9242
9415
|
buffer.orphan();
|
|
9243
9416
|
this.forget(buffer);
|
|
9244
9417
|
}
|
|
9245
|
-
renamed(from, to, replacedLinked) {
|
|
9418
|
+
renamed(from, to, replacedLinked, foreign = false) {
|
|
9246
9419
|
if (from === to) return;
|
|
9247
|
-
if (this.shared) this.kernel.call({ op: "fd-path-renamed", from, to });
|
|
9420
|
+
if (this.shared && !foreign) this.kernel.call({ op: "fd-path-renamed", from, to });
|
|
9248
9421
|
for (const e of this.table.values()) {
|
|
9249
9422
|
if (e.type === "kernel" && e.path !== void 0 && within(e.path, from)) {
|
|
9250
9423
|
e.path = to + e.path.slice(from.length);
|
|
@@ -9252,6 +9425,7 @@ var init_wasi_fds = __esm({
|
|
|
9252
9425
|
}
|
|
9253
9426
|
const moved = [];
|
|
9254
9427
|
for (const [p, buffer] of this.buffers) {
|
|
9428
|
+
if (foreign && buffer.isOrphan()) continue;
|
|
9255
9429
|
if (within(p, from)) moved.push([p, buffer]);
|
|
9256
9430
|
else if (within(p, to)) {
|
|
9257
9431
|
this.detach(buffer, replacedLinked);
|
|
@@ -9393,6 +9567,7 @@ var init_wasi_fds = __esm({
|
|
|
9393
9567
|
}
|
|
9394
9568
|
file(path, existing, oflags, rights, fdflags, mode, created = false) {
|
|
9395
9569
|
const { readable: readable3, writable: writable2 } = openAccess(existing, oflags, rights);
|
|
9570
|
+
this.followRenames();
|
|
9396
9571
|
let buffer = created ? void 0 : this.buffers.get(path);
|
|
9397
9572
|
if (buffer?.handle !== void 0 && this.fs.kept?.(buffer.handle)) {
|
|
9398
9573
|
this.buffers.delete(path);
|
|
@@ -9440,6 +9615,7 @@ var init_wasi_fds = __esm({
|
|
|
9440
9615
|
st
|
|
9441
9616
|
);
|
|
9442
9617
|
const buffer = new FileBuffer(io, path, empty, st.maxFile, ranged, st.version, watch);
|
|
9618
|
+
buffer.moved = (missing2) => this.followRenames(missing2);
|
|
9443
9619
|
buffer.handle = handle;
|
|
9444
9620
|
this.buffers.set(path, buffer);
|
|
9445
9621
|
const id = this.identity(st);
|
|
@@ -11197,8 +11373,9 @@ var init_wasi_host = __esm({
|
|
|
11197
11373
|
const to = at(fd2, p2, l2);
|
|
11198
11374
|
fds.flushPath(from);
|
|
11199
11375
|
const replaced = fds.holdsUnder(to) ? linkedElsewhere(o.fs, to) : void 0;
|
|
11200
|
-
o.fs.rename(from, to);
|
|
11376
|
+
const seq = o.fs.rename(from, to);
|
|
11201
11377
|
fds.renamed(from, to, replaced);
|
|
11378
|
+
fds.ownRename(typeof seq === "number" ? seq : void 0);
|
|
11202
11379
|
},
|
|
11203
11380
|
path_symlink: (tp, tl, dirfd, p, l) => {
|
|
11204
11381
|
const path = at(dirfd, p, l);
|