@ai-ecoverse/slicc-kernel 1.102.0 → 1.102.2

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.
package/dist/node.js CHANGED
@@ -7490,6 +7490,11 @@ function devRemoval(path, cred) {
7490
7490
  if (cred && cred.euid !== 0) return "EACCES";
7491
7491
  return path === "/dev" ? "EBUSY" : "EPERM";
7492
7492
  }
7493
+ function devCreation(path, cred) {
7494
+ if (path === "/proc" || path.startsWith("/proc/")) return "EROFS";
7495
+ if (path === "/dev" || !inDevTree(path)) return void 0;
7496
+ return cred && cred.euid !== 0 ? "EACCES" : "EPERM";
7497
+ }
7493
7498
 
7494
7499
  // src/fs/fresh-modules.ts
7495
7500
  var MAGIC = [0, 97, 115, 109];
@@ -10245,12 +10250,29 @@ async function guardAndResolve(entry, path, req) {
10245
10250
  };
10246
10251
  }
10247
10252
  var REMOVALS = /* @__PURE__ */ new Set(["unlink", "rmdir", "rm"]);
10253
+ var CREATIONS = /* @__PURE__ */ new Set(["write", "mkdir", "symlink", "create"]);
10254
+ var NAMING = /* @__PURE__ */ new Set(["link", "rename"]);
10255
+ async function newDevName(entry, path, req) {
10256
+ const named = NAMING.has(req.op);
10257
+ if (!named && !CREATIONS.has(req.op)) return void 0;
10258
+ const target = named ? entry.fs.resolvePath(entry.cwd, req.arg2 ?? "") : path;
10259
+ const refused2 = devCreation(target, entry.cred?.());
10260
+ if (!refused2) return void 0;
10261
+ const there = await entry.fs.lstat(target).then(
10262
+ () => true,
10263
+ () => false
10264
+ );
10265
+ if (there) return void 0;
10266
+ return { ok: false, errno: refused2, message: `${target}: no new names in /dev or /proc` };
10267
+ }
10248
10268
  async function dispatchOne(entry, req) {
10249
10269
  const { fs, cwd } = entry;
10250
10270
  try {
10251
10271
  const path = fs.resolvePath(cwd, req.path);
10252
10272
  const device = REMOVALS.has(req.op) ? devRemoval(path, entry.cred?.()) : void 0;
10253
10273
  if (device) return { ok: false, errno: device, message: `${path}: a device entry stays` };
10274
+ const made2 = await newDevName(entry, path, req);
10275
+ if (made2) return made2;
10254
10276
  const held = await byHandle(entry, path, req);
10255
10277
  if (held) return held;
10256
10278
  if (req.op === "access") return await accessOp(entry, path, req);
@@ -11107,7 +11129,7 @@ var PATH_OPS = new Set(SYNC_FS_OPS);
11107
11129
  var EARLY_WHOLE_FILE = 64 * 1024;
11108
11130
 
11109
11131
  // src/version.ts
11110
- var KERNEL_VERSION = true ? "1.102.0" : "0.0.0-dev";
11132
+ var KERNEL_VERSION = true ? "1.102.2" : "0.0.0-dev";
11111
11133
  var OS_RELEASE = "6.0.0-slicc";
11112
11134
  function procVersion() {
11113
11135
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -11621,6 +11643,41 @@ var EventFd = class _EventFd {
11621
11643
  }
11622
11644
  };
11623
11645
 
11646
+ // src/kernel/timer.ts
11647
+ var TIMER_MAX_MS = 2147483647;
11648
+ function timerAt(deadline, fire) {
11649
+ let timer;
11650
+ const arm = () => {
11651
+ const left = deadline - performance.now();
11652
+ if (left > 0) {
11653
+ timer = setTimeout(arm, Math.min(left, TIMER_MAX_MS));
11654
+ return;
11655
+ }
11656
+ timer = void 0;
11657
+ fire();
11658
+ };
11659
+ timer = setTimeout(arm, Math.min(Math.max(0, deadline - performance.now()), TIMER_MAX_MS));
11660
+ return () => clearTimeout(timer);
11661
+ }
11662
+ function timerAfter(ms, fire) {
11663
+ return timerAt(performance.now() + ms, fire);
11664
+ }
11665
+ function repeating(first, every, fire) {
11666
+ let next2 = performance.now() + first;
11667
+ let cancel = () => {
11668
+ };
11669
+ const tick = () => {
11670
+ fire();
11671
+ if (every <= 0) return;
11672
+ next2 += every;
11673
+ const now = performance.now();
11674
+ if (next2 <= now) next2 += (Math.floor((now - next2) / every) + 1) * every;
11675
+ cancel = timerAt(next2, tick);
11676
+ };
11677
+ cancel = timerAt(next2, tick);
11678
+ return () => cancel();
11679
+ }
11680
+
11624
11681
  // src/kernel/epoll.ts
11625
11682
  var EPOLL = {
11626
11683
  IN: 1,
@@ -11672,11 +11729,11 @@ function lookup(fds, fd) {
11672
11729
  }
11673
11730
  function pause(ms, signal) {
11674
11731
  return new Promise((resolve2) => {
11675
- const timer = setTimeout(resolve2, ms);
11732
+ const cancel = timerAfter(ms, resolve2);
11676
11733
  signal.addEventListener(
11677
11734
  "abort",
11678
11735
  () => {
11679
- clearTimeout(timer);
11736
+ cancel();
11680
11737
  resolve2();
11681
11738
  },
11682
11739
  { once: true }
@@ -11742,17 +11799,14 @@ var EpollFile = class _EpollFile {
11742
11799
  const round = new AbortController();
11743
11800
  const woken = this.changes.wait(AbortSignal.any([round.signal, signal]));
11744
11801
  woken.catch(() => void 0);
11745
- let timer;
11746
- const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [
11747
- new Promise(
11748
- (resolve2) => timer = setTimeout(resolve2, deadline - performance.now())
11749
- )
11750
- ];
11802
+ let cancel = () => {
11803
+ };
11804
+ const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [new Promise((resolve2) => cancel = timerAt(deadline, resolve2))];
11751
11805
  try {
11752
11806
  await Promise.race([woken, ...expiry]);
11753
11807
  } finally {
11754
11808
  round.abort();
11755
- clearTimeout(timer);
11809
+ cancel();
11756
11810
  }
11757
11811
  }
11758
11812
  }
@@ -12097,9 +12151,10 @@ var AsyncOps = class {
12097
12151
  }
12098
12152
  sleep(timeoutMs, signal) {
12099
12153
  return new Promise((resolve2, reject) => {
12100
- let timer;
12154
+ let cancel = () => {
12155
+ };
12101
12156
  const cleanup = () => {
12102
- clearTimeout(timer);
12157
+ cancel();
12103
12158
  this.waiters.delete(wake);
12104
12159
  signal.removeEventListener("abort", abort);
12105
12160
  };
@@ -12114,10 +12169,10 @@ var AsyncOps = class {
12114
12169
  this.waiters.add(wake);
12115
12170
  signal.addEventListener("abort", abort, { once: true });
12116
12171
  if (timeoutMs !== void 0) {
12117
- timer = setTimeout(() => {
12172
+ cancel = timerAfter(timeoutMs, () => {
12118
12173
  cleanup();
12119
12174
  resolve2(false);
12120
- }, timeoutMs);
12175
+ });
12121
12176
  }
12122
12177
  });
12123
12178
  }
@@ -14168,14 +14223,14 @@ async function runChild(req, deps) {
14168
14223
  return frame2(outcome2, new Uint8Array(0), new Uint8Array(0));
14169
14224
  }
14170
14225
  if (failure !== void 0) kill();
14171
- const timer = req.timeoutMs !== void 0 && req.timeoutMs > 0 ? setTimeout(() => stop("ETIMEDOUT"), req.timeoutMs) : void 0;
14226
+ const cancel = req.timeoutMs !== void 0 && req.timeoutMs > 0 ? timerAfter(req.timeoutMs, () => stop("ETIMEDOUT")) : void 0;
14172
14227
  let status;
14173
14228
  try {
14174
14229
  status = await reaped(deps, pid);
14175
14230
  const open = controls.filter((c) => c.opened);
14176
14231
  await Promise.race([Promise.all(open.map((c) => c.eof)), decided.promise]);
14177
14232
  } finally {
14178
- clearTimeout(timer);
14233
+ cancel?.();
14179
14234
  for (const control of controls) control.shut = true;
14180
14235
  }
14181
14236
  const out = deps.children.captured(pid, 1);
@@ -14231,27 +14286,23 @@ async function waitReady(fds, read, write, deadline, interrupted3) {
14231
14286
  const file = fds.get(fd).file;
14232
14287
  return file.changed === void 0 ? [] : [file.changed(round.signal).catch(() => void 0)];
14233
14288
  });
14234
- let timer;
14235
- const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [
14236
- new Promise(
14237
- (resolve2) => timer = setTimeout(resolve2, deadline - performance.now())
14238
- )
14239
- ];
14289
+ let cancel = () => {
14290
+ };
14291
+ const expiry = deadline === Number.POSITIVE_INFINITY ? [] : [new Promise((resolve2) => cancel = timerAt(deadline, resolve2))];
14240
14292
  try {
14241
14293
  await Promise.race([...changes, ...expiry, interrupted3]);
14242
14294
  } finally {
14243
14295
  round.abort();
14244
- clearTimeout(timer);
14296
+ cancel();
14245
14297
  }
14246
14298
  }
14247
14299
  }
14248
14300
 
14249
14301
  // src/kernel/sem.ts
14250
14302
  var SEM_VALUE_MAX = 2147483647;
14251
- var SEM_NAMES_MAX = 4096;
14252
- var SEM_HANDLES_MAX = 256;
14303
+ var SEM_NAMES_MAX = 65536;
14304
+ var SEM_HANDLES_MAX = 65536;
14253
14305
  var NAME_MAX = 251;
14254
- var TIMER_MAX_MS = 2147483647;
14255
14306
  var SEM_OPS = [
14256
14307
  "sem-open",
14257
14308
  "sem-close",
@@ -14288,11 +14339,12 @@ var Semaphore = class {
14288
14339
  if (signal.aborted) return Promise.reject(new KernelError("EINTR"));
14289
14340
  return new Promise((resolve2, reject) => {
14290
14341
  const deadline = timeoutMs < 0 ? Number.POSITIVE_INFINITY : performance.now() + timeoutMs;
14291
- let timer;
14342
+ let cancel = () => {
14343
+ };
14292
14344
  const leave = () => {
14293
14345
  const at = this.waiters.indexOf(waiter);
14294
14346
  if (at >= 0) this.waiters.splice(at, 1);
14295
- clearTimeout(timer);
14347
+ cancel();
14296
14348
  signal.removeEventListener("abort", abort);
14297
14349
  };
14298
14350
  const waiter = {
@@ -14306,18 +14358,13 @@ var Semaphore = class {
14306
14358
  reject(new KernelError("EINTR"));
14307
14359
  };
14308
14360
  const expire = () => {
14309
- const left = deadline - performance.now();
14310
- if (left > 0) {
14311
- timer = setTimeout(expire, Math.min(left, TIMER_MAX_MS));
14312
- return;
14313
- }
14314
14361
  leave();
14315
14362
  resolve2(false);
14316
14363
  };
14317
14364
  this.waiters.push(waiter);
14318
14365
  signal.addEventListener("abort", abort, { once: true });
14319
14366
  if (deadline !== Number.POSITIVE_INFINITY) {
14320
- timer = setTimeout(expire, Math.min(timeoutMs, TIMER_MAX_MS));
14367
+ cancel = timerAt(deadline, expire);
14321
14368
  }
14322
14369
  });
14323
14370
  }
@@ -14352,6 +14399,10 @@ var SemTable = class {
14352
14399
  var SemHandles = class _SemHandles {
14353
14400
  byHandle = /* @__PURE__ */ new Map();
14354
14401
  next = 1;
14402
+ limit;
14403
+ constructor(limit = SEM_HANDLES_MAX) {
14404
+ this.limit = limit;
14405
+ }
14355
14406
  add(sem) {
14356
14407
  for (const [handle2, entry] of this.byHandle) {
14357
14408
  if (entry.sem === sem) {
@@ -14359,7 +14410,7 @@ var SemHandles = class _SemHandles {
14359
14410
  return handle2;
14360
14411
  }
14361
14412
  }
14362
- if (this.byHandle.size >= SEM_HANDLES_MAX) throw new KernelError("EMFILE");
14413
+ if (this.byHandle.size >= this.limit) throw new KernelError("EMFILE");
14363
14414
  const handle = this.next++;
14364
14415
  this.byHandle.set(handle, { sem, opens: 1 });
14365
14416
  return handle;
@@ -14375,7 +14426,7 @@ var SemHandles = class _SemHandles {
14375
14426
  if (--entry.opens === 0) this.byHandle.delete(handle);
14376
14427
  }
14377
14428
  fork() {
14378
- const child = new _SemHandles();
14429
+ const child = new _SemHandles(this.limit);
14379
14430
  child.next = this.next;
14380
14431
  for (const [handle, entry] of this.byHandle) child.byHandle.set(handle, { ...entry });
14381
14432
  return child;
@@ -16662,17 +16713,12 @@ var WasmProcess = class {
16662
16713
  (req, cancelled) => this.syscall(req, cancelled),
16663
16714
  () => this.options.onAsync?.()
16664
16715
  );
16665
- alarmEvery;
16666
16716
  setAlarm(sig, first, every, timer) {
16667
16717
  if (!isSignal(sig)) throw new KernelError("EINVAL");
16668
16718
  this.clearAlarm();
16669
16719
  if (first <= 0) return;
16670
16720
  const fire = timer === void 0 ? () => this.options.raise?.(sig) : () => this.timerExpired(timer);
16671
- this.alarm = setTimeout(() => {
16672
- this.alarm = void 0;
16673
- fire();
16674
- if (every > 0) this.alarmEvery = setInterval(fire, every);
16675
- }, first);
16721
+ this.alarm = repeating(first, every, fire);
16676
16722
  }
16677
16723
  timerExpired(which) {
16678
16724
  this.options.onTimer?.(which);
@@ -16681,10 +16727,8 @@ var WasmProcess = class {
16681
16727
  blocked2.abort();
16682
16728
  }
16683
16729
  clearAlarm() {
16684
- clearTimeout(this.alarm);
16685
- clearInterval(this.alarmEvery);
16730
+ this.alarm?.();
16686
16731
  this.alarm = void 0;
16687
- this.alarmEvery = void 0;
16688
16732
  }
16689
16733
  async exit() {
16690
16734
  if (this.exited) return;