@ai-ecoverse/slicc-kernel 1.108.0 → 1.108.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
@@ -322,7 +322,7 @@ A WASI command can name an ES module of its package that provides imports of its
322
322
 
323
323
  - `memory()`, `instance()` (after instantiation), `tid` (1 for the main thread), `argv`, `env`, `cwd()`;
324
324
  - `fs`: the synchronous filesystem the WASI calls use (absolute paths);
325
- - `fds`: `open(path, { read, write, append, create, exclusive, truncate, directory, nofollow, mode })` returns a WASI descriptor of the program; `close`, `fstat` (`{ kind, path, mode, uid, gid, size, ino, mtimeMs }`), `fchmod`, and `tryLock(fd, exclusive)` / `unlock(fd)`: advisory locks held by the kernel across processes and threads, keyed by path, released on unlock, on closing the descriptor and at exit (`tryLock` returns 0, or 6 when another process holds the lock);
325
+ - `fds`: `open(path, { read, write, append, create, exclusive, truncate, directory, nofollow, mode })` returns a WASI descriptor of the program; `mode` is a new file's mode. With `create` and `exclusive` under users `report` or `enforce`, the file is created with it, less the umask, as `open(2)` does, and the name is only checked by the create itself (a symlink there is `EEXIST`). Otherwise the mode is set exactly once the file is open; `close`, `fstat` (`{ kind, path, mode, uid, gid, size, ino, mtimeMs }`), `fchmod`, and `tryLock(fd, exclusive)` / `unlock(fd)`: advisory locks held by the kernel across processes and threads, keyed by path, released on unlock, on closing the descriptor and at exit (`tryLock` returns 0, or 6 when another process holds the lock);
326
326
  - `syscall(req)`: a kernel syscall, synchronously;
327
327
  - `net.connect({ host, port, nonblock })` connects a TCP socket to the kernel's loopback and returns its kernel descriptor. `host` is `localhost` or `127.x.y.z`; anything else, or a port outside 1–65535, is `EINVAL`. A refused connection throws `ECONNREFUSED`. The connection carries the program's own identity, as any connect from its process does, so a [page facade](#page-facades) such as `SLICC_LINK_URL` sees the program's stamp. With `nonblock` it returns at once, and `net.ready(fd)` answers 0 once a connect is complete, `EINPROGRESS` (26) while it isn't, or the connect's WASI errno (`SO_ERROR`). On the loopback a connect completes at once, so `ready` is 0 straight away. `ready` is meant for a descriptor from `net.connect`. The descriptor is read and written with `fd-read` and `fd-write` and closed with `fd-close`, as below, and `fd-select` (`{ op: 'fd-select', read: [fds], write: [fds], timeoutMs }`, answering `{ read, write }` with the ready ones; `timeoutMs: -1` waits without a limit) waits until it's readable or writable;
328
328
  - `spawn({ argv, env, cwd, stdin, stdout, stderr })` starts a command (resolved like `kernel.run`) as a child and returns `{ pid, stdin, stdout, stderr }`. `env` is the child's whole environment (the program's own by default), `cwd` the program's by default. Each stdio is `'inherit'` (the default: the program's own), `'null'`, or `'pipe'`: a kernel pipe whose end the result holds as a descriptor, read and written with `fd-read` (`{ op: 'fd-read', fd, max }`, an empty read at the end), `fd-write` (`{ op: 'fd-write', fd, body }`) and `fd-close`, through `syscall` or `async.submit`; the child's ends are closed in the program. A command that does not exist throws `ENOENT`;
@@ -7985,7 +7985,7 @@ function satisfies(version, range2) {
7985
7985
  }
7986
7986
 
7987
7987
  // src/version.ts
7988
- var KERNEL_VERSION = true ? "1.108.0" : "0.0.0-dev";
7988
+ var KERNEL_VERSION = true ? "1.108.1" : "0.0.0-dev";
7989
7989
  var OS_RELEASE = "6.0.0-slicc";
