@ai-ecoverse/slicc-kernel 1.140.0 → 1.140.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.
package/README.md CHANGED
@@ -330,7 +330,7 @@ On top of preview1 a WASI program gets:
330
330
  A kernel without the imports answers `ENOSYS`, and the libc reports `SI_USER` with pid and uid 0, as before. **SIGCHLD:** with `SIGCHLD` set to `SIG_IGN` (by the program, or inherited), or with `SA_NOCLDWAIT` in the flags `slicc.sigaction_set` gets for `SIGCHLD`, an exited child is reaped at once and never stays a zombie: `waitpid` for it is `ECHILD`, and `wait` blocks until every child has exited, then fails with `ECHILD`, as on Linux. `SIGCHLD` is still sent. An explicit `SIG_DFL` turns it back off. A child that a process waits on for `exec`, or that `kernel.run` and the run calls collect, is never reaped that way.
331
331
  - **Pipes** have no file type for WASI and WASIX programs' `fstat` (`st_mode` type 0), because WASI has no FIFO file type. A socket type, as kernels 1.47.3 to 1.48.1 gave them, made Ruby treat a `popen` pipe as a socket (`close_write` then never ends the child's input). The kernel's `slicc_fs.fd_mode` answers `S_IFIFO | 0600` (Linux numbering) for a pipe, and wasix-sysroot 2025.9.30-21 and later take the type from it, so programs built on it see a FIFO (`S_ISFIFO`); older libcs keep only the permission bits. Until then Python's asyncio refuses a pipe for a subprocess (`Pipe transport is only for pipes, sockets and character devices`). They are read and written as pipes; socket calls on them fail with `ENOTSOCK`, and `isatty()` is false. Emscripten programs, bash included, see a FIFO. The same holds for any kernel descriptor that is neither seekable nor a terminal or device, such as captured output.
