@ai-ecoverse/slicc-kernel 1.127.0 → 1.128.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 +5 -1
- package/dist/index.js.map +1 -1
- package/dist/kernel-worker.js +244 -37
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +2 -2
- package/dist/node-process-worker.js +50 -3
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +244 -37
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +50 -3
- package/dist/process-worker.js.map +3 -3
- package/dist/types/fs/copy.d.ts +2 -0
- package/dist/types/fs/opfs.d.ts +10 -1
- package/dist/types/fs/types.d.ts +6 -0
- package/dist/types/kernel/proc-info.d.ts +1 -0
- package/dist/types/process/wasi/wasi-host.d.ts +2 -0
- package/dist/types/realm/sync-fs-wire.d.ts +2 -1
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -795,6 +795,12 @@ var ProtectedFs = class {
|
|
|
795
795
|
st && marked(`${dir}/${name2}`, st)
|
|
796
796
|
]);
|
|
797
797
|
},
|
|
798
|
+
...fs.copyFile ? {
|
|
799
|
+
async copyFile(...args) {
|
|
800
|
+
await check(args[1], false);
|
|
801
|
+
return fs.copyFile?.(...args);
|
|
802
|
+
}
|
|
803
|
+
} : {},
|
|
798
804
|
...fs.createExclusive ? {
|
|
799
805
|
async createExclusive(...args) {
|
|
800
806
|
await check(args[0], true);
|
|
@@ -1330,7 +1336,7 @@ var OpfsFs = class {
|
|
|
1330
1336
|
}
|
|
1331
1337
|
async recounting(handle, target) {
|
|
1332
1338
|
if (this.counted.length === 0) return;
|
|
1333
|
-
const where = await this.root.resolve(handle).catch(() => null);
|
|
1339
|
+
const where = await this.io(this.root.resolve(handle)).catch(() => null);
|
|
1334
1340
|
await this.counting(where ? `/${where.join("/")}` : target);
|
|
1335
1341
|
}
|
|
1336
1342
|
resolvePath(base, path) {
|
|
@@ -1532,9 +1538,17 @@ var OpfsFs = class {
|
|
|
1532
1538
|
}
|
|
1533
1539
|
exact = 0;
|
|
1534
1540
|
calls = 0;
|
|
1541
|
+
others = 0;
|
|
1535
1542
|
opfsCalls() {
|
|
1536
1543
|
return this.calls;
|
|
1537
1544
|
}
|
|
1545
|
+
opfsOps() {
|
|
1546
|
+
return this.calls + this.others;
|
|
1547
|
+
}
|
|
1548
|
+
io(request2) {
|
|
1549
|
+
this.others++;
|
|
1550
|
+
return request2;
|
|
1551
|
+
}
|
|
1538
1552
|
fresh() {
|
|
1539
1553
|
this.changes++;
|
|
1540
1554
|
this.absent.clear();
|
|
@@ -1558,7 +1572,13 @@ var OpfsFs = class {
|
|
|
1558
1572
|
this.absent.set(path, performance.now());
|
|
1559
1573
|
}
|
|
1560
1574
|
remember(path, handle, looked = false) {
|
|
1561
|
-
if (handle.kind !== "file")
|
|
1575
|
+
if (handle.kind !== "file") {
|
|
1576
|
+
if (looked) {
|
|
1577
|
+
this.dirs.set(path, handle);
|
|
1578
|
+
this.checked.set(handle, performance.now());
|
|
1579
|
+
}
|
|
1580
|
+
return handle;
|
|
1581
|
+
}
|
|
1562
1582
|
if (looked) {
|
|
1563
1583
|
this.found.set(handle, performance.now());
|
|
1564
1584
|
this.glances.delete(handle);
|
|
@@ -1939,7 +1959,7 @@ var OpfsFs = class {
|
|
|
1939
1959
|
async readFileBuffer(path) {
|
|
1940
1960
|
const bytes = await this.reading(
|
|
1941
1961
|
path,
|
|
1942
|
-
async (handle) => new Uint8Array(await (await handle.getFile()).arrayBuffer())
|
|
1962
|
+
async (handle) => new Uint8Array(await (await this.io(handle.getFile())).arrayBuffer())
|
|
1943
1963
|
);
|
|
1944
1964
|
await this.refuseNode(path, bytes.length === 0);
|
|
1945
1965
|
return bytes;
|
|
@@ -1947,7 +1967,7 @@ var OpfsFs = class {
|
|
|
1947
1967
|
async readVersioned(path, cached = false) {
|
|
1948
1968
|
return this.reading(path, async (handle) => {
|
|
1949
1969
|
const stamp = await this.stamp(path, cached);
|
|
1950
|
-
const file = await handle.getFile();
|
|
1970
|
+
const file = await this.io(handle.getFile());
|
|
1951
1971
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
1952
1972
|
await this.refuseNode(path, bytes.length === 0);
|
|
1953
1973
|
return { bytes, version: `${file.lastModified}:${file.size}:${stamp}` };
|
|
@@ -1956,23 +1976,53 @@ var OpfsFs = class {
|
|
|
1956
1976
|
async version(path, cached = false) {
|
|
1957
1977
|
return this.reading(path, async (handle) => {
|
|
1958
1978
|
const stamp = await this.stamp(path, cached);
|
|
1959
|
-
const file = await handle.getFile();
|
|
1979
|
+
const file = await this.io(handle.getFile());
|
|
1960
1980
|
return `${file.lastModified}:${file.size}:${stamp}`;
|
|
1961
1981
|
});
|
|
1962
1982
|
}
|
|
1963
1983
|
async pread(path, offset, length2) {
|
|
1964
1984
|
return this.reading(path, async (handle) => {
|
|
1965
|
-
const file = await handle.getFile();
|
|
1985
|
+
const file = await this.io(handle.getFile());
|
|
1966
1986
|
await this.refuseNode(path, file.size === 0);
|
|
1967
1987
|
return new Uint8Array(await file.slice(offset, offset + length2).arrayBuffer());
|
|
1968
1988
|
});
|
|
1969
1989
|
}
|
|
1970
1990
|
async pwrite(path, offset, bytes) {
|
|
1971
|
-
const [
|
|
1991
|
+
const [kept, target] = await this.keptFor(path);
|
|
1992
|
+
if (kept) {
|
|
1993
|
+
try {
|
|
1994
|
+
await this.writeAt(kept, target, path, offset, bytes);
|
|
1995
|
+
return;
|
|
1996
|
+
} catch (err) {
|
|
1997
|
+
if (err.code !== "ENOENT") throw err;
|
|
1998
|
+
this.files.delete(target);
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
const [handle] = await this.fileFor(path);
|
|
2002
|
+
await this.writeAt(handle, target, path, offset, bytes);
|
|
2003
|
+
}
|
|
2004
|
+
async keptFor(path) {
|
|
2005
|
+
const at = normalizePath(path);
|
|
2006
|
+
const cached = this.files.get(at);
|
|
2007
|
+
const fresh2 = cached && performance.now() - (this.found.get(cached) ?? -CHECK_MS) < CHECK_MS;
|
|
2008
|
+
const [target, existed] = fresh2 ? [at, true] : await this.writeTarget(path);
|
|
2009
|
+
if (!existed) return [void 0, target];
|
|
2010
|
+
this.refuse(target);
|
|
2011
|
+
const [entry] = await this.meta.get([target]);
|
|
2012
|
+
if (entry?.fifo || entry?.socket) throw fsError("ENXIO", path);
|
|
2013
|
+
const kept = fresh2 ? cached : this.files.get(target);
|
|
2014
|
+
const usable2 = kept && performance.now() - (this.found.get(kept) ?? -CHECK_MS) < CHECK_MS;
|
|
2015
|
+
return [usable2 ? kept : void 0, target];
|
|
2016
|
+
}
|
|
2017
|
+
async writeAt(handle, target, path, offset, bytes) {
|
|
1972
2018
|
await this.counting(target);
|
|
1973
2019
|
this.wrote(handle);
|
|
1974
2020
|
try {
|
|
1975
|
-
await this.retrying(
|
|
2021
|
+
await this.retrying(
|
|
2022
|
+
path,
|
|
2023
|
+
() => this.io(positioned(handle, (io) => io.write(offset, bytes))),
|
|
2024
|
+
true
|
|
2025
|
+
);
|
|
1976
2026
|
} finally {
|
|
1977
2027
|
this.wrote(handle);
|
|
1978
2028
|
await this.recounting(handle, target);
|
|
@@ -1981,13 +2031,13 @@ var OpfsFs = class {
|
|
|
1981
2031
|
}
|
|
1982
2032
|
async truncate(path, size) {
|
|
1983
2033
|
const handle = await this.existing(path, true);
|
|
1984
|
-
await this.refuseNode(path, (await handle.getFile()).size === 0);
|
|
2034
|
+
await this.refuseNode(path, (await this.io(handle.getFile())).size === 0);
|
|
1985
2035
|
const resolve2 = this.ranged || this.remote?.watched();
|
|
1986
2036
|
const target = resolve2 || this.counted.length > 0 ? (await this.locate(path, true)).path : path;
|
|
1987
2037
|
await this.counting(target);
|
|
1988
2038
|
this.wrote(handle);
|
|
1989
2039
|
try {
|
|
1990
|
-
await this.retrying(path, () => positioned(handle, (io) => io.truncate(size)), true);
|
|
2040
|
+
await this.retrying(path, () => this.io(positioned(handle, (io) => io.truncate(size))), true);
|
|
1991
2041
|
} finally {
|
|
1992
2042
|
this.wrote(handle);
|
|
1993
2043
|
await this.recounting(handle, target);
|
|
@@ -1998,7 +2048,7 @@ var OpfsFs = class {
|
|
|
1998
2048
|
const [handle, , target] = await this.fileFor(path);
|
|
1999
2049
|
const writable2 = await this.retrying(
|
|
2000
2050
|
path,
|
|
2001
|
-
() => handle.createWritable({ keepExistingData: !truncate }),
|
|
2051
|
+
() => this.io(handle.createWritable({ keepExistingData: !truncate })),
|
|
2002
2052
|
true
|
|
2003
2053
|
);
|
|
2004
2054
|
return {
|
|
@@ -2047,7 +2097,7 @@ var OpfsFs = class {
|
|
|
2047
2097
|
try {
|
|
2048
2098
|
const handle = await this.inDir(
|
|
2049
2099
|
dir,
|
|
2050
|
-
(parent) => parent.getFileHandle(name2, { create: true })
|
|
2100
|
+
(parent) => this.io(parent.getFileHandle(name2, { create: true }))
|
|
2051
2101
|
);
|
|
2052
2102
|
if (!existed) this.touch(Date.now(), parentOf3(target));
|
|
2053
2103
|
return [handle, existed, target];
|
|
@@ -2063,7 +2113,7 @@ var OpfsFs = class {
|
|
|
2063
2113
|
let writable2;
|
|
2064
2114
|
this.wrote(file);
|
|
2065
2115
|
try {
|
|
2066
|
-
writable2 = await file.createWritable();
|
|
2116
|
+
writable2 = await this.io(file.createWritable());
|
|
2067
2117
|
await writable2.write(content);
|
|
2068
2118
|
await writable2.close();
|
|
2069
2119
|
} catch (err) {
|
|
@@ -2079,6 +2129,7 @@ var OpfsFs = class {
|
|
|
2079
2129
|
const handle = found.handle;
|
|
2080
2130
|
if (handle.kind !== "directory") throw fsError("ENOTDIR", path);
|
|
2081
2131
|
const children3 = /* @__PURE__ */ new Map();
|
|
2132
|
+
this.others++;
|
|
2082
2133
|
for await (const child of handle.values()) children3.set(child.name, child);
|
|
2083
2134
|
for (const link2 of await this.meta.links(found.path)) {
|
|
2084
2135
|
const name2 = baseOf(link2.path);
|
|
@@ -2132,7 +2183,7 @@ var OpfsFs = class {
|
|
|
2132
2183
|
const parent = await this.locate(parentOf3(path), true);
|
|
2133
2184
|
if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
|
|
2134
2185
|
this.refuse(resolvePath(parent.path, baseOf(path)));
|
|
2135
|
-
await parent.handle.getDirectoryHandle(baseOf(path), { create: true });
|
|
2186
|
+
await this.io(parent.handle.getDirectoryHandle(baseOf(path), { create: true }));
|
|
2136
2187
|
const now = Date.now();
|
|
2137
2188
|
const made2 = `${parent.path === "/" ? "" : parent.path}/${baseOf(path)}`;
|
|
2138
2189
|
await this.stampNew(made2, owner, true);
|
|
@@ -2153,7 +2204,7 @@ var OpfsFs = class {
|
|
|
2153
2204
|
if (found !== void 0 && !found.vacated) await this.meta.remove([path]);
|
|
2154
2205
|
this.forget(physical);
|
|
2155
2206
|
this.refuse(physical);
|
|
2156
|
-
await dir.getDirectoryHandle(name2, { create: true });
|
|
2207
|
+
await this.io(dir.getDirectoryHandle(name2, { create: true }));
|
|
2157
2208
|
const now = Date.now();
|
|
2158
2209
|
const made2 = `${parent.path === "/" ? "" : parent.path}/${name2}`;
|
|
2159
2210
|
await this.stampNew(made2, owner, true);
|
|
@@ -2175,9 +2226,10 @@ var OpfsFs = class {
|
|
|
2175
2226
|
if (found !== void 0 && !found.vacated) await this.meta.remove([path]);
|
|
2176
2227
|
this.forget(physical);
|
|
2177
2228
|
this.refuse(physical);
|
|
2178
|
-
await dir.getFileHandle(name2, { create: true });
|
|
2229
|
+
const handle = await this.io(dir.getFileHandle(name2, { create: true }));
|
|
2179
2230
|
const now = Date.now();
|
|
2180
2231
|
const made2 = `${parent.path === "/" ? "" : parent.path}/${name2}`;
|
|
2232
|
+
this.remember(made2, handle, true);
|
|
2181
2233
|
await this.stampNew(made2, owner, false);
|
|
2182
2234
|
this.touch(now, parent.path, made2);
|
|
2183
2235
|
});
|
|
@@ -2209,7 +2261,7 @@ var OpfsFs = class {
|
|
|
2209
2261
|
try {
|
|
2210
2262
|
await this.inDir(
|
|
2211
2263
|
dir,
|
|
2212
|
-
(parent) => parent.removeEntry(name2, { recursive: options.recursive === true })
|
|
2264
|
+
(parent) => this.io(parent.removeEntry(name2, { recursive: options.recursive === true }))
|
|
2213
2265
|
);
|
|
2214
2266
|
} catch (err) {
|
|
2215
2267
|
throw translate(err, path);
|
|
@@ -2394,10 +2446,11 @@ var OpfsFs = class {
|
|
|
2394
2446
|
return intents.length;
|
|
2395
2447
|
}
|
|
2396
2448
|
async settledRename(path) {
|
|
2397
|
-
if (this.renamingDirs.size === 0 || typeof path !== "string")
|
|
2449
|
+
if (this.renamingDirs.size === 0 && this.copying.size === 0 || typeof path !== "string")
|
|
2450
|
+
return;
|
|
2398
2451
|
const at = normalizePath(path);
|
|
2399
2452
|
for (let real; ; ) {
|
|
2400
|
-
const busy = this.
|
|
2453
|
+
const busy = this.busyAt(at) ?? (real === void 0 ? void 0 : this.busyAt(real));
|
|
2401
2454
|
if (busy) {
|
|
2402
2455
|
await busy.done;
|
|
2403
2456
|
continue;
|
|
@@ -2408,6 +2461,62 @@ var OpfsFs = class {
|
|
|
2408
2461
|
if (real === at) return;
|
|
2409
2462
|
}
|
|
2410
2463
|
}
|
|
2464
|
+
busyAt(at) {
|
|
2465
|
+
return this.renameAt(at) ?? this.copying.get(at);
|
|
2466
|
+
}
|
|
2467
|
+
copying = /* @__PURE__ */ new Map();
|
|
2468
|
+
async copyFile(from, to, options) {
|
|
2469
|
+
const source = await this.locate(from, true);
|
|
2470
|
+
if (source.handle?.kind !== "file") throw fsError("EINVAL", `${from}: not a regular file`);
|
|
2471
|
+
const [entry] = await this.meta.get([source.path]);
|
|
2472
|
+
if (entry?.fifo || entry?.socket) throw fsError("EINVAL", `${from}: not a regular file`);
|
|
2473
|
+
const parent = await this.locate(parentOf3(to), true);
|
|
2474
|
+
if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", to);
|
|
2475
|
+
const destination = resolvePath(parent.path, baseOf(to));
|
|
2476
|
+
if (destination === source.path) throw fsError("EINVAL", `${from}: copied onto itself`);
|
|
2477
|
+
const file = await this.reading(source.path, (handle) => handle.getFile());
|
|
2478
|
+
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
2479
|
+
while (this.copying.has(destination)) await this.copying.get(destination)?.done;
|
|
2480
|
+
this.copying.set(destination, { done: promise });
|
|
2481
|
+
try {
|
|
2482
|
+
await this.copyInto(file, destination, to, options);
|
|
2483
|
+
} finally {
|
|
2484
|
+
this.copying.delete(destination);
|
|
2485
|
+
resolve2();
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
async copyInto(file, destination, to, options) {
|
|
2489
|
+
let created4 = false;
|
|
2490
|
+
if (options.exclusive) {
|
|
2491
|
+
await this.createExclusive(destination, options.owner);
|
|
2492
|
+
created4 = true;
|
|
2493
|
+
}
|
|
2494
|
+
let target = destination;
|
|
2495
|
+
let writable2;
|
|
2496
|
+
let handle;
|
|
2497
|
+
try {
|
|
2498
|
+
const [made2, existed, at] = await this.fileFor(destination);
|
|
2499
|
+
handle = made2;
|
|
2500
|
+
target = at;
|
|
2501
|
+
if (!existed && !created4) {
|
|
2502
|
+
created4 = true;
|
|
2503
|
+
await this.stampNew(target, options.owner, false);
|
|
2504
|
+
}
|
|
2505
|
+
const [entry] = await this.meta.get([target]);
|
|
2506
|
+
if (entry?.fifo || entry?.socket) throw fsError("ENXIO", to);
|
|
2507
|
+
this.wrote(handle);
|
|
2508
|
+
writable2 = await handle.createWritable();
|
|
2509
|
+
await writable2.write(file);
|
|
2510
|
+
await writable2.close();
|
|
2511
|
+
} catch (err) {
|
|
2512
|
+
await writable2?.abort().catch(() => void 0);
|
|
2513
|
+
if (created4) await this.rm(target, { file: true }).catch(() => void 0);
|
|
2514
|
+
throw translate(err, to, "commit", false);
|
|
2515
|
+
} finally {
|
|
2516
|
+
if (handle) this.wrote(handle);
|
|
2517
|
+
}
|
|
2518
|
+
this.committed(target);
|
|
2519
|
+
}
|
|
2411
2520
|
renameAt(at) {
|
|
2412
2521
|
for (const m of this.renamingDirs) {
|
|
2413
2522
|
if (within2(at, m.from) || within2(at, m.to) || at === parentOf3(m.from) || at === parentOf3(m.to))
|
|
@@ -2450,7 +2559,9 @@ var OpfsFs = class {
|
|
|
2450
2559
|
}
|
|
2451
2560
|
}
|
|
2452
2561
|
async place(handle, dir, name2) {
|
|
2453
|
-
const
|
|
2562
|
+
const move = handle.move;
|
|
2563
|
+
if (move) this.others++;
|
|
2564
|
+
const moved2 = await move?.call(handle, dir, name2).then(
|
|
2454
2565
|
() => true,
|
|
2455
2566
|
() => false
|
|
2456
2567
|
);
|
|
@@ -2460,7 +2571,7 @@ var OpfsFs = class {
|
|
|
2460
2571
|
await this.copy(handle, dir, name2);
|
|
2461
2572
|
} catch (err) {
|
|
2462
2573
|
if (handle.kind === "directory" && this.fileMoves === before) {
|
|
2463
|
-
await dir.removeEntry(name2, { recursive: true });
|
|
2574
|
+
await this.io(dir.removeEntry(name2, { recursive: true }));
|
|
2464
2575
|
}
|
|
2465
2576
|
throw translate(err, name2);
|
|
2466
2577
|
}
|
|
@@ -2469,6 +2580,7 @@ var OpfsFs = class {
|
|
|
2469
2580
|
fileMoves = 0;
|
|
2470
2581
|
async copy(handle, dir, name2) {
|
|
2471
2582
|
if (handle.kind === "file" && movable(handle)) {
|
|
2583
|
+
this.others++;
|
|
2472
2584
|
const moved2 = await handle.move?.(dir, name2).then(
|
|
2473
2585
|
() => true,
|
|
2474
2586
|
() => false
|
|
@@ -2479,12 +2591,14 @@ var OpfsFs = class {
|
|
|
2479
2591
|
}
|
|
2480
2592
|
}
|
|
2481
2593
|
if (handle.kind === "file") {
|
|
2482
|
-
const
|
|
2483
|
-
|
|
2594
|
+
const made2 = await this.io(dir.getFileHandle(name2, { create: true }));
|
|
2595
|
+
const writable2 = await this.io(made2.createWritable());
|
|
2596
|
+
await writable2.write(await this.io(handle.getFile()));
|
|
2484
2597
|
await writable2.close();
|
|
2485
2598
|
return;
|
|
2486
2599
|
}
|
|
2487
|
-
const target = await dir.getDirectoryHandle(name2, { create: true });
|
|
2600
|
+
const target = await this.io(dir.getDirectoryHandle(name2, { create: true }));
|
|
2601
|
+
this.others++;
|
|
2488
2602
|
for await (const child of handle.values()) await this.copy(child, target, child.name);
|
|
2489
2603
|
}
|
|
2490
2604
|
async symlink(target, path, owner) {
|
|
@@ -2557,7 +2671,7 @@ var OpfsFs = class {
|
|
|
2557
2671
|
return;
|
|
2558
2672
|
}
|
|
2559
2673
|
const handle = found.handle;
|
|
2560
|
-
const file = handle.kind === "file" ? await handle.getFile() : void 0;
|
|
2674
|
+
const file = handle.kind === "file" ? await this.io(handle.getFile()) : void 0;
|
|
2561
2675
|
this.dirTimes.delete(found.path);
|
|
2562
2676
|
this.fileTimes.delete(found.path);
|
|
2563
2677
|
const ctimeMs = Date.now();
|
|
@@ -2650,6 +2764,7 @@ var READS = [
|
|
|
2650
2764
|
"readVersioned"
|
|
2651
2765
|
];
|
|
2652
2766
|
var WRITES = [
|
|
2767
|
+
"copyFile",
|
|
2653
2768
|
"writeFile",
|
|
2654
2769
|
"pwrite",
|
|
2655
2770
|
"truncate",
|
|
@@ -6823,7 +6938,7 @@ function satisfies(version, range2) {
|
|
|
6823
6938
|
}
|
|
6824
6939
|
|
|
6825
6940
|
// src/version.ts
|
|
6826
|
-
var KERNEL_VERSION = true ? "1.
|
|
6941
|
+
var KERNEL_VERSION = true ? "1.128.0" : "0.0.0-dev";
|
|
6827
6942
|
var OS_RELEASE = "6.0.0-slicc";
|
|
6828
6943
|
function procVersion() {
|
|
6829
6944
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9447,6 +9562,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
9447
9562
|
...fs.realpath ? { realpath: fs.realpath.bind(fs) } : {},
|
|
9448
9563
|
...fs.chown ? { chown: fs.chown.bind(fs) } : {},
|
|
9449
9564
|
...fs.createExclusive ? { createExclusive: fs.createExclusive.bind(fs) } : {},
|
|
9565
|
+
...fs.copyFile ? { copyFile: fs.copyFile.bind(fs) } : {},
|
|
9450
9566
|
...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
|
|
9451
9567
|
...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
|
|
9452
9568
|
chmod: (path, mode) => fs.chmod(path, mode),
|
|
@@ -9848,6 +9964,12 @@ var FsWatchers = class {
|
|
|
9848
9964
|
const overrides = {
|
|
9849
9965
|
writeFile: content(fs.writeFile.bind(fs), written2),
|
|
9850
9966
|
...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs), () => ["rename"]) } : {},
|
|
9967
|
+
...fs.copyFile ? {
|
|
9968
|
+
copyFile: (from, to, options) => content(
|
|
9969
|
+
(_to) => fs.copyFile?.(from, to, options),
|
|
9970
|
+
written2
|
|
9971
|
+
)(to)
|
|
9972
|
+
} : {},
|
|
9851
9973
|
mkdir: async (path, options) => {
|
|
9852
9974
|
const created4 = [];
|
|
9853
9975
|
if (options?.recursive) {
|
|
@@ -10505,6 +10627,33 @@ var FifoTable = class {
|
|
|
10505
10627
|
}
|
|
10506
10628
|
};
|
|
10507
10629
|
|
|
10630
|
+
// src/fs/copy.ts
|
|
10631
|
+
async function present2(fs, path) {
|
|
10632
|
+
return fs.lstat(path).then(
|
|
10633
|
+
() => true,
|
|
10634
|
+
(err) => {
|
|
10635
|
+
if (err?.code === "ENOENT") return false;
|
|
10636
|
+
throw err;
|
|
10637
|
+
}
|
|
10638
|
+
);
|
|
10639
|
+
}
|
|
10640
|
+
async function copyByBytes(fs, from, to, options) {
|
|
10641
|
+
if (!(await fs.stat(from)).isFile) throw fsError("EINVAL", `${from}: not a regular file`);
|
|
10642
|
+
const bytes = await fs.readFileBuffer(from);
|
|
10643
|
+
let created4 = false;
|
|
10644
|
+
if (options.exclusive) {
|
|
10645
|
+
if (fs.createExclusive) await fs.createExclusive(to, options.owner);
|
|
10646
|
+
else if (await present2(fs, to)) throw fsError("EEXIST", to);
|
|
10647
|
+
created4 = true;
|
|
10648
|
+
} else created4 = !await present2(fs, to);
|
|
10649
|
+
try {
|
|
10650
|
+
await fs.writeFile(to, bytes, options.owner);
|
|
10651
|
+
} catch (err) {
|
|
10652
|
+
if (created4) await fs.rm(to, { file: true }).catch(() => void 0);
|
|
10653
|
+
throw err;
|
|
10654
|
+
}
|
|
10655
|
+
}
|
|
10656
|
+
|
|
10508
10657
|
// src/mount/protocol.ts
|
|
10509
10658
|
var DRIVER_PROTOCOL = [1, 3];
|
|
10510
10659
|
function driverVersionError(theirs) {
|
|
@@ -10888,12 +11037,12 @@ var MountTable = class {
|
|
|
10888
11037
|
}
|
|
10889
11038
|
list() {
|
|
10890
11039
|
const mounted = [...this.mounts.values()].map(
|
|
10891
|
-
({ type, source, target, options, state, error, present:
|
|
11040
|
+
({ type, source, target, options, state, error, present: present4 }) => ({
|
|
10892
11041
|
type,
|
|
10893
11042
|
source,
|
|
10894
11043
|
target,
|
|
10895
11044
|
options: { ...options },
|
|
10896
|
-
state: state === "ok" &&
|
|
11045
|
+
state: state === "ok" && present4?.() === false ? "nomedium" : state,
|
|
10897
11046
|
...error ? { error } : {}
|
|
10898
11047
|
})
|
|
10899
11048
|
);
|
|
@@ -11568,6 +11717,23 @@ var MountFs = class _MountFs {
|
|
|
11568
11717
|
throw err;
|
|
11569
11718
|
}
|
|
11570
11719
|
}
|
|
11720
|
+
async copyFile(from, to, options, redirects = 0) {
|
|
11721
|
+
const source = await realTarget(this, normalizePath(from));
|
|
11722
|
+
const a = this.at(source);
|
|
11723
|
+
const b = this.at(to);
|
|
11724
|
+
const copy = this.base.copyFile?.bind(this.base);
|
|
11725
|
+
if (!a && !b && copy) {
|
|
11726
|
+
return this.based(
|
|
11727
|
+
[source, to],
|
|
11728
|
+
redirects,
|
|
11729
|
+
() => copy(source, to, options),
|
|
11730
|
+
([f, t], n) => this.copyFile(f, t, options, n)
|
|
11731
|
+
);
|
|
11732
|
+
}
|
|
11733
|
+
if (a?.mount !== b?.mount) throw errnoError("EXDEV", `${from} -> ${to}`);
|
|
11734
|
+
if (a) this.writable(a.mount, normalizePath(to));
|
|
11735
|
+
return copyByBytes(this, source, to, options);
|
|
11736
|
+
}
|
|
11571
11737
|
async createExclusive(path, owner, redirects = 0) {
|
|
11572
11738
|
const exclusive = this.base.createExclusive?.bind(this.base);
|
|
11573
11739
|
if (!this.at(path) && exclusive) {
|
|
@@ -11995,6 +12161,7 @@ var SYNC_FS_OPS = [
|
|
|
11995
12161
|
"rm",
|
|
11996
12162
|
"rename",
|
|
11997
12163
|
"link",
|
|
12164
|
+
"copy",
|
|
11998
12165
|
"unlink",
|
|
11999
12166
|
"rmdir",
|
|
12000
12167
|
"symlink",
|
|
@@ -12194,6 +12361,8 @@ async function run(entry, path, req) {
|
|
|
12194
12361
|
case "symlink":
|
|
12195
12362
|
await fs.symlink(req.arg2 ?? "", path, ownerFor2(entry));
|
|
12196
12363
|
return done;
|
|
12364
|
+
case "copy":
|
|
12365
|
+
return copyOp(entry, path, req);
|
|
12197
12366
|
case "mkfifo": {
|
|
12198
12367
|
const owner = ownerFor2(entry, req.mode ?? 438) ?? { uid: 0, gid: 0 };
|
|
12199
12368
|
await createExclusive(fs, path, { ...owner, fifo: true });
|
|
@@ -12300,6 +12469,16 @@ async function guard(g, path, req, cwd) {
|
|
|
12300
12469
|
const toWalked = await walkSafe(g, to, false);
|
|
12301
12470
|
return { path: fromWalked, arg2: toWalked };
|
|
12302
12471
|
}
|
|
12472
|
+
case "copy": {
|
|
12473
|
+
const to = other();
|
|
12474
|
+
await readable(g, op, path);
|
|
12475
|
+
const there = !req.exclusive && await g.fs.lstat(to).then(
|
|
12476
|
+
() => true,
|
|
12477
|
+
() => false
|
|
12478
|
+
);
|
|
12479
|
+
await (there ? writable(g, op, to) : inParent(g, op, to));
|
|
12480
|
+
return { path: await walkSafe(g, path, true), arg2: await walkSafe(g, to, false) };
|
|
12481
|
+
}
|
|
12303
12482
|
case "link": {
|
|
12304
12483
|
const to = other();
|
|
12305
12484
|
const follow2 = req.mode === 1;
|
|
@@ -12400,6 +12579,9 @@ async function mayChange(entry, path, req) {
|
|
|
12400
12579
|
const { mayChange: mayChange2 } = entry.fs;
|
|
12401
12580
|
if (!mayChange2) return;
|
|
12402
12581
|
const { op } = req;
|
|
12582
|
+
if (op === "copy") {
|
|
12583
|
+
return mayChange2.call(entry.fs, entry.fs.resolvePath(entry.cwd, req.arg2 ?? ""), false);
|
|
12584
|
+
}
|
|
12403
12585
|
if (CONTENT.has(op) && req.handle === void 0) return mayChange2.call(entry.fs, path, true);
|
|
12404
12586
|
if (!CHANGING.has(op)) return;
|
|
12405
12587
|
const follow2 = op === "utimes" || op === "chmod" || op === "chown";
|
|
@@ -12423,6 +12605,17 @@ async function guarded(entry, path, req) {
|
|
|
12423
12605
|
return { refused: refused3 };
|
|
12424
12606
|
}
|
|
12425
12607
|
}
|
|
12608
|
+
async function copyOp(entry, path, req) {
|
|
12609
|
+
const { fs, cwd } = entry;
|
|
12610
|
+
const to = fs.resolvePath(cwd, req.arg2 ?? "");
|
|
12611
|
+
const mode = (req.mode ?? 438) & 4095 & ~(entry.umask?.() ?? 18);
|
|
12612
|
+
const owner = ownerFor2(entry, mode);
|
|
12613
|
+
const options = { exclusive: req.exclusive === true, ...owner ? { owner } : {} };
|
|
12614
|
+
await (fs.copyFile ? fs.copyFile(path, to, options) : copyByBytes(fs, path, to, options));
|
|
12615
|
+
if (!owner) await fs.chmod(to, mode);
|
|
12616
|
+
entry.fresh?.(to);
|
|
12617
|
+
return done;
|
|
12618
|
+
}
|
|
12426
12619
|
async function createExclusive(fs, path, owner) {
|
|
12427
12620
|
if (fs.createExclusive) return fs.createExclusive(path, owner);
|
|
12428
12621
|
if (await fs.lstat(path).then(
|
|
@@ -12597,7 +12790,7 @@ var CREATIONS = /* @__PURE__ */ new Set([
|
|
|
12597
12790
|
"create",
|
|
12598
12791
|
"mkfifo"
|
|
12599
12792
|
]);
|
|
12600
|
-
var NAMING = /* @__PURE__ */ new Set(["link", "rename"]);
|
|
12793
|
+
var NAMING = /* @__PURE__ */ new Set(["link", "rename", "copy"]);
|
|
12601
12794
|
async function newDevName(entry, path, req) {
|
|
12602
12795
|
const named = NAMING.has(req.op);
|
|
12603
12796
|
if (!named && !CREATIONS.has(req.op)) return void 0;
|
|
@@ -13268,6 +13461,8 @@ var SYS_TREE = {
|
|
|
13268
13461
|
slicc_fs_calls: (listing) => `${listing.fsCalls ?? 0}
|
|
13269
13462
|
`,
|
|
13270
13463
|
slicc_opfs_calls: (listing) => `${listing.opfsCalls ?? 0}
|
|
13464
|
+
`,
|
|
13465
|
+
slicc_opfs_ops: (listing) => `${listing.opfsOps ?? 0}
|
|
13271
13466
|
`
|
|
13272
13467
|
}
|
|
13273
13468
|
};
|
|
@@ -19872,7 +20067,7 @@ var VfsNodes = class {
|
|
|
19872
20067
|
if (held) throw fsError("EEXIST", path);
|
|
19873
20068
|
const exclusive = this.fs.createExclusive;
|
|
19874
20069
|
if (exclusive) return exclusive.call(this.fs, path, owner);
|
|
19875
|
-
if (await
|
|
20070
|
+
if (await present3(this.fs, path)) throw fsError("EEXIST", path);
|
|
19876
20071
|
await this.fs.writeFile(path, new Uint8Array(0), owner);
|
|
19877
20072
|
});
|
|
19878
20073
|
}
|
|
@@ -20103,7 +20298,7 @@ var VfsNodes = class {
|
|
|
20103
20298
|
}
|
|
20104
20299
|
}
|
|
20105
20300
|
};
|
|
20106
|
-
async function
|
|
20301
|
+
async function present3(fs, path, follow2 = false) {
|
|
20107
20302
|
const look = (follow2 ? void 0 : fs.lstat) ?? fs.stat;
|
|
20108
20303
|
try {
|
|
20109
20304
|
await (look ? look.call(fs, path) : fs.readFileBuffer(path));
|
|
@@ -20281,7 +20476,18 @@ function keepingOpen(fs, nodes, changed = () => {
|
|
|
20281
20476
|
await nodes.onEntry(key, () => fs.link(from, to, follow2));
|
|
20282
20477
|
await nodes.linked(at, key);
|
|
20283
20478
|
},
|
|
20284
|
-
mkdir: (path, options) => nodes.onEntry(fs.resolvePath("/", path), () => fs.mkdir(path, options))
|
|
20479
|
+
mkdir: (path, options) => nodes.onEntry(fs.resolvePath("/", path), () => fs.mkdir(path, options)),
|
|
20480
|
+
...fs.copyFile ? {
|
|
20481
|
+
async copyFile(from, to, options) {
|
|
20482
|
+
const source = await nodes.targetKey(fs.resolvePath("/", from));
|
|
20483
|
+
await nodes.flush(source);
|
|
20484
|
+
await nodes.flushLinked(source);
|
|
20485
|
+
const at = fs.resolvePath("/", to);
|
|
20486
|
+
const key = await nodes.entryKey(at);
|
|
20487
|
+
if (await heldAt(fs, nodes, at)) return copyByBytes(this, from, to, options);
|
|
20488
|
+
await nodes.onEntry(key, () => fs.copyFile?.(from, to, options));
|
|
20489
|
+
}
|
|
20490
|
+
} : {}
|
|
20285
20491
|
};
|
|
20286
20492
|
}
|
|
20287
20493
|
function vfsFile(fs, opts, nodes) {
|
|
@@ -21141,7 +21347,7 @@ var WasmProcess = class {
|
|
|
21141
21347
|
} else if (req.create) {
|
|
21142
21348
|
await nodes.onEntry(path, async () => {
|
|
21143
21349
|
const marks = this.options.owners || plain2 !== void 0;
|
|
21144
|
-
const fresh2 = marks && !await
|
|
21350
|
+
const fresh2 = marks && !await present3(fs, path, true);
|
|
21145
21351
|
this.fds.installAt(fd, this.openVfsFile(open, await nodes.identify(path), fs));
|
|
21146
21352
|
await this.fds.get(fd).file.stat?.();
|
|
21147
21353
|
if (fresh2 && plain2 !== void 0) await fs.chmod?.(path, plain2);
|
|
@@ -21160,7 +21366,7 @@ var WasmProcess = class {
|
|
|
21160
21366
|
{ at: path, gen }
|
|
21161
21367
|
);
|
|
21162
21368
|
}
|
|
21163
|
-
if (req.existing && !await
|
|
21369
|
+
if (req.existing && !await present3(fs, path, true)) {
|
|
21164
21370
|
throw new KernelError("ENOENT");
|
|
21165
21371
|
}
|
|
21166
21372
|
} catch (err) {
|
|
@@ -21528,12 +21734,12 @@ var WasmProcess = class {
|
|
|
21528
21734
|
async stillOpen(at, handle) {
|
|
21529
21735
|
if (handle === void 0 || this.keptHandle?.(handle) !== void 0) return;
|
|
21530
21736
|
if (this.holdsHandle?.(handle) !== false) return;
|
|
21531
|
-
if (!await
|
|
21737
|
+
if (!await present3(this.options.fs, at, true)) throw new KernelError("ENOENT");
|
|
21532
21738
|
}
|
|
21533
21739
|
async keptOr(path, handle) {
|
|
21534
21740
|
if (handle !== void 0) return this.keptHandle?.(handle) ?? path;
|
|
21535
21741
|
const kept = this.keptPath?.(path);
|
|
21536
|
-
return kept !== void 0 && !await
|
|
21742
|
+
return kept !== void 0 && !await present3(this.options.fs, path, true) ? kept : path;
|
|
21537
21743
|
}
|
|
21538
21744
|
async promote(req) {
|
|
21539
21745
|
if (!this.fds.get(req.fd).file.held) throw new KernelError("EBADF");
|
|
@@ -26950,7 +27156,8 @@ var Launcher = class {
|
|
|
26950
27156
|
wasm: this.memories.count(),
|
|
26951
27157
|
peers: Number(this.locks.shared?.() === true),
|
|
26952
27158
|
fsCalls: servedFsCalls(),
|
|
26953
|
-
opfsCalls: this.rootFs.opfsCalls?.() ?? 0
|
|
27159
|
+
opfsCalls: this.rootFs.opfsCalls?.() ?? 0,
|
|
27160
|
+
opfsOps: this.rootFs.opfsOps?.() ?? 0
|
|
26954
27161
|
}),
|
|
26955
27162
|
sudo: (call, signal) => this.sudo(pid, call, signal),
|
|
26956
27163
|
crontab: (call) => this.crontab(pid, call),
|