7990
7990
  function procVersion() {
7991
7991
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -2497,7 +2497,7 @@ var init_wasi_fds = __esm({
2497
2497
  const flags = want === 6 ? O_RDWR : want === 2 ? O_WRONLY : 0;
2498
2498
  return openDevice2.call(this.kernel.sys, flags);
2499
2499
  }
2500
- open(path, oflags, rights, fdflags) {
2500
+ open(path, oflags, rights, fdflags, mode) {
2501
2501
  const device2 = deviceOf(path);
2502
2502
  if (device2) return this.install({ type: "device", device: device2 });
2503
2503
  const kernelDevice = this.openKernelDevice(path, oflags, fdflags, rights);
@@ -2518,13 +2518,16 @@ var init_wasi_fds = __esm({
2518
2518
  }
2519
2519
  if (!s && !(oflags & OFLAGS.CREAT)) throw new WasiError("ENOENT");
2520
2520
  refuseWrite(s, oflags, rights);
2521
- return this.regular(path, s, oflags, rights, fdflags);
2521
+ return this.regular(path, s, oflags, rights, fdflags, mode);
2522
2522
  }
2523
- regular(path, s, oflags, rights, fdflags) {
2523
+ regular(path, s, oflags, rights, fdflags, mode) {
2524
2524
  if (this.shared || this.kernelHolds(path, s)) {
2525
- return this.kernelFile(path, s, oflags, rights, fdflags);
2525
+ return this.kernelFile(path, s, oflags, rights, fdflags, mode);
2526
2526
  }
2527
- return this.install({ type: "file", file: this.file(path, s, oflags, rights, fdflags) });
2527
+ return this.install({
2528
+ type: "file",
2529
+ file: this.file(path, s, oflags, rights, fdflags, mode)
2530
+ });
2528
2531
  }
2529
2532
  kernelHolds(path, st) {
2530
2533
  for (const [fd, e] of this.table) {
@@ -2546,7 +2549,7 @@ var init_wasi_fds = __esm({
2546
2549
  } catch {
2547
2550
  }
2548
2551
  }
2549
- file(path, existing, oflags, rights, fdflags) {
2552
+ file(path, existing, oflags, rights, fdflags, mode) {
2550
2553
  const { readable: readable3, writable: writable2 } = openAccess(existing, oflags, rights);
2551
2554
  let buffer = this.buffers.get(path);
2552
2555
  if (buffer?.handle !== void 0 && this.fs.kept?.(buffer.handle)) {
@@ -2559,13 +2562,13 @@ var init_wasi_fds = __esm({
2559
2562
  if (this.fs.owners) this.fs.access?.(path, want, "open");
2560
2563
  if (oflags & OFLAGS.TRUNC) buffer.truncate(0);
2561
2564
  } else {
2562
- buffer = this.freshBuffer(path, existing, oflags, want);
2565
+ buffer = this.freshBuffer(path, existing, oflags, want, mode);
2563
2566
  }
2564
2567
  buffer.opens++;
2565
2568
  return new LocalFile(buffer, readable3, writable2, (fdflags & FDFLAGS.APPEND) !== 0);
2566
2569
  }
2567
- freshBuffer(path, existing, oflags, want) {
2568
- const made = !existing && this.createNew(path, oflags);
2570
+ freshBuffer(path, existing, oflags, want, mode) {
2571
+ const made = !existing && this.createNew(path, oflags, mode);
2569
2572
  const empty = made || (oflags & OFLAGS.TRUNC) !== 0;
2570
2573
  if (existing?.ranged) this.fs.invalidate?.();
2571
2574
  const seen = this.fs.changes?.now();
@@ -2595,11 +2598,11 @@ var init_wasi_fds = __esm({
2595
2598
  if (id !== void 0) this.know(buffer, id);
2596
2599
  return buffer;
2597
2600
  }
2598
- kernelFile(path, existing, oflags, rights, fdflags) {
2601
+ kernelFile(path, existing, oflags, rights, fdflags, mode) {
2599
2602
  const { readable: readable3, writable: writable2 } = openAccess(existing, oflags, rights);
2600
2603
  const append = (fdflags & FDFLAGS.APPEND) !== 0;
2601
2604
  const flags = (writable2 ? readable3 ? O_RDWR : O_WRONLY : 0) | (append ? O_APPEND : 0);
2602
- const made = !existing && this.createNew(path, oflags);
2605
+ const made = !existing && this.createNew(path, oflags, mode);
2603
2606
  const truncate = made || (oflags & OFLAGS.TRUNC) !== 0;
2604
2607
  const fd = this.kernel.sys.openVfs(path, flags, 0, {
2605
2608
  ...truncate ? { truncate } : {},
@@ -2612,13 +2615,13 @@ var init_wasi_fds = __esm({
2612
2615
  this.bump();
2613
2616
  return fd;
2614
2617
  }
2615
- createNew(path, oflags) {
2618
+ createNew(path, oflags, mode) {
2616
2619
  if (!this.fs.create) {
2617
2620
  this.fs.writeFile(path, new Uint8Array(0));
2618
2621
  return true;
2619
2622
  }
2620
2623
  try {
2621
- this.fs.create(path, void 0, true);
2624
+ this.fs.create(path, mode, true);
2622
2625
  return true;
2623
2626
  } catch (err) {
2624
2627
  if (oflags & OFLAGS.EXCL || err.code !== "EEXIST") throw err;
@@ -4897,13 +4900,15 @@ function importsContext({
4897
4900
  const fds = {
4898
4901
  open(path, o = {}) {
4899
4902
  const abs = host.fds.resolve(3, path);
4900
- if (o.nofollow && fs.exists(abs) && fs.lstat(abs).isSymbolicLink)
4903
+ const fresh = o.create === true && o.exclusive === true && owners && fs.create !== void 0;
4904
+ if (!fresh && o.nofollow && fs.exists(abs) && fs.lstat(abs).isSymbolicLink)
4901
4905
  throw new WasiError("ELOOP");
4902
- const existed = fs.exists(abs);
4906
+ const existed = !fresh && fs.exists(abs);
4903
4907
  const oflags = (o.create ? OFLAGS.CREAT : 0) | (o.exclusive ? OFLAGS.EXCL : 0) | (o.truncate ? OFLAGS.TRUNC : 0) | (o.directory ? OFLAGS.DIRECTORY : 0);
4904
4908
  const rights = (o.write ? RIGHTS.FD_WRITE : 0n) | (o.read || !o.write ? RIGHTS.FD_READ : 0n);
4905
- const fd = host.fds.open(abs, oflags, rights, o.append ? FDFLAGS.APPEND : 0);
4906
- if (o.mode !== void 0 && !existed) fs.chmod(abs, o.mode);
4909
+ const flags = o.append ? FDFLAGS.APPEND : 0;
4910
+ const fd = host.fds.open(abs, oflags, rights, flags, fresh ? o.mode : void 0);
4911
+ if (o.mode !== void 0 && !existed && !fresh) fs.chmod(abs, o.mode);
4907
4912
  return fd;
4908
4913
  },
4909
4914
  close(fd) {
@@ -5167,7 +5172,7 @@ var KERNEL_VERSION, OS_RELEASE;
5167
5172
  var init_version = __esm({
5168
5173
  "src/version.ts"() {
5169
5174
  "use strict";
5170
- KERNEL_VERSION = true ? "1.108.0" : "0.0.0-dev";
5175
+ KERNEL_VERSION = true ? "1.108.1" : "0.0.0-dev";
5171
5176
  OS_RELEASE = "6.0.0-slicc";
5172
5177
  }
5173
5178
  });