@ai-ecoverse/slicc-kernel 1.123.2 → 1.124.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.
@@ -4442,6 +4442,111 @@ var Routes = class {
4442
4442
  }
4443
4443
  };
4444
4444
 
4445
+ // src/kernel/net/switch-conn.ts
4446
+ var SwitchConn = class {
4447
+ raw;
4448
+ box = [];
4449
+ pulling = false;
4450
+ waiters = [];
4451
+ switching = false;
4452
+ secure;
4453
+ failed;
4454
+ constructor(raw) {
4455
+ this.raw = raw;
4456
+ }
4457
+ get localAddr() {
4458
+ return this.raw.localAddr;
4459
+ }
4460
+ get remoteAddr() {
4461
+ return this.raw.remoteAddr;
4462
+ }
4463
+ get upgraded() {
4464
+ return this.switching || this.secure !== void 0;
4465
+ }
4466
+ wake() {
4467
+ for (const wake of this.waiters.splice(0)) wake();
4468
+ }
4469
+ changed() {
4470
+ return new Promise((resolve2) => this.waiters.push(resolve2));
4471
+ }
4472
+ pull() {
4473
+ if (this.pulling || this.box.length > 0) return;
4474
+ this.pulling = true;
4475
+ this.raw.read().then(
4476
+ (bytes) => this.box.push(bytes),
4477
+ (err) => this.box.push(err instanceof Error ? err : new Error(String(err)))
4478
+ ).finally(() => {
4479
+ this.pulling = false;
4480
+ this.wake();
4481
+ });
4482
+ }
4483
+ take() {
4484
+ const next3 = this.box.shift();
4485
+ if (next3 instanceof Error) throw next3;
4486
+ return next3;
4487
+ }
4488
+ async rawRead() {
4489
+ while (this.box.length === 0) {
4490
+ this.pull();
4491
+ await this.changed();
4492
+ }
4493
+ return this.take();
4494
+ }
4495
+ async read() {
4496
+ for (; ; ) {
4497
+ if (this.failed) throw this.failed;
4498
+ if (this.secure) return this.secure.read();
4499
+ if (!this.switching && this.box.length > 0) return this.take();
4500
+ if (!this.switching) this.pull();
4501
+ await this.changed();
4502
+ }
4503
+ }
4504
+ async settled() {
4505
+ while (this.switching) await this.changed();
4506
+ if (this.failed) throw this.failed;
4507
+ return this.secure ?? this.raw;
4508
+ }
4509
+ async write(bytes) {
4510
+ return (await this.settled()).write(bytes);
4511
+ }
4512
+ closeWrite() {
4513
+ void this.settled().then(
4514
+ (conn) => conn.closeWrite(),
4515
+ () => void 0
4516
+ );
4517
+ }
4518
+ close() {
4519
+ this.failed ??= new Error("closed");
4520
+ this.secure?.close();
4521
+ this.raw.close();
4522
+ this.wake();
4523
+ }
4524
+ async upgrade(make) {
4525
+ if (this.upgraded) throw new Error("already upgraded");
4526
+ this.switching = true;
4527
+ this.wake();
4528
+ const view2 = {
4529
+ localAddr: this.raw.localAddr,
4530
+ remoteAddr: this.raw.remoteAddr,
4531
+ read: () => this.rawRead(),
4532
+ write: (bytes) => this.raw.write(bytes),
4533
+ closeWrite: () => this.raw.closeWrite(),
4534
+ close: () => this.raw.close()
4535
+ };
4536
+ try {
4537
+ const { conn, info } = await make(view2);
4538
+ this.secure = conn;
4539
+ return info;
4540
+ } catch (err) {
4541
+ this.failed = err instanceof Error ? err : new Error(String(err));
4542
+ throw err;
4543
+ } finally {
4544
+ this.switching = false;
4545
+ this.wake();
4546
+ }
4547
+ }
4548
+ };
4549
+
4445
4550
  // src/kernel/net/uplink-socket.ts
4446
4551
  var CHUNK = 64 * 1024;
4447
4552
  function hostPort(text) {
@@ -4766,7 +4871,18 @@ var KernelSocket = class _KernelSocket {
4766
4871
  clearTimeout(timer);
4767
4872
  }
4768
4873
  }
