@ai-ecoverse/slicc-kernel 1.97.0 → 1.97.2

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.
@@ -4529,7 +4529,7 @@ var KERNEL_VERSION, OS_RELEASE;
4529
4529
  var init_version = __esm({
4530
4530
  "src/version.ts"() {
4531
4531
  "use strict";
4532
- KERNEL_VERSION = true ? "1.97.0" : "0.0.0-dev";
4532
+ KERNEL_VERSION = true ? "1.97.2" : "0.0.0-dev";
4533
4533
  OS_RELEASE = "6.0.0-slicc";
4534
4534
  }
4535
4535
  });
@@ -6417,8 +6417,8 @@ function createSyncFsSabBridge(transport, opts = {}) {
6417
6417
  access: (path, mode, kind = "access", nofollow) => {
6418
6418
  run({ op: "access", path, mode, arg2: kind, ...nofollow ? { nofollow } : {} }, path);
6419
6419
  },
6420
- hold: (path, held, open, handle, want = 0) => {
6421
- const mode = (held ? 1 : 0) | (open ? 2 : 0);
6420
+ hold: (path, held2, open, handle, want = 0) => {
6421
+ const mode = (held2 ? 1 : 0) | (open ? 2 : 0);
6422
6422
  if (mode === 3) return json2({ op: "hold", path, mode: mode | want }, path);
6423
6423
  run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
6424
6424
  return void 0;
@@ -6968,7 +6968,7 @@ function appendThrough(h, stream, bytes) {
6968
6968
  }
6969
6969
  function createStreamOps(h) {
6970
6970
  const { Fs, statOf, ensureLoaded, ensureCapacity, flushNode, bridgeOf, rangedOf } = h;
6971
- const held = (stream, change) => {
6971
+ const held2 = (stream, change) => {
6972
6972
  const s = stream.node.live;
6973
6973
  if ((stream.flags & 3) === 0 || s.orphan) return;
6974
6974
  const before = s.writers ?? 0;
@@ -7049,12 +7049,12 @@ function createStreamOps(h) {
7049
7049
  if (stream.fd !== void 0) Fs.closeStream?.(stream.fd);
7050
7050
  throw err;
7051
7051
  }
7052
- held(stream, 1);
7052
+ held2(stream, 1);
7053
7053
  },
7054
7054
  dup(stream) {
7055
7055
  if (!Fs.isFile(stream.node.mode)) return;
7056
7056
  stream.node.live.openCount++;
7057
- held(stream, 1);
7057
+ held2(stream, 1);
7058
7058
  },
7059
7059
  close(stream) {
7060
7060
  const node = stream.node;
@@ -7062,7 +7062,7 @@ function createStreamOps(h) {
7062
7062
  const s = node.live;
7063
7063
  s.openCount = Math.max(0, s.openCount - 1);
7064
7064
  if (s.openCount > 0) {
7065
- held(stream, -1);
7065
+ held2(stream, -1);
7066
7066
  return;
7067
7067
  }
7068
7068
  try {
@@ -7073,7 +7073,7 @@ function createStreamOps(h) {
7073
7073
  s.ranges = false;
7074
7074
  s.len = 0;
7075
7075
  s.loaded = false;
7076
- held(stream, -1);
7076
+ held2(stream, -1);
7077
7077
  opened2(node, false);
7078
7078
  }
7079
7079
  },
@@ -7261,6 +7261,7 @@ function liveRoot(Fs, bridge) {
7261
7261
  invalidateLiveVfs(Fs, plugin);
7262
7262
  guardRenames(Fs);
7263
7263
  guardKeptNodes(Fs, plugin.handled);
7264
+ guardStaleNodes(Fs, plugin);
7264
7265
  guardStatfs(Fs);
7265
7266
  const memfs = root.memfs ?? root.node_ops;
7266
7267
  const live = plugin.node_ops;
@@ -7328,7 +7329,7 @@ function guardKeptNodes(Fs, handled) {
7328
7329
  const lookupPath = Fs.lookupPath.bind(Fs);
7329
7330
  Fs.open = (path, flags, mode) => {
7330
7331
  const name2 = path.slice(path.lastIndexOf("/") + 1);
7331
- if (![...handled].some((held) => held.name === name2)) return open(path, flags, mode);
7332
+ if (![...handled].some((held2) => held2.name === name2)) return open(path, flags, mode);
7332
7333
  let node;
7333
7334
  try {
7334
7335
  node = lookupPath(path, { follow: true }).node;
@@ -7339,6 +7340,33 @@ function guardKeptNodes(Fs, handled) {
7339
7340
  return open(path, flags, mode);
7340
7341
  };
7341
7342
  }
7343
+ function outdated(node, view, before) {
7344
+ const s = node.live;
7345
+ if (s.named === void 0) {
7346
+ s.named = before;
7347
+ return false;
7348
+ }
7349
+ if (s.named === before) return false;
7350
+ const { now, changed: changed2 } = view.changedSince(s.named, liveNodePath(node));
7351
+ s.named = now;
7352
+ return changed2 && s.openCount === 0 && !s.dirty && node !== node.mount.root && !node.mounted;
7353
+ }
7354
+ function guardStaleNodes(Fs, plugin) {
7355
+ const lookupNode = Fs.lookupNode?.bind(Fs);
7356
+ const forget = Fs.hashRemoveNode?.bind(Fs);
7357
+ if (!lookupNode || !forget || Fs.sliccStale) return;
7358
+ Fs.sliccStale = true;
7359
+ Fs.lookupNode = (parent, name2) => {
7360
+ const view = parent.live ? parent.mount.opts.bridge.changes : void 0;
7361
+ const before = view?.now() ?? 0;
7362
+ const node = lookupNode(parent, name2);
7363
+ if (!view || !ownedBy(plugin, node) || !outdated(node, view, before)) return node;
7364
+ forget(node);
7365
+ const fresh = lookupNode(parent, name2);
7366
+ if (fresh.live) fresh.live.named = before;
7367
+ return fresh;
7368
+ };
7369
+ }
7342
7370
  function guardRenames(Fs) {
7343
7371
  const rename = Fs.rename?.bind(Fs);
7344
7372
  if (!rename || Fs.sliccRename) return;
@@ -7431,8 +7459,8 @@ function linkLive(Fs, from, to, follow2) {
7431
7459
  try {
7432
7460
  bridge.link(path, base === "/" ? `/${name2}` : `${base}/${name2}`);
7433
7461
  } catch (err) {
7434
- const refused2 = toErrno(Fs, err);
7435
- if (refused2.errno !== wasiErrno("EPERM") || linkable(bridge, path)) throw refused2;
7462
+ const refused3 = toErrno(Fs, err);
7463
+ if (refused3.errno !== wasiErrno("EPERM") || linkable(bridge, path)) throw refused3;
7436
7464
  throw new Fs.ErrnoError(wasiErrno("EMLINK"));
7437
7465
  }
7438
7466
  source.live.stat = void 0;
@@ -7480,6 +7508,118 @@ var init_live_vfs_fs = __esm({
7480
7508
  }
7481
7509
  });
7482
7510
 
7511
+ // src/process/process-locks.ts
7512
+ function lockTarget(stream) {
7513
+ if (stream.sliccKernelFile && stream.sliccKernelFd !== void 0) {
7514
+ return { fd: stream.sliccKernelFd };
7515
+ }
7516
+ const node = stream.node;
7517
+ return node.live && node.mount ? { path: liveNodePath(node) } : void 0;
7518
+ }
7519
+ function errnoOf(err) {
7520
+ const code2 = err?.code;
7521
+ if (typeof code2 === "string") return wasiErrno(code2);
7522
+ const errno2 = err?.errno;
7523
+ return typeof errno2 === "number" ? errno2 : wasiErrno("EIO");
7524
+ }
7525
+ function sizeOf(Fs, stream) {
7526
+ const st = Fs.fstat?.(stream.fd);
7527
+ return st?.size ?? 0;
7528
+ }
7529
+ function kindOf(type) {
7530
+ if (type === F_RDLCK) return "read";
7531
+ if (type === F_WRLCK) return "write";
7532
+ return type === F_UNLCK ? "unlock" : void 0;
7533
+ }
7534
+ function readFlock(view, at, base) {
7535
+ const kind = kindOf(view.getInt16(at, true));
7536
+ if (kind === void 0) return void 0;
7537
+ const start2 = base(view.getInt16(at + 2, true)) + Number(view.getBigInt64(at + 8, true));
7538
+ return { kind, start: start2, len: Number(view.getBigInt64(at + 16, true)) };
7539
+ }
7540
+ function writeHolder(view, at, found) {
7541
+ if (!found) {
7542
+ view.setInt16(at, F_UNLCK, true);
7543
+ return;
7544
+ }
7545
+ view.setInt16(at, found.kind === "read" ? F_RDLCK : F_WRLCK, true);
7546
+ view.setInt16(at + 2, 0, true);
7547
+ view.setBigInt64(at + 8, BigInt(found.start), true);
7548
+ view.setBigInt64(at + 16, BigInt(found.len), true);
7549
+ view.setInt32(at + 24, found.pid, true);
7550
+ }
7551
+ function refused2(kind, flags) {
7552
+ const access = flags & O_ACCMODE2;
7553
+ return kind === "write" && access === O_RDONLY || kind === "read" && access === O_WRONLY4;
7554
+ }
7555
+ function baseOf(Fs, stream) {
7556
+ return (whence) => whence === SEEK_CUR2 ? stream.position : whence === SEEK_END2 ? sizeOf(Fs, stream) : 0;
7557
+ }
7558
+ function recordLock(fcntl, deps) {
7559
+ return (fd, cmd, varargs) => {
7560
+ if (cmd !== F_GETLK && cmd !== F_SETLK && cmd !== F_SETLKW) return fcntl(fd, cmd, varargs);
7561
+ const Fs = deps.fs();
7562
+ const buffer = deps.memory();
7563
+ const stream = Fs?.getStream(fd);
7564
+ const target = stream ? lockTarget(stream) : void 0;
7565
+ if (!Fs || !buffer || !stream || !target) return fcntl(fd, cmd, varargs);
7566
+ const view = new DataView(buffer);
7567
+ const at = view.getUint32(varargs, true);
7568
+ const lock = readFlock(view, at, baseOf(Fs, stream));
7569
+ if (!lock || cmd === F_GETLK && lock.kind === "unlock") return -wasiErrno("EINVAL");
7570
+ try {
7571
+ if (cmd === F_GETLK) {
7572
+ writeHolder(
7573
+ view,
7574
+ at,
7575
+ deps.kernel.getLock(target, lock.kind, lock.start, lock.len)
7576
+ );
7577
+ return 0;
7578
+ }
7579
+ if (refused2(lock.kind, stream.flags)) return -wasiErrno("EBADF");
7580
+ if (lock.kind !== "write") deps.flush();
7581
+ deps.kernel.setLock(target, lock.kind, lock.start, lock.len, cmd === F_SETLKW);
7582
+ if (lock.kind !== "unlock") held.set(Fs, true);
7583
+ return 0;
7584
+ } catch (err) {
7585
+ return -errnoOf(err);
7586
+ }
7587
+ };
7588
+ }
7589
+ function closeDropsLocks(Fs, kernel) {
7590
+ const close = Fs.close;
7591
+ if (typeof close !== "function") return;
7592
+ Fs.close = (stream) => {
7593
+ const target = held.has(Fs) && !stream.sliccKernelFile ? lockTarget(stream) : void 0;
7594
+ close.call(Fs, stream);
7595
+ if (!target) return;
7596
+ try {
7597
+ kernel.closeLocks(target);
7598
+ } catch {
7599
+ }
7600
+ };
7601
+ }
7602
+ var F_GETLK, F_SETLK, F_SETLKW, F_RDLCK, F_WRLCK, F_UNLCK, SEEK_CUR2, SEEK_END2, O_ACCMODE2, O_RDONLY, O_WRONLY4, held;
7603
+ var init_process_locks = __esm({
7604
+ "src/process/process-locks.ts"() {
7605
+ "use strict";
7606
+ init_live_vfs_fs();
7607
+ init_wasi_errno();
7608
+ F_GETLK = 12;
7609
+ F_SETLK = 13;
7610
+ F_SETLKW = 14;
7611
+ F_RDLCK = 0;
7612
+ F_WRLCK = 1;
7613
+ F_UNLCK = 2;
7614
+ SEEK_CUR2 = 1;
7615
+ SEEK_END2 = 2;
7616
+ O_ACCMODE2 = 3;
7617
+ O_RDONLY = 0;
7618
+ O_WRONLY4 = 1;
7619
+ held = /* @__PURE__ */ new WeakMap();
7620
+ }
7621
+ });
7622
+
7483
7623
  // src/process/process-pty.ts
7484
7624
  function failed2(e) {
7485
7625
  const code2 = e?.code;
@@ -7635,7 +7775,7 @@ function wrapperFactories(deps) {
7635
7775
  const { pty, timer } = deps;
7636
7776
  return {
7637
7777
  ...timer ? { setitimer: (f) => kernelTimer(f, timer) } : {},
7638
- fcntl: (f) => cloexecFcntl(f, deps),
7778
+ fcntl: (f) => cloexecFcntl(deps.locks ? recordLock(f, { ...deps.locks, fs: deps.fs }) : f, deps),
7639
7779
  pipe2: (f) => cloexecPipe2(f, deps),
7640
7780
  dup3: (f) => cloexecByFlag(quietTarget(f, deps), 2, deps),
7641
7781
  socket: (f) => cloexecByFlag(f, 1, deps),
@@ -7769,7 +7909,7 @@ function noFollowUtimes(imports, fs, glue, memory = () => void 0) {
7769
7909
  }
7770
7910
  );
7771
7911
  }
7772
- function errnoOf(err) {
7912
+ function errnoOf2(err) {
7773
7913
  const { errno: errno2, code: code2 } = err ?? {};
7774
7914
  if (typeof errno2 === "number") return errno2;
7775
7915
  if (typeof code2 === "string") return wasiErrno(code2);
@@ -7804,7 +7944,7 @@ function syncFsync(imports, fs, glue) {
7804
7944
  const result = stream.stream_ops.fsync?.(stream);
7805
7945
  return typeof result === "number" ? result : 0;
7806
7946
  } catch (err) {
7807
- return errnoOf(err);
7947
+ return errnoOf2(err);
7808
7948
  }
7809
7949
  };
7810
7950
  }
@@ -7845,7 +7985,7 @@ function positioned(original, write2, deps) {
7845
7985
  if (moved < len) break;
7846
7986
  }
7847
7987
  } catch (err) {
7848
- return errnoOf(err);
7988
+ return errnoOf2(err);
7849
7989
  }
7850
7990
  view.setUint32(Number(rest2[rest2.length - 1]), done, true);
7851
7991
  return 0;
@@ -7881,7 +8021,7 @@ function useFileMmap(Fs, deps) {
7881
8021
  const shared = (flags & MAP_TYPE) !== MAP_PRIVATE && (prot & PROT_WRITE) !== 0;
7882
8022
  const kfd = stream.sliccKernelFile ? stream.sliccKernelFd : void 0;
7883
8023
  if (shared && kfd !== void 0) throw new Fs.ErrnoError(wasiErrno("ENODEV"));
7884
- if (stream.stream_ops.mmap && kfd === void 0 || !memalign || !memory || length <= 0 || shared || (stream.flags & O_ACCMODE2) === O_WRONLY4 || !Fs.isFile(stream.node.mode)) {
8024
+ if (stream.stream_ops.mmap && kfd === void 0 || !memalign || !memory || length <= 0 || shared || (stream.flags & O_ACCMODE3) === O_WRONLY5 || !Fs.isFile(stream.node.mode)) {
7885
8025
  return mmap.call(fs, stream, length, position, prot, flags);
7886
8026
  }
7887
8027
  const data = staging(Fs, length);
@@ -7894,7 +8034,7 @@ function useFileMmap(Fs, deps) {
7894
8034
  }
7895
8035
  }
7896
8036
  } catch (err) {
7897
- throw new Fs.ErrnoError(errnoOf(err));
8037
+ throw new Fs.ErrnoError(errnoOf2(err));
7898
8038
  }
7899
8039
  const size = Math.ceil(length / MAP_ALIGN) * MAP_ALIGN;
7900
8040
  const ptr = memalign(MAP_ALIGN, size);
@@ -8003,8 +8143,8 @@ function useDevRemoval(Fs) {
8003
8143
  const remove = fs[name2];
8004
8144
  if (typeof remove !== "function") continue;
8005
8145
  fs[name2] = (path) => {
8006
- const refused2 = devRemoval(absoluteOf(path, Fs.cwd()), fs.sliccCred);
8007
- if (refused2) throw new Fs.ErrnoError(wasiErrno(refused2));
8146
+ const refused3 = devRemoval(absoluteOf(path, Fs.cwd()), fs.sliccCred);
8147
+ if (refused3) throw new Fs.ErrnoError(wasiErrno(refused3));
8008
8148
  remove.call(Fs, path);
8009
8149
  };
8010
8150
  }
@@ -8107,7 +8247,7 @@ function useMounts(Fs, env = {}, live = false) {
8107
8247
  const open = Fs.open.bind(Fs);
8108
8248
  Fs.open = (path, flags, mode) => {
8109
8249
  const instead = backing[path];
8110
- if (!instead || (flags & (O_ACCMODE2 | O_CREAT)) !== 0) return open(path, flags, mode);
8250
+ if (!instead || (flags & (O_ACCMODE3 | O_CREAT)) !== 0) return open(path, flags, mode);
8111
8251
  try {
8112
8252
  return open(path, flags, mode);
8113
8253
  } catch (e) {
@@ -8120,14 +8260,14 @@ function cString(memory, at) {
8120
8260
  const bytes = new Uint8Array(memory.buffer, at);
8121
8261
  return new TextDecoder().decode(bytes.subarray(0, bytes.indexOf(0)));
8122
8262
  }
8123
- function baseOf(Fs, dirfd) {
8263
+ function baseOf2(Fs, dirfd) {
8124
8264
  return dirfd === AT_FDCWD ? Fs.cwd?.() ?? "/" : Fs.getStream?.(dirfd)?.path ?? "/";
8125
8265
  }
8126
8266
  function readonlyRefusal(Fs, memory, call2) {
8127
8267
  if (!(call2.amode & W_ACCESS)) return 0;
8128
8268
  try {
8129
8269
  const name2 = cString(memory, call2.path);
8130
- const abs = name2.startsWith("/") ? name2 : `${baseOf(Fs, call2.dirfd)}/${name2}`;
8270
+ const abs = name2.startsWith("/") ? name2 : `${baseOf2(Fs, call2.dirfd)}/${name2}`;
8131
8271
  const follow2 = (call2.flags & AT_SYMLINK_NOFOLLOW2) === 0;
8132
8272
  const { node } = Fs.lookupPath.call(Fs, abs, {
8133
8273
  follow: follow2
@@ -8142,7 +8282,7 @@ function readonlyRefusal(Fs, memory, call2) {
8142
8282
  }
8143
8283
  function kernelChecks(Fs, memory, call2) {
8144
8284
  const name2 = cString(memory, call2.path);
8145
- const abs = name2.startsWith("/") ? name2 : `${baseOf(Fs, call2.dirfd)}/${name2}`;
8285
+ const abs = name2.startsWith("/") ? name2 : `${baseOf2(Fs, call2.dirfd)}/${name2}`;
8146
8286
  const lookupPath = Fs.lookupPath;
8147
8287
  const { node } = lookupPath.call(Fs, abs, { follow: (call2.flags & AT_SYMLINK_NOFOLLOW2) === 0 });
8148
8288
  const bridge = node.live ? node.mount.opts.bridge : void 0;
@@ -8156,14 +8296,14 @@ function kernelAccess(imports, fs, memory, glue) {
8156
8296
  const Fs = fs();
8157
8297
  const heap = memory();
8158
8298
  const call2 = { dirfd, path, amode: amode & 7, flags };
8159
- const refused2 = Fs?.lookupPath && heap ? readonlyRefusal(Fs, heap, call2) : 0;
8160
- if (refused2 !== 0) return refused2;
8299
+ const refused3 = Fs?.lookupPath && heap ? readonlyRefusal(Fs, heap, call2) : 0;
8300
+ if (refused3 !== 0) return refused3;
8161
8301
  const rc = own(dirfd, path, amode, flags);
8162
8302
  if (rc !== 0 || !Fs?.lookupPath || !heap) return rc;
8163
8303
  try {
8164
8304
  return kernelChecks(Fs, heap, { dirfd, path, amode: amode & 7, flags });
8165
8305
  } catch (err) {
8166
- return -errnoOf(err);
8306
+ return -errnoOf2(err);
8167
8307
  }
8168
8308
  });
8169
8309
  }
@@ -8178,7 +8318,7 @@ function kernelLink(imports, fs, memory, glue) {
8178
8318
  if (!Fs?.lookupPath || !heap) return own(olddirfd, oldpath, newdirfd, newpath, flags);
8179
8319
  const at = (dirfd, ptr) => {
8180
8320
  const name2 = cString(heap, ptr);
8181
- return name2.startsWith("/") ? name2 : `${baseOf(Fs, dirfd)}/${name2}`;
8321
+ return name2.startsWith("/") ? name2 : `${baseOf2(Fs, dirfd)}/${name2}`;
8182
8322
  };
8183
8323
  try {
8184
8324
  const from = at(olddirfd, oldpath);
@@ -8186,7 +8326,7 @@ function kernelLink(imports, fs, memory, glue) {
8186
8326
  const follow2 = (flags & AT_SYMLINK_FOLLOW) !== 0;
8187
8327
  if (linkLive(Fs, from, to, follow2)) return 0;
8188
8328
  } catch (err) {
8189
- return -errnoOf(err);
8329
+ return -errnoOf2(err);
8190
8330
  }
8191
8331
  return own(olddirfd, oldpath, newdirfd, newpath, flags);
8192
8332
  },
@@ -8203,7 +8343,7 @@ function kernelChdir(Fs) {
8203
8343
  try {
8204
8344
  bridge?.access?.(liveNodePath(node), X_ACCESS, "eaccess", false);
8205
8345
  } catch (err) {
8206
- throw new ErrnoError(errnoOf(err));
8346
+ throw new ErrnoError(errnoOf2(err));
8207
8347
  }
8208
8348
  chdir.call(Fs, path);
8209
8349
  };
@@ -8220,13 +8360,14 @@ function linuxDevices(Fs) {
8220
8360
  }
8221
8361
  }
8222
8362
  }
8223
- var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, AT_SYMLINK_NOFOLLOW2, EMSCRIPTEN_EPERM, O_PATH2, LITERALS, UTIME_NOW, UTIME_OMIT, PROT_WRITE, MAP_PRIVATE, MAP_TYPE, O_WRONLY4, MAP_ALIGN, DIR_MODE, LINK_MODE, CHAR_DEVICE, O_ACCMODE2, O_CREAT, field, pinnedRoot, rootKind, NAME, AT_FDCWD, AT_EACCESS2, W_ACCESS, X_ACCESS, AT_SYMLINK_FOLLOW, DEVICE_MODES;
8363
+ var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, AT_SYMLINK_NOFOLLOW2, EMSCRIPTEN_EPERM, O_PATH2, LITERALS, UTIME_NOW, UTIME_OMIT, PROT_WRITE, MAP_PRIVATE, MAP_TYPE, O_WRONLY5, MAP_ALIGN, DIR_MODE, LINK_MODE, CHAR_DEVICE, O_ACCMODE3, O_CREAT, field, pinnedRoot, rootKind, NAME, AT_FDCWD, AT_EACCESS2, W_ACCESS, X_ACCESS, AT_SYMLINK_FOLLOW, DEVICE_MODES;
8224
8364
  var init_process_fds = __esm({
8225
8365
  "src/process/process-fds.ts"() {
8226
8366
  "use strict";
8227
8367
  init_dev_removal();
8228
8368
  init_loopback_names();
8229
8369
  init_live_vfs_fs();
8370
+ init_process_locks();
8230
8371
  init_process_pty();
8231
8372
  init_wasi_errno();
8232
8373
  O_CLOEXEC = 524288;
@@ -8269,12 +8410,12 @@ var init_process_fds = __esm({
8269
8410
  PROT_WRITE = 2;
8270
8411
  MAP_PRIVATE = 2;
8271
8412
  MAP_TYPE = 15;
8272
- O_WRONLY4 = 1;
8413
+ O_WRONLY5 = 1;
8273
8414
  MAP_ALIGN = 65536;
8274
8415
  DIR_MODE = 16749;
8275
8416
  LINK_MODE = 41408;
8276
8417
  CHAR_DEVICE = 8630;
8277
- O_ACCMODE2 = 3;
8418
+ O_ACCMODE3 = 3;
8278
8419
  O_CREAT = 64;
8279
8420
  field = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
8280
8421
  rootKind = () => globalThis.navigator?.storage ? "opfs" : "memory";
@@ -8873,10 +9014,10 @@ function procfsBridge(fs, tree) {
8873
9014
  ],
8874
9015
  () => fs.link(from, to, follow2)
8875
9016
  ),
8876
- hold: (p, held, open, handle, want) => {
9017
+ hold: (p, held2, open, handle, want) => {
8877
9018
  if (handle !== void 0 && snapshots.delete(handle)) return void 0;
8878
- if (!held) return fs.hold?.(p, held, open, handle);
8879
- return via(p, snapshot, () => fs.hold?.(p, held, open, void 0, want) ?? late(p));
9019
+ if (!held2) return fs.hold?.(p, held2, open, handle);
9020
+ return via(p, snapshot, () => fs.hold?.(p, held2, open, void 0, want) ?? late(p));
8880
9021
  },
8881
9022
  kept: (handle) => snapshots.has(handle) || fs.kept?.(handle) === true,
8882
9023
  pinned: (handle) => {
@@ -11250,12 +11391,12 @@ function vfsPromoter(Fs, sys, streams, livePath) {
11250
11391
  const version = ranged?.pinnedVersion;
11251
11392
  const pin = ranged && version !== void 0 ? { version, size: ranged.size() } : void 0;
11252
11393
  const handle = stream.node.live?.handle;
11253
- const held = { ...pin ? { pin } : {}, ...handle !== void 0 ? { handle } : {} };
11394
+ const held2 = { ...pin ? { pin } : {}, ...handle !== void 0 ? { handle } : {} };
11254
11395
  kfd = sys.openVfs(
11255
11396
  livePath(stream),
11256
11397
  stream.flags,
11257
11398
  stream.position,
11258
- contents !== void 0 ? { contents, orphan: true } : Object.keys(held).length > 0 ? held : void 0
11399
+ contents !== void 0 ? { contents, orphan: true } : Object.keys(held2).length > 0 ? held2 : void 0
11259
11400
  );
11260
11401
  promoted.set(stream.shared, kfd);
11261
11402
  }
@@ -11284,7 +11425,7 @@ function kernelEntry2(stream, kernel) {
11284
11425
  }
11285
11426
  const device2 = stream.path === void 0 ? void 0 : NAMED_DEVICES[stream.path];
11286
11427
  const kind = stream.sliccKernelFile ? "file" : stream.tty ? "tty" : device2 ?? "stream";
11287
- const access = kind === "tty" ? O_RDWR4 : (stream.flags ?? O_RDWR4) & O_ACCMODE3;
11428
+ const access = kind === "tty" ? O_RDWR4 : (stream.flags ?? O_RDWR4) & O_ACCMODE4;
11288
11429
  return { fd: stream.fd, kernel, kind, flags: access, ...cloexec };
11289
11430
  }
11290
11431
  function describeInherited(Fs, sys, streams, livePath, actions = []) {
@@ -11314,7 +11455,7 @@ function describeInherited(Fs, sys, streams, livePath, actions = []) {
11314
11455
  function deviceOfStream(stream) {
11315
11456
  const device2 = stream.path === void 0 ? void 0 : DEVICES2[stream.path];
11316
11457
  if (!device2 || stream.sliccKernelFd !== void 0) return void 0;
11317
- const access = ACCESS[stream.flags & O_ACCMODE3];
11458
+ const access = ACCESS[stream.flags & O_ACCMODE4];
11318
11459
  return { device: device2, ...access ? { access } : {} };
11319
11460
  }
11320
11461
  function inheritedSlot(fd, stream) {
@@ -11387,13 +11528,13 @@ function restoreForkedStreams(Fs, streams, table) {
11387
11528
  }
11388
11529
  }
11389
11530
  }
11390
- var O_RDWR4, O_ACCMODE3, O_CREAT3, O_EXCL2, O_TRUNC3, PLACEHOLDER_DIR, NAMED_DEVICES, ACCESS, DEVICES2, FIFO_MODE, nextStreamIno, streamInos;
11531
+ var O_RDWR4, O_ACCMODE4, O_CREAT3, O_EXCL2, O_TRUNC3, PLACEHOLDER_DIR, NAMED_DEVICES, ACCESS, DEVICES2, FIFO_MODE, nextStreamIno, streamInos;
11391
11532
  var init_process_fork = __esm({
11392
11533
  "src/process/process-fork.ts"() {
11393
11534
  "use strict";
11394
11535
  init_process_fds();
11395
11536
  O_RDWR4 = 2;
11396
- O_ACCMODE3 = 3;
11537
+ O_ACCMODE4 = 3;
11397
11538
  O_CREAT3 = 64;
11398
11539
  O_EXCL2 = 128;
11399
11540
  O_TRUNC3 = 512;
@@ -11863,7 +12004,7 @@ function socketNode(Fs, addr) {
11863
12004
  const fs = Fs;
11864
12005
  let stream;
11865
12006
  try {
11866
- stream = Fs.open(addr.path, O_WRONLY5 | O_CREAT4 | O_EXCL3, 493);
12007
+ stream = Fs.open(addr.path, O_WRONLY6 | O_CREAT4 | O_EXCL3, 493);
11867
12008
  } catch (e) {
11868
12009
  if (e?.errno === wasiErrno("EEXIST")) {
11869
12010
  throw new SyscallError("EADDRINUSE");
@@ -11995,7 +12136,7 @@ function createSocketKernel(deps) {
11995
12136
  })
11996
12137
  };
11997
12138
  }
11998
- var O_RDWR5, KILLED_BY_SIGPIPE2, O_WRONLY5, O_CREAT4, O_EXCL3;
12139
+ var O_RDWR5, KILLED_BY_SIGPIPE2, O_WRONLY6, O_CREAT4, O_EXCL3;
11999
12140
  var init_process_sockets = __esm({
12000
12141
  "src/process/process-sockets.ts"() {
12001
12142
  "use strict";
@@ -12005,7 +12146,7 @@ var init_process_sockets = __esm({
12005
12146
  init_wasi_errno();
12006
12147
  O_RDWR5 = 2;
12007
12148
  KILLED_BY_SIGPIPE2 = 128 + 13;
12008
- O_WRONLY5 = 1;
12149
+ O_WRONLY6 = 1;
12009
12150
  O_CREAT4 = 64;
12010
12151
  O_EXCL3 = 128;
12011
12152
  }
@@ -12180,6 +12321,16 @@ function kernelSys(transport) {
12180
12321
  mountList() {
12181
12322
  return json2(call2({ op: "mount-list" }, "mount-list"));
12182
12323
  },
12324
+ setLock(target, kind, start2, len, wait2) {
12325
+ const req = { op: "lk-set", ...target, kind, start: start2, len, ...wait2 ? { wait: wait2 } : {} };
12326
+ call2(req, "lk-set");
12327
+ },
12328
+ getLock(target, kind, start2, len) {
12329
+ return json2(call2({ op: "lk-get", ...target, kind, start: start2, len }, "lk-get"));
12330
+ },
12331
+ closeLocks(target) {
12332
+ call2({ op: "lk-close", ...target }, "lk-close");
12333
+ },
12183
12334
  ptyNumber(fd) {
12184
12335
  return json2(call2({ op: "pty-number", fd }, `pty-number ${fd}`));
12185
12336
  },
@@ -12209,7 +12360,7 @@ function openDevice(Fs, fd, meta) {
12209
12360
  return openAt(Fs, fd, `/dev/${meta.device}`, accessMode(meta.access));
12210
12361
  }
12211
12362
  function openHeld(Fs, fd, meta) {
12212
- return "dir" in meta ? openAt(Fs, fd, meta.dir, O_RDONLY | O_DIRECTORY2) : openDevice(Fs, fd, meta);
12363
+ return "dir" in meta ? openAt(Fs, fd, meta.dir, O_RDONLY2 | O_DIRECTORY2) : openDevice(Fs, fd, meta);
12213
12364
  }
12214
12365
  function openAt(Fs, fd, path, flags) {
12215
12366
  let stream;
@@ -12232,7 +12383,7 @@ function wireKernelStdio(Fs, streams, sys) {
12232
12383
  const meta = kind === "device" || kind === "held" ? sys?.heldMeta?.(fd) : void 0;
12233
12384
  if (meta && openHeld(Fs, fd, meta)) continue;
12234
12385
  if (kind && PLACED.has(kind)) {
12235
- const flags = sys?.access ? stream.flags & ~O_ACCMODE4 | accessMode(sys.access(fd)) : stream.flags;
12386
+ const flags = sys?.access ? stream.flags & ~O_ACCMODE5 | accessMode(sys.access(fd)) : stream.flags;
12236
12387
  Fs.closeStream(fd);
12237
12388
  const kernel = { fd, kernel: fd, kind, flags };
12238
12389
  placeKernelStream(Fs, streams, kernel).flags = flags;
@@ -12384,6 +12535,7 @@ async function runWasmProcess(init, port3, deps = {}) {
12384
12535
  fs: () => ownValue(module, "FS"),
12385
12536
  heap: () => memory ? new Int32Array(memory.buffer) : void 0,
12386
12537
  pty: sys,
12538
+ locks: { kernel: sys, memory: () => memory?.buffer, flush: () => early() },
12387
12539
  timer: {
12388
12540
  arm: (ms) => {
12389
12541
  transport.call(
@@ -12441,6 +12593,7 @@ async function runWasmProcess(init, port3, deps = {}) {
12441
12593
  cred: init.owners ? init.cred : void 0
12442
12594
  });
12443
12595
  early = () => signals.quiet(() => vfs.flushDirty());
12596
+ closeDropsLocks(running.FS, sys);
12444
12597
  const sigpipe = () => running.sliccSigpipe?.() === 1;
12445
12598
  const restartable = () => signals.restartable();
12446
12599
  const owners = init.owners ? { owners: true } : {};
@@ -12457,7 +12610,6 @@ async function runWasmProcess(init, port3, deps = {}) {
12457
12610
  atExit = () => streams.exiting();
12458
12611
  useMounts(running.FS, init.env, true);
12459
12612
  useZeroDevices(running.FS);
12460
- useDevRemoval(running.FS);
12461
12613
  useProcfs(running.FS, sys, init.pid);
12462
12614
  if (init.fork) restoreForkedStreams(running.FS, streams, init.fork.streams ?? []);
12463
12615
  else {
@@ -12469,6 +12621,7 @@ async function runWasmProcess(init, port3, deps = {}) {
12469
12621
  streams.useControllingTerminal();
12470
12622
  streams.useKernelFdMetadata();
12471
12623
  useDevFd(running.FS);
12624
+ useDevRemoval(running.FS);
12472
12625
  useFileMmap(running.FS, {
12473
12626
  sys,
12474
12627
  memory: () => memory,
@@ -12568,7 +12721,7 @@ function runMain(running, init) {
12568
12721
  return status2;
12569
12722
  }
12570
12723
  }
12571
- var FS_OPS, O_RDONLY, O_WRONLY6, O_RDWR6, O_ACCMODE4, O_DIRECTORY2, accessMode, PLACED, GLUE_TRAILER, evaluateGlue, EVAL_BLOCKED;
12724
+ var FS_OPS, O_RDONLY2, O_WRONLY7, O_RDWR6, O_ACCMODE5, O_DIRECTORY2, accessMode, PLACED, GLUE_TRAILER, evaluateGlue, EVAL_BLOCKED;
12572
12725
  var init_process_runtime = __esm({
12573
12726
  "src/process/process-runtime.ts"() {
12574
12727
  "use strict";
@@ -12584,18 +12737,19 @@ var init_process_runtime = __esm({
12584
12737
  init_process_fds();
12585
12738
  init_process_fork();
12586
12739
  init_process_http();
12740
+ init_process_locks();
12587
12741
  init_process_signals();
12588
12742
  init_process_sockets();
12589
12743
  init_procfs();
12590
12744
  init_realm_user();
12591
12745
  init_kernel_streams();
12592
12746
  FS_OPS = new Set(SYNC_FS_OPS);
12593
- O_RDONLY = 0;
12594
- O_WRONLY6 = 1;
12747
+ O_RDONLY2 = 0;
12748
+ O_WRONLY7 = 1;
12595
12749
  O_RDWR6 = 2;
12596
- O_ACCMODE4 = 3;
12750
+ O_ACCMODE5 = 3;
12597
12751
  O_DIRECTORY2 = 65536;
12598
- accessMode = (access) => access === "read" ? O_RDONLY : access === "write" ? O_WRONLY6 : O_RDWR6;
12752
+ accessMode = (access) => access === "read" ? O_RDONLY2 : access === "write" ? O_WRONLY7 : O_RDWR6;
12599
12753
  PLACED = /* @__PURE__ */ new Set(["stream", "file", "socket", "clipboard", "sealed"]);
12600
12754
  GLUE_TRAILER = [
12601
12755
  "if (typeof ENV !== 'undefined') Object.assign(ENV, Module.sliccEnv);",
@@ -14704,12 +14858,12 @@ function unsupportedImport(module, memory, extended = false, foreign = {}) {
14704
14858
  const wasix = imports.some((i) => i.module === WASIX);
14705
14859
  const wasi = wasix || imports.some((i) => i.module === PREVIEW1);
14706
14860
  const scope2 = { extended, wasi, wasix, pie: dylinkInfo(module) !== void 0, memory };
14707
- const refused2 = imports.find((imp) => !accepted(imp, scope2));
14708
- if (refused2) {
14709
- if (refused2.kind === "memory" || refused2.module === "wasi") {
14710
- return `imports ${refused2.module}.${refused2.name}: no WASI program this host runs`;
14861
+ const refused3 = imports.find((imp) => !accepted(imp, scope2));
14862
+ if (refused3) {
14863
+ if (refused3.kind === "memory" || refused3.module === "wasi") {
14864
+ return `imports ${refused3.module}.${refused3.name}: no WASI program this host runs`;
14711
14865
  }
14712
- return `imports ${refused2.module}.${refused2.name}: no WASI preview1 program (an Emscripten one runs with its glue)`;
14866
+ return `imports ${refused3.module}.${refused3.name}: no WASI preview1 program (an Emscripten one runs with its glue)`;
14713
14867
  }
14714
14868
  const unanswerable = extended ? void 0 : firstOther(foreign);
14715
14869
  if (unanswerable) return noErrno(unanswerable);
@@ -14770,7 +14924,7 @@ function fillMemory(memory, copy2) {
14770
14924
  if (pages2 > 0) memory.grow(pages2);
14771
14925
  new Uint8Array(memory.buffer).set(copy2);
14772
14926
  }
14773
- function sizeOf(main) {
14927
+ function sizeOf2(main) {
14774
14928
  return () => main.memory?.buffer.byteLength ?? 0;
14775
14929
  }
14776
14930
  function memoryOf(instance, imported) {
@@ -14964,19 +15118,19 @@ async function runWasiProcess(init, port3) {
14964
15118
  call: kernelCall,
14965
15119
  say,
14966
15120
  gate
14967
- } = kernelOf(init, port3, signals, sizeOf(main));
15121
+ } = kernelOf(init, port3, signals, sizeOf2(main));
14968
15122
  const id = identify(transport, init);
14969
15123
  const stats = init.env.SLICC_WASI_STATS === "1" ? new WasiStats() : void 0;
14970
15124
  const call2 = stats ? timedCalls(stats, kernelCall) : kernelCall;
14971
15125
  const { module } = init.program;
14972
- const refused2 = unsupportedImport(
15126
+ const refused3 = unsupportedImport(
14973
15127
  module,
14974
15128
  init.program.memory,
14975
15129
  init.program.imports !== void 0,
14976
15130
  init.program.foreign
14977
15131
  );
14978
- if (refused2) {
14979
- say(refused2);
15132
+ if (refused3) {
15133
+ say(refused3);
14980
15134
  return 126;
14981
15135
  }
14982
15136
  const fork = init.fork?.wasi;
@@ -15017,7 +15171,7 @@ async function runWasiProcess(init, port3) {
15017
15171
  });
15018
15172
  restoreExportedMemory(instance, memory, init);
15019
15173
  main.memory = memoryOf(instance, memory);
15020
- publishMemory(init.sab, sizeOf(main)());
15174
+ publishMemory(init.sab, sizeOf2(main)());
15021
15175
  signals.bind(instance.exports);
15022
15176
  if (importsSigactionHook(module)) signals.useHook();
15023
15177
  if (fork?.signals) signals.restore(fork.signals);
@@ -15361,17 +15515,17 @@ function processEntry(port3, run = runWasmProcess, wasi = loadWasi, js = loadJs,
15361
15515
  message: err instanceof Error ? err.stack ?? err.message : String(err),
15362
15516
  ...code2 === void 0 ? {} : { code: code2 }
15363
15517
  });
15364
- let refused2;
15518
+ let refused3;
15365
15519
  const sealOnce = () => {
15366
- if (refused2 === void 0) {
15520
+ if (refused3 === void 0) {
15367
15521
  try {
15368
15522
  seal();
15369
- refused2 = null;
15523
+ refused3 = null;
15370
15524
  } catch (error) {
15371
- refused2 = { error };
15525
+ refused3 = { error };
15372
15526
  }
15373
15527
  }
15374
- return refused2;
15528
+ return refused3;
15375
15529
  };
15376
15530
  return (data) => {
15377
15531
  const type = data?.type;