@ai-ecoverse/slicc-kernel 1.90.0 → 1.92.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.
@@ -44,17 +44,20 @@ function hide(target, names) {
44
44
  }
45
45
  function vacate(target, names) {
46
46
  for (const name2 of names) {
47
- for (let at = target; at && at !== Object.prototype; ) {
48
- if (Object.getOwnPropertyDescriptor(at, name2)?.configurable) Reflect.deleteProperty(at, name2);
49
- at = Object.getPrototypeOf(at);
47
+ const holders = chain(target);
48
+ for (const holder of holders) {
49
+ if (Object.getOwnPropertyDescriptor(holder, name2)?.configurable) {
50
+ Reflect.deleteProperty(holder, name2);
51
+ }
50
52
  }
51
- Reflect.defineProperty(target, name2, {
53
+ const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name2));
54
+ const opened2 = Reflect.defineProperty(target, name2, {
52
55
  value: void 0,
53
56
  writable: true,
54
57
  enumerable: false,
55
58
  configurable: true
56
59
  });
57
- if (Reflect.get(target, name2) !== void 0) {
60
+ if (kept || !opened2 || Reflect.get(target, name2) !== void 0) {
58
61
  throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
59
62
  }
60
63
  }
@@ -80,7 +83,6 @@ var init_lockdown = __esm({
80
83
  "cookieStore",
81
84
  "Worker",
82
85
  "SharedWorker",
83
- "BroadcastChannel",
84
86
  "postMessage",
85
87
  "close",
86
88
  "webkitRequestFileSystem",
@@ -97,7 +99,7 @@ var init_lockdown = __esm({
97
99
  "hid",
98
100
  "serial"
99
101
  ];
100
- OPEN_SLOTS = ["fetch", "WebSocket"];
102
+ OPEN_SLOTS = ["fetch", "WebSocket", "BroadcastChannel"];
101
103
  }
102
104
  });
103
105
 
@@ -2305,34 +2307,40 @@ function readyEvents(subs, ready) {
2305
2307
  hangup: ready.hangup?.includes(s.fd) === true
2306
2308
  }));
2307
2309
  }
2310
+ function selectOnce(deps, read2, write2, timeoutMs) {
2311
+ try {
2312
+ const ready = deps.kernel.call({ op: "fd-select", read: read2, write: write2, timeoutMs });
2313
+ return { ready, interrupted: false };
2314
+ } catch (e) {
2315
+ if (!deps.interruptWakes || e.code !== "EINTR") throw e;
2316
+ return { ready: { read: [], write: [] }, interrupted: true };
2317
+ }
2318
+ }
2319
+ function waitEvents(deps, subs, { events, read: read2, write: write2 }, entered) {
2320
+ const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
2321
+ const timeout = () => {
2322
+ if (events.length > 0 || entered) return 0;
2323
+ return earliest === Infinity ? -1 : Math.max(0, Math.ceil(earliest - performance.now()));
2324
+ };
2325
+ for (; ; ) {
2326
+ const { ready, interrupted } = selectOnce(deps, read2, write2, timeout());
2327
+ events.push(...readyEvents(subs, ready));
2328
+ if (interrupted) return true;
2329
+ if (events.length > 0 || entered || earliest === Infinity) return false;
2330
+ if (performance.now() >= earliest) return false;
2331
+ }
2332
+ }
2308
2333
  function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
2309
2334
  if (nsubs === 0) return E.INVAL;
2310
- const { mem, kernel } = deps;
2335
+ const { mem } = deps;
2311
2336
  const subs = readSubscriptions(mem, inPtr, nsubs, deps.now);
