@ai-ecoverse/slicc-kernel 1.85.1 → 1.87.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.
@@ -1984,12 +1984,10 @@ var init_wasi_fds = __esm({
1984
1984
  let fd;
1985
1985
  let kind;
1986
1986
  if (path === SEALED_PATH && openSealed) {
1987
- if (oflags & OFLAGS.DIRECTORY) throw new WasiError("ENOTDIR");
1988
- if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
1989
- fd = openSealed.call(this.kernel.sys);
1987
+ fd = this.openCharDevice(openSealed, oflags, rights);
1990
1988
  kind = "sealed";
1991
1989
  } else if (path === CLIPBOARD_PATH && openClipboard) {
1992
- fd = this.openClipboard(openClipboard, oflags, rights);
1990
+ fd = this.openCharDevice(openClipboard, oflags, rights);
1993
1991
  kind = "clipboard";
1994
1992
  } else if (path === "/dev/tty" || /^\/dev\/tty\d+$/.test(path)) {
1995
1993
  fd = openTty?.call(this.kernel.sys, path === "/dev/tty" ? void 0 : path);
@@ -2000,12 +1998,12 @@ var init_wasi_fds = __esm({
2000
1998
  this.bump();
2001
1999
  return fd;
2002
2000
  }
2003
- openClipboard(openClipboard, oflags, rights) {
2001
+ openCharDevice(openDevice2, oflags, rights) {
2004
2002
  if (oflags & OFLAGS.DIRECTORY) throw new WasiError("ENOTDIR");
2005
2003
  if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
2006
2004
  const want = wantOf(oflags, rights);
2007
2005
  const flags = want === 6 ? O_RDWR : want === 2 ? O_WRONLY : 0;
2008
- return openClipboard.call(this.kernel.sys, flags);
2006
+ return openDevice2.call(this.kernel.sys, flags);
2009
2007
  }
2010
2008
  open(path, oflags, rights, fdflags) {
2011
2009
  const device2 = deviceOf(path);
@@ -2591,7 +2589,7 @@ var init_wasi_host = __esm({
2591
2589
  }
2592
2590
  return path;
2593
2591
  };
2594
- const modeOf = (st) => (st.mode ?? 0) & 4095;
2592
+ const modeOf2 = (st) => (st.mode ?? 0) & 4095;
2595
2593
  const chown = (path, uid, gid, follow2) => {
2596
2594
  const { chown: own } = this.o.fs;
2597
2595
  if (!own) throw new WasiError("ENOSYS");
@@ -2670,7 +2668,7 @@ var init_wasi_host = __esm({
2670
2668
  fd_mode: (fd, out) => {
2671
2669
  const e = fds.get(fd);
2672
2670
  const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
2673
- const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf(this.o.fs.stat(pathOf(fd)));
2671
+ const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf2(this.o.fs.stat(pathOf(fd)));
2674
2672
  mem.view().setUint32(out, mode, true);
2675
2673
  },
2676
2674
  path_mode: (dirfd, p, l, flags, out) => {
@@ -2678,7 +2676,7 @@ var init_wasi_host = __esm({
2678
2676
  if (this.synthetic(path) && deviceOf(path) === void 0)
2679
2677
  return void mem.view().setUint32(out, SEALED_MODE, true);
2680
2678
  const st = flags & AT_SYMLINK_NOFOLLOW ? this.o.fs.lstat(path) : this.o.fs.stat(path);
2681
- mem.view().setUint32(out, modeOf(st), true);
2679
+ mem.view().setUint32(out, modeOf2(st), true);
2682
2680
  }
2683
2681
  });
2684
2682
  }
@@ -3621,7 +3619,7 @@ function importsContext({
3621
3619
  }
3622
3620
  function processes(host, call2, inThread) {
3623
3621
  const close = (fd) => void call2({ op: "fd-close", fd });
3624
- const slot = (n, how, mine, theirs) => {
3622
+ const slot2 = (n, how, mine, theirs) => {
3625
3623
  if (how === "inherit") return { fd: n };
3626
3624
  if (how === "null") return { none: true };
3627
3625
  const [read2, write2] = call2({ op: "fd-pipe" });
@@ -3635,7 +3633,7 @@ function processes(host, call2, inThread) {
3635
3633
  const theirs = [];
3636
3634
  host.fds.promoteFiles();
3637
3635
  try {
3638
- const stdio = STDIO.map((name2, n) => slot(n, o[name2] ?? "inherit", mine, theirs));
3636
+ const stdio = STDIO.map((name2, n) => slot2(n, o[name2] ?? "inherit", mine, theirs));
3639
3637
  const req = {
3640
3638
  op: "proc-spawn",
3641
3639
  file: o.argv[0],
@@ -3822,6 +3820,12 @@ var init_signals = __esm({
3822
3820
  });
3823
3821
 
3824
3822
  // src/process/js/js-kernel.ts
3823
+ function modeOf(mode) {
3824
+ if (!Number.isInteger(mode) || mode < 0 || mode > 4095) {
3825
+ throw new JsCallError("EINVAL", "chmod");
3826
+ }
3827
+ return mode;
3828
+ }
3825
3829
  function callError(result, op) {
3826
3830
  const { errno: errno2, message: message2 } = result;
3827
3831
  const detailed = typeof message2 === "string" && message2 !== errno2 && DETAILED.has(op);
@@ -4075,7 +4079,7 @@ function writable(io, fd) {
4075
4079
  abort: () => io.close(fd)
4076
4080
  });
4077
4081
  }
4078
- function childOps(kernel, io, defaults) {
4082
+ function childOps(kernel, io, defaults, sync) {
4079
4083
  const wait2 = async (pid) => {
4080
4084
  const r = await kernel.blocking({ op: "proc-wait", pid, nohang: false });
4081
4085
  const [, status2] = r.ok && r.kind === "json" ? r.json : [0, 0];
@@ -4095,25 +4099,43 @@ function childOps(kernel, io, defaults) {
4095
4099
  kill: (signal) => kill(pid, signal)
4096
4100
  };
4097
4101
  };
4098
- const spawn = async (o) => {
4102
+ const request = (o) => {
4099
4103
  const [file] = o.argv;
4100
4104
  if (file === void 0) throw new JsCallError("EINVAL", "spawn");
4101
4105
  const group = groupOf(o, "spawn");
4102
4106
  const named = argv0Of(o.argv0, "spawn");
4107
+ return (stdio) => ({
4108
+ op: "proc-spawn",
4109
+ file,
4110
+ argv: [...o.argv],
4111
+ ...named,
4112
+ env: { ...o.env ?? defaults.env },
4113
+ cwd: o.cwd ?? defaults.cwd,
4114
+ stdio,
4115
+ ...group
4116
+ });
4117
+ };
4118
+ const spawnSync = (o) => {
4119
+ const spawning = request(o);
4120
+ const mine = [];
4121
+ const theirs = [];
4122
+ try {
4123
+ const stdio = slotsSync(sync, o, mine, theirs);
4124
+ return childOf(sync.json(spawning(stdio)), mine);
4125
+ } catch (err) {
4126
+ closeAllSync(sync, mine);
4127
+ throw err;
4128
+ } finally {
4129
+ closeAllSync(sync, theirs);
4130
+ }
4131
+ };
4132
+ const spawn = async (o) => {
4133
+ const spawning = request(o);
4103
4134
  const mine = [];
4104
4135
  const theirs = [];
4105
4136
  try {
4106
4137
  const stdio = await slots2(kernel, o, mine, theirs);
4107
- const pid = await kernel.json({
4108
- op: "proc-spawn",
4109
- file,
4110
- argv: [...o.argv],
4111
- ...named,
4112
- env: { ...o.env ?? defaults.env },
4113
- cwd: o.cwd ?? defaults.cwd,
4114
- stdio,
4115
- ...group
4116
- });
4138
+ const pid = await kernel.json(spawning(stdio));
4117
4139
  return childOf(pid, mine);
4118
4140
  } catch (err) {
4119
4141
  await closeAll(io, mine);
@@ -4122,7 +4144,7 @@ function childOps(kernel, io, defaults) {
4122
4144
  await closeAll(io, theirs);
4123
4145
  }
4124
4146
  };
4125
- return { spawn, wait: wait2, kill };
4147
+ return { spawn, wait: wait2, kill, spawnSync };
4126
4148
  }
4127
4149
  function groupOf(o, call2) {
4128
4150
  const { pgid, session } = o;
@@ -4141,27 +4163,43 @@ function argv0Of(argv0, call2) {
4141
4163
  async function closeAll(io, fds) {
4142
4164
  for (const fd of fds) if (fd !== void 0) await io.close(fd).catch(() => void 0);
4143
4165
  }
4144
- async function preflight(kernel, hows) {
4166
+ function closeAllSync(sync, fds) {
4167
+ for (const fd of fds) if (fd !== void 0) sync.raw({ op: "fd-close", fd });
4168
+ }
4169
+ function checked(hows) {
4170
+ const fds = [];
4145
4171
  for (const [n, how] of hows.entries()) {
4146
4172
  if (how === "pipe" || how === "null") continue;
4147
4173
  if (how !== "inherit" && typeof how !== "number") throw new JsCallError("EINVAL", "spawn");
4148
- await kernel.json({ op: "fd-info", fd: how === "inherit" ? n : how });
4174
+ fds.push(how === "inherit" ? n : how);
4149
4175
  }
4176
+ return fds;
4177
+ }
4178
+ async function preflight(kernel, hows) {
4179
+ for (const fd of checked(hows)) await kernel.json({ op: "fd-info", fd });
4180
+ }
4181
+ function slot(n, how, pipe, mine, theirs) {
4182
+ if (how === "inherit") return { fd: n };
4183
+ if (how === "null") return { none: true };
4184
+ if (typeof how === "number") return { fd: how };
4185
+ const [read2, write2] = pipe();
4186
+ mine[n] = n === 0 ? write2 : read2;
4187
+ theirs.push(n === 0 ? read2 : write2);
4188
+ return { fd: n === 0 ? read2 : write2 };
4189
+ }
4190
+ function slotsSync(sync, o, mine, theirs) {
4191
+ const hows = STDIO2.map((name2) => o[name2] ?? "inherit");
4192
+ for (const fd of checked(hows)) sync.json({ op: "fd-info", fd });
4193
+ const pipe = () => sync.json({ op: "fd-pipe" });
4194
+ return hows.map((how, n) => slot(n, how, pipe, mine, theirs));
4150
4195
  }
4151
4196
  async function slots2(kernel, o, mine, theirs) {
4152
4197
  const hows = STDIO2.map((name2) => o[name2] ?? "inherit");
4153
4198
  await preflight(kernel, hows);
4154
4199
  const stdio = [];
4155
4200
  for (const [n, how] of hows.entries()) {
4156
- if (how === "inherit") stdio.push({ fd: n });
4157
- else if (how === "null") stdio.push({ none: true });
4158
- else if (typeof how === "number") stdio.push({ fd: how });
4159
- else {
4160
- const [read2, write2] = await kernel.json({ op: "fd-pipe" });
4161
- mine[n] = n === 0 ? write2 : read2;
4162
- theirs.push(n === 0 ? read2 : write2);
4163
- stdio.push({ fd: n === 0 ? read2 : write2 });
4164
- }
4201
+ const pair = how === "pipe" ? await kernel.json({ op: "fd-pipe" }) : [];
4202
+ stdio.push(slot(n, how, () => pair, mine, theirs));
4165
4203
  }
4166
4204
  return stdio;
4167
4205
  }
@@ -4427,6 +4465,10 @@ function* aliasOf(fd, abs, o) {
4427
4465
  }
4428
4466
  return { fd: copy2, file };
4429
4467
  }
4468
+ function accessFlags(o) {
4469
+ const write2 = o.write === true || o.append === true || o.truncate === true;
4470
+ return write2 ? o.read === true ? 2 : 1 : 0;
4471
+ }
4430
4472
  function* opened(abs, o) {
4431
4473
  const node = yield* lookup(abs);
4432
4474
  if (isExclusive(o)) throw new JsCallError("EEXIST", abs);
@@ -4435,13 +4477,13 @@ function* opened(abs, o) {
4435
4477
  return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
4436
4478
  case "tty":
4437
4479
  return { fd: yield { op: "fd-open-tty" }, file: false };
4438
- case "clipboard": {
4439
- const write2 = o.write === true || o.append === true || o.truncate === true;
4440
- const flags = write2 ? o.read === true ? 2 : 1 : 0;
4441
- return { fd: yield { op: "fd-open-clipboard", flags }, file: false };
4442
- }
4480
+ case "clipboard":
4481
+ return {
4482
+ fd: yield { op: "fd-open-clipboard", flags: accessFlags(o) },
4483
+ file: false
4484
+ };
4443
4485
  case "sealed":
4444
- return { fd: yield { op: "fd-open-sealed" }, file: false };
4486
+ return { fd: yield { op: "fd-open-sealed", flags: accessFlags(o) }, file: false };
4445
4487
  case "terminal": {
4446
4488
  const req = node.pts === void 0 ? { op: "fd-open-tty", name: node.name } : { op: "pty-slave-open", n: node.pts, noctty: true };
4447
4489
  return { fd: yield req, file: false };
@@ -5655,10 +5697,15 @@ function syncPathOps(kernel, resolve, statOf, open) {
5655
5697
  if (inDev(abs)) return devSync(kernel, devReaddir(abs));
5656
5698
  return kernel.json({ op: "readdir", path: abs });
5657
5699
  },
5658
- mkdir: (path) => void kernel.call({ op: "mkdir", path: resolve(path) }),
5700
+ mkdir: (path, options) => void kernel.call({
5701
+ op: "mkdir",
5702
+ path: resolve(path),
5703
+ ...options?.recursive === false ? { exclusive: true } : {}
5704
+ }),
5659
5705
  rm: (path) => void kernel.call({ op: "rm", path: resolve(path) }),
5660
5706
  unlink: (path) => void kernel.call({ op: "unlink", path: resolve(path) }),
5661
5707
  rename: (from, to) => void kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
5708
+ chmod: (path, mode) => void kernel.call({ op: "chmod", path: resolve(path), mode: modeOf(mode) }),
5662
5709
  link: (from, to) => void kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
5663
5710
  symlink: (target, path) => void kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
5664
5711
  readlink(path) {
@@ -6154,6 +6201,7 @@ function createContext(o) {
6154
6201
  const sync = {
6155
6202
  ...syncOps(syncKernel, { pid: o.pid, resolve, random, infos, handles }),
6156
6203
  run: (options) => runSync(syncKernel, { env: o.env, cwd: o.cwd, resolve, signal: signalNumber }, options),
6204
+ spawn: (options) => spawnSync(options),
6157
6205
  exit: (status2 = 0) => {
6158
6206
  exiting ??= status2 & 255;
6159
6207
  return exitAtOnce(lane, [...writes], terminal.modes(), exiting);
@@ -6161,12 +6209,15 @@ function createContext(o) {
6161
6209
  kill: killer({ self: o.pid, kernel, syncKernel, lane, writes, modes: terminal.modes }),
6162
6210
  cred: () => syncKernel.json({ op: "proc-cred" }),
6163
6211
  setcred(change) {
6164
- if (typeof change !== "object" || change === null) throw new JsCallError("EINVAL", "setcred");
6212
+ if (typeof change !== "object" || change === null || Array.isArray(change)) {
6213
+ throw new JsCallError("EINVAL", "setcred");
6214
+ }
6165
6215
  return syncKernel.json({ op: "proc-setcred", change: { ...change } });
6166
6216
  }
6167
6217
  };
6168
6218
  const io = { read: read2, send: writeAll, close: (fd) => ctx.close(fd) };
6169
- const children = childOps(kernel, io, { env: o.env, cwd: o.cwd, signal: signalNumber });
6219
+ const defaults = { env: o.env, cwd: o.cwd, signal: signalNumber };
6220
+ const { spawnSync, ...children } = childOps(kernel, io, defaults, syncKernel);
6170
6221
  const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
6171
6222
  const ctx = {
6172
6223
  argv: o.argv,
@@ -6357,10 +6408,15 @@ function pathOps(kernel, resolve, statOf, open) {
6357
6408
  if (inDev(abs)) return devAsync(kernel, devReaddir(abs));
6358
6409
  return await kernel.json({ op: "readdir", path: abs });
6359
6410
  },
6360
- mkdir: async (path) => void await kernel.call({ op: "mkdir", path: resolve(path) }),
6411
+ mkdir: async (path, options) => void await kernel.call({
6412
+ op: "mkdir",
6413
+ path: resolve(path),
6414
+ ...options?.recursive === false ? { exclusive: true } : {}
6415
+ }),
6361
6416
  rm: async (path) => void await kernel.call({ op: "rm", path: resolve(path) }),
6362
6417
  unlink: async (path) => void await kernel.call({ op: "unlink", path: resolve(path) }),
6363
6418
  rename: async (from, to) => void await kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
6419
+ chmod: async (path, mode) => void await kernel.call({ op: "chmod", path: resolve(path), mode: modeOf(mode) }),
6364
6420
  link: async (from, to) => void await kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
6365
6421
  symlink: async (target, path) => void await kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
6366
6422
  async readlink(path) {
@@ -6617,10 +6673,14 @@ function liveNodePath(node) {
6617
6673
  const root = node.mount.opts.root.replace(/\/+$/, "");
6618
6674
  return parts.length === 0 ? root || "/" : `${root}/${parts.reverse().join("/")}`;
6619
6675
  }
6620
- function modeFromStat(st) {
6676
+ function exactIn(node) {
6677
+ return node?.mount.opts.bridge.owners === true;
6678
+ }
6679
+ function modeFromStat(st, exact = false) {
6621
6680
  const type = st.isSymbolicLink ? S_IFLNK : st.isDirectory ? S_IFDIR : S_IFREG;
6622
6681
  const fallback = st.isDirectory || st.isSymbolicLink ? 511 : 438;
6623
- return type | ((st.mode ?? fallback) & PERM_MASK || fallback);
6682
+ const perm = (st.mode ?? fallback) & PERM_MASK;
6683
+ return type | (exact ? perm : perm || fallback);
6624
6684
  }
6625
6685
  function toMs(v) {
6626
6686
  if (v === void 0 || v === null) return void 0;
@@ -6728,7 +6788,7 @@ function createHelpers(Fs, ops) {
6728
6788
  return { ...stat ? { stat, statAt } : {}, len: 0, loaded: false, dirty: false, openCount: 0 };
6729
6789
  }
6730
6790
  function makeNode(parent, name2, st) {
6731
- const node = Fs.createNode(parent, name2, modeFromStat(st), 0);
6791
+ const node = Fs.createNode(parent, name2, modeFromStat(st, exactIn(parent)), 0);
6732
6792
  node.node_ops = ops.node;
6733
6793
  node.stream_ops = ops.stream;
6734
6794
  node.live = freshState(st);
@@ -6742,7 +6802,7 @@ function createHelpers(Fs, ops) {
6742
6802
  if (!cachedStat(node.live, Fs.isDir(node.mode))) {
6743
6803
  const st = call2(() => bridgeOf(node).lstat(liveNodePath(linked.holder(node))));
6744
6804
  Object.assign(node.live, { stat: st, statAt: syncCallCount() });
6745
- node.mode = modeFromStat(st);
6805
+ node.mode = modeFromStat(st, exactIn(node));
6746
6806
  }
6747
6807
  return node.live.stat;
6748
6808
  }
@@ -7080,9 +7140,21 @@ function createStreamOps(h) {
7080
7140
  }
7081
7141
  return want;
7082
7142
  };
7143
+ const directory = (stream) => {
7144
+ const bridge = bridgeOf(stream.node);
7145
+ if (!bridge.owners || !Fs.isDir(stream.node.mode) || stream.flags & O_PATH) return;
7146
+ try {
7147
+ h.call(
7148
+ () => bridge.access?.(liveNodePath(stream.node), accessOf(wantOf2(stream.flags)), "open")
7149
+ );
7150
+ } catch (err) {
7151
+ if (stream.fd !== void 0) Fs.closeStream?.(stream.fd);
7152
+ throw err;
7153
+ }
7154
+ };
7083
7155
  return {
7084
7156
  open(stream) {
7085
- if (!Fs.isFile(stream.node.mode)) return;
7157
+ if (!Fs.isFile(stream.node.mode)) return directory(stream);
7086
7158
  const s = stream.node.live;
7087
7159
  const created = s.created === true;
7088
7160
  s.created = void 0;
@@ -7214,6 +7286,7 @@ function createLiveVfsPlugin(Fs) {
7214
7286
  const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
7215
7287
  if (!st.isDirectory) throw new Fs.ErrnoError(wasiErrno("ENOTDIR"));
7216
7288
  const root = h.makeNode(null, "/", st);
7289
+ root.mode = modeFromStat(st, mount.opts.bridge.owners === true);
7217
7290
  mounts.add(mount);
7218
7291
  return root;
7219
7292
  }
@@ -7423,7 +7496,7 @@ function useLiveChown(Fs) {
7423
7496
  Fs.chown(target, uid, gid);
7424
7497
  };
7425
7498
  }
7426
- var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE, O_ACCMODE, O_TRUNC, stale;
7499
+ var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE, O_ACCMODE, O_TRUNC, O_PATH, stale;
7427
7500
  var init_live_vfs_fs = __esm({
7428
7501
  "src/realm/live-vfs-fs.ts"() {
7429
7502
  "use strict";
@@ -7443,6 +7516,7 @@ var init_live_vfs_fs = __esm({
7443
7516
  EARLY_WHOLE_FILE = 64 * 1024;
7444
7517
  O_ACCMODE = 3;
7445
7518
  O_TRUNC = 512;
7519
+ O_PATH = 2097152;
7446
7520
  stale = (s) => !!s.orphan && !s.kept;
7447
7521
  }
7448
7522
  });
@@ -7865,7 +7939,7 @@ var init_kernel_streams = __esm({
7865
7939
  openSealed(open, path, flags, mode) {
7866
7940
  const { openSealed } = this.sys;
7867
7941
  if (path !== SEALED_PATH2 || !openSealed) return void 0;
7868
- const kfd = this.call(() => openSealed.call(this.sys));
7942
+ const kfd = this.call(() => openSealed.call(this.sys, flags & 3));
7869
7943
  return this.vessel(open, kfd, { path, flags, mode }, false);
7870
7944
  }
7871
7945
  openClipboard(open, path, flags, mode) {
@@ -8262,7 +8336,7 @@ function pathOpensLinks(Fs) {
8262
8336
  const fs = Fs;
8263
8337
  const { mayOpen, isLink } = fs;
8264
8338
  if (!mayOpen || !isLink) return;
8265
- fs.mayOpen = (node, flags) => flags & O_PATH && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
8339
+ fs.mayOpen = (node, flags) => flags & O_PATH2 && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
8266
8340
  }
8267
8341
  function importKey(namespace, name2, glue) {
8268
8342
  const own = glue?.[name2];
@@ -8739,7 +8813,24 @@ function kernelAccess(imports, fs, memory, glue) {
8739
8813
  }
8740
8814
  });
8741
8815
  }
8816
+ function kernelChdir(Fs) {
8817
+ const { chdir, lookupPath, ErrnoError } = Fs;
8818
+ if (!chdir || !lookupPath || !ErrnoError) return;
8819
+ Fs.chdir = (path) => {
8820
+ const { node } = lookupPath.call(Fs, path, { follow: true });
8821
+ const directory = Fs.isDir?.(node.mode) === true;
8822
+ const bridge = node.live && directory ? node.mount.opts.bridge : void 0;
8823
+ try {
8824
+ bridge?.access?.(liveNodePath(node), X_ACCESS, "eaccess", false);
8825
+ } catch (err) {
8826
+ throw new ErrnoError(errnoOf(err));
8827
+ }
8828
+ chdir.call(Fs, path);
8829
+ };
8830
+ }
8742
8831
  function linuxDevices(Fs) {
8832
+ Fs.ignorePermissions = true;
8833
+ kernelChdir(Fs);
8743
8834
  const { chmod } = Fs;
8744
8835
  if (!chmod) return;
8745
8836
  for (const [path, mode] of DEVICE_MODES) {
@@ -8749,7 +8840,7 @@ function linuxDevices(Fs) {
8749
8840
  }
8750
8841
  }
8751
8842
  }
8752
- 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_PATH, LITERALS, UTIME_NOW, UTIME_OMIT, PROT_WRITE, MAP_PRIVATE, MAP_TYPE, O_WRONLY4, MAP_ALIGN, DIR_MODE, LINK_MODE, CHAR_DEVICE, O_ACCMODE2, O_CREAT2, field, pinnedRoot, rootKind, NAME, AT_FDCWD, AT_EACCESS2, W_ACCESS, DEVICE_MODES;
8843
+ 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_CREAT2, field, pinnedRoot, rootKind, NAME, AT_FDCWD, AT_EACCESS2, W_ACCESS, X_ACCESS, DEVICE_MODES;
8753
8844
  var init_process_fds = __esm({
8754
8845
  "src/process/process-fds.ts"() {
8755
8846
  "use strict";
@@ -8777,7 +8868,7 @@ var init_process_fds = __esm({
8777
8868
  EBADF = 8;
8778
8869
  AT_SYMLINK_NOFOLLOW2 = 256;
8779
8870
  EMSCRIPTEN_EPERM = 63;
8780
- O_PATH = 2097152;
8871
+ O_PATH2 = 2097152;
8781
8872
  LITERALS = {
8782
8873
  openat: "__syscall_openat",
8783
8874
  mkdirat: "__syscall_mkdirat",
@@ -8809,6 +8900,7 @@ var init_process_fds = __esm({
8809
8900
  AT_FDCWD = -100;
8810
8901
  AT_EACCESS2 = 512;
8811
8902
  W_ACCESS = 2;
8903
+ X_ACCESS = 1;
8812
8904
  DEVICE_MODES = [
8813
8905
  ["/", 493],
8814
8906
  ["/dev", 493],
@@ -8899,8 +8991,8 @@ function describeInherited(Fs, sys, streams, livePath, actions = []) {
8899
8991
  const out = [];
8900
8992
  for (const [fd, stream] of slots3) {
8901
8993
  promote(stream);
8902
- const slot = inheritedSlot(fd, stream);
8903
- if (slot) out.push(slot);
8994
+ const slot2 = inheritedSlot(fd, stream);
8995
+ if (slot2) out.push(slot2);
8904
8996
  }
8905
8997
  return out;
8906
8998
  }
@@ -9118,7 +9210,7 @@ function createProcessKernel(deps) {
9118
9210
  const reaped = /* @__PURE__ */ new Map();
9119
9211
  const call2 = (req, label) => transport.call(req, Infinity, label);
9120
9212
  const at = (path) => path === "" || path.startsWith("/") ? path : `${Fs.cwd()}/${path}`;
9121
- const slot = (fd, n, promote) => {
9213
+ const slot2 = (fd, n, promote) => {
9122
9214
  const stream = fd >= 0 ? Fs.getStream(fd) : null;
9123
9215
  if (!stream) return { none: true };
9124
9216
  promote?.(stream);
@@ -9167,7 +9259,7 @@ function createProcessKernel(deps) {
9167
9259
  const unflushed = flushed(deps.beforeSpawn);
9168
9260
  if (unflushed < 0) return unflushed;
9169
9261
  const promote = deps.stdioPromoter?.();
9170
- const stdio = [0, 1, 2].map((n) => slot(fds[n] ?? -1, n, promote));
9262
+ const stdio = [0, 1, 2].map((n) => slot2(fds[n] ?? -1, n, promote));
9171
9263
  const inherit = deps.inherit?.(actions) ?? [];
9172
9264
  const req = {
9173
9265
  op: "proc-spawn",
@@ -10092,8 +10184,8 @@ function kernelSys(transport) {
10092
10184
  openPts(n, noctty) {
10093
10185
  return json2(call2({ op: "pty-slave-open", n, noctty }, `pty-slave-open ${n}`));
10094
10186
  },
10095
- openSealed() {
10096
- return json2(call2({ op: "fd-open-sealed" }, "fd-open-sealed"));
10187
+ openSealed(flags) {
10188
+ return json2(call2({ op: "fd-open-sealed", flags }, "fd-open-sealed"));
10097
10189
  },
10098
10190
  openClipboard(flags) {
10099
10191
  return json2(call2({ op: "fd-open-clipboard", flags }, "fd-open-clipboard"));