@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/node.js
CHANGED
|
@@ -4062,6 +4062,12 @@ var ProtectedFs = class {
|
|
|
4062
4062
|
st && marked(`${dir}/${name2}`, st)
|
|
4063
4063
|
]);
|
|
4064
4064
|
},
|
|
4065
|
+
...fs.copyFile ? {
|
|
4066
|
+
async copyFile(...args) {
|
|
4067
|
+
await check(args[1], false);
|
|
4068
|
+
return fs.copyFile?.(...args);
|
|
4069
|
+
}
|
|
4070
|
+
} : {},
|
|
4065
4071
|
...fs.createExclusive ? {
|
|
4066
4072
|
async createExclusive(...args) {
|
|
4067
4073
|
await check(args[0], true);
|
|
@@ -4593,7 +4599,7 @@ var OpfsFs = class {
|
|
|
4593
4599
|
}
|
|
4594
4600
|
async recounting(handle, target) {
|
|
4595
4601
|
if (this.counted.length === 0) return;
|
|
4596
|
-
const where = await this.root.resolve(handle).catch(() => null);
|
|
4602
|
+
const where = await this.io(this.root.resolve(handle)).catch(() => null);
|
|
4597
4603
|
await this.counting(where ? `/${where.join("/")}` : target);
|
|
4598
4604
|
}
|
|
4599
4605
|
resolvePath(base, path) {
|
|
@@ -4795,9 +4801,17 @@ var OpfsFs = class {
|
|
|
4795
4801
|
}
|
|
4796
4802
|
exact = 0;
|
|
4797
4803
|
calls = 0;
|
|
4804
|
+
others = 0;
|
|
4798
4805
|
opfsCalls() {
|
|
4799
4806
|
return this.calls;
|
|
4800
4807
|
}
|
|
4808
|
+
opfsOps() {
|
|
4809
|
+
return this.calls + this.others;
|
|
4810
|
+
}
|
|
4811
|
+
io(request) {
|
|
4812
|
+
this.others++;
|
|
4813
|
+
return request;
|
|
4814
|
+
}
|
|
4801
4815
|
fresh() {
|
|
4802
4816
|
this.changes++;
|
|
4803
4817
|
this.absent.clear();
|
|
@@ -4821,7 +4835,13 @@ var OpfsFs = class {
|
|
|
4821
4835
|
this.absent.set(path, performance.now());
|
|
4822
4836
|
}
|
|
4823
4837
|
remember(path, handle, looked = false) {
|
|
4824
|
-
if (handle.kind !== "file")
|
|
4838
|
+
if (handle.kind !== "file") {
|
|
4839
|
+
if (looked) {
|
|
4840
|
+
this.dirs.set(path, handle);
|
|
4841
|
+
this.checked.set(handle, performance.now());
|
|
4842
|
+
}
|
|
4843
|
+
return handle;
|
|
4844
|
+
}
|
|
4825
4845
|
if (looked) {
|
|
4826
4846
|
this.found.set(handle, performance.now());
|
|
4827
4847
|
this.glances.delete(handle);
|
|
@@ -5202,7 +5222,7 @@ var OpfsFs = class {
|
|
|
5202
5222
|
async readFileBuffer(path) {
|
|
5203
5223
|
const bytes = await this.reading(
|
|
5204
5224
|
path,
|
|
5205
|
-
async (handle) => new Uint8Array(await (await handle.getFile()).arrayBuffer())
|
|
5225
|
+
async (handle) => new Uint8Array(await (await this.io(handle.getFile())).arrayBuffer())
|
|
5206
5226
|
);
|
|
5207
5227
|
await this.refuseNode(path, bytes.length === 0);
|
|
5208
5228
|
return bytes;
|
|
@@ -5210,7 +5230,7 @@ var OpfsFs = class {
|
|
|
5210
5230
|
async readVersioned(path, cached = false) {
|
|
5211
5231
|
return this.reading(path, async (handle) => {
|
|
5212
5232
|
const stamp = await this.stamp(path, cached);
|
|
5213
|
-
const file = await handle.getFile();
|
|
5233
|
+
const file = await this.io(handle.getFile());
|
|
5214
5234
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
5215
5235
|
await this.refuseNode(path, bytes.length === 0);
|
|
5216
5236
|
return { bytes, version: `${file.lastModified}:${file.size}:${stamp}` };
|
|
@@ -5219,23 +5239,53 @@ var OpfsFs = class {
|
|
|
5219
5239
|
async version(path, cached = false) {
|
|
5220
5240
|
return this.reading(path, async (handle) => {
|
|
5221
5241
|
const stamp = await this.stamp(path, cached);
|
|
5222
|
-
const file = await handle.getFile();
|
|
5242
|
+
const file = await this.io(handle.getFile());
|
|
5223
5243
|
return `${file.lastModified}:${file.size}:${stamp}`;
|
|
5224
5244
|
});
|
|
5225
5245
|
}
|
|
5226
5246
|
async pread(path, offset, length2) {
|
|
5227
5247
|
return this.reading(path, async (handle) => {
|
|
5228
|
-
const file = await handle.getFile();
|
|
5248
|
+
const file = await this.io(handle.getFile());
|
|
5229
5249
|
await this.refuseNode(path, file.size === 0);
|
|
5230
5250
|
return new Uint8Array(await file.slice(offset, offset + length2).arrayBuffer());
|
|
5231
5251
|
});
|
|
5232
5252
|
}
|
|
5233
5253
|
async pwrite(path, offset, bytes) {
|
|
5234
|
-
const [
|
|
5254
|
+
const [kept, target] = await this.keptFor(path);
|
|
5255
|
+
if (kept) {
|
|
5256
|
+
try {
|
|
5257
|
+
await this.writeAt(kept, target, path, offset, bytes);
|
|
5258
|
+
return;
|
|
5259
|
+
} catch (err) {
|
|
5260
|
+
if (err.code !== "ENOENT") throw err;
|
|
5261
|
+
this.files.delete(target);
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
const [handle] = await this.fileFor(path);
|
|
5265
|
+
await this.writeAt(handle, target, path, offset, bytes);
|
|
5266
|
+
}
|
|
5267
|
+
async keptFor(path) {
|
|
5268
|
+
const at = normalizePath(path);
|
|
5269
|
+
const cached = this.files.get(at);
|
|
5270
|
+
const fresh2 = cached && performance.now() - (this.found.get(cached) ?? -CHECK_MS) < CHECK_MS;
|
|
5271
|
+
const [target, existed] = fresh2 ? [at, true] : await this.writeTarget(path);
|
|
5272
|
+
if (!existed) return [void 0, target];
|
|
5273
|
+
this.refuse(target);
|
|
5274
|
+
const [entry] = await this.meta.get([target]);
|
|
5275
|
+
if (entry?.fifo || entry?.socket) throw fsError("ENXIO", path);
|
|
5276
|
+
const kept = fresh2 ? cached : this.files.get(target);
|
|
5277
|
+
const usable2 = kept && performance.now() - (this.found.get(kept) ?? -CHECK_MS) < CHECK_MS;
|
|
5278
|
+
return [usable2 ? kept : void 0, target];
|
|
5279
|
+
}
|
|
5280
|
+
async writeAt(handle, target, path, offset, bytes) {
|
|
5235
5281
|
await this.counting(target);
|
|
5236
5282
|
this.wrote(handle);
|
|
5237
5283
|
try {
|
|
5238
|
-
await this.retrying(
|
|
5284
|
+
await this.retrying(
|
|
5285
|
+
path,
|
|
5286
|
+
() => this.io(positioned(handle, (io) => io.write(offset, bytes))),
|
|
5287
|
+
true
|
|
5288
|
+
);
|
|
5239
5289
|
} finally {
|
|
5240
5290
|
this.wrote(handle);
|
|
5241
5291
|
await this.recounting(handle, target);
|
|
@@ -5244,13 +5294,13 @@ var OpfsFs = class {
|
|
|
5244
5294
|
}
|
|
5245
5295
|
async truncate(path, size) {
|
|
5246
5296
|
const handle = await this.existing(path, true);
|
|
5247
|
-
await this.refuseNode(path, (await handle.getFile()).size === 0);
|
|
5297
|
+
await this.refuseNode(path, (await this.io(handle.getFile())).size === 0);
|
|
5248
5298
|
const resolve2 = this.ranged || this.remote?.watched();
|
|
5249
5299
|
const target = resolve2 || this.counted.length > 0 ? (await this.locate(path, true)).path : path;
|
|
5250
5300
|
await this.counting(target);
|
|
5251
5301
|
this.wrote(handle);
|
|
5252
5302
|
try {
|
|
5253
|
-
await this.retrying(path, () => positioned(handle, (io) => io.truncate(size)), true);
|
|
5303
|
+
await this.retrying(path, () => this.io(positioned(handle, (io) => io.truncate(size))), true);
|
|
5254
5304
|
} finally {
|
|
5255
5305
|
this.wrote(handle);
|
|
5256
5306
|
await this.recounting(handle, target);
|
|
@@ -5261,7 +5311,7 @@ var OpfsFs = class {
|
|
|
5261
5311
|
const [handle, , target] = await this.fileFor(path);
|
|
5262
5312
|
const writable2 = await this.retrying(
|
|
5263
5313
|
path,
|
|
5264
|
-
() => handle.createWritable({ keepExistingData: !truncate }),
|
|
5314
|
+
() => this.io(handle.createWritable({ keepExistingData: !truncate })),
|
|
5265
5315
|
true
|
|
5266
5316
|
);
|
|
5267
5317
|
return {
|
|
@@ -5310,7 +5360,7 @@ var OpfsFs = class {
|
|
|
5310
5360
|
try {
|
|
5311
5361
|
const handle = await this.inDir(
|
|
5312
5362
|
dir,
|
|
5313
|
-
(parent) => parent.getFileHandle(name2, { create: true })
|
|
5363
|
+
(parent) => this.io(parent.getFileHandle(name2, { create: true }))
|
|
5314
5364
|
);
|
|
5315
5365
|
if (!existed) this.touch(Date.now(), parentOf4(target));
|
|
5316
5366
|
return [handle, existed, target];
|
|
@@ -5326,7 +5376,7 @@ var OpfsFs = class {
|
|
|
5326
5376
|
let writable2;
|
|
5327
5377
|
this.wrote(file);
|
|
5328
5378
|
try {
|
|
5329
|
-
writable2 = await file.createWritable();
|
|
5379
|
+
writable2 = await this.io(file.createWritable());
|
|
5330
5380
|
await writable2.write(content);
|
|
5331
5381
|
await writable2.close();
|
|
5332
5382
|
} catch (err) {
|
|
@@ -5342,6 +5392,7 @@ var OpfsFs = class {
|
|
|
5342
5392
|
const handle = found.handle;
|
|
5343
5393
|
if (handle.kind !== "directory") throw fsError("ENOTDIR", path);
|
|
5344
5394
|
const children3 = /* @__PURE__ */ new Map();
|
|
5395
|
+
this.others++;
|
|
5345
5396
|
for await (const child of handle.values()) children3.set(child.name, child);
|
|
5346
5397
|
for (const link2 of await this.meta.links(found.path)) {
|
|
5347
5398
|
const name2 = baseOf(link2.path);
|
|
@@ -5395,7 +5446,7 @@ var OpfsFs = class {
|
|
|
5395
5446
|
const parent = await this.locate(parentOf4(path), true);
|
|
5396
5447
|
if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
|
|
5397
5448
|
this.refuse(resolvePath(parent.path, baseOf(path)));
|
|
5398
|
-
await parent.handle.getDirectoryHandle(baseOf(path), { create: true });
|
|
5449
|
+
await this.io(parent.handle.getDirectoryHandle(baseOf(path), { create: true }));
|
|
5399
5450
|
const now = Date.now();
|
|
5400
5451
|
const made2 = `${parent.path === "/" ? "" : parent.path}/${baseOf(path)}`;
|
|
5401
5452
|
await this.stampNew(made2, owner, true);
|
|
@@ -5416,7 +5467,7 @@ var OpfsFs = class {
|
|
|
5416
5467
|
if (found !== void 0 && !found.vacated) await this.meta.remove([path]);
|
|
5417
5468
|
this.forget(physical);
|
|
5418
5469
|
this.refuse(physical);
|
|
5419
|
-
await dir.getDirectoryHandle(name2, { create: true });
|
|
5470
|
+
await this.io(dir.getDirectoryHandle(name2, { create: true }));
|
|
5420
5471
|
const now = Date.now();
|
|
5421
5472
|
const made2 = `${parent.path === "/" ? "" : parent.path}/${name2}`;
|
|
5422
5473
|
await this.stampNew(made2, owner, true);
|
|
@@ -5438,9 +5489,10 @@ var OpfsFs = class {
|
|
|
5438
5489
|
if (found !== void 0 && !found.vacated) await this.meta.remove([path]);
|
|
5439
5490
|
this.forget(physical);
|
|
5440
5491
|
this.refuse(physical);
|
|
5441
|
-
await dir.getFileHandle(name2, { create: true });
|
|
5492
|
+
const handle = await this.io(dir.getFileHandle(name2, { create: true }));
|
|
5442
5493
|
const now = Date.now();
|
|
5443
5494
|
const made2 = `${parent.path === "/" ? "" : parent.path}/${name2}`;
|
|
5495
|
+
this.remember(made2, handle, true);
|
|
5444
5496
|
await this.stampNew(made2, owner, false);
|
|
5445
5497
|
this.touch(now, parent.path, made2);
|
|
5446
5498
|
});
|
|
@@ -5472,7 +5524,7 @@ var OpfsFs = class {
|
|
|
5472
5524
|
try {
|
|
5473
5525
|
await this.inDir(
|
|
5474
5526
|
dir,
|
|
5475
|
-
(parent) => parent.removeEntry(name2, { recursive: options.recursive === true })
|
|
5527
|
+
(parent) => this.io(parent.removeEntry(name2, { recursive: options.recursive === true }))
|
|
5476
5528
|
);
|
|
5477
5529
|
} catch (err) {
|
|
5478
5530
|
throw translate(err, path);
|
|
@@ -5657,10 +5709,11 @@ var OpfsFs = class {
|
|
|
5657
5709
|
return intents.length;
|
|
5658
5710
|
}
|
|
5659
5711
|
async settledRename(path) {
|
|
5660
|
-
if (this.renamingDirs.size === 0 || typeof path !== "string")
|
|
5712
|
+
if (this.renamingDirs.size === 0 && this.copying.size === 0 || typeof path !== "string")
|
|
5713
|
+
return;
|
|
5661
5714
|
const at = normalizePath(path);
|
|
5662
5715
|
for (let real; ; ) {
|
|
5663
|
-
const busy = this.
|
|
5716
|
+
const busy = this.busyAt(at) ?? (real === void 0 ? void 0 : this.busyAt(real));
|
|
5664
5717
|
if (busy) {
|
|
5665
5718
|
await busy.done;
|
|
5666
5719
|
continue;
|
|
@@ -5671,6 +5724,62 @@ var OpfsFs = class {
|
|
|
5671
5724
|
if (real === at) return;
|
|
5672
5725
|
}
|
|
5673
5726
|
}
|
|
5727
|
+
busyAt(at) {
|
|
5728
|
+
return this.renameAt(at) ?? this.copying.get(at);
|
|
5729
|
+
}
|
|
5730
|
+
copying = /* @__PURE__ */ new Map();
|
|
5731
|
+
async copyFile(from, to, options) {
|
|
5732
|
+
const source = await this.locate(from, true);
|
|
5733
|
+
if (source.handle?.kind !== "file") throw fsError("EINVAL", `${from}: not a regular file`);
|
|
5734
|
+
const [entry] = await this.meta.get([source.path]);
|
|
5735
|
+
if (entry?.fifo || entry?.socket) throw fsError("EINVAL", `${from}: not a regular file`);
|
|
5736
|
+
const parent = await this.locate(parentOf4(to), true);
|
|
5737
|
+
if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", to);
|
|
5738
|
+
const destination = resolvePath(parent.path, baseOf(to));
|
|
5739
|
+
if (destination === source.path) throw fsError("EINVAL", `${from}: copied onto itself`);
|
|
5740
|
+
const file = await this.reading(source.path, (handle) => handle.getFile());
|
|
5741
|
+
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
5742
|
+
while (this.copying.has(destination)) await this.copying.get(destination)?.done;
|
|
5743
|
+
this.copying.set(destination, { done: promise });
|
|
5744
|
+
try {
|
|
5745
|
+
await this.copyInto(file, destination, to, options);
|
|
5746
|
+
} finally {
|
|
5747
|
+
this.copying.delete(destination);
|
|
5748
|
+
resolve2();
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
async copyInto(file, destination, to, options) {
|
|
5752
|
+
let created4 = false;
|
|
5753
|
+
if (options.exclusive) {
|
|
5754
|
+
await this.createExclusive(destination, options.owner);
|
|
5755
|
+
created4 = true;
|
|
5756
|
+
}
|
|
5757
|
+
let target = destination;
|
|
5758
|
+
let writable2;
|
|
5759
|
+
let handle;
|
|
5760
|
+
try {
|
|
5761
|
+
const [made2, existed, at] = await this.fileFor(destination);
|
|
5762
|
+
handle = made2;
|
|
5763
|
+
target = at;
|
|
5764
|
+
if (!existed && !created4) {
|
|
5765
|
+
created4 = true;
|
|
5766
|
+
await this.stampNew(target, options.owner, false);
|
|
5767
|
+
}
|
|
5768
|
+
const [entry] = await this.meta.get([target]);
|
|
5769
|
+
if (entry?.fifo || entry?.socket) throw fsError("ENXIO", to);
|
|
5770
|
+
this.wrote(handle);
|
|
5771
|
+
writable2 = await handle.createWritable();
|
|
5772
|
+
await writable2.write(file);
|
|
5773
|
+
await writable2.close();
|
|
5774
|
+
} catch (err) {
|
|
5775
|
+
await writable2?.abort().catch(() => void 0);
|
|
5776
|
+
if (created4) await this.rm(target, { file: true }).catch(() => void 0);
|
|
5777
|
+
throw translate(err, to, "commit", false);
|
|
5778
|
+
} finally {
|
|
5779
|
+
if (handle) this.wrote(handle);
|
|
5780
|
+
}
|
|
5781
|
+
this.committed(target);
|
|
5782
|
+
}
|
|
5674
5783
|
renameAt(at) {
|
|
5675
5784
|
for (const m of this.renamingDirs) {
|
|
5676
5785
|
if (within3(at, m.from) || within3(at, m.to) || at === parentOf4(m.from) || at === parentOf4(m.to))
|
|
@@ -5713,7 +5822,9 @@ var OpfsFs = class {
|
|
|
5713
5822
|
}
|
|
5714
5823
|
}
|
|
5715
5824
|
async place(handle, dir, name2) {
|
|
5716
|
-
const
|
|
5825
|
+
const move = handle.move;
|
|
5826
|
+
if (move) this.others++;
|
|
5827
|
+
const moved2 = await move?.call(handle, dir, name2).then(
|
|
5717
5828
|
() => true,
|
|
5718
5829
|
() => false
|
|
5719
5830
|
);
|
|
@@ -5723,7 +5834,7 @@ var OpfsFs = class {
|
|
|
5723
5834
|
await this.copy(handle, dir, name2);
|
|
5724
5835
|
} catch (err) {
|
|
5725
5836
|
if (handle.kind === "directory" && this.fileMoves === before) {
|
|
5726
|
-
await dir.removeEntry(name2, { recursive: true });
|
|
5837
|
+
await this.io(dir.removeEntry(name2, { recursive: true }));
|
|
5727
5838
|
}
|
|
5728
5839
|
throw translate(err, name2);
|
|
5729
5840
|
}
|
|
@@ -5732,6 +5843,7 @@ var OpfsFs = class {
|
|
|
5732
5843
|
fileMoves = 0;
|
|
5733
5844
|
async copy(handle, dir, name2) {
|
|
5734
5845
|
if (handle.kind === "file" && movable(handle)) {
|
|
5846
|
+
this.others++;
|
|
5735
5847
|
const moved2 = await handle.move?.(dir, name2).then(
|
|
5736
5848
|
() => true,
|
|
5737
5849
|
() => false
|
|
@@ -5742,12 +5854,14 @@ var OpfsFs = class {
|
|
|
5742
5854
|
}
|
|
5743
5855
|
}
|
|
5744
5856
|
if (handle.kind === "file") {
|
|
5745
|
-
const
|
|
5746
|
-
|
|
5857
|
+
const made2 = await this.io(dir.getFileHandle(name2, { create: true }));
|
|
5858
|
+
const writable2 = await this.io(made2.createWritable());
|
|
5859
|
+
await writable2.write(await this.io(handle.getFile()));
|
|
5747
5860
|
await writable2.close();
|
|
5748
5861
|
return;
|
|
5749
5862
|
}
|
|
5750
|
-
const target = await dir.getDirectoryHandle(name2, { create: true });
|
|
5863
|
+
const target = await this.io(dir.getDirectoryHandle(name2, { create: true }));
|
|
5864
|
+
this.others++;
|
|
5751
5865
|
for await (const child of handle.values()) await this.copy(child, target, child.name);
|
|
5752
5866
|
}
|
|
5753
5867
|
async symlink(target, path, owner) {
|
|
@@ -5820,7 +5934,7 @@ var OpfsFs = class {
|
|
|
5820
5934
|
return;
|
|
5821
5935
|
}
|
|
5822
5936
|
const handle = found.handle;
|
|
5823
|
-
const file = handle.kind === "file" ? await handle.getFile() : void 0;
|
|
5937
|
+
const file = handle.kind === "file" ? await this.io(handle.getFile()) : void 0;
|
|
5824
5938
|
this.dirTimes.delete(found.path);
|
|
5825
5939
|
this.fileTimes.delete(found.path);
|
|
5826
5940
|
const ctimeMs = Date.now();
|
|
@@ -5913,6 +6027,7 @@ var READS = [
|
|
|
5913
6027
|
"readVersioned"
|
|
5914
6028
|
];
|
|
5915
6029
|
var WRITES = [
|
|
6030
|
+
"copyFile",
|
|
5916
6031
|
"writeFile",
|
|
5917
6032
|
"pwrite",
|
|
5918
6033
|
"truncate",
|
|
@@ -7277,7 +7392,7 @@ function satisfies(version, range2) {
|
|
|
7277
7392
|
}
|
|
7278
7393
|
|
|
7279
7394
|
// src/version.ts
|
|
7280
|
-
var KERNEL_VERSION = true ? "1.
|
|
7395
|
+
var KERNEL_VERSION = true ? "1.128.0" : "0.0.0-dev";
|
|
7281
7396
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7282
7397
|
function procVersion() {
|
|
7283
7398
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9542,6 +9657,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
9542
9657
|
...fs.realpath ? { realpath: fs.realpath.bind(fs) } : {},
|
|
9543
9658
|
...fs.chown ? { chown: fs.chown.bind(fs) } : {},
|
|
9544
9659
|
...fs.createExclusive ? { createExclusive: fs.createExclusive.bind(fs) } : {},
|
|
9660
|
+
...fs.copyFile ? { copyFile: fs.copyFile.bind(fs) } : {},
|
|
9545
9661
|
...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
|
|
9546
9662
|
...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
|
|
9547
9663
|
chmod: (path, mode) => fs.chmod(path, mode),
|
|
@@ -9943,6 +10059,12 @@ var FsWatchers = class {
|
|
|
9943
10059
|
const overrides = {
|
|
9944
10060
|
writeFile: content(fs.writeFile.bind(fs), written2),
|
|
9945
10061
|
...fs.createExclusive ? { createExclusive: content(fs.createExclusive.bind(fs), () => ["rename"]) } : {},
|
|
10062
|
+
...fs.copyFile ? {
|
|
10063
|
+
copyFile: (from, to, options) => content(
|
|
10064
|
+
(_to) => fs.copyFile?.(from, to, options),
|
|
10065
|
+
written2
|
|
10066
|
+
)(to)
|
|
10067
|
+
} : {},
|
|
9946
10068
|
mkdir: async (path, options) => {
|
|
9947
10069
|
const created4 = [];
|
|
9948
10070
|
if (options?.recursive) {
|
|
@@ -10600,6 +10722,33 @@ var FifoTable = class {
|
|
|
10600
10722
|
}
|
|
10601
10723
|
};
|
|
10602
10724
|
|
|
10725
|
+
// src/fs/copy.ts
|
|
10726
|
+
async function present2(fs, path) {
|
|
10727
|
+
return fs.lstat(path).then(
|
|
10728
|
+
() => true,
|
|
10729
|
+
(err) => {
|
|
10730
|
+
if (err?.code === "ENOENT") return false;
|
|
10731
|
+
throw err;
|
|
10732
|
+
}
|
|
10733
|
+
);
|
|
10734
|
+
}
|
|
10735
|
+
async function copyByBytes(fs, from, to, options) {
|
|
10736
|
+
if (!(await fs.stat(from)).isFile) throw fsError("EINVAL", `${from}: not a regular file`);
|
|
10737
|
+
const bytes = await fs.readFileBuffer(from);
|
|
10738
|
+
let created4 = false;
|
|
10739
|
+
if (options.exclusive) {
|
|
10740
|
+
if (fs.createExclusive) await fs.createExclusive(to, options.owner);
|
|
10741
|
+
else if (await present2(fs, to)) throw fsError("EEXIST", to);
|
|
10742
|
+
created4 = true;
|
|
10743
|
+
} else created4 = !await present2(fs, to);
|
|
10744
|
+
try {
|
|
10745
|
+
await fs.writeFile(to, bytes, options.owner);
|
|
10746
|
+
} catch (err) {
|
|
10747
|
+
if (created4) await fs.rm(to, { file: true }).catch(() => void 0);
|
|
10748
|
+
throw err;
|
|
10749
|
+
}
|
|
10750
|
+
}
|
|
10751
|
+
|
|
10603
10752
|
// src/mount/protocol.ts
|
|
10604
10753
|
var DRIVER_PROTOCOL = [1, 3];
|
|
10605
10754
|
function driverVersionError(theirs) {
|
|
@@ -10983,12 +11132,12 @@ var MountTable = class {
|
|
|
10983
11132
|
}
|
|
10984
11133
|
list() {
|
|
10985
11134
|
const mounted = [...this.mounts.values()].map(
|
|
10986
|
-
({ type, source, target, options, state, error, present:
|
|
11135
|
+
({ type, source, target, options, state, error, present: present4 }) => ({
|
|
10987
11136
|
type,
|
|
10988
11137
|
source,
|
|
10989
11138
|
target,
|
|
10990
11139
|
options: { ...options },
|
|
10991
|
-
state: state === "ok" &&
|
|
11140
|
+
state: state === "ok" && present4?.() === false ? "nomedium" : state,
|
|
10992
11141
|
...error ? { error } : {}
|
|
10993
11142
|
})
|
|
10994
11143
|
);
|
|
@@ -11663,6 +11812,23 @@ var MountFs = class _MountFs {
|
|
|
11663
11812
|
throw err;
|
|
11664
11813
|
}
|
|
11665
11814
|
}
|
|
11815
|
+
async copyFile(from, to, options, redirects = 0) {
|
|
11816
|
+
const source = await realTarget(this, normalizePath(from));
|
|
11817
|
+
const a = this.at(source);
|
|
11818
|
+
const b = this.at(to);
|
|
11819
|
+
const copy = this.base.copyFile?.bind(this.base);
|
|
11820
|
+
if (!a && !b && copy) {
|
|
11821
|
+
return this.based(
|
|
11822
|
+
[source, to],
|
|
11823
|
+
redirects,
|
|
11824
|
+
() => copy(source, to, options),
|
|
11825
|
+
([f, t], n) => this.copyFile(f, t, options, n)
|
|
11826
|
+
);
|
|
11827
|
+
}
|
|
11828
|
+
if (a?.mount !== b?.mount) throw errnoError("EXDEV", `${from} -> ${to}`);
|
|
11829
|
+
if (a) this.writable(a.mount, normalizePath(to));
|
|
11830
|
+
return copyByBytes(this, source, to, options);
|
|
11831
|
+
}
|
|
11666
11832
|
async createExclusive(path, owner, redirects = 0) {
|
|
11667
11833
|
const exclusive = this.base.createExclusive?.bind(this.base);
|
|
11668
11834
|
if (!this.at(path) && exclusive) {
|
|
@@ -12090,6 +12256,7 @@ var SYNC_FS_OPS = [
|
|
|
12090
12256
|
"rm",
|
|
12091
12257
|
"rename",
|
|
12092
12258
|
"link",
|
|
12259
|
+
"copy",
|
|
12093
12260
|
"unlink",
|
|
12094
12261
|
"rmdir",
|
|
12095
12262
|
"symlink",
|
|
@@ -12289,6 +12456,8 @@ async function run(entry, path, req) {
|
|
|
12289
12456
|
case "symlink":
|
|
12290
12457
|
await fs.symlink(req.arg2 ?? "", path, ownerFor2(entry));
|
|
12291
12458
|
return done;
|
|
12459
|
+
case "copy":
|
|
12460
|
+
return copyOp(entry, path, req);
|
|
12292
12461
|
case "mkfifo": {
|
|
12293
12462
|
const owner = ownerFor2(entry, req.mode ?? 438) ?? { uid: 0, gid: 0 };
|
|
12294
12463
|
await createExclusive(fs, path, { ...owner, fifo: true });
|
|
@@ -12395,6 +12564,16 @@ async function guard(g, path, req, cwd) {
|
|
|
12395
12564
|
const toWalked = await walkSafe(g, to, false);
|
|
12396
12565
|
return { path: fromWalked, arg2: toWalked };
|
|
12397
12566
|
}
|
|
12567
|
+
case "copy": {
|
|
12568
|
+
const to = other();
|
|
12569
|
+
await readable(g, op, path);
|
|
12570
|
+
const there = !req.exclusive && await g.fs.lstat(to).then(
|
|
12571
|
+
() => true,
|
|
12572
|
+
() => false
|
|
12573
|
+
);
|
|
12574
|
+
await (there ? writable(g, op, to) : inParent(g, op, to));
|
|
12575
|
+
return { path: await walkSafe(g, path, true), arg2: await walkSafe(g, to, false) };
|
|
12576
|
+
}
|
|
12398
12577
|
case "link": {
|
|
12399
12578
|
const to = other();
|
|
12400
12579
|
const follow2 = req.mode === 1;
|
|
@@ -12495,6 +12674,9 @@ async function mayChange(entry, path, req) {
|
|
|
12495
12674
|
const { mayChange: mayChange2 } = entry.fs;
|
|
12496
12675
|
if (!mayChange2) return;
|
|
12497
12676
|
const { op } = req;
|
|
12677
|
+
if (op === "copy") {
|
|
12678
|
+
return mayChange2.call(entry.fs, entry.fs.resolvePath(entry.cwd, req.arg2 ?? ""), false);
|
|
12679
|
+
}
|
|
12498
12680
|
if (CONTENT.has(op) && req.handle === void 0) return mayChange2.call(entry.fs, path, true);
|
|
12499
12681
|
if (!CHANGING.has(op)) return;
|
|
12500
12682
|
const follow2 = op === "utimes" || op === "chmod" || op === "chown";
|
|
@@ -12518,6 +12700,17 @@ async function guarded(entry, path, req) {
|
|
|
12518
12700
|
return { refused: refused3 };
|
|
12519
12701
|
}
|
|
12520
12702
|
}
|
|
12703
|
+
async function copyOp(entry, path, req) {
|
|
12704
|
+
const { fs, cwd } = entry;
|
|
12705
|
+
const to = fs.resolvePath(cwd, req.arg2 ?? "");
|
|
12706
|
+
const mode = (req.mode ?? 438) & 4095 & ~(entry.umask?.() ?? 18);
|
|
12707
|
+
const owner = ownerFor2(entry, mode);
|
|
12708
|
+
const options = { exclusive: req.exclusive === true, ...owner ? { owner } : {} };
|
|
12709
|
+
await (fs.copyFile ? fs.copyFile(path, to, options) : copyByBytes(fs, path, to, options));
|
|
12710
|
+
if (!owner) await fs.chmod(to, mode);
|
|
12711
|
+
entry.fresh?.(to);
|
|
12712
|
+
return done;
|
|
12713
|
+
}
|
|
12521
12714
|
async function createExclusive(fs, path, owner) {
|
|
12522
12715
|
if (fs.createExclusive) return fs.createExclusive(path, owner);
|
|
12523
12716
|
if (await fs.lstat(path).then(
|
|
@@ -12692,7 +12885,7 @@ var CREATIONS = /* @__PURE__ */ new Set([
|
|
|
12692
12885
|
"create",
|
|
12693
12886
|
"mkfifo"
|
|
12694
12887
|
]);
|
|
12695
|
-
var NAMING = /* @__PURE__ */ new Set(["link", "rename"]);
|
|
12888
|
+
var NAMING = /* @__PURE__ */ new Set(["link", "rename", "copy"]);
|
|
12696
12889
|
async function newDevName(entry, path, req) {
|
|
12697
12890
|
const named = NAMING.has(req.op);
|
|
12698
12891
|
if (!named && !CREATIONS.has(req.op)) return void 0;
|
|
@@ -13363,6 +13556,8 @@ var SYS_TREE = {
|
|
|
13363
13556
|
slicc_fs_calls: (listing) => `${listing.fsCalls ?? 0}
|
|
13364
13557
|
`,
|
|
13365
13558
|
slicc_opfs_calls: (listing) => `${listing.opfsCalls ?? 0}
|
|
13559
|
+
`,
|
|
13560
|
+
slicc_opfs_ops: (listing) => `${listing.opfsOps ?? 0}
|
|
13366
13561
|
`
|
|
13367
13562
|
}
|
|
13368
13563
|
};
|
|
@@ -19809,7 +20004,7 @@ var VfsNodes = class {
|
|
|
19809
20004
|
if (held) throw fsError("EEXIST", path);
|
|
19810
20005
|
const exclusive = this.fs.createExclusive;
|
|
19811
20006
|
if (exclusive) return exclusive.call(this.fs, path, owner);
|
|
19812
|
-
if (await
|
|
20007
|
+
if (await present3(this.fs, path)) throw fsError("EEXIST", path);
|
|
19813
20008
|
await this.fs.writeFile(path, new Uint8Array(0), owner);
|
|
19814
20009
|
});
|
|
19815
20010
|
}
|
|
@@ -20040,7 +20235,7 @@ var VfsNodes = class {
|
|
|
20040
20235
|
}
|
|
20041
20236
|
}
|
|
20042
20237
|
};
|
|
20043
|
-
async function
|
|
20238
|
+
async function present3(fs, path, follow2 = false) {
|
|
20044
20239
|
const look = (follow2 ? void 0 : fs.lstat) ?? fs.stat;
|
|
20045
20240
|
try {
|
|
20046
20241
|
await (look ? look.call(fs, path) : fs.readFileBuffer(path));
|
|
@@ -20218,7 +20413,18 @@ function keepingOpen(fs, nodes, changed = () => {
|
|
|
20218
20413
|
await nodes.onEntry(key, () => fs.link(from, to, follow2));
|
|
20219
20414
|
await nodes.linked(at, key);
|
|
20220
20415
|
},
|
|
20221
|
-
mkdir: (path, options) => nodes.onEntry(fs.resolvePath("/", path), () => fs.mkdir(path, options))
|
|
20416
|
+
mkdir: (path, options) => nodes.onEntry(fs.resolvePath("/", path), () => fs.mkdir(path, options)),
|
|
20417
|
+
...fs.copyFile ? {
|
|
20418
|
+
async copyFile(from, to, options) {
|
|
20419
|
+
const source = await nodes.targetKey(fs.resolvePath("/", from));
|
|
20420
|
+
await nodes.flush(source);
|
|
20421
|
+
await nodes.flushLinked(source);
|
|
20422
|
+
const at = fs.resolvePath("/", to);
|
|
20423
|
+
const key = await nodes.entryKey(at);
|
|
20424
|
+
if (await heldAt(fs, nodes, at)) return copyByBytes(this, from, to, options);
|
|
20425
|
+
await nodes.onEntry(key, () => fs.copyFile?.(from, to, options));
|
|
20426
|
+
}
|
|
20427
|
+
} : {}
|
|
20222
20428
|
};
|
|
20223
20429
|
}
|
|
20224
20430
|
function vfsFile(fs, opts, nodes) {
|
|
@@ -21078,7 +21284,7 @@ var WasmProcess = class {
|
|
|
21078
21284
|
} else if (req.create) {
|
|
21079
21285
|
await nodes.onEntry(path, async () => {
|
|
21080
21286
|
const marks = this.options.owners || plain2 !== void 0;
|
|
21081
|
-
const fresh2 = marks && !await
|
|
21287
|
+
const fresh2 = marks && !await present3(fs, path, true);
|
|
21082
21288
|
this.fds.installAt(fd, this.openVfsFile(open, await nodes.identify(path), fs));
|
|
21083
21289
|
await this.fds.get(fd).file.stat?.();
|
|
21084
21290
|
if (fresh2 && plain2 !== void 0) await fs.chmod?.(path, plain2);
|
|
@@ -21097,7 +21303,7 @@ var WasmProcess = class {
|
|
|
21097
21303
|
{ at: path, gen }
|
|
21098
21304
|
);
|
|
21099
21305
|
}
|
|
21100
|
-
if (req.existing && !await
|
|
21306
|
+
if (req.existing && !await present3(fs, path, true)) {
|
|
21101
21307
|
throw new KernelError("ENOENT");
|
|
21102
21308
|
}
|
|
21103
21309
|
} catch (err) {
|
|
@@ -21465,12 +21671,12 @@ var WasmProcess = class {
|
|
|
21465
21671
|
async stillOpen(at, handle) {
|
|
21466
21672
|
if (handle === void 0 || this.keptHandle?.(handle) !== void 0) return;
|
|
21467
21673
|
if (this.holdsHandle?.(handle) !== false) return;
|
|
21468
|
-
if (!await
|
|
21674
|
+
if (!await present3(this.options.fs, at, true)) throw new KernelError("ENOENT");
|
|
21469
21675
|
}
|
|
21470
21676
|
async keptOr(path, handle) {
|
|
21471
21677
|
if (handle !== void 0) return this.keptHandle?.(handle) ?? path;
|
|
21472
21678
|
const kept = this.keptPath?.(path);
|
|
21473
|
-
return kept !== void 0 && !await
|
|
21679
|
+
return kept !== void 0 && !await present3(this.options.fs, path, true) ? kept : path;
|
|
21474
21680
|
}
|
|
21475
21681
|
async promote(req) {
|
|
21476
21682
|
if (!this.fds.get(req.fd).file.held) throw new KernelError("EBADF");
|
|
@@ -26955,7 +27161,8 @@ var Launcher = class {
|
|
|
26955
27161
|
wasm: this.memories.count(),
|
|
26956
27162
|
peers: Number(this.locks.shared?.() === true),
|
|
26957
27163
|
fsCalls: servedFsCalls(),
|
|
26958
|
-
opfsCalls: this.rootFs.opfsCalls?.() ?? 0
|
|
27164
|
+
opfsCalls: this.rootFs.opfsCalls?.() ?? 0,
|
|
27165
|
+
opfsOps: this.rootFs.opfsOps?.() ?? 0
|
|
26959
27166
|
}),
|
|
26960
27167
|
sudo: (call, signal) => this.sudo(pid, call, signal),
|
|
26961
27168
|
crontab: (call) => this.crontab(pid, call),
|