2312
- const { events, read: read2, write: write2 } = classify(deps.fds, subs);
2313
- let interrupted = false;
2314
- const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
2315
- const expired = () => performance.now() >= earliest;
2316
- if (read2.length > 0 || write2.length > 0 || events.length === 0) {
2317
- do {
2318
- let timeoutMs = -1;
2319
- if (events.length > 0) timeoutMs = 0;
2320
- else if (earliest !== Infinity)
2321
- timeoutMs = Math.max(0, Math.ceil(earliest - performance.now()));
2322
- let ready;
2323
- try {
2324
- ready = kernel.call({ op: "fd-select", read: read2, write: write2, timeoutMs });
2325
- } catch (e) {
2326
- if (!deps.interruptWakes || e.code !== "EINTR") throw e;
2327
- interrupted = true;
2328
- ready = { read: [], write: [] };
2329
- }
2330
- events.push(
2331
- ...readyEvents(subs, ready)
2332
- );
2333
- } while (events.length === 0 && !interrupted && earliest !== Infinity && !expired());
2334
- }
2337
+ const found = classify(deps.fds, subs);
2338
+ const { events, read: read2, write: write2 } = found;
2339
+ const entered = deps.entered === true && deps.interruptWakes !== true;
2340
+ const waits = read2.length > 0 || write2.length > 0 || events.length === 0;
2341
+ const interrupted = waits && waitEvents(deps, subs, found, entered);
2335
2342
  const after = performance.now();
