@ai-ecoverse/slicc-kernel 1.127.1 → 1.128.1

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/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);
@@ -5703,10 +5709,11 @@ var OpfsFs = class {
5703
5709
  return intents.length;
5704
5710
  }
5705
5711
  async settledRename(path) {
5706
- if (this.renamingDirs.size === 0 || typeof path !== "string") return;
5712
+ if (this.renamingDirs.size === 0 && this.copying.size === 0 || typeof path !== "string")
5713
+ return;
5707
5714
  const at = normalizePath(path);
5708
5715
  for (let real; ; ) {
5709
- const busy = this.renameAt(at) ?? (real === void 0 ? void 0 : this.renameAt(real));
5716
+ const busy = this.busyAt(at) ?? (real === void 0 ? void 0 : this.busyAt(real));
5710
5717
  if (busy) {
5711
5718
  await busy.done;
5712
5719
  continue;
@@ -5717,6 +5724,62 @@ var OpfsFs = class {
5717
5724
  if (real === at) return;
5718
5725
  }
5719
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
+ }
5720
5783
  renameAt(at) {
5721
5784
  for (const m of this.renamingDirs) {
5722
5785
  if (within3(at, m.from) || within3(at, m.to) || at === parentOf4(m.from) || at === parentOf4(m.to))
@@ -5964,6 +6027,7 @@ var READS = [
5964
6027
  "readVersioned"
5965
6028
  ];
5966
6029
  var WRITES = [
6030
+ "copyFile",
5967
6031
  "writeFile",
5968
6032
  "pwrite",
5969
6033
  "truncate",
@@ -7328,7 +7392,7 @@ function satisfies(version, range2) {
7328
7392
  }
7329
7393
 
7330
7394
  // src/version.ts
7331
- var KERNEL_VERSION = true ? "1.127.1" : "0.0.0-dev";
7395
+ var KERNEL_VERSION = true ? "1.128.1" : "0.0.0-dev";
7332
7396
  var OS_RELEASE = "6.0.0-slicc";
7333
7397
  function procVersion() {
7334
7398
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -9593,6 +9657,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
9593
9657
  ...fs.realpath ? { realpath: fs.realpath.bind(fs) } : {},
9594
9658
  ...fs.chown ? { chown: fs.chown.bind(fs) } : {},
9595
9659
  ...fs.createExclusive ? { createExclusive: fs.createExclusive.bind(fs) } : {},
9660
+ ...fs.copyFile ? { copyFile: fs.copyFile.bind(fs) } : {},
9596
9661
  ...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
9597
9662
  ...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
9598
9663
  chmod: (path, mode) => fs.chmod(path, mode),
@@ -9994,6 +10059,12 @@ var FsWatchers = class {
9994
10059
  const overrides = {
9995
10060
  writeFile: content(fs.writeFile.bind(fs), written2),
9996
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
+ } : {},
9997
10068
  mkdir: async (path, options) => {
9998
10069
  const created4 = [];
9999
10070
  if (options?.recursive) {
@@ -10651,6 +10722,33 @@ var FifoTable = class {
10651
10722
  }
10652
10723
  };
10653
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
+
10654
10752
  // src/mount/protocol.ts
10655
10753
  var DRIVER_PROTOCOL = [1, 3];
10656
10754
  function driverVersionError(theirs) {
@@ -11034,12 +11132,12 @@ var MountTable = class {
11034
11132
  }
11035
11133
  list() {
11036
11134
  const mounted = [...this.mounts.values()].map(
11037
- ({ type, source, target, options, state, error, present: present3 }) => ({
11135
+ ({ type, source, target, options, state, error, present: present4 }) => ({
11038
11136
  type,
11039
11137
  source,
11040
11138
  target,
11041
11139
  options: { ...options },
11042
- state: state === "ok" && present3?.() === false ? "nomedium" : state,
11140
+ state: state === "ok" && present4?.() === false ? "nomedium" : state,
11043
11141
  ...error ? { error } : {}
11044
11142
  })
11045
11143
  );
@@ -11714,6 +11812,23 @@ var MountFs = class _MountFs {
11714
11812
  throw err;
11715
11813
  }
11716
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
+ }
11717
11832
  async createExclusive(path, owner, redirects = 0) {
11718
11833
  const exclusive = this.base.createExclusive?.bind(this.base);
11719
11834
  if (!this.at(path) && exclusive) {
@@ -12141,6 +12256,7 @@ var SYNC_FS_OPS = [
12141
12256
  "rm",
12142
12257
  "rename",
12143
12258
  "link",
12259
+ "copy",
12144
12260
  "unlink",
12145
12261
  "rmdir",
12146
12262
  "symlink",
@@ -12340,6 +12456,8 @@ async function run(entry, path, req) {
12340
12456
  case "symlink":
12341
12457
  await fs.symlink(req.arg2 ?? "", path, ownerFor2(entry));
12342
12458
  return done;
12459
+ case "copy":
12460
+ return copyOp(entry, path, req);
12343
12461
  case "mkfifo": {
12344
12462
  const owner = ownerFor2(entry, req.mode ?? 438) ?? { uid: 0, gid: 0 };
12345
12463
  await createExclusive(fs, path, { ...owner, fifo: true });
@@ -12446,6 +12564,16 @@ async function guard(g, path, req, cwd) {
12446
12564
  const toWalked = await walkSafe(g, to, false);
12447
12565
  return { path: fromWalked, arg2: toWalked };
12448
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
+ }
12449
12577
  case "link": {
12450
12578
  const to = other();
12451
12579
  const follow2 = req.mode === 1;
@@ -12546,6 +12674,9 @@ async function mayChange(entry, path, req) {
12546
12674
  const { mayChange: mayChange2 } = entry.fs;
12547
12675
  if (!mayChange2) return;
12548
12676
  const { op } = req;
12677
+ if (op === "copy") {
12678
+ return mayChange2.call(entry.fs, entry.fs.resolvePath(entry.cwd, req.arg2 ?? ""), false);
12679
+ }
12549
12680
  if (CONTENT.has(op) && req.handle === void 0) return mayChange2.call(entry.fs, path, true);
12550
12681
  if (!CHANGING.has(op)) return;
12551
12682
  const follow2 = op === "utimes" || op === "chmod" || op === "chown";
@@ -12569,6 +12700,17 @@ async function guarded(entry, path, req) {
12569
12700
  return { refused: refused3 };
12570
12701
  }
12571
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
+ }
12572
12714
  async function createExclusive(fs, path, owner) {
12573
12715
  if (fs.createExclusive) return fs.createExclusive(path, owner);
12574
12716
  if (await fs.lstat(path).then(
@@ -12743,7 +12885,7 @@ var CREATIONS = /* @__PURE__ */ new Set([
12743
12885
  "create",
12744
12886
  "mkfifo"
12745
12887
  ]);
12746
- var NAMING = /* @__PURE__ */ new Set(["link", "rename"]);
12888
+ var NAMING = /* @__PURE__ */ new Set(["link", "rename", "copy"]);
12747
12889
  async function newDevName(entry, path, req) {
12748
12890
  const named = NAMING.has(req.op);
12749
12891
  if (!named && !CREATIONS.has(req.op)) return void 0;
@@ -19862,7 +20004,7 @@ var VfsNodes = class {
19862
20004
  if (held) throw fsError("EEXIST", path);
19863
20005
  const exclusive = this.fs.createExclusive;
19864
20006
  if (exclusive) return exclusive.call(this.fs, path, owner);
19865
- if (await present2(this.fs, path)) throw fsError("EEXIST", path);
20007
+ if (await present3(this.fs, path)) throw fsError("EEXIST", path);
19866
20008
  await this.fs.writeFile(path, new Uint8Array(0), owner);
19867
20009
  });
19868
20010
  }
@@ -20093,7 +20235,7 @@ var VfsNodes = class {
20093
20235
  }
20094
20236
  }
20095
20237
  };
20096
- async function present2(fs, path, follow2 = false) {
20238
+ async function present3(fs, path, follow2 = false) {
20097
20239
  const look = (follow2 ? void 0 : fs.lstat) ?? fs.stat;
20098
20240
  try {
20099
20241
  await (look ? look.call(fs, path) : fs.readFileBuffer(path));
@@ -20271,7 +20413,18 @@ function keepingOpen(fs, nodes, changed = () => {
20271
20413
  await nodes.onEntry(key, () => fs.link(from, to, follow2));
20272
20414
  await nodes.linked(at, key);
20273
20415
  },
20274
- 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
+ } : {}
20275
20428
  };
20276
20429
  }
20277
20430
  function vfsFile(fs, opts, nodes) {
@@ -21131,7 +21284,7 @@ var WasmProcess = class {
21131
21284
  } else if (req.create) {
21132
21285
  await nodes.onEntry(path, async () => {
21133
21286
  const marks = this.options.owners || plain2 !== void 0;
21134
- const fresh2 = marks && !await present2(fs, path, true);
21287
+ const fresh2 = marks && !await present3(fs, path, true);
21135
21288
  this.fds.installAt(fd, this.openVfsFile(open, await nodes.identify(path), fs));
21136
21289
  await this.fds.get(fd).file.stat?.();
21137
21290
  if (fresh2 && plain2 !== void 0) await fs.chmod?.(path, plain2);
@@ -21150,7 +21303,7 @@ var WasmProcess = class {
21150
21303
  { at: path, gen }
21151
21304
  );
21152
21305
  }
21153
- if (req.existing && !await present2(fs, path, true)) {
21306
+ if (req.existing && !await present3(fs, path, true)) {
21154
21307
  throw new KernelError("ENOENT");
21155
21308
  }
21156
21309
  } catch (err) {
@@ -21518,12 +21671,12 @@ var WasmProcess = class {
21518
21671
  async stillOpen(at, handle) {
21519
21672
  if (handle === void 0 || this.keptHandle?.(handle) !== void 0) return;
21520
21673
  if (this.holdsHandle?.(handle) !== false) return;
21521
- if (!await present2(this.options.fs, at, true)) throw new KernelError("ENOENT");
21674
+ if (!await present3(this.options.fs, at, true)) throw new KernelError("ENOENT");
21522
21675
  }
21523
21676
  async keptOr(path, handle) {
21524
21677
  if (handle !== void 0) return this.keptHandle?.(handle) ?? path;
21525
21678
  const kept = this.keptPath?.(path);
21526
- return kept !== void 0 && !await present2(this.options.fs, path, true) ? kept : path;
21679
+ return kept !== void 0 && !await present3(this.options.fs, path, true) ? kept : path;
21527
21680
  }
21528
21681
  async promote(req) {
21529
21682
  if (!this.fds.get(req.fd).file.held) throw new KernelError("EBADF");