@ai-ecoverse/slicc-kernel 1.158.1 → 1.159.1

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.1" : "0.0.0-dev";
8196
+ var KERNEL_VERSION = true ? "1.159.1" : "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
@@ -14662,8 +14743,8 @@ async function guarded(entry, path, req) {
14662
14743
  const paths = await guard(g, path, req, entry.cwd);
14663
14744
  return { paths };
14664
14745
  } catch (err) {
14665
- const refusal = err.code === "EACCES";
14666
- 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);
14667
14748
  return { refused: refused3 };
14668
14749
  }
14669
14750
  }
@@ -21600,19 +21681,6 @@ var KernelDgram = class {
21600
21681
  }
21601
21682
  };
21602
21683
 
21603
- // src/kernel/net/datagram-wire.ts
21604
- function encodeReceived(got) {
21605
- const host = new TextEncoder().encode(got.host);
21606
- const out = new Uint8Array(4 + host.length + got.bytes.length);
21607
- const view2 = new DataView(out.buffer);
21608
- view2.setUint8(0, (got.truncated ? 1 : 0) | (got.unix ? 2 : 0));
21609
- view2.setUint16(1, got.port);
21610
- view2.setUint8(3, host.length);
21611
- out.set(host, 4);
21612
- out.set(got.bytes, 4 + host.length);
21613
- return out;
21614
- }
21615
-
21616
21684
  // src/kernel/net/sealed-binding.ts
21617
21685
  var HASH_OF_SIGNATURE = {
21618
21686
  "1.2.840.113549.1.1.4": "SHA-256",
@@ -23332,6 +23400,120 @@ function isDatagram(file) {
23332
23400
  return file instanceof KernelDgram || file instanceof UnixDgram;
23333
23401
  }
23334
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
+
23335
23517
  // src/kernel/socket-syscalls.ts
23336
23518
  var SOCKET_OPS = [
23337
23519
  "sock-open",
@@ -23342,6 +23524,8 @@ var SOCKET_OPS = [
23342
23524
  "sock-connect",
23343
23525
  "sock-shutdown",
23344
23526
  "sock-reset",
23527
+ "sock-sendmsg",
23528
+ "sock-recvmsg",
23345
23529
  "sock-name",
23346
23530
  "sock-getopt",
23347
23531
  "sock-setopt",
@@ -23412,6 +23596,10 @@ async function socketSyscall(req, proc) {
23412
23596
  case "sock-reset":
23413
23597
  socketAt(fds, req.fd).resetOnClose();
23414
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()) };
23415
23603
  case "sock-name": {
23416
23604
  const socket = anySocketAt(fds, req.fd);
23417
23605
  const addr = req.peer ? socket.peer : socket.local;