@ai-ecoverse/slicc-kernel 1.45.0 → 1.46.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.
@@ -1594,6 +1594,9 @@ var KernelSocket = class _KernelSocket {
1594
1594
  get listening() {
1595
1595
  return this.state === "listening";
1596
1596
  }
1597
+ get unconnected() {
1598
+ return this.state === "open" || this.state === "listening";
1599
+ }
1597
1600
  connection() {
1598
1601
  if (!this.link || this.state !== "connected") throw new KernelError("ENOTCONN");
1599
1602
  return this.link;
@@ -2138,6 +2141,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2138
2141
  peer.postMessage({
2139
2142
  net: "head",
2140
2143
  nid: call.nid,
2144
+ ...response.redirected ? { url: response.url, redirected: true } : {},
2141
2145
  status: response.status,
2142
2146
  statusText: response.statusText,
2143
2147
  headers: response.headers
@@ -4716,7 +4720,7 @@ var RemoteTransport = class {
4716
4720
  finish();
4717
4721
  throw e;
4718
4722
  }
4719
- const { status, statusText, headers } = head;
4723
+ const { status, statusText, headers, url, redirected } = head;
4720
4724
  const read = async () => {
4721
4725
  if (finished) return void 0;
4722
4726
  const reply = await this.ask({ net: "read", nid }).catch((e) => {
@@ -4733,6 +4737,7 @@ var RemoteTransport = class {
4733
4737
  this.cancel(nid);
4734
4738
  };
4735
4739
  return {
4740
+ ...redirected ? { url, redirected } : {},
4736
4741
  status,
4737
4742
  statusText,
4738
4743
  headers,
@@ -7722,6 +7727,8 @@ var WsHandles = class {
7722
7727
  // src/kernel/net/http-syscalls.ts
7723
7728
  var HTTP_OPS = [
7724
7729
  "net-request",
7730
+ "net-open",
7731
+ "net-head",
7725
7732
  "net-read",
7726
7733
  "net-close",
7727
7734
  "net-traits",
@@ -7746,6 +7753,8 @@ var HttpHandles = class {
7746
7753
  syscall(req) {
7747
7754
  if (req.op.startsWith("net-ws-")) return this.ws.syscall(req);
7748
7755
  if (req.op === "net-request") return this.request(req);
7756
+ if (req.op === "net-open") return Promise.resolve(this.opened(req));
7757
+ if (req.op === "net-head") return this.head(req.handle);
7749
7758
  if (req.op === "net-read") return this.read(req.handle, req.max);
7750
7759
  if (req.op === "net-traits") return Promise.resolve(this.traits());
7751
7760
  return this.close(req.handle);
@@ -7755,56 +7764,70 @@ var HttpHandles = class {
7755
7764
  if (unavailable) return { ok: false, errno: "ENETUNREACH", message: NO_TRANSPORT };
7756
7765
  return { ok: true, kind: "json", json: { ...rest2, crossOrigin } };
7757
7766
  }
7758
- add(abort, body, cancel) {
7767
+ async request(req) {
7768
+ const { handle, head } = this.start(req);
7769
+ const result = await head;
7770
+ if (!result.ok) this.open.delete(handle);
7771
+ return result;
7772
+ }
7773
+ opened(req) {
7774
+ return { ok: true, kind: "json", json: this.start(req).handle };
7775
+ }
7776
+ start(req) {
7759
7777
  const handle = ++this.nextHandle;
7760
- this.open.set(handle, {
7778
+ const abort = new AbortController();
7779
+ const entry = {
7761
7780
  abort,
7762
- body: body[Symbol.asyncIterator](),
7781
+ head: Promise.resolve({ ok: true, kind: "void" }),
7782
+ body: once(EMPTY),
7763
7783
  left: EMPTY,
7764
7784
  done: false,
7765
7785
  reading: Promise.resolve(),
7766
- cancel
7767
- });
7768
- return handle;
7786
+ cancel: async () => void 0
7787
+ };
7788
+ this.open.set(handle, entry);
7789
+ entry.head = this.respond(handle, req, entry);
7790
+ return { handle, head: entry.head };
7769
7791
  }
7770
- async request(req) {
7771
- const abort = new AbortController();
7792
+ async respond(handle, req, entry) {
7772
7793
  try {
7773
7794
  const response = await this.transport.fetch({
7774
7795
  url: req.url,
7775
7796
  method: req.method,
7776
7797
  headers: req.headers,
7777
7798
  ...req.body ? { body: req.body } : {},
7778
- signal: abort.signal
7799
+ signal: entry.abort.signal
7779
7800
  });
7780
- const handle = this.add(abort, response.body, () => response.cancel());
7781
- const head = {
7782
- handle,
7783
- status: response.status,
7784
- statusText: response.statusText,
7785
- url: req.url,
7786
- headers: response.headers
7787
- };
7788
- return { ok: true, kind: "json", json: head };
7801
+ entry.body = response.body[Symbol.asyncIterator]();
7802
+ entry.cancel = () => response.cancel();
7803
+ if (!this.open.has(handle)) await entry.cancel().catch(() => void 0);
7804
+ const head = this.headOf(handle, response.url ?? req.url, response);
7805
+ return response.redirected ? { ...head, json: { ...head.json, redirected: true } } : head;
7789
7806
  } catch (e) {
7790
7807
  const text = message2(e);
7791
- if (text === NO_TRANSPORT) return { ok: false, errno: "ENETUNREACH", message: text };
7792
7808
  const status = e.status;
7793
- if (typeof status !== "number" || status === 502) {
7794
- return { ok: false, errno: "ECONNREFUSED", message: text };
7809
+ if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
7810
+ const errno = text === NO_TRANSPORT ? "ENETUNREACH" : "ECONNREFUSED";
7811
+ return { ok: false, errno, message: text };
7795
7812
  }
7796
- const body = new TextEncoder().encode(text);
7797
- const handle = this.add(abort, once(body), async () => void 0);
7798
- const head = {
7799
- handle,
7813
+ entry.body = once(new TextEncoder().encode(text))[Symbol.asyncIterator]();
7814
+ return this.headOf(handle, req.url, {
7800
7815
  status,
7801
7816
  statusText: "",
7802
- url: req.url,
7803
7817
  headers: [["content-type", "text/plain; charset=utf-8"]]
7804
- };
7805
- return { ok: true, kind: "json", json: head };
7818
+ });
7806
7819
  }
7807
7820
  }
7821
+ headOf(handle, url, response) {
7822
+ const { status, statusText, headers } = response;
7823
+ return { ok: true, kind: "json", json: { handle, status, statusText, url, headers } };
7824
+ }
7825
+ head(handle) {
7826
+ const entry = this.open.get(handle);
7827
+ if (!entry)
7828
+ return Promise.resolve({ ok: false, errno: "EBADF", message: `no request ${handle}` });
7829
+ return entry.head;
7830
+ }
7808
7831
  async read(handle, max) {
7809
7832
  const entry = this.open.get(handle);
7810
7833
  if (!entry) return { ok: false, errno: "EBADF", message: `no request ${handle}` };
@@ -9587,6 +9610,9 @@ var WasmProcess = class {
9587
9610
  throw e;
9588
9611
  }
9589
9612
  }
9613
+ refuseIfPending(restart) {
9614
+ if (restart && this.options.hasPending?.()) throw new KernelError("EINTR");
9615
+ }
9590
9616
  blockingSignal() {
9591
9617
  if (this.options.hasPending?.()) throw new KernelError("EINTR");
9592
9618
  return this.interrupt.signal;
@@ -9597,6 +9623,7 @@ var WasmProcess = class {
9597
9623
  if (!read) throw new KernelError(req.peek && file.read ? "EOPNOTSUPP" : "EBADF");
9598
9624
  if (file.tty) this.checkForeground(file.tty);
9599
9625
  if (req.max <= 0) return new Uint8Array(0);
9626
+ if (file instanceof KernelSocket && file.unconnected) throw new KernelError("ENOTCONN");
9600
9627
  const ready2 = pollFile(file).readable;
9601
9628
  if (!ready2 && req.nonblock) throw new KernelError("EAGAIN");
9602
9629
  const signal = ready2 ? this.interrupt.signal : this.blockingSignal();
@@ -9919,8 +9946,10 @@ var WasmProcess = class {
9919
9946
  async procSyscall(req) {
9920
9947
  switch (req.op) {
9921
9948
  case "proc-fork":
9949
+ this.refuseIfPending(req.restart);
9922
9950
  return { ok: true, kind: "json", json: await this.children.fork(req.state) };
9923
9951
  case "proc-spawn":
9952
+ this.refuseIfPending(req.restart);
9924
9953
  return { ok: true, kind: "json", json: await this.spawn(req) };
9925
9954
  case "proc-wait": {
9926
9955
  const signal = req.nohang ? this.interrupt.signal : this.blockingSignal();