2343
+ if (entered && events.length === 0 && !subs.some((s) => s.deadline <= after)) return E.INTR;
2336
2344
  for (const s of subs) {
2337
2345
  if (s.type === EVENTTYPE.CLOCK && (interrupted || s.deadline <= after)) {
2338
2346
  events.push({ userdata: s.userdata, error: E.SUCCESS, type: s.type });
@@ -2538,6 +2546,7 @@ var init_wasi_host = __esm({
2538
2546
  cache;
2539
2547
  startCwd;
2540
2548
  interruptWakes = false;
2549
+ entered = false;
2541
2550
  onRaise;
2542
2551
  muted;
2543
2552
  signals;
@@ -2761,7 +2770,8 @@ var init_wasi_host = __esm({
2761
2770
  fds: this.fds,
2762
2771
  kernel: this.o.kernel,
2763
2772
  now: (id) => this.now(id),
2764
- interruptWakes: this.interruptWakes
2773
+ interruptWakes: this.interruptWakes,
2774
+ entered: this.entered
2765
2775
  },
2766
2776
  inPtr,
2767
2777
  outPtr,
@@ -2778,7 +2788,7 @@ var init_wasi_host = __esm({
2778
2788
  this.mem.view().setUint32(nevents, 0, true);
2779
2789
  if (mask.deliverUnblocked()) return E.INTR;
2780
2790
  if (n > 0) return this.poll(inPtr, outPtr, n, nevents);
2781
- return this.suspend();
2791
+ return this.entered ? E.INTR : this.suspend();
2782
2792
  } finally {
2783
2793
  mask.deliverUnblocked();
2784
2794
  mask.restore(old);
@@ -3630,6 +3640,7 @@ function importsContext({
3630
3640
  fs,
3631
3641
  fds,
3632
3642
  syscall: call2,
3643
+ net: network(raw, call2),
3633
3644
  ...processes(host, call2, tid !== MAIN_TID),
3634
3645
  async: {
3635
3646
  submit: (req) => call2({ op: "async-submit", req }),
@@ -3665,6 +3676,30 @@ function importsContext({
3665
3676
  gid: { get: () => live().gid, enumerable: true }
3666
3677
  });
3667
3678
  }
3679
+ function loopbackHost(host) {
3680
+ if (host === "localhost") return "127.0.0.1";
3681
+ if (typeof host === "string" && LOOPBACK.test(host)) return host;
3682
+ throw new WasiError("EINVAL");
3683
+ }
3684
+ function network(raw, call2) {
3685
+ return {
3686
+ connect({ host, port: port3, nonblock = false }) {
3687
+ const to = loopbackHost(host);
3688
+ if (!Number.isInteger(port3) || port3 < 1 || port3 > 65535) throw new WasiError("EINVAL");
3689
+ const fd = call2({ op: "sock-open", domain: "inet" });
3690
+ const addr = { family: "inet", host: to, port: port3 };
3691
+ const r = raw({ op: "sock-connect", fd, addr, ...nonblock ? { nonblock: true } : {} });
3692
+ if (r.ok || nonblock && r.errno === "EINPROGRESS") return fd;
3693
+ raw({ op: "fd-close", fd });
3694
+ throw new WasiError(r.errno);
3695
+ },
3696
+ ready(fd) {
3697
+ const sel = call2({ op: "fd-select", read: [], write: [fd], timeoutMs: 0 });
3698
+ if (!sel.write.includes(fd)) return E.INPROGRESS;
3699
+ return call2({ op: "sock-getopt", fd, level: SOL_SOCKET, name: SO_ERROR });
3700
+ }
3701
+ };
3702
+ }
3668
3703
  function processes(host, call2, inThread) {
3669
3704
  const close = (fd) => void call2({ op: "fd-close", fd });
3670
3705
  const slot2 = (n, how, mine, theirs) => {
@@ -3722,7 +3757,7 @@ function processes(host, call2, inThread) {
3722
3757
  }
3723
3758
  };
3724
3759
  }
3725
- var UID, STDIO;
3760
+ var UID, LOOPBACK, SOL_SOCKET, SO_ERROR, STDIO;
3726
3761
  var init_wasi_imports = __esm({
3727
3762
  "src/process/wasi/wasi-imports.ts"() {
3728
3763
  "use strict";
@@ -3731,6 +3766,9 @@ var init_wasi_imports = __esm({
3731
3766
  init_wasi_threads();
3732
3767
  init_wasix_process();
3733
3768
  UID = 1e3;
3769
+ LOOPBACK = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
3770
+ SOL_SOCKET = 1;
3771
+ SO_ERROR = 4;
3734
3772
  STDIO = ["stdin", "stdout", "stderr"];
3735
3773
  }
3736
3774
  });
@@ -3876,12 +3914,19 @@ var KERNEL_VERSION, OS_RELEASE;
3876
3914
  var init_version = __esm({
3877
3915
  "src/version.ts"() {
3878
3916
  "use strict";
3879
- KERNEL_VERSION = true ? "1.90.0" : "0.0.0-dev";
3917
+ KERNEL_VERSION = true ? "1.92.0" : "0.0.0-dev";
3880
3918
  OS_RELEASE = "6.0.0-slicc";
3881
3919
  }
3882
3920
  });
3883
3921
 
3884
3922
  // src/process/js/js-kernel.ts
3923
+ function umaskRequest(mask) {
3924
+ if (mask === void 0) return { op: "proc-umask" };
3925
+ if (!Number.isInteger(mask) || mask < 0 || mask > 511) {
3926
+ throw new JsCallError("EINVAL", "umask");
3927
+ }
3928
+ return { op: "proc-umask", mask };
3929
+ }
3885
3930
  function modeOf(mode) {
3886
3931
  if (!Number.isInteger(mode) || mode < 0 || mode > 4095) {
3887
3932
  throw new JsCallError("EINVAL", "chmod");
@@ -4363,7 +4408,8 @@ function openRequest(abs, o) {
4363
4408
  flags: flagsOf(o),
4364
4409
  position: 0,
4365
4410
  ...isExclusive(o) ? { exclusive: true } : o.create ? { create: true } : { existing: true },
4366
- ...o.truncate ? { truncate: true } : {}
4411
+ ...o.truncate ? { truncate: true } : {},
4412
+ ...o.create || isExclusive(o) ? { mode: o.mode === void 0 ? 438 : modeOf(o.mode) } : {}
4367
4413
  };
4368
4414
  }
4369
4415
  function index2(n, what) {
@@ -4812,6 +4858,52 @@ var init_js_exit = __esm({
4812
4858
  }
4813
4859
  });
4814
4860
 
4861
+ // src/kernel/net/loopback-names.ts
4862
+ function isKernelLoopbackHost(hostname) {
4863
+ const host = hostname.replace(/^\[(.*)\]$/, "$1").replace(/\.$/, "").toLowerCase();
4864
+ return host === "localhost" || host.endsWith(".localhost") || host === "0.0.0.0" || LOOPBACK_V4.test(host) || LOOPBACK_V6.has(host) || MAPPED_V4.test(host);
4865
+ }
4866
+ function reserved(name2) {
4867
+ const lower = name2.toLowerCase();
4868
+ return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
4869
+ }
4870
+ function isHostname(name2) {
4871
+ if (typeof name2 !== "string" || name2.length > 253 || reserved(name2)) return false;
4872
+ return name2.split(".").every((l) => LABEL.test(l));
4873
+ }
4874
+ function hostnameOf(env) {
4875
+ return isHostname(env.HOSTNAME) ? env.HOSTNAME : DEFAULT_HOSTNAME;
4876
+ }
4877
+ function ownNames(hostname) {
4878
+ return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
4879
+ }
4880
+ function hostsFile(hostname = DEFAULT_HOSTNAME) {
4881
+ return [
4882
+ "127.0.0.1 localhost localhost.localdomain",
4883
+ "::1 localhost ip6-localhost",
4884
+ `${HOSTNAME_ADDRESS} ${ownNames(hostname).join(" ")}`,
4885
+ `${HOST_LOOPBACK_ADDRESS.join(".")} ${HOST_LOOPBACK}`,
4886
+ ""
4887
+ ].join("\n");
4888
+ }
4889
+ var HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS, PAGE_LOOPBACK, PAGE_LOOPBACK_URL, LOOPBACK_V4, LOOPBACK_V6, MAPPED_V4, DEFAULT_HOSTNAME, HOSTNAME_ADDRESS, LIBC_HOSTNAMES, LABEL;
4890
+ var init_loopback_names = __esm({
4891
+ "src/kernel/net/loopback-names.ts"() {
4892
+ "use strict";
4893
+ HOST_LOOPBACK = "host.slicc.internal";
4894
+ HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
4895
+ PAGE_LOOPBACK = "kernel.localhost";
4896
+ PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
4897
+ LOOPBACK_V4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
4898
+ LOOPBACK_V6 = /* @__PURE__ */ new Set(["::1", "::", "0:0:0:0:0:0:0:1"]);
4899
+ MAPPED_V4 = /^::ffff:7f[0-9a-f]{2}:[0-9a-f]{1,4}$/;
4900
+ DEFAULT_HOSTNAME = "slicc";
4901
+ HOSTNAME_ADDRESS = "127.0.1.1";
4902
+ LIBC_HOSTNAMES = ["emscripten", "wasmer.sh"];
4903
+ LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
4904
+ }
4905
+ });
4906
+
4815
4907
  // src/process/js/js-fetch.ts
4816
4908
  function withoutFragment(url) {
4817
4909
  url.hash = "";
@@ -4826,11 +4918,20 @@ function plain(status2, text) {
4826
4918
  headers: { "content-type": "text/plain; charset=utf-8" }
4827
4919
  });
4828
4920
  }
4921
+ function local2(url) {
4922
+ return isKernelLoopbackHost(new URL(url).hostname);
4923
+ }
4829
4924
  function rewrite(hop, status2, location) {
4830
4925
  const next2 = new URL(location, hop.url);
4831
4926
  if (next2.protocol !== "http:" && next2.protocol !== "https:") {
4832
4927
  throw failed(new JsCallError("EPROTONOSUPPORT", next2.protocol));
4833
4928
  }
4929
+ if (local2(next2.href) && !local2(hop.url)) {
4930
+ const from = new URL(hop.url).origin;
4931
+ throw failed(
4932
+ new JsCallError("EACCES", `a redirect from ${from} into the kernel's loopback: ${next2.href}`)
4933
+ );
4934
+ }
4834
4935
  const toGet = (status2 === 301 || status2 === 302) && hop.method === "POST" || status2 === 303 && hop.method !== "GET" && hop.method !== "HEAD";
4835
4936
  const crossOrigin = next2.origin !== new URL(hop.url).origin;
4836
4937
  const headers = hop.headers.filter(
@@ -4999,13 +5100,15 @@ async function bodyOf(request, cap, signal) {
4999
5100
  return out;
5000
5101
  }
5001
5102
  function fetchOp(kernel) {
5002
- let traits;
5003
- const traitsOf = () => {
5004
- traits ??= kernel.json({ op: "net-traits" });
5005
- traits.catch(() => {
5006
- traits = void 0;
5103
+ const traits = /* @__PURE__ */ new Map();
5104
+ const traitsOf = (url) => {
5105
+ const own = local2(url);
5106
+ const known = traits.get(own) ?? kernel.json({ op: "net-traits", url });
5107
+ traits.set(own, known);
5108
+ known.catch(() => {
5109
+ traits.delete(own);
5007
5110
  });
5008
- return traits;
5111
+ return known;
5009
5112
  };
5010
5113
  const close = (handle) => kernel.raw({ op: "net-close", handle });
5011
5114
  const send = async (hop, signal) => {
@@ -5092,6 +5195,13 @@ function fetchOp(kernel) {
5092
5195
  });
5093
5196
  return withMeta(response, head.url, redirected);
5094
5197
  };
5198
+ const traitsAt = (at) => traitsOf(at).catch((err) => {
5199
+ throw failed(err);
5200
+ });
5201
+ const redirect = async (hop, status2, location, known) => {
5202
+ const next2 = rewrite(hop, status2, location);
5203
+ return [next2, local2(next2.url) === local2(hop.url) ? known : await traitsAt(next2.url)];
5204
+ };
5095
5205
  return async (input, init) => {
5096
5206
  const request = new Request(input, init);
5097
5207
  const { signal } = request;
@@ -5101,9 +5211,7 @@ function fetchOp(kernel) {
5101
5211
  if (protocol !== "http:" && protocol !== "https:") {
5102
5212
  throw failed(new JsCallError("EPROTONOSUPPORT", protocol));
5103
5213
  }
5104
- const known = await traitsOf().catch((err) => {
5105
- throw failed(err);
5106
- });
5214
+ let known = await traitsAt(request.url);
5107
5215
  if (!known.manualRedirects && request.redirect !== "follow") {
5108
5216
  throw failed(new JsCallError("ENOTSUP", `redirect: ${request.redirect}`));
5109
5217
  }
@@ -5129,7 +5237,7 @@ function fetchOp(kernel) {
5129
5237
  await close(head.handle);
5130
5238
  if (request.redirect === "error") throw failed(new JsCallError("EREDIRECT", hop.url));
5131
5239
  if (hops >= MAX_REDIRECTS) throw failed(new JsCallError("ELOOP", hop.url));
5132
- hop = rewrite(hop, head.status, location);
5240
+ [hop, known] = await redirect(hop, head.status, location, known);
5133
5241
  }
5134
5242
  };
5135
5243
  }
@@ -5137,6 +5245,7 @@ var CHUNK2, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTI
5137
5245
  var init_js_fetch = __esm({
5138
5246
  "src/process/js/js-fetch.ts"() {
5139
5247
  "use strict";
5248
+ init_loopback_names();
5140
5249
  init_js_kernel();
5141
5250
  CHUNK2 = 64 * 1024;
5142
5251
  MAX_REDIRECTS = 20;
@@ -5176,7 +5285,7 @@ function port(n) {
5176
5285
  function netOps(kernel, io) {
5177
5286
  const name2 = async (fd, peer) => addressOf(await kernel.json({ op: "sock-name", fd, peer }));
5178
5287
  const connection = async (fd) => {
5179
- const [local2, remote] = [await name2(fd, false), await name2(fd, true)];
5288
+ const [local3, remote] = [await name2(fd, false), await name2(fd, true)];
5180
5289
  const stop = new AbortController();
5181
5290
  let closed;
5182
5291
  const close = () => {
@@ -5201,7 +5310,7 @@ function netOps(kernel, io) {
5201
5310
  close: async () => void await shut(SHUT_WR),
5202
5311
  abort: () => close()
5203
5312
  });
5204
- return { fd, local: local2, remote, readable: readable3, writable: writable2, close };
5313
+ return { fd, local: local3, remote, readable: readable3, writable: writable2, close };
5205
5314
  };
5206
5315
  const resolve = async (host, signal) => {
5207
5316
  if (IPV4.test(host)) return host;
@@ -5277,8 +5386,8 @@ function netOps(kernel, io) {
5277
5386
  const failed5 = await kernel.json({
5278
5387
  op: "sock-getopt",
5279
5388
  fd,
5280
- level: SOL_SOCKET,
5281
- name: SO_ERROR
5389
+ level: SOL_SOCKET2,
5390
+ name: SO_ERROR2
5282
5391
  });
5283
5392
  if (failed5 !== 0) throw new JsCallError(errnoName(failed5), "connect");
5284
5393
  return connection(fd);
@@ -5286,7 +5395,7 @@ function netOps(kernel, io) {
5286
5395
  }
5287
5396
  };
5288
5397
  }
5289
- var SHUT_RD, SHUT_WR, IPV4, NEVER, SOL_SOCKET, SO_ERROR;
5398
+ var SHUT_RD, SHUT_WR, IPV4, NEVER, SOL_SOCKET2, SO_ERROR2;
5290
5399
  var init_js_net = __esm({
5291
5400
  "src/process/js/js-net.ts"() {
5292
5401
  "use strict";
@@ -5296,47 +5405,8 @@ var init_js_net = __esm({
5296
5405
  SHUT_WR = 1;
5297
5406
  IPV4 = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
5298
5407
  NEVER = new AbortController().signal;
5299
- SOL_SOCKET = 1;
5300
- SO_ERROR = 4;
5301
- }
5302
- });
5303
-
5304
- // src/kernel/net/loopback-names.ts
5305
- function reserved(name2) {
5306
- const lower = name2.toLowerCase();
5307
- return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
5308
- }
5309
- function isHostname(name2) {
5310
- if (typeof name2 !== "string" || name2.length > 253 || reserved(name2)) return false;
5311
- return name2.split(".").every((l) => LABEL.test(l));
5312
- }
5313
- function hostnameOf(env) {
5314
- return isHostname(env.HOSTNAME) ? env.HOSTNAME : DEFAULT_HOSTNAME;
5315
- }
5316
- function ownNames(hostname) {
5317
- return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
5318
- }
5319
- function hostsFile(hostname = DEFAULT_HOSTNAME) {
5320
- return [
5321
- "127.0.0.1 localhost localhost.localdomain",
5322
- "::1 localhost ip6-localhost",
5323
- `${HOSTNAME_ADDRESS} ${ownNames(hostname).join(" ")}`,
5324
- `${HOST_LOOPBACK_ADDRESS.join(".")} ${HOST_LOOPBACK}`,
5325
- ""
5326
- ].join("\n");
5327
- }
5328
- var HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS, PAGE_LOOPBACK, PAGE_LOOPBACK_URL, DEFAULT_HOSTNAME, HOSTNAME_ADDRESS, LIBC_HOSTNAMES, LABEL;
5329
- var init_loopback_names = __esm({
5330
- "src/kernel/net/loopback-names.ts"() {
5331
- "use strict";
5332
- HOST_LOOPBACK = "host.slicc.internal";
5333
- HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
5334
- PAGE_LOOPBACK = "kernel.localhost";
5335
- PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
5336
- DEFAULT_HOSTNAME = "slicc";
5337
- HOSTNAME_ADDRESS = "127.0.1.1";
5338
- LIBC_HOSTNAMES = ["emscripten", "wasmer.sh"];
5339
- LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
5408
+ SOL_SOCKET2 = 1;
5409
+ SO_ERROR2 = 4;
5340
5410
  }
5341
5411
  });
5342
5412
 
@@ -5614,6 +5684,7 @@ function toMs(v) {
5614
5684
  return v instanceof Date ? v.getTime() : v;
5615
5685
  }
5616
5686
  function wantOf2(flags) {
5687
+ if (flags & O_PATH) return 0;
5617
5688
  const mode = flags & O_ACCMODE;
5618
5689
  const read2 = mode === 1 ? 0 : HOLD_READ;
5619
5690
  const write2 = mode !== 0 || (flags & O_TRUNC) !== 0 ? HOLD_WRITE : 0;
@@ -8452,7 +8523,8 @@ function syncPathOps(kernel, resolve, statOf, open) {
8452
8523
  mkdir: (path, options) => void kernel.call({
8453
8524
  op: "mkdir",
8454
8525
  path: resolve(path),
8455
- ...options?.recursive === false ? { exclusive: true } : {}
8526
+ ...options?.recursive === false ? { exclusive: true } : {},
8527
+ mode: options?.mode === void 0 ? 511 : modeOf(options.mode)
8456
8528
  }),
8457
8529
  rm: (path) => void kernel.call({ op: "rm", path: resolve(path) }),
8458
8530
  unlink: (path) => void kernel.call({ op: "unlink", path: resolve(path) }),
@@ -8476,8 +8548,14 @@ function syncPathOps(kernel, resolve, statOf, open) {
8476
8548
  kernel.call({ op: "fd-path-flush", path: abs });
8477
8549
  return kernel.bytes({ op: "read", path: abs });
8478
8550
  },
8479
- writeFile(path, data) {
8480
- const file = open(path, { write: true, create: true, truncate: true });
8551
+ writeFile(path, data, options) {
8552
+ const mode = options?.mode;
8553
+ const file = open(path, {
8554
+ write: true,
8555
+ create: true,
8556
+ truncate: true,
8557
+ ...mode !== void 0 ? { mode } : {}
8558
+ });
8481
8559
  try {
8482
8560
  file.write(0, typeof data === "string" ? encoder3.encode(data) : data);
8483
8561
  } finally {
@@ -8976,6 +9054,7 @@ function createContext(o) {
8976
9054
  },
8977
9055
  kill: killer({ self: o.pid, kernel, syncKernel, lane, writes, modes: terminal.modes }),
8978
9056
  cred: () => syncKernel.json({ op: "proc-cred" }),
9057
+ umask: (mask) => syncKernel.json(umaskRequest(mask)),
8979
9058
  setcred(change) {
8980
9059
  if (typeof change !== "object" || change === null || Array.isArray(change)) {
8981
9060
  throw new JsCallError("EINVAL", "setcred");
@@ -9022,6 +9101,7 @@ function createContext(o) {
9022
9101
  },
9023
9102
  sync,
9024
9103
  fetch: fetchOp(kernel),
9104
+ umask: async (mask) => await kernel.json(umaskRequest(mask)),
9025
9105
  sudo: async (args) => await kernel.json({
9026
9106
  op: "proc-sudo",
9027
9107
  args: [...args],
@@ -9171,7 +9251,8 @@ function pathOps(kernel, resolve, statOf, open) {
9171
9251
  mkdir: async (path, options) => void await kernel.call({
9172
9252
  op: "mkdir",
9173
9253
  path: resolve(path),
9174
- ...options?.recursive === false ? { exclusive: true } : {}
9254
+ ...options?.recursive === false ? { exclusive: true } : {},
9255
+ mode: options?.mode === void 0 ? 511 : modeOf(options.mode)
9175
9256
  }),
9176
9257
  rm: async (path) => void await kernel.call({ op: "rm", path: resolve(path) }),
9177
9258
  unlink: async (path) => void await kernel.call({ op: "unlink", path: resolve(path) }),
@@ -9195,8 +9276,14 @@ function pathOps(kernel, resolve, statOf, open) {
9195
9276
  await kernel.call({ op: "fd-path-flush", path: abs });
9196
9277
  return kernel.bytes({ op: "read", path: abs });
9197
9278
  },
9198
- async writeFile(path, data) {
9199
- const file = await open(path, { write: true, create: true, truncate: true });
9279
+ async writeFile(path, data, options) {
9280
+ const mode = options?.mode;
9281
+ const file = await open(path, {
9282
+ write: true,
9283
+ create: true,
9284
+ truncate: true,
9285
+ ...mode !== void 0 ? { mode } : {}
9286
+ });
9200
9287
  try {
9201
9288
  await file.write(0, typeof data === "string" ? encoder4.encode(data) : data);
9202
9289
  } finally {
@@ -10292,12 +10379,12 @@ function anySelect(Fs, transport, read2, write2, timeoutMs) {
10292
10379
  const kernelRead = read2.filter((fd) => !own(fd));
10293
10380
  const kernelWrite = write2.filter((fd) => !own(fd));
10294
10381
  for (; ; ) {
10295
- const local2 = ownReady(Fs, read2.filter(own), write2.filter(own));
10296
- const pending = local2.read.length > 0 || local2.write.length > 0;
10382
+ const local3 = ownReady(Fs, read2.filter(own), write2.filter(own));
10383
+ const pending = local3.read.length > 0 || local3.write.length > 0;
10297
10384
  const slice = pending ? 0 : Math.min(SELECT_SLICE_MS, Math.max(0, deadline - Date.now()));
10298
10385
  const got = kernelSelect(Fs, transport, kernelRead, kernelWrite, slice);
10299
10386
  if (typeof got === "number") return got;
10300
- const ready = { read: [...local2.read, ...got.read], write: [...local2.write, ...got.write] };
10387
+ const ready = { read: [...local3.read, ...got.read], write: [...local3.write, ...got.write] };
10301
10388
  if (ready.read.length > 0 || ready.write.length > 0 || Date.now() >= deadline) {
10302
10389
  return ready;
10303
10390
  }
@@ -12837,7 +12924,7 @@ function readAddr(view, ptr) {
12837
12924
  function ipv6Host(bytes) {
12838
12925
  const zeros = (n) => bytes.subarray(0, n).every((b) => b === 0);
12839
12926
  if (zeros(16)) return "0.0.0.0";
12840
- if (zeros(15) && bytes[15] === 1) return LOOPBACK;
12927
+ if (zeros(15) && bytes[15] === 1) return LOOPBACK2;
12841
12928
  if (zeros(10) && bytes[10] === 255 && bytes[11] === 255) return bytes.subarray(12).join(".");
12842
12929
  const groups = [0, 2, 4, 6, 8, 10, 12, 14].map(
12843
12930
  (i) => (bytes[i] << 8 | bytes[i + 1]).toString(16)
@@ -12994,7 +13081,7 @@ function wasixSocketImports(host, preview1) {
12994
13081
  }
12995
13082
  };
12996
13083
  }
12997
- var INET4, INET6, UNIX, STREAM, ADDR_IP_SIZE, LOOPBACK, OPTIONS;
13084
+ var INET4, INET6, UNIX, STREAM, ADDR_IP_SIZE, LOOPBACK2, OPTIONS;
12998
13085
  var init_wasix_sockets = __esm({
12999
13086
  "src/process/wasi/wasix-sockets.ts"() {
13000
13087
  "use strict";
@@ -13006,7 +13093,7 @@ var init_wasix_sockets = __esm({
13006
13093
  UNIX = 3;
13007
13094
  STREAM = 1;
13008
13095
  ADDR_IP_SIZE = 18;
13009
- LOOPBACK = "127.0.0.1";
13096
+ LOOPBACK2 = "127.0.0.1";
13010
13097
  OPTIONS = {
13011
13098
  1: [1, 15],
13012
13099
  2: [1, 2],
@@ -13393,10 +13480,8 @@ var init_wasix_host = __esm({
13393
13480
  const v = mem.view();
13394
13481
  const timed = timeoutPtr !== 0 && v.getUint8(timeoutPtr) === 1;
13395
13482
  const ms = timed ? Number(v.getBigUint64(timeoutPtr + 8, true)) / 1e6 : Number.POSITIVE_INFINITY;
13396
- v.setUint8(
13397
- wokenPtr,
13398
- futexWait(i32(), ptr >> 2, expected | 0, ms, host.interrupted) ? 1 : 0
13399
- );
13483
+ const woken = host.entered || futexWait(i32(), ptr >> 2, expected | 0, ms, host.interrupted);
13484
+ v.setUint8(wokenPtr, woken ? 1 : 0);
13400
13485
  },
13401
13486
  futex_wake: (ptr, wokenPtr) => {
13402
13487
  Atomics.notify(i32(), ptr >> 2, 1);
@@ -13564,9 +13649,10 @@ function delivering(ns, table, host, driver, before) {
13564
13649
  }
13565
13650
  const fn = value2;
13566
13651
  out[name2] = (...args) => {
13652
+ host.entered = false;
13567
13653
  if (driver.idle) {
13568
13654
  before?.();
13569
- host.interrupted?.();
13655
+ host.entered = host.interrupted?.() === true;
13570
13656
  }
13571
13657
  return fn(...args);
13572
13658
  };