332
332
  - **Sockets**: the WASIX socket calls (`sock_open`, `sock_pair` for an `AF_UNIX` stream or datagram pair, `bind`, `listen`, `connect`, `accept`, options, local and peer names) are the kernel's loopback sockets, and preview1's `sock_recv` / `sock_send` / `sock_shutdown` work on them and on inherited ones. Writing to a socket whose peer is gone fails with `EPIPE`, through `fd_write` as through `sock_send`, as if `MSG_NOSIGNAL` were set. A write to a pipe, FIFO or terminal whose reader is gone follows the program's `SIGPIPE` disposition, as the kernel knows it (#810): at the default it ends the program with status 141; ignored (also an ignore inherited across `exec` and spawn, as bash's `trap '' PIPE` passes on), the write fails with `EPIPE`; with a handler, the handler runs on the thread that wrote and then the write fails with `EPIPE` (#820); blocked, `SIGPIPE` stays pending and the write fails with `EPIPE`. An Emscripten program's write to a pipe, and its `send` without `MSG_NOSIGNAL`, follow the same rules, except that the kernel doesn't see an Emscripten program's signal mask, so a blocked `SIGPIPE` there still ends it. A WASIX program's libc reads an inherited ignore back through `slicc.sigaction_inherited` (wasix-sysroot -32 and later; see below). An Emscripten program's shim reads it from `Module.sliccKernel.sigInherited()` (#965, homescoop#973). That's a mask with bit n set for signal n (not bit n-1, as the WASIX import has it) holding only inherited `SIG_IGN`s, never `SIGKILL` or `SIGSTOP`. The shim seeds its `sigaction` table from it in a constructor that runs before any user constructor. The kernel puts the function on `Module.sliccKernel` before the glue runs constructors, ahead of the rest of `sliccKernel`. On a kernel without the function it is undefined, and the shim keeps the defaults. HTTP and HTTPS leave through the realm proxy that `https_proxy` names, as for any other program; `resolve` answers `/etc/hosts` names and literal addresses, and the [uplink](#uplink)'s names. `sock_open(SOCK_DGRAM)` on `AF_INET`/`AF_INET6` gives a [datagram socket](#datagram-sockets-udp); `sock_send_to` and `sock_recv_from` carry its addresses, and `RECV_DATA_TRUNCATED` is set in `ro_flags` when a datagram did not fit.
333
- - **Diagnostics**: a trap ends the program with 134 and its message on stderr; a program that crashes its worker otherwise (a JS stack overflow, `RangeError: Maximum call stack size exceeded`, or any other uncaught error) ends with 70, and its message goes to the process's own fd 2 too, so `2>` catches it (#1237), or to the session's stderr when it has no fd 2 to write; with `SLICC_WASM_BACKTRACE=1` the wasm frames follow, named from the module's name section, or from a sidecar for a module shipped without one (`<module>.names` beside it, or the same path in a `<package>-names` package). `SLICC_WASI_STATS=1` makes a program print its calls, counted and timed, as it ends.
333
+ - **Diagnostics**: a trap ends the program with 134 and its message on stderr; a program that crashes its worker otherwise (a JS stack overflow, `RangeError: Maximum call stack size exceeded`, or any other uncaught error) ends with 70, and its message goes to the process's own fd 2 too, so `2>` catches it (#1237), or to the session's stderr when it has no fd 2 to write; with `SLICC_WASM_BACKTRACE=1` the wasm frames follow, named from the module's name section, or from a sidecar for a module shipped without one (`<module>.names` beside it, or the same path in a `<package>-names` package). A sidecar that doesn't fit the module, naming another number of functions than the module has (imported and defined), gets one warning line before the trap message, and the frames keep their raw indices instead of wrong names (#1239). `SLICC_WASI_STATS=1` makes a program print its calls, counted and timed, as it ends.
334
334
 
335
335
  ### Program imports
336
336
 
@@ -118,8 +118,9 @@ var MemoryMeta = class {
118
118
  this.entries.set(to, moved(root(carried.find((entry) => entry.path === from)), to));
119
119
  if (left) this.entries.set(from, left);
120
120
  }
121
- async remove(paths) {
121
+ async remove(paths, left) {
122
122
  for (const path of paths) this.entries.deleteTree(path);
123
+ if (left) this.entries.set(left.path, left);
123
124
  }
124
125
  absent(path) {
125
126
  return !this.entries.has(path);
@@ -265,9 +266,9 @@ var IndexedDbMeta = class {
265
266
  }
266
267
  removing = /* @__PURE__ */ new Map();
267
268
  removeTimer;
268
- async remove(paths) {
269
+ async remove(paths, left) {
269
270
  this.settleRemoves();
270
- return this.removeNow(paths);
271
+ return this.removeNow(paths, left);
271
272
  }
272
273
  async removeFile(path) {
273
274
  const known = this.cache.get(path);
@@ -281,14 +282,16 @@ var IndexedDbMeta = class {
281
282
  REMOVE_WAIT_MS
282
283
  );
283
284
  }
284
- async removeNow(paths) {
285
+ async removeNow(paths, left) {
285
286
  const [transaction, store] = this.transaction("readwrite");
286
287
  for (const path of paths) {
287
288
  store.delete(path);
288
289
  store.delete(descendants(path));
289
290
  }
291
+ if (left) store.put(left);
290
292
  await settle(transaction, () => void 0);
291
293
  this.changed({ trees: paths });
294
+ if (left) this.cache.set(left.path, left);
292
295
  }
293
296
  settleRemoves() {
294
297
  if (this.removing.size > 0) void this.flushRemoves().catch(() => void 0);
@@ -2316,10 +2319,10 @@ var OpfsFs = class {
2316
2319
  return;
2317
2320
  }
2318
2321
  }
2319
- await this.meta.remove([found.path]);
2320
- if (found.handle?.kind === "directory") {
2321
- await this.meta.update(found.path, (entry) => entry ?? vacatedAt(found.path));
2322
- }
2322
+ await this.meta.remove(
2323
+ [found.path],
2324
+ found.handle?.kind === "directory" ? vacatedAt(found.path) : void 0
2325
+ );
2323
2326
  this.touch(Date.now(), parentOf3(found.path));
2324
2327
  }
2325
2328
  links() {
@@ -7125,7 +7128,7 @@ function satisfies(version, range2) {
7125
7128
  }
7126
7129
 
7127
7130
  // src/version.ts
7128
- var KERNEL_VERSION = true ? "1.140.0" : "0.0.0-dev";
7131
+ var KERNEL_VERSION = true ? "1.140.1" : "0.0.0-dev";
7129
7132
  var OS_RELEASE = "6.0.0-slicc";
7130
7133
  function procVersion() {
7131
7134
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC