@ai-ecoverse/slicc-kernel 1.158.0 → 1.159.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.
@@ -5193,6 +5193,9 @@ var KernelPipe = class {
5193
5193
  readers = 0;
5194
5194
  writers = 0;
5195
5195
  waiters = [];
5196
+ pushed = 0;
5197
+ taken = 0;
5198
+ marks = [];
5196
5199
  capacity;
5197
5200
  constructor(capacity = PIPE_CAPACITY) {
5198
5201
  this.capacity = capacity;
@@ -5223,6 +5226,7 @@ var KernelPipe = class {
5223
5226
  if (this.readers === 0) {
5224
5227
  this.chunks = [];
5225
5228
  this.size = 0;
5229
+ this.dropMarks(() => true);
5226
5230
  }
5227
5231
  this.wake();
5228
5232
  }
@@ -5235,10 +5239,59 @@ var KernelPipe = class {
5235
5239
  if (this.writers === 0) return new Uint8Array(0);
5236
5240
  await this.changed(signal);
5237
5241
  }
5238
- const out = this.take(Math.min(max, this.size));
5242
+ const out = this.take(this.bounded(Math.min(max, this.size)));
5243
+ this.dropMarks((mark) => mark.at < this.taken);
5239
5244
  this.wake();
5240
5245
  return out;
5241
5246
  }
5247
+ get inFlight() {
5248
+ return this.marks.reduce((sum, mark) => sum + mark.count, 0);
5249
+ }
5250
+ async receive(max, nonblock, signal) {
5251
+ while (this.size === 0) {
5252
+ if (this.writers === 0) return { bytes: new Uint8Array(0), marks: [] };
5253
+ if (nonblock) throw new PipeError("EAGAIN");
5254
+ await this.changed(signal);
5255
+ }
5256
+ const marks = this.marks.filter((mark) => mark.at === this.taken);
5257
+ this.marks = this.marks.filter((mark) => mark.at !== this.taken);
5258
+ const bytes = this.take(this.bounded(Math.min(max, this.size)));
5259
+ this.dropMarks((mark) => mark.at < this.taken);
5260
+ this.wake();
5261
+ return { bytes, marks };
5262
+ }
5263
+ async writeMarked(bytes, mark, nonblock, signal) {
5264
+ while (this.readers > 0 && this.size >= this.capacity) {
5265
+ if (nonblock) throw new PipeError("EAGAIN");
5266
+ await this.changed(signal);
5267
+ }
5268
+ if (this.readers === 0) throw new PipeError("EPIPE");
5269
+ const before = this.pushed;
5270
+ const made2 = mark(before);
5271
+ this.marks.push(made2);
5272
+ try {
5273
+ const n = await this.write(bytes, signal);
5274
+ this.orphan(made2, before);
5275
+ return n;
5276
+ } catch (err) {
5277
+ this.orphan(made2, before);
5278
+ throw err;
5279
+ }
5280
+ }
5281
+ orphan(made2, before) {
5282
+ if (this.pushed !== before) return;
5283
+ this.dropMarks((mark) => mark === made2);
5284
+ }
5285
+ bounded(n) {
5286
+ const next3 = this.marks.find((mark) => mark.at > this.taken);
5287
+ return next3 ? Math.min(n, next3.at - this.taken) : n;
5288
+ }
5289
+ dropMarks(gone) {
5290
+ const dropped2 = this.marks.filter(gone);
5291
+ if (dropped2.length === 0) return;
5292
+ this.marks = this.marks.filter((mark) => !gone(mark));
5293
+ for (const mark of dropped2) mark.drop();
5294
+ }
5242
5295
  async peek(max, signal) {
5243
5296
  while (this.size === 0) {
5244
5297
  if (this.writers === 0) return new Uint8Array(0);
@@ -5271,6 +5324,7 @@ var KernelPipe = class {
5271
5324
  const n = Math.min(room, bytes.length - offset);
5272
5325
  this.chunks.push(bytes.slice(offset, offset + n));
5273
5326
  this.size += n;
5327
+ this.pushed += n;
5274
5328
  offset += n;
5275
5329
  this.wake();
5276
5330
  }
@@ -5288,6 +5342,7 @@ var KernelPipe = class {
5288
5342
  else this.chunks[0] = head.subarray(count2);
5289
5343
  }
5290
5344
  this.size -= n;
5345
+ this.taken += n;
5291
5346
  return out;
5292
5347
  }
5293
5348
  changed(signal) {
@@ -6164,6 +6219,30 @@ var KernelSocket = class _KernelSocket {
6164
6219
  if (bytes.length === 0 && this.reset) throw this.reset;
6165
6220
  return bytes;
6166
6221
  }
6222
+ rightsLink() {
6223
+ const link2 = this.connection();
6224
+ if (this.domain !== "unix" || this.switch || this.served) throw new KernelError("EOPNOTSUPP");
6225
+ if (this.refused) throw this.refused;
6226
+ return link2;
6227
+ }
6228
+ sendRights(bytes, mark, nonblock, signal) {
6229
+ const { tx } = this.rightsLink();
6230
+ if (this.writeShut) throw new KernelError("EPIPE");
6231
+ return pipeCall(() => tx.writeMarked(bytes, (at) => mark(at, tx.inFlight), nonblock, signal));
6232
+ }
6233
+ async receiveRights(max, nonblock, signal) {
6234
+ const { rx } = this.rightsLink();
6235
+ if (this.readShut || max <= 0) return { bytes: EMPTY, marks: [] };
6236
+ const got = await pipeCall(() => rx.receive(max, nonblock, signal));
6237
+ if (this.refused) {
6238
+ for (const mark of got.marks) mark.drop();
6239
+ throw this.refused;
6240
+ }
6241
+ return got;
6242
+ }
6243
+ get secured() {
6244
+ return this.served || this.tlsDial || this.serving !== void 0 || !!this.switch?.upgraded;
6245
+ }
6167
6246
  async write(bytes, signal) {
6168
6247
  const { tx } = this.connection();
6169
6248
  if (this.refused) throw this.refused;
@@ -6305,11 +6384,13 @@ var KernelSocket = class _KernelSocket {
6305
6384
  switch;
6306
6385
  connectSecure(addr, route2, secure2) {
6307
6386
  if (this.state !== "open") throw new KernelError("EISCONN");
6387
+ this.tlsDial = true;
6308
6388
  return this.dial(addr, route2, secure2);
6309
6389
  }
6310
6390
  serving;
6311
6391
  pending;
6312
6392
  served = false;
6393
+ tlsDial = false;
6313
6394
  get loopbackLinked() {
6314
6395
  return this.state === "connected" && !this.switch;
6315
6396
  }
@@ -8112,7 +8193,7 @@ function satisfies(version, range2) {
8112
8193
  }
8113
8194
 
8114
8195
  // src/version.ts
8115
- var KERNEL_VERSION = true ? "1.158.0" : "0.0.0-dev";
8196
+ var KERNEL_VERSION = true ? "1.159.0" : "0.0.0-dev";
8116
8197
  var OS_RELEASE = "6.0.0-slicc";
8117
8198
  function procVersion() {
8118
8199
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -12022,6 +12103,7 @@ function replyStream(reply) {
12022
12103
  }
12023
12104
  });
12024
12105
  }
12106
+ var HELD_MAX = 16;
12025
12107
  var Throttle = class {
12026
12108
  window = 0;
12027
12109
  count = 0;
@@ -12037,7 +12119,8 @@ var Throttle = class {
12037
12119
  var EmbedderChannel = class {
12038
12120
  access;
12039
12121
  owner;
12040
- caller;
12122
+ current;
12123
+ held = [];
12041
12124
  broker;
12042
12125
  header = new Uint8Array(0);
12043
12126
  body;
@@ -12053,12 +12136,24 @@ var EmbedderChannel = class {
12053
12136
  constructor(broker, access2, caller) {
12054
12137
  this.broker = broker;
12055
12138
  this.access = access2;
12056
- this.caller = caller;
12139
+ this.current = caller;
12057
12140
  this.owner = caller.pid;
12058
12141
  }
12059
12142
  get dispatched() {
12060
12143
  return this.body !== void 0;
12061
12144
  }
12145
+ get caller() {
12146
+ return this.current;
12147
+ }
12148
+ set caller(caller) {
12149
+ this.current = caller;
12150
+ const held = this.held;
12151
+ this.held = [];
12152
+ for (const line of held) this.tell(line);
12153
+ }
12154
+ tell(line) {
12155
+ if (!this.current.progress(line) && this.held.length < HELD_MAX) this.held.push(line);
12156
+ }
12062
12157
  fail(err) {
12063
12158
  this.failure ??= embedderFailure(err);
12064
12159
  return this.failure;
@@ -12075,7 +12170,7 @@ var EmbedderChannel = class {
12075
12170
  this.body = body;
12076
12171
  const prefix = this.caller.name;
12077
12172
  const progress = (line) => {
12078
- if (this.throttle.allow(Date.now())) this.caller.progress(`${prefix}: ${lineOf2(line)}`);
12173
+ if (this.throttle.allow(Date.now())) this.tell(`${prefix}: ${lineOf2(line)}`);
12079
12174
  };
12080
12175
  const asked = Promise.resolve().then(
12081
12176
  () => hook.handle({
@@ -14648,8 +14743,8 @@ async function guarded(entry, path, req) {
14648
14743
  const paths = await guard(g, path, req, entry.cwd);
14649
14744
  return { paths };
14650
14745
  } catch (err) {
14651
- const refusal = err.code === "EACCES";
14652
- const refused3 = req.op === "exists" && refusal ? json2(false) : toErrno(err);
14746
+ const refusal2 = err.code === "EACCES";
14747
+ const refused3 = req.op === "exists" && refusal2 ? json2(false) : toErrno(err);
14653
14748
  return { refused: refused3 };
14654
14749
  }
14655
14750
  }
@@ -21586,19 +21681,6 @@ var KernelDgram = class {
21586
21681
  }
21587
21682
  };
21588
21683
 
21589
- // src/kernel/net/datagram-wire.ts
21590
- function encodeReceived(got) {
21591
- const host = new TextEncoder().encode(got.host);
21592
- const out = new Uint8Array(4 + host.length + got.bytes.length);
21593
- const view2 = new DataView(out.buffer);
21594
- view2.setUint8(0, (got.truncated ? 1 : 0) | (got.unix ? 2 : 0));
21595
- view2.setUint16(1, got.port);
21596
- view2.setUint8(3, host.length);
21597
- out.set(host, 4);
21598
- out.set(got.bytes, 4 + host.length);
21599
- return out;
21600
- }
21601
-
21602
21684
  // src/kernel/net/sealed-binding.ts
21603
21685
  var HASH_OF_SIGNATURE = {
21604
21686
  "1.2.840.113549.1.1.4": "SHA-256",
@@ -23318,6 +23400,120 @@ function isDatagram(file) {
23318
23400
  return file instanceof KernelDgram || file instanceof UnixDgram;
23319
23401
  }
23320
23402
 
23403
+ // src/kernel/fd-rights.ts
23404
+ var RIGHTS_MAX = 253;
23405
+ var RIGHTS_IN_FLIGHT = 1024;
23406
+ var RECEIVE_MAX = 1024 * 1024;
23407
+ var CTRUNC = 1;
23408
+ var RightsMark = class {
23409
+ at;
23410
+ passed;
23411
+ constructor(at, passed) {
23412
+ this.at = at;
23413
+ this.passed = passed;
23414
+ }
23415
+ get count() {
23416
+ return this.passed.length;
23417
+ }
23418
+ drop() {
23419
+ for (const { file } of this.passed) void Promise.resolve(file.release()).catch(() => void 0);
23420
+ }
23421
+ };
23422
+ function refusal(file) {
23423
+ if (file instanceof KernelSocket) {
23424
+ if (file.domain === "unix") return "EOPNOTSUPP";
23425
+ return file.secured ? "EPERM" : void 0;
23426
+ }
23427
+ if (file instanceof UnixDgram) return "EOPNOTSUPP";
23428
+ if (file instanceof EpollFile || file instanceof TlsContext) return "EPERM";
23429
+ return file.sealed || file.clipboard || file.embedder ? "EPERM" : void 0;
23430
+ }
23431
+ function carrierAt(fds, fd) {
23432
+ const file = fds.get(fd).file;
23433
+ if (!(file instanceof KernelSocket)) {
23434
+ throw new KernelError(file instanceof UnixDgram ? "EOPNOTSUPP" : "ENOTSOCK");
23435
+ }
23436
+ return file;
23437
+ }
23438
+ async function sendRights(fds, req, signal) {
23439
+ const carrier = carrierAt(fds, req.fd);
23440
+ if (req.nonblock && !carrier.poll().writable) throw new KernelError("EAGAIN");
23441
+ if (req.nonblock) signal = AbortSignal.abort();
23442
+ if (req.fds.length === 0) return carrier.write(req.body, signal);
23443
+ if (req.fds.length > RIGHTS_MAX || req.body.length === 0) throw new KernelError("EINVAL");
23444
+ const passed = req.fds.map((fd) => ({ file: fds.get(fd), status: fds.statusFlags(fd) }));
23445
+ for (const { file } of passed) {
23446
+ const errno3 = refusal(file.file);
23447
+ if (errno3) throw new KernelError(errno3, "this descriptor cannot be passed");
23448
+ }
23449
+ for (const { file } of passed) file.retain();
23450
+ let handed2 = false;
23451
+ const mark = (at, inFlight) => {
23452
+ if (inFlight + passed.length > RIGHTS_IN_FLIGHT) {
23453
+ throw new KernelError("EMFILE", "too many descriptors in flight");
23454
+ }
23455
+ handed2 = true;
23456
+ return new RightsMark(at, passed);
23457
+ };
23458
+ try {
23459
+ return await carrier.sendRights(req.body, mark, req.nonblock, signal);
23460
+ } catch (err) {
23461
+ if (!handed2) new RightsMark(0, passed).drop();
23462
+ throw err;
23463
+ }
23464
+ }
23465
+ function installed(fds, passed, cloexec) {
23466
+ let fd;
23467
+ try {
23468
+ fd = fds.install(passed.file);
23469
+ } catch {
23470
+ return void 0;
23471
+ }
23472
+ if (passed.status !== void 0) fds.setStatusFlags(fd, passed.status);
23473
+ if (cloexec) fds.setCloseOnExec(fd);
23474
+ return fd;
23475
+ }
23476
+ function encodeRights(bytes, got, truncated2) {
23477
+ const out = new Uint8Array(8 + got.length * 4 + bytes.length);
23478
+ const view2 = new DataView(out.buffer);
23479
+ view2.setUint32(0, got.length, true);
23480
+ view2.setUint32(4, truncated2 ? CTRUNC : 0, true);
23481
+ for (const [i, fd] of got.entries()) view2.setUint32(8 + i * 4, fd, true);
23482
+ out.set(bytes, 8 + got.length * 4);
23483
+ return out;
23484
+ }
23485
+ async function receiveRights(fds, req, signal) {
23486
+ const carrier = carrierAt(fds, req.fd);
23487
+ const { bytes, marks } = await carrier.receiveRights(
23488
+ Math.min(req.max, RECEIVE_MAX),
23489
+ req.nonblock,
23490
+ signal
23491
+ );
23492
+ const got = [];
23493
+ let truncated2 = false;
23494
+ for (const mark of marks) {
23495
+ for (const passed of mark.passed) {
23496
+ const fd = installed(fds, passed, req.cloexec);
23497
+ if (fd === void 0) truncated2 = true;
23498
+ else got.push(fd);
23499
+ }
23500
+ }
23501
+ return encodeRights(bytes, got, truncated2);
23502
+ }
23503
+
23504
+ // src/kernel/net/datagram-wire.ts
23505
+ function encodeReceived(got) {
23506
+ const host = new TextEncoder().encode(got.host);
23507
+ const out = new Uint8Array(4 + host.length + got.bytes.length);
23508
+ const view2 = new DataView(out.buffer);
23509
+ view2.setUint8(0, (got.truncated ? 1 : 0) | (got.unix ? 2 : 0));
23510
+ view2.setUint16(1, got.port);
23511
+ view2.setUint8(3, host.length);
23512
+ out.set(host, 4);
23513
+ out.set(got.bytes, 4 + host.length);
23514
+ return out;
23515
+ }
23516
+
23321
23517
  // src/kernel/socket-syscalls.ts
23322
23518
  var SOCKET_OPS = [
23323
23519
  "sock-open",
@@ -23328,6 +23524,8 @@ var SOCKET_OPS = [
23328
23524
  "sock-connect",
23329
23525
  "sock-shutdown",
23330
23526
  "sock-reset",
23527
+ "sock-sendmsg",
23528
+ "sock-recvmsg",
23331
23529
  "sock-name",
23332
23530
  "sock-getopt",
23333
23531
  "sock-setopt",
@@ -23398,6 +23596,10 @@ async function socketSyscall(req, proc) {
23398
23596
  case "sock-reset":
23399
23597
  socketAt(fds, req.fd).resetOnClose();
23400
23598
  return ok3();
23599
+ case "sock-sendmsg":
23600
+ return ok3(await sendRights(fds, req, proc.blocking()));
23601
+ case "sock-recvmsg":
23602
+ return { ok: true, kind: "bytes", bytes: await receiveRights(fds, req, proc.blocking()) };
23401
23603
  case "sock-name": {
23402
23604
  const socket = anySocketAt(fds, req.fd);
23403
23605
  const addr = req.peer ? socket.peer : socket.local;
@@ -25277,7 +25479,11 @@ var WasmProcess = class {
25277
25479
  client: session.client,
25278
25480
  tags: this.options.embedder?.tagsOf(this.pid),
25279
25481
  name: name2,
25280
- progress: (line) => void this.complainLine(line),
25482
+ progress: (line) => {
25483
+ if (!this.fds.has(2)) return false;
25484
+ void this.complainLine(line);
25485
+ return true;
25486
+ },
25281
25487
  closing: () => AbortSignal.any([this.interrupt.signal, this.gone.signal])
25282
25488
  };
25283
25489
  }
@@ -27987,7 +28193,7 @@ function enableDnsStub(net, stub) {
27987
28193
 
27988
28194
  // src/kernel/net/redirect-hops.ts
27989
28195
  var HELD_MS = 3e4;
27990
- var HELD_MAX = 64;
28196
+ var HELD_MAX2 = 64;
27991
28197
  var HELD_PER_OWNER = 8;
27992
28198
  var MATCHED = ["range", "if-none-match", "if-modified-since", "if-range", "accept-encoding"];
27993
28199
  var KERNEL = -1;
@@ -28033,7 +28239,7 @@ function replayingHops(inner, heldMs = HELD_MS) {
28033
28239
  drop(key);
28034
28240
  const mine = [...held.keys()].filter((k) => held.get(k)?.owner === chain2.owner);
28035
28241
  if (mine.length >= HELD_PER_OWNER) drop(mine[0]);
28036
- if (held.size >= HELD_MAX) drop(held.keys().next().value);
28242
+ if (held.size >= HELD_MAX2) drop(held.keys().next().value);
28037
28243
  const timer = setTimeout(() => drop(key), heldMs);
28038
28244
  timer.unref?.();
28039
28245
  held.set(key, { ...chain2, timer });