4769
- dial(addr, route) {
4874
+ switch;
4875
+ connectSecure(addr, route, secure2) {
4876
+ if (this.state !== "open") throw new KernelError("EISCONN");
4877
+ return this.dial(addr, route, secure2);
4878
+ }
4879
+ upgradeSecure(make) {
4880
+ if (this.state !== "connected") throw new KernelError("ENOTCONN");
4881
+ if (!this.switch) throw new KernelError("EOPNOTSUPP");
4882
+ if (this.switch.upgraded || this.writeShut || this.readShut) throw new KernelError("EINVAL");
4883
+ return this.switch.upgrade(make);
4884
+ }
4885
+ dial(addr, route, secure2) {
4770
4886
  this.state = "connecting";
4771
4887
  const abort = new AbortController();
4772
4888
  this.dialing = abort;
@@ -4787,11 +4903,25 @@ var KernelSocket = class _KernelSocket {
4787
4903
  () => void 0
4788
4904
  );
4789
4905
  return Promise.race([dialled, abandoned]).then(
4790
- (conn) => {
4906
+ async (raw) => {
4791
4907
  if (abort.signal.aborted) throw dialError(abort.signal.reason, timedOut, true);
4908
+ const conn = new SwitchConn(raw);
4909
+ if (secure2) {
4910
+ clearTimeout(timer);
4911
+ try {
4912
+ await Promise.race([secure2(conn), abandoned]);
4913
+ } catch (e) {
4914
+ conn.close();
4915
+ throw this.dialFailed(
4916
+ abort,
4917
+ e instanceof KernelError ? e : new KernelError("ENOTSUP", e instanceof Error ? e.message : String(e))
4918
+ );
4919
+ }
4920
+ }
4792
4921
  this.local = { family: "inet", host: "0.0.0.0", port: 0, ...hostPort(conn.localAddr) };
4793
4922
  this.peer = { ...addr, ...hostPort(conn.remoteAddr) };
4794
4923
  this.dialing = void 0;
4924
+ this.switch = conn;
4795
4925
  this.attach(
4796
4926
  uplinkLink(conn, () => {
4797
4927
  this.reset = true;
@@ -4800,17 +4930,19 @@ var KernelSocket = class _KernelSocket {
4800
4930
  );
4801
4931
  },
4802
4932
  (e) => {
4803
- const error = dialError(e, timedOut, abort.signal.aborted);
4804
- if (this.dialing === abort) {
4805
- this.dialing = void 0;
4806
- this.failed = error.code;
4807
- this.state = "open";
4808
- this.changes.wake();
4809
- }
4810
- throw error;
4933
+ throw this.dialFailed(abort, dialError(e, timedOut, abort.signal.aborted));
4811
4934
  }
4812
4935
  ).finally(() => clearTimeout(timer));
4813
4936
  }
4937
+ dialFailed(abort, error) {
4938
+ if (this.dialing === abort) {
4939
+ this.dialing = void 0;
4940
+ this.failed = error.code;
4941
+ this.state = "open";
4942
+ this.changes.wake();
4943
+ }
4944
+ return error;
4945
+ }
4814
4946
  unlink() {
4815
4947
  const link2 = this.link;
4816
4948
  if (link2) {
@@ -4916,6 +5048,7 @@ var LoopbackNet = class {
4916
5048
  useUplink(route) {
4917
5049
  this.route = route;
4918
5050
  }
5051
+ tlsClient;
4919
5052
  uplinkFor(host) {
4920
5053
  const route = this.route;
4921
5054
  if (!route) return void 0;
@@ -5057,12 +5190,12 @@ function serveSocket(socket, port, onClose) {
5057
5190
  let writes = Promise.resolve();
5058
5191
  let credit = 0;
5059
5192
  let granted2;
5060
- const send = (message3, transfer) => {
5193
+ const send2 = (message3, transfer) => {
5061
5194
  if (!closed) port.postMessage(message3, transfer);
5062
5195
  };
5063
5196
  const close = (reset = false) => {
5064
5197
  if (closed) return;
5065
- if (reset) send({ error: "ECONNRESET" });
5198
+ if (reset) send2({ error: "ECONNRESET" });
5066
5199
  closed = true;
5067
5200
  granted2?.();
5068
5201
  socket.close();
@@ -5074,9 +5207,9 @@ function serveSocket(socket, port, onClose) {
5074
5207
  if (closed) return;
5075
5208
  try {
5076
5209
  await socket.write(data);
5077
- send({ ack: true });
5210
+ send2({ ack: true });
5078
5211
  } catch (err) {
5079
- send({ error: codeOf(err) });
5212
+ send2({ error: codeOf(err) });
5080
5213
  }
5081
5214
  });
5082
5215
  };
@@ -5101,11 +5234,11 @@ function serveSocket(socket, port, onClose) {
5101
5234
  const chunk2 = await socket.read(CHUNK2);
5102
5235
  if (chunk2.length === 0) break;
5103
5236
  credit--;
5104
- send(chunk2, [chunk2.buffer]);
5237
+ send2(chunk2, [chunk2.buffer]);
5105
5238
  }
5106
- send({ end: true });
5239
+ send2({ end: true });
5107
5240
  } catch (err) {
5108
- send({ error: codeOf(err) });
5241
+ send2({ error: codeOf(err) });
5109
5242
  }
5110
5243
  })();
5111
5244
  return () => close(true);
@@ -6018,7 +6151,7 @@ function joinable(l, pgid, ours) {
6018
6151
  if (sid === void 0) throw fsError("ESRCH", `no process group ${pgid}`);
6019
6152
  if (!ours(sid)) throw fsError("EPERM", `process group ${pgid} is in another session`);
6020
6153
  }
6021
- function cdpRegistry(send, gone) {
6154
+ function cdpRegistry(send2, gone) {
6022
6155
  const registered = /* @__PURE__ */ new Map();
6023
6156
  const drop = (id2) => {
6024
6157
  registered.get(id2)?.();
@@ -6027,7 +6160,7 @@ function cdpRegistry(send, gone) {
6027
6160
  return {
6028
6161
  serve(l, req) {
6029
6162
  const hook = portCdpHook(
6030
- (request2, cdp) => send({ cdpOpen: { ...request2, registration: req.id }, port: cdp }, [
6163
+ (request2, cdp) => send2({ cdpOpen: { ...request2, registration: req.id }, port: cdp }, [
6031
6164
  cdp
6032
6165
  ]),
6033
6166
  gone
@@ -6041,7 +6174,7 @@ function cdpRegistry(send, gone) {
6041
6174
  }
6042
6175
  };
6043
6176
  }
6044
- function facadeRegistry(send, gone) {
6177
+ function facadeRegistry(send2, gone) {
6045
6178
  const registered = /* @__PURE__ */ new Map();
6046
6179
  const drop = (id2) => {
6047
6180
  registered.get(id2)?.();
@@ -6050,7 +6183,7 @@ function facadeRegistry(send, gone) {
6050
6183
  return {
6051
6184
  serve(l, req) {
6052
6185
  const hook = portFacadeHook(
6053
- (request2, facade) => send({ facadeOpen: { ...request2, registration: req.id }, port: facade }, [
6186
+ (request2, facade) => send2({ facadeOpen: { ...request2, registration: req.id }, port: facade }, [
6054
6187
  facade
6055
6188
  ]),
6056
6189
  gone
@@ -6064,9 +6197,9 @@ function facadeRegistry(send, gone) {
6064
6197
  }
6065
6198
  };
6066
6199
  }
6067
- function hostRegistries(send, gone) {
6068
- const cdps = cdpRegistry(send, gone);
6069
- const facades = facadeRegistry(send, gone);
6200
+ function hostRegistries(send2, gone) {
6201
+ const cdps = cdpRegistry(send2, gone);
6202
+ const facades = facadeRegistry(send2, gone);
6070
6203
  return {
6071
6204
  answer(l, req) {
6072
6205
  if (req.op === "serve-cdp") return cdps.serve(l, req);
@@ -6093,21 +6226,21 @@ function visibleTo(g, notify) {
6093
6226
  });
6094
6227
  };
6095
6228
  }
6096
- async function watchOp(l, req, watches, send, g) {
6229
+ async function watchOp(l, req, watches, send2, g) {
6097
6230
  if (req.op === "unwatch") {
6098
6231
  watches.get(req.watch)?.();
6099
6232
  watches.delete(req.watch);
6100
6233
  return { result: true };
6101
6234
  }
6102
6235
  if (g) for (const path of req.paths) await readable(g, "watch", l.fs.resolvePath("/", path));
6103
- const notify = visibleTo(g, (change) => send({ watch: req.id, change }));
6236
+ const notify = visibleTo(g, (change) => send2({ watch: req.id, change }));
6104
6237
  const unwatch = l.watchers.watch(req.paths, { recursive: req.recursive }, notify);
6105
6238
  watches.set(req.id, unwatch);
6106
6239
  return { result: req.id };
6107
6240
  }
6108
6241
  var TRAITS_WATCH = -1;
6109
- function traitsWatch(launcher, transport, send) {
6110
- return launcher.onTraits(() => send({ traits: transport.traits }));
6242
+ function traitsWatch(launcher, transport, send2) {
6243
+ return launcher.onTraits(() => send2({ traits: transport.traits }));
6111
6244
  }
6112
6245
  function serveClient(port, host) {
6113
6246
  let state = "new";
@@ -6119,14 +6252,14 @@ function serveClient(port, host) {
6119
6252
  const watches = /* @__PURE__ */ new Map();
6120
6253
  let net;
6121
6254
  const ended = Promise.withResolvers();
6122
- const send = (message3, transfer = []) => {
6255
+ const send2 = (message3, transfer = []) => {
6123
6256
  if (state !== "closed") port.postMessage(message3, transfer);
6124
6257
  };
6125
- const reply = (id2, body, transfer) => send({ id: id2, ...body }, transfer);
6126
- const hosts = hostRegistries(send, ended.promise);
6258
+ const reply = (id2, body, transfer) => send2({ id: id2, ...body }, transfer);
6259
+ const hosts = hostRegistries(send2, ended.promise);
6127
6260
  function detach(kill = false, bye = "the slicc-kernel detached this client") {
6128
6261
  if (state === "closed") return;
6129
- send({ bye });
6262
+ send2({ bye });
6130
6263
  state = "closed";
6131
6264
  net?.close();
6132
6265
  for (const unwatch of watches.values()) unwatch();
@@ -6140,19 +6273,19 @@ function serveClient(port, host) {
6140
6273
  ended.resolve();
6141
6274
  }
6142
6275
  async function hello(message3) {
6143
- const refused2 = versionError(message3.protocol);
6144
- if (refused2) {
6145
- send({ hello: { protocol: PROTOCOL, error: refused2 } });
6276
+ const refused3 = versionError(message3.protocol);
6277
+ if (refused3) {
6278
+ send2({ hello: { protocol: PROTOCOL, error: refused3 } });
6146
6279
  detach();
6147
6280
  return;
6148
6281
  }
6149
6282
  const launcher = await host.launcher();
6150
6283
  if (host.scope !== "transport") self = await accountOf(launcher, host.user ?? 0);
6151
6284
  const transport = host.transport?.() ?? launcher.transport;
6152
- net = serveTransport({ postMessage: (m, t) => send(m, t) }, transport);
6285
+ net = serveTransport({ postMessage: (m, t) => send2(m, t) }, transport);
6153
6286
  state = "open";
6154
6287
  if (message3.lock && host.locks) void host.locks.request(message3.lock, () => detach());
6155
- send({
6288
+ send2({
6156
6289
  hello: {
6157
6290
  protocol: PROTOCOL,
6158
6291
  traits: transport.traits,
@@ -6160,7 +6293,7 @@ function serveClient(port, host) {
6160
6293
  ...host.lock ? { lock: host.lock } : {}
6161
6294
  }
6162
6295
  });
6163
- watches.set(TRAITS_WATCH, traitsWatch(launcher, transport, send));
6296
+ watches.set(TRAITS_WATCH, traitsWatch(launcher, transport, send2));
6164
6297
  }
6165
6298
  async function terminal(req, l) {
6166
6299
  const session = await l.openTerminal(req.argv, {
@@ -6224,7 +6357,7 @@ function serveClient(port, host) {
6224
6357
  return clientFs(l, host.tag, self, req);
6225
6358
  case "watch":
6226
6359
  case "unwatch":
6227
- return watchOp(l, req, watches, send, guard2(l));
6360
+ return watchOp(l, req, watches, send2, guard2(l));
6228
6361
  case "mount":
6229
6362
  return { result: await l.mountAs(clientCred(self), req.spec) };
6230
6363
  case "umount":
@@ -6250,7 +6383,7 @@ function serveClient(port, host) {
6250
6383
  if (data.hello) {
6251
6384
  if (state === "new") {
6252
6385
  hello(data.hello).catch((err) => {
6253
- send({ hello: { protocol: PROTOCOL, error: String(err?.message ?? err) } });
6386
+ send2({ hello: { protocol: PROTOCOL, error: String(err?.message ?? err) } });
6254
6387
  detach();
6255
6388
  });
6256
6389
  }
@@ -6432,7 +6565,7 @@ function satisfies(version, range2) {
6432
6565
  }
6433
6566
 
6434
6567
  // src/version.ts
6435
- var KERNEL_VERSION = true ? "1.123.2" : "0.0.0-dev";
6568
+ var KERNEL_VERSION = true ? "1.124.0" : "0.0.0-dev";
6436
6569
  var OS_RELEASE = "6.0.0-slicc";
6437
6570
  function procVersion() {
6438
6571
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -6714,13 +6847,13 @@ async function tierPackages(fs, physical, roots, bins, kernel) {
6714
6847
  const own = commandsOf(pkg, manifest);
6715
6848
  const named = new Set(own.map((command) => command.name));
6716
6849
  const extra = bins ? await binCommandsOf(physical, pkg, manifest, named) : [];
6717
- const refused2 = engineRefusal(manifest, kernel);
6850
+ const refused3 = engineRefusal(manifest, kernel);
6718
6851
  const commands = [...own, ...extra];
6719
6852
  out.push({
6720
6853
  name: pkg.slice(root.length + 1),
6721
6854
  pkg,
6722
6855
  replaces: replacesOf(manifest),
6723
- commands: refused2 ? commands.map((command) => ({ ...command, refused: refused2 })) : commands
6856
+ commands: refused3 ? commands.map((command) => ({ ...command, refused: refused3 })) : commands
6724
6857
  });
6725
6858
  }
6726
6859
  }
@@ -8305,8 +8438,8 @@ var RealmProxy = class {
8305
8438
  }
8306
8439
  async connect(conn, incoming, req, idle) {
8307
8440
  const target = tunnelTarget(req);
8308
- const refused2 = target.port === 443 ? await this.tunnelReady(target) : void 0;
8309
- if (refused2) throw refused2;
8441
+ const refused3 = target.port === 443 ? await this.tunnelReady(target) : void 0;
8442
+ if (refused3) throw refused3;
8310
8443
  await conn.write(latin1Bytes("HTTP/1.1 200 Connection Established\r\n\r\n"), this.stop.signal);
8311
8444
  try {
8312
8445
  const first = await incoming.peek(this.stop.signal);
@@ -9960,8 +10093,8 @@ var DriverConnection = class _DriverConnection {
9960
10093
  } finally {
9961
10094
  clearTimeout(timer);
9962
10095
  }
9963
- const refused2 = driverVersionError(hello.protocol);
9964
- if (refused2) throw errnoError("EPROTO", refused2);
10096
+ const refused3 = driverVersionError(hello.protocol);
10097
+ if (refused3) throw errnoError("EPROTO", refused3);
9965
10098
  if (hello.error) throw errnoError(hello.errno ?? "EIO", hello.error);
9966
10099
  return new _DriverConnection(port, hello.capabilities ?? {}, waiting, timeoutMs, options);
9967
10100
  }
@@ -11783,8 +11916,8 @@ async function guarded(entry, path, req) {
11783
11916
  return { paths };
11784
11917
  } catch (err) {
11785
11918
  const refusal = err.code === "EACCES";
11786
- const refused2 = req.op === "exists" && refusal ? json2(false) : toErrno(err);
11787
- return { refused: refused2 };
11919
+ const refused3 = req.op === "exists" && refusal ? json2(false) : toErrno(err);
11920
+ return { refused: refused3 };
11788
11921
  }
11789
11922
  }
11790
11923
  async function createExclusive(fs, path, owner) {
@@ -11895,13 +12028,13 @@ async function dispatchSyncFs(req) {
11895
12028
  }
11896
12029
  }
11897
12030
  var DENIED = /* @__PURE__ */ new Set(["EACCES", "EPERM"]);
11898
- async function rmPermitted(entry, path, req, refused2) {
12031
+ async function rmPermitted(entry, path, req, refused3) {
11899
12032
  const st = await entry.fs.lstat(path).catch(() => void 0);
11900
- if (!st?.isDirectory) return refused2;
12033
+ if (!st?.isDirectory) return refused3;
11901
12034
  const unlisted = await guarded(entry, path, { ...req, op: "readdir" });
11902
12035
  if ("refused" in unlisted) return unlisted.refused;
11903
12036
  const names = await entry.fs.readdir(path).catch(() => void 0);
11904
- if (!names) return refused2;
12037
+ if (!names) return refused3;
11905
12038
  let first;
11906
12039
  for (const name2 of names) {
11907
12040
  const child = await dispatchOne(entry, {
@@ -11952,14 +12085,14 @@ async function newDevName(entry, path, req) {
11952
12085
  const named = NAMING.has(req.op);
11953
12086
  if (!named && !CREATIONS.has(req.op)) return void 0;
11954
12087
  const target = named ? entry.fs.resolvePath(entry.cwd, req.arg2 ?? "") : path;
11955
- const refused2 = devCreation(target, entry.cred?.());
11956
- if (!refused2) return void 0;
12088
+ const refused3 = devCreation(target, entry.cred?.());
12089
+ if (!refused3) return void 0;
11957
12090
  const there = await entry.fs.lstat(target).then(
11958
12091
  () => true,
11959
12092
  () => false
11960
12093
  );
11961
12094
  if (there) return void 0;
11962
- return { ok: false, errno: refused2, message: `${target}: no new names in /dev or /proc` };
12095
+ return { ok: false, errno: refused3, message: `${target}: no new names in /dev or /proc` };
11963
12096
  }
11964
12097
  async function dispatchOne(entry, req) {
11965
12098
  const { fs, cwd } = entry;
@@ -13362,6 +13495,9 @@ var FlockTable = class {
13362
13495
  held = /* @__PURE__ */ new Map();
13363
13496
  keys = /* @__PURE__ */ new WeakMap();
13364
13497
  wakers = /* @__PURE__ */ new Map();
13498
+ isFree(key, owner, kind) {
13499
+ return this.free(key, owner, kind);
13500
+ }
13365
13501
  free(key, owner, kind) {
13366
13502
  for (const [other, has] of this.held.get(key) ?? [])
13367
13503
  if (other !== owner && (kind === "exclusive" || has === "exclusive")) return false;
@@ -13488,9 +13624,18 @@ var LockTable = class {
13488
13624
  );
13489
13625
  this.wake(key);
13490
13626
  }
13627
+ wholeFree(pid, path, exclusive) {
13628
+ for (const [other, h] of this.held.get(path) ?? []) {
13629
+ if (other !== pid && (exclusive || h.exclusive)) return false;
13630
+ }
13631
+ return true;
13632
+ }
13633
+ flockFree(key, owner, kind) {
13634
+ return this.flocks.isFree(key, owner, kind);
13635
+ }
13491
13636
  lock(pid, path, exclusive, fd) {
13637
+ if (!this.wholeFree(pid, path, exclusive)) return false;
13492
13638
  const holders = this.held.get(path) ?? /* @__PURE__ */ new Map();
13493
- for (const [other, h] of holders) if (other !== pid && (exclusive || h.exclusive)) return false;
13494
13639
  const mine = holders.get(pid) ?? { exclusive, fds: /* @__PURE__ */ new Set() };
13495
13640
  mine.exclusive = exclusive;
13496
13641
  mine.fds.add(fd);
@@ -13675,12 +13820,12 @@ var AsyncOps = class {
13675
13820
  async function hostSyscall(req, ctx) {
13676
13821
  switch (req.op) {
13677
13822
  case "lock":
13678
- if (!ctx.locks) throw new KernelError("ENOSYS");
13679
- if (!ctx.locks.lock(ctx.pid, req.path, req.exclusive, req.fd))
13680
- throw new KernelError("EAGAIN");
13681
- return done2;
13823
+ return wholeLock(req, ctx);
13682
13824
  case "unlock":
13683
13825
  ctx.locks?.unlock(ctx.pid, req.path);
13826
+ if (req.fd !== void 0 && ctx.locks?.shared?.() && ctx.flockOf) {
13827
+ return flock({ op: "flock", fd: req.fd, kind: "unlock" }, ctx);
13828
+ }
13684
13829
  return done2;
13685
13830
  case "lk-set":
13686
13831
  case "lk-get":
@@ -13710,6 +13855,23 @@ async function hostSyscall(req, ctx) {
13710
13855
  return done2;
13711
13856
  }
13712
13857
  }
13858
+ async function wholeLock(req, ctx) {
13859
+ const { locks, flockOf } = ctx;
13860
+ if (!locks) throw new KernelError("ENOSYS");
13861
+ const kind = req.exclusive ? "exclusive" : "shared";
13862
+ if (locks.shared?.() && flockOf) {
13863
+ if (locks.wholeFree?.(ctx.pid, req.path, req.exclusive) === false) {
13864
+ throw new KernelError("EAGAIN");
13865
+ }
13866
+ return flock({ op: "flock", fd: req.fd, kind }, ctx);
13867
+ }
13868
+ if (flockOf && locks.flockFree) {
13869
+ const { key, owner } = await flockOf(req.fd);
13870
+ if (!locks.flockFree(key, owner, kind)) throw new KernelError("EAGAIN");
13871
+ }
13872
+ if (!locks.lock(ctx.pid, req.path, req.exclusive, req.fd)) throw new KernelError("EAGAIN");
13873
+ return done2;
13874
+ }
13713
13875
  var FLOCK_KINDS = /* @__PURE__ */ new Set(["shared", "exclusive", "unlock"]);
13714
13876
  async function flock(req, ctx) {
13715
13877
  const { locks, flockOf } = ctx;
@@ -13896,8 +14058,8 @@ var KernelLoopback = class {
13896
14058
  );
13897
14059
  } catch (err) {
13898
14060
  socket.close();
13899
- const refused2 = err instanceof KernelError && err.code === "ECONNREFUSED";
13900
- throw refused2 ? errno2("ECONNREFUSED", `nothing listens on the kernel's port ${port}`) : err;
14061
+ const refused3 = err instanceof KernelError && err.code === "ECONNREFUSED";
14062
+ throw refused3 ? errno2("ECONNREFUSED", `nothing listens on the kernel's port ${port}`) : err;
13901
14063
  }
13902
14064
  signal.addEventListener("abort", () => socket.close(), { once: true });
13903
14065
  return socket;
@@ -14433,6 +14595,7 @@ function realmCa(owner, store) {
14433
14595
  }
14434
14596
 
14435
14597
  // src/kernel/net/tls-engine.ts
14598
+ var TLS_CLIENT_INSECURE_SKIP_VERIFY = 1;
14436
14599
  var SCRATCH = 64 * 1024;
14437
14600
  var EOF = -1;
14438
14601
  var TlsError = class extends Error {
@@ -14493,6 +14656,76 @@ var TlsEngine = class {
14493
14656
  const n = fn(this.scratch, SCRATCH);
14494
14657
  return n > 0 ? this.taken(n) : n;
14495
14658
  }
14659
+ get client() {
14660
+ return typeof this.m._tls_client_new === "function" ? this.m : void 0;
14661
+ }
14662
+ clientModule() {
14663
+ const m = this.client;
14664
+ if (!m) throw new TlsError(0, "tls client: the installed tls engine has no client sessions");
14665
+ return m;
14666
+ }
14667
+ store() {
14668
+ const m = this.clientModule();
14669
+ const ptr = m._tls_ca_new();
14670
+ if (!ptr) throw this.error(m._tls_last_error(), "trust store");
14671
+ return new TlsStore(this, m, ptr);
14672
+ }
14673
+ clientSession(store, servername, alpn, flags2) {
14674
+ const m = this.clientModule();
14675
+ const wire = alpnWire(alpn);
14676
+ const name2 = this.put(new TextEncoder().encode(servername));
14677
+ try {
14678
+ const at = store?.ptr ?? 0;
14679
+ const ptr = this.withBytes(wire, (p) => m._tls_client_new(at, name2, p, wire.length, flags2));
14680
+ if (!ptr) throw this.error(m._tls_last_error(), "tls client");
14681
+ return new TlsSession(this, m, ptr);
14682
+ } finally {
14683
+ this.m._free(name2);
14684
+ }
14685
+ }
14686
+ verifyInfo(flags2) {
14687
+ const m = this.clientModule();
14688
+ const n = m._tls_verify_info(flags2, this.scratch, SCRATCH);
14689
+ const end = this.m.HEAPU8.indexOf(0, this.scratch);
14690
+ const text = new TextDecoder().decode(this.m.HEAPU8.subarray(this.scratch, end));
14691
+ return n < 0 ? `${text}\u2026` : text;
14692
+ }
14693
+ };
14694
+ function alpnWire(names) {
14695
+ const parts2 = names.map((name2) => new TextEncoder().encode(name2));
14696
+ const out = new Uint8Array(parts2.reduce((n, p) => n + p.length + 1, 0));
14697
+ let at = 0;
14698
+ for (const part of parts2) {
14699
+ out[at++] = part.length;
14700
+ out.set(part, at);
14701
+ at += part.length;
14702
+ }
14703
+ return out;
14704
+ }
14705
+ var TlsStore = class {
14706
+ engine;
14707
+ m;
14708
+ ptr;
14709
+ constructor(engine, m, ptr) {
14710
+ this.engine = engine;
14711
+ this.m = m;
14712
+ this.ptr = ptr;
14713
+ }
14714
+ add(der) {
14715
+ const ret = this.engine.withBytes(der, (p) => this.m._tls_ca_add_der(this.ptr, p, der.length));
14716
+ if (ret !== 0) throw this.engine.error(ret, "trust store certificate");
14717
+ }
14718
+ addBundle(bytes) {
14719
+ const n = this.engine.withBytes(
14720
+ bytes,
14721
+ (p) => this.m._tls_ca_add_bundle(this.ptr, p, bytes.length)
14722
+ );
14723
+ if (n < 0) throw this.engine.error(n, "trust store bundle");
14724
+ return n;
14725
+ }
14726
+ release() {
14727
+ this.m._tls_ca_free(this.ptr);
14728
+ }
14496
14729
  };
14497
14730
  var TlsLeaf = class {
14498
14731
  engine;
@@ -14557,6 +14790,33 @@ var TlsSession = class {
14557
14790
  free() {
14558
14791
  this.m._tls_session_free(this.ptr);
14559
14792
  }
14793
+ get c() {
14794
+ return this.m;
14795
+ }
14796
+ handshake() {
14797
+ const ret = this.c._tls_handshake(this.ptr);
14798
+ if (ret < 0) throw this.engine.error(ret, "tls handshake");
14799
+ return ret === 1;
14800
+ }
14801
+ get verifyResult() {
14802
+ return this.c._tls_verify_result(this.ptr);
14803
+ }
14804
+ get version() {
14805
+ return this.c._tls_version(this.ptr);
14806
+ }
14807
+ get alpn() {
14808
+ const out = this.engine.intoScratch((p, max) => this.c._tls_alpn(this.ptr, p, max));
14809
+ return out instanceof Uint8Array ? new TextDecoder().decode(out) : void 0;
14810
+ }
14811
+ peerChain() {
14812
+ const chain2 = [];
14813
+ const count2 = this.c._tls_peer_count(this.ptr);
14814
+ for (let i = 0; i < count2; i++) {
14815
+ const der = this.engine.intoScratch((p, max) => this.c._tls_peer_der(this.ptr, i, p, max));
14816
+ if (der instanceof Uint8Array) chain2.push(der);
14817
+ }
14818
+ return chain2;
14819
+ }
14560
14820
  };
14561
14821
  var loading = /* @__PURE__ */ new WeakMap();
14562
14822
  function loadTlsEngine(load) {
@@ -14769,6 +15029,16 @@ function packageTlsEngine(fs, modules) {
14769
15029
  return factory.default({ wasmBinary, locateFile: (path) => path });
14770
15030
  };
14771
15031
  }
15032
+ function packageTlsRoots(fs, modules) {
15033
+ const file = `${modules.replace(/\/+$/, "")}/${TLS_ENGINE_PACKAGE}/dist/roots.der`;
15034
+ return async () => {
15035
+ try {
15036
+ return await fs.readFileBuffer(file);
15037
+ } catch {
15038
+ throw new Error(`TLS client sessions need ${TLS_ENGINE_PACKAGE}'s roots.der in ${modules}`);
15039
+ }
15040
+ };
15041
+ }
14772
15042
  function kernelCa(store) {
14773
15043
  return () => realmCa(CA_OWNER, store);
14774
15044
  }
@@ -14800,6 +15070,7 @@ async function writeCaFile(fs, ca, locks = globalThis.navigator?.locks) {
14800
15070
  function enableNetwork(net, options) {
14801
15071
  let proxy;
14802
15072
  const transport = options.transport ?? missingTransport();
15073
+ if (options.roots) net.tlsClient = { engine: options.engine, roots: options.roots };
14803
15074
  const start2 = () => {
14804
15075
  const tls = new TlsTerminator({
14805
15076
  ca: options.ca,
@@ -16579,6 +16850,285 @@ function encodeReceived(got) {
16579
16850
  return out;
16580
16851
  }
16581
16852
 
16853
+ // src/kernel/net/tls-client.ts
16854
+ var WRITE_CHUNK = 16 * 1024;
16855
+ var BADCERT = [
16856
+ [8, "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"],
16857
+ [1, "CERT_HAS_EXPIRED"],
16858
+ [512, "CERT_NOT_YET_VALID"],
16859
+ [2, "CERT_REVOKED"],
16860
+ [4, "ERR_TLS_CERT_ALTNAME_INVALID"],
16861
+ [2048, "INVALID_PURPOSE"],
16862
+ [4096, "INVALID_PURPOSE"]
16863
+ ];
16864
+ function verifyCode(flags2) {
16865
+ if (flags2 === 0) return void 0;
16866
+ if (flags2 === -1) return "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
16867
+ return BADCERT.find(([bit]) => (flags2 & bit) !== 0)?.[1] ?? "UNABLE_TO_VERIFY_LEAF_SIGNATURE";
16868
+ }
16869
+ var Ciphertext = class {
16870
+ queue = [];
16871
+ ended = false;
16872
+ conn;
16873
+ session;
16874
+ constructor(conn, session) {
16875
+ this.conn = conn;
16876
+ this.session = session;
16877
+ }
16878
+ hand(bytes) {
16879
+ if (bytes.length > 0) this.queue.push(bytes);
16880
+ }
16881
+ async more() {
16882
+ if (this.queue.length === 0 && !this.ended) {
16883
+ const bytes = await this.conn.read();
16884
+ if (bytes) this.queue.push(bytes);
16885
+ else this.ended = true;
16886
+ }
16887
+ if (this.queue.length === 0) {
16888
+ this.session.feedEnd();
16889
+ return false;
16890
+ }
16891
+ while (this.queue.length > 0) {
16892
+ const head = this.queue[0];
16893
+ const n = this.session.feed(head);
16894
+ if (n < head.length) {
16895
+ this.queue[0] = head.subarray(n);
16896
+ break;
16897
+ }
16898
+ this.queue.shift();
16899
+ }
16900
+ return true;
16901
+ }
16902
+ };
16903
+ async function send(conn, session) {
16904
+ for (; ; ) {
16905
+ const out = session.take();
16906
+ if (out.length === 0) return;
16907
+ for (let at = 0; at < out.length; ) {
16908
+ const n = await conn.write(out.subarray(at));
16909
+ if (!(n > 0)) throw new KernelError("EPIPE");
16910
+ at += n;
16911
+ }
16912
+ }
16913
+ }
16914
+ function refused2(engine, session, err) {
16915
+ const flags2 = session.verifyResult;
16916
+ const code = verifyCode(flags2);
16917
+ if (code && flags2 !== -1)
16918
+ return new KernelError("EPROTO", `${code}: ${engine.verifyInfo(flags2).trim()}`);
16919
+ const text = err instanceof TlsError ? err.message : String(err);
16920
+ return new KernelError("EPROTO", `ERR_SSL_HANDSHAKE_FAILURE: ${text}`);
16921
+ }
16922
+ async function handshake(conn, o, session, inbox) {
16923
+ for (; ; ) {
16924
+ let done4;
16925
+ try {
16926
+ done4 = session.handshake();
16927
+ } catch (err) {
16928
+ await send(conn, session).catch(() => void 0);
16929
+ throw refused2(o.engine, session, err);
16930
+ }
16931
+ await send(conn, session);
16932
+ if (done4) return;
16933
+ if (!await inbox.more()) {
16934
+ throw new KernelError(
16935
+ "ECONNRESET",
16936
+ "the server closed the connection during the TLS handshake"
16937
+ );
16938
+ }
16939
+ }
16940
+ }
16941
+ function infoOf(o, session) {
16942
+ const flags2 = session.verifyResult;
16943
+ const code = verifyCode(flags2);
16944
+ return {
16945
+ protocol: session.version === 772 ? "TLSv1.3" : "TLSv1.2",
16946
+ alpnProtocol: session.alpn ?? false,
16947
+ authorized: code === void 0,
16948
+ ...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
16949
+ peerCertificates: session.peerChain()
16950
+ };
16951
+ }
16952
+ function plaintext(conn, session, inbox) {
16953
+ let freed = false;
16954
+ let writeClosed = false;
16955
+ const free = () => {
16956
+ if (freed) return;
16957
+ freed = true;
16958
+ session.free();
16959
+ };
16960
+ return {
16961
+ localAddr: conn.localAddr,
16962
+ remoteAddr: conn.remoteAddr,
16963
+ async read() {
16964
+ for (; ; ) {
16965
+ if (freed) return null;
16966
+ const got = session.read();
16967
+ await send(conn, session);
16968
+ if (got instanceof Uint8Array) return got;
16969
+ if (got === "eof") return null;
16970
+ await inbox.more();
16971
+ }
16972
+ },
16973
+ async write(bytes) {
16974
+ if (freed) throw new KernelError("EPIPE");
16975
+ for (; ; ) {
16976
+ const n = session.write(bytes.subarray(0, WRITE_CHUNK));
16977
+ await send(conn, session);
16978
+ if (n > 0) return n;
16979
+ }
16980
+ },
16981
+ closeWrite() {
16982
+ if (writeClosed || freed) return;
16983
+ writeClosed = true;
16984
+ session.close();
16985
+ void send(conn, session).catch(() => void 0).finally(() => conn.closeWrite());
16986
+ },
16987
+ close() {
16988
+ free();
16989
+ conn.close();
16990
+ }
16991
+ };
16992
+ }
16993
+ async function tlsClient(conn, o, taken = new Uint8Array(0)) {
16994
+ const flags2 = o.insecure ? TLS_CLIENT_INSECURE_SKIP_VERIFY : 0;
16995
+ const session = o.engine.clientSession(o.store, o.servername, o.alpn, flags2);
16996
+ const inbox = new Ciphertext(conn, session);
16997
+ inbox.hand(taken);
16998
+ try {
16999
+ await handshake(conn, o, session, inbox);
17000
+ return { conn: plaintext(conn, session, inbox), info: infoOf(o, session) };
17001
+ } catch (err) {
17002
+ session.free();
17003
+ throw err;
17004
+ }
17005
+ }
17006
+
17007
+ // src/kernel/net/tls-uplink.ts
17008
+ var isIP = (text) => ipv4Bytes(text) !== void 0 || text.includes(":") && ipv6Groups(text) !== void 0;
17009
+ var LABEL2 = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$/;
17010
+ function serverName(name2) {
17011
+ if (isIP(name2.replace(/^\[|\]$/g, ""))) return name2.replace(/^\[|\]$/g, "");
17012
+ const bare = name2.endsWith(".") ? name2.slice(0, -1) : name2;
17013
+ if (bare.length === 0 || bare.length > 253 || !bare.split(".").every((l) => LABEL2.test(l))) {
17014
+ throw new KernelError(
17015
+ "EINVAL",
17016
+ `ERR_INVALID_ARG_VALUE: not a host name: ${JSON.stringify(name2)}`
17017
+ );
17018
+ }
17019
+ return name2;
17020
+ }
17021
+ var defaults = /* @__PURE__ */ new WeakMap();
17022
+ function defaultStore(engine, roots) {
17023
+ let store = defaults.get(engine);
17024
+ if (!store) {
17025
+ const made2 = roots().then((bundle) => {
17026
+ const s = engine.store();
17027
+ s.addBundle(bundle);
17028
+ return s;
17029
+ });
17030
+ store = made2;
17031
+ defaults.set(engine, made2);
17032
+ made2.catch(() => {
17033
+ if (defaults.get(engine) === made2) defaults.delete(engine);
17034
+ });
17035
+ }
17036
+ return store;
17037
+ }
17038
+ function base64Der(text) {
17039
+ const bin = atob(text);
17040
+ const out = new Uint8Array(bin.length);
17041
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
17042
+ return out;
17043
+ }
17044
+ function encode(bytes) {
17045
+ let bin = "";
17046
+ for (const b of bytes) bin += String.fromCharCode(b);
17047
+ return btoa(bin);
17048
+ }
17049
+ function sessionOf(info, servername) {
17050
+ return {
17051
+ path: "kernel",
17052
+ substitutes: false,
17053
+ protocol: info.protocol,
17054
+ alpnProtocol: info.alpnProtocol,
17055
+ authorized: info.authorized,
17056
+ ...info.authorizationError ? {
17057
+ authorizationError: info.authorizationError,
17058
+ authorizationText: info.authorizationText
17059
+ } : {},
17060
+ servername,
17061
+ peerCertificates: info.peerCertificates.map(encode)
17062
+ };
17063
+ }
17064
+ async function setUp(support, req) {
17065
+ const engine = await support.engine();
17066
+ if (!engine.client)
17067
+ throw new KernelError("ENOTSUP", "the installed tls engine has no client sessions");
17068
+ const custom = Array.isArray(req.ca) ? req.ca : void 0;
17069
+ if (!custom) return { engine, store: await defaultStore(engine, support.roots), own: void 0 };
17070
+ if (custom.length === 0)
17071
+ throw new KernelError("EINVAL", "ERR_INVALID_ARG_VALUE: ca has no certificate");
17072
+ const own = engine.store();
17073
+ try {
17074
+ for (const der of custom) own.add(base64Der(der));
17075
+ } catch (err) {
17076
+ own.release();
17077
+ throw new KernelError("EINVAL", `ERR_INVALID_ARG_VALUE: ca: ${err.message}`);
17078
+ }
17079
+ return { engine, store: own, own };
17080
+ }
17081
+ function secure(support, req, servername) {
17082
+ return async (raw) => {
17083
+ const { engine, store, own } = await setUp(support, req);
17084
+ try {
17085
+ return await tlsClient(raw, {
17086
+ engine,
17087
+ store,
17088
+ servername,
17089
+ alpn: req.alpn ?? [],
17090
+ insecure: req.insecure === true
17091
+ });
17092
+ } finally {
17093
+ own?.release();
17094
+ }
17095
+ };
17096
+ }
17097
+ function supportOf(net) {
17098
+ const support = net.tlsClient;
17099
+ if (!support) throw new KernelError("ENOTSUP", "no tls engine for client sessions");
17100
+ return support;
17101
+ }
17102
+ async function uplinkAddress(proc, host) {
17103
+ const bare = host.replace(/^\[|\]$/g, "");
17104
+ if (isIP(bare)) return bare;
17105
+ const [first] = await proc.resolve(host, 0, () => proc.blocking());
17106
+ if (!first) throw new KernelError("ENOENT", `ENOTFOUND: ${host}`);
17107
+ return first;
17108
+ }
17109
+ async function connectSecure(proc, socket, host, port, req) {
17110
+ const servername = serverName(req.servername || host);
17111
+ if (isLoopbackHost(servername) || isLoopbackHost(host)) throw new KernelError("ENOTSUP");
17112
+ const address = await uplinkAddress(proc, host);
17113
+ const route = proc.net.uplinkFor(address);
17114
+ if (!route)
17115
+ throw new KernelError("ENOTSUP", "TLS in the kernel needs a destination the uplink routes");
17116
+ const support = supportOf(proc.net);
17117
+ let info;
17118
+ const make = secure(support, req, servername);
17119
+ await socket.connectSecure({ family: "inet", host: address, port }, route, async (conn) => {
17120
+ info = await conn.upgrade(make);
17121
+ });
17122
+ return sessionOf(info, servername);
17123
+ }
17124
+ async function upgradeSecure(proc, socket, req) {
17125
+ const peer = socket.peer;
17126
+ const host = req.servername || (peer?.family === "inet" ? peer.host : "");
17127
+ const servername = serverName(host);
17128
+ const info = await socket.upgradeSecure(secure(supportOf(proc.net), req, servername));
17129
+ return sessionOf(info, servername);
17130
+ }
17131
+
16582
17132
  // src/kernel/unix-dgram.ts
16583
17133
  var SOL_SOCKET3 = 1;
16584
17134
  var SO_TYPE3 = 3;
@@ -16740,7 +17290,8 @@ var SOCKET_OPS = [
16740
17290
  "sock-resolve",
16741
17291
  "sock-sendto",
16742
17292
  "sock-recvfrom",
16743
- "sock-tls"
17293
+ "sock-tls",
17294
+ "sock-tls-upgrade"
16744
17295
  ];
16745
17296
  function socketAt(fds, fd) {
16746
17297
  const file = anySocketAt(fds, fd);
@@ -16813,7 +17364,9 @@ async function socketSyscall(req, proc) {
16813
17364
  return ok3(addresses);
16814
17365
  }
16815
17366
  case "sock-tls":
16816
- return ok3(tlsOverTransport(req, proc));
17367
+ return ok3(await secureConnect(req, proc));
17368
+ case "sock-tls-upgrade":
17369
+ return ok3(await upgradeSecure(proc, socketAt(fds, req.fd), req));
16817
17370
  default:
16818
17371
  return datagram(req, proc);
16819
17372
  }
@@ -16935,6 +17488,36 @@ var NOT_HTTP_PORTS = /* @__PURE__ */ new Set([
16935
17488
  8883
16936
17489
  ]);
16937
17490
  var HOST_NAME = /^[A-Za-z0-9.-]+$|^\[?[0-9A-Fa-f:.]+\]?$/;
17491
+ function wantsKernel(req) {
17492
+ if (req.path === "kernel") return true;
17493
+ if (req.path === "transport") return false;
17494
+ return Array.isArray(req.ca) || req.alpn !== void 0 && req.alpn.length > 0 && !req.alpn.includes("http/1.1") || NOT_HTTP_PORTS.has(req.port);
17495
+ }
17496
+ async function secureConnect(req, proc) {
17497
+ if (!Number.isInteger(req.port) || req.port < 1 || req.port > 65535)
17498
+ throw new KernelError("EINVAL");
17499
+ const kernelPath = wantsKernel(req) && await uplinked(proc, req.host);
17500
+ if (!kernelPath) {
17501
+ if (req.path === "kernel" || Array.isArray(req.ca)) throw new KernelError("ENOTSUP");
17502
+ return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
17503
+ }
17504
+ const socket = proc.net.socket("inet");
17505
+ const fd = proc.fds.install(new OpenFile(socket), 3);
17506
+ try {
17507
+ return { fd, ...await connectSecure(proc, socket, req.host, req.port, req) };
17508
+ } catch (e) {
17509
+ await Promise.resolve(proc.fds.close(fd));
17510
+ throw e;
17511
+ }
17512
+ }
17513
+ async function uplinked(proc, host) {
17514
+ if (!proc.net.tlsClient || isLoopbackHost(host)) return false;
17515
+ try {
17516
+ return proc.net.uplinkFor(await uplinkAddress(proc, host)) !== void 0;
17517
+ } catch {
17518
+ return false;
17519
+ }
17520
+ }
16938
17521
  function tlsOverTransport(req, proc) {
16939
17522
  if (req.ca) throw new KernelError("ENOTSUP");
16940
17523
  if (req.alpn && req.alpn.length > 0 && !req.alpn.includes("http/1.1")) {
@@ -19935,10 +20518,10 @@ var JobTable = class {
19935
20518
  signalForeground(tty, fallback, sig) {
19936
20519
  this.killGroup(this.tcgetpgrp(tty, fallback), sig);
19937
20520
  }
19938
- fromKeyboard(send) {
20521
+ fromKeyboard(send2) {
19939
20522
  this.keyboard = true;
19940
20523
  try {
19941
- send();
20524
+ send2();
19942
20525
  } finally {
19943
20526
  this.keyboard = false;
19944
20527
  }
@@ -20249,6 +20832,12 @@ var LockService = class {
20249
20832
  lock(pid, path, exclusive, fd) {
20250
20833
  return this.table.lock(pid, path, exclusive, fd);
20251
20834
  }
20835
+ wholeFree(pid, path, exclusive) {
20836
+ return this.table.wholeFree(pid, path, exclusive);
20837
+ }
20838
+ flockFree(key, owner, kind) {
20839
+ return this.table.flockFree(key, owner, kind);
20840
+ }
20252
20841
  unlock(pid, path) {
20253
20842
  this.table.unlock(pid, path);
20254
20843
  }
@@ -20924,7 +21513,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
20924
21513
  await changed(signal);
20925
21514
  }
20926
21515
  };
20927
- const send = async (out, signal) => {
21516
+ const send2 = async (out, signal) => {
20928
21517
  const write = file.write;
20929
21518
  for (let at = 0; at < out.length; ) {
20930
21519
  try {
@@ -20959,7 +21548,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
20959
21548
  raise();
20960
21549
  if (timer !== void 0) clearTimeout(timer);
20961
21550
  timer = void 0;
20962
- await send(stream.push(taken), signal);
21551
+ await send2(stream.push(taken), signal);
20963
21552
  } finally {
20964
21553
  busy = false;
20965
21554
  if (quiet2()) wake();
@@ -21305,19 +21894,19 @@ var SettlingChildren = class {
21305
21894
  this.held = this.held.filter((h) => this.blocking(h.pgid));
21306
21895
  for (const h of ready2) h.send();
21307
21896
  }
21308
- deliver(sig, pgid, send, foreground) {
21897
+ deliver(sig, pgid, send2, foreground) {
21309
21898
  if (!KEY_SIGNALS.has(sig)) {
21310
- send();
21899
+ send2();
21311
21900
  } else if (this.blocking(pgid)) {
21312
- this.held.push({ pgid, send });
21901
+ this.held.push({ pgid, send: send2 });
21313
21902
  } else if (foreground) {
21314
- send();
21903
+ send2();
21315
21904
  const moved2 = () => {
21316
- if (foreground() !== pgid) send();
21905
+ if (foreground() !== pgid) send2();
21317
21906
  };
21318
21907
  this.parked.push({ pgid, send: moved2 });
21319
21908
  } else {
21320
- send();
21909
+ send2();
21321
21910
  }
21322
21911
  }
21323
21912
  blocking(pgid) {
@@ -21462,9 +22051,9 @@ function serveFilesystem(port, handlers, capabilities = {}, options = {}) {
21462
22051
  let open = false;
21463
22052
  const reply = (message3, transfer = []) => port.postMessage(message3, transfer);
21464
22053
  async function hello(message3) {
21465
- const refused2 = driverVersionError(message3.protocol);
21466
- if (refused2) {
21467
- reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused2, errno: "EPROTO" } });
22054
+ const refused3 = driverVersionError(message3.protocol);
22055
+ if (refused3) {
22056
+ reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused3, errno: "EPROTO" } });
21468
22057
  return;
21469
22058
  }
21470
22059
  try {
@@ -23533,9 +24122,9 @@ function interpreter(head) {
23533
24122
  if (words2[0] === "-S") words2.shift();
23534
24123
  return baseName2(words2[0] ?? "");
23535
24124
  }
23536
- function expandDefaults(defaults, env) {
24125
+ function expandDefaults(defaults2, env) {
23537
24126
  const out = {};
23538
- for (const [key, value2] of Object.entries(defaults ?? {})) {
24127
+ for (const [key, value2] of Object.entries(defaults2 ?? {})) {
23539
24128
  let missing4 = false;
23540
24129
  const expanded = value2.replace(ENV_REFERENCE, (_, name2) => {
23541
24130
  const set3 = Object.hasOwn(env, name2) ? env[name2] : void 0;
@@ -23785,6 +24374,7 @@ var Launcher = class {
23785
24374
  enableNetwork(this.net, {
23786
24375
  transport: this.transport,
23787
24376
  engine: kernelTlsEngine(packageTlsEngine(this.verifiedFs(options.fs), this.modulesDir)),
24377
+ roots: packageTlsRoots(this.verifiedFs(options.fs), this.modulesDir),
23788
24378
  ca: this.ca
23789
24379
  });
23790
24380
  enableCdp(this.net, this.cdp);
@@ -24197,13 +24787,13 @@ var Launcher = class {
24197
24787
  if (planned?.target.copy) await need(g, "exec", planned.target.copy, R_OK | X_OK);
24198
24788
  }
24199
24789
  async checkedPlan(req, { ppid, cred, scope }, fds) {
24200
- const refused2 = async (err) => {
24790
+ const refused3 = async (err) => {
24201
24791
  await fds.closeAll();
24202
24792
  throw err.code === "EACCES" ? new SpawnError("EACCES") : err;
24203
24793
  };
24204
- const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused2);
24794
+ const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused3);
24205
24795
  const planned = await this.plan(file, req.argv, req.cwd, scope, req.argv0);
24206
- await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(refused2);
24796
+ await this.mayExec(cred, { ...req, file, pid: ppid }, planned).catch(refused3);
24207
24797
  if (planned) return planned;
24208
24798
  await fds.closeAll();
24209
24799
  throw new SpawnError(await this.unrunnable(file, req.cwd, scope));
@@ -25038,10 +25628,10 @@ var Launcher = class {
25038
25628
  return childHandle(await this.admitted(parent.program.abi !== "js", given, fresh2));
25039
25629
  };
25040
25630
  }
25041
- keySignal(tty, fallback, sig, send) {
25631
+ keySignal(tty, fallback, sig, send2) {
25042
25632
  const pgid = this.jobs.tcgetpgrp(tty, fallback);
25043
25633
  const foreground = () => this.jobs.tcgetpgrp(tty, fallback);
25044
- const keyed = () => this.jobs.fromKeyboard(send);
25634
+ const keyed = () => this.jobs.fromKeyboard(send2);
25045
25635
  this.settling.deliver(sig, pgid, keyed, tty.reading ? void 0 : foreground);
25046
25636
  }
25047
25637
  async resolvePrefixes() {