@volter/browser-wali 0.1.206 → 0.1.208

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.
@@ -337,6 +337,11 @@ export class WaliFileDescriptorTable {
337
337
  }
338
338
  currentWorkingDirectory() { return this.cwd; }
339
339
  creationMask() { return this.fileCreationMask; }
340
+ setProcessIdentity(pid, executablePath) {
341
+ this.options.pid = pid;
342
+ if (executablePath !== undefined)
343
+ this.options.executablePath = executablePath;
344
+ }
340
345
  // Translated from Emscripten libsyscall.js and wasmfs/syscalls.cpp (MIT),
341
346
  // 862dc0d48acc4134a0088d27ac8f5dd18baba1cd. The kernel owns the description;
342
347
  // terminal settings are dispatched separately to the attached tty.
@@ -501,6 +506,45 @@ export class WaliFileDescriptorTable {
501
506
  // O_CLOEXEC is recorded here for every kind of descriptor open makes: musl
502
507
  // no longer follows it with F_SETFD (musl 0003), which was the only thing
503
508
  // marking these special files (review of dfd87b6).
509
+ const proc = this.procEntry(path);
510
+ if (proc?.kind === "file") {
511
+ if (flags & O_DIRECTORY)
512
+ throw errno("ENOTDIR");
513
+ if ((flags & O_CREAT) && (flags & O_EXCL))
514
+ throw errno("EEXIST");
515
+ if ((flags & O_ACCMODE) !== 0 || (flags & O_TRUNC))
516
+ throw errno("EACCES");
517
+ const fd = this.allocateFd();
518
+ let contents, position = 0;
519
+ this.specialDescriptors.set(fd, {
520
+ stat: () => this.procStat(path, "file"),
521
+ read: length => {
522
+ if (!contents) {
523
+ const entry = this.procEntry(path);
524
+ if (entry?.kind !== "file")
525
+ return -3n;
526
+ contents = new TextEncoder().encode(entry.text);
527
+ }
528
+ const bytes = contents.slice(position, position + length);
529
+ position += bytes.byteLength;
530
+ return bytes;
531
+ },
532
+ seek: (offset, whence) => {
533
+ if (whence !== 0 && whence !== 1)
534
+ return -22n;
535
+ const next = whence === 0 ? offset : position + offset;
536
+ if (!Number.isSafeInteger(next) || next < 0)
537
+ return -22n;
538
+ position = next;
539
+ if (position === 0)
540
+ contents = undefined;
541
+ return BigInt(position);
542
+ },
543
+ poll: events => events & 1,
544
+ fcntl: command => command === 3 ? BigInt(flags & ~O_CLOEXEC_FLAG) : 0n,
545
+ });
546
+ return this.markCloseOnExecNumber(fd, flags);
547
+ }
504
548
  if (path === "/dev/tty") {
505
549
  if (flags & O_DIRECTORY)
506
550
  throw errno("ENOTDIR");
@@ -580,7 +624,8 @@ export class WaliFileDescriptorTable {
580
624
  fs.writeFileSync(path, new Uint8Array());
581
625
  }
582
626
  const directory = stat.isDirectory();
583
- const virtualDirectory = ["/proc", "/proc/self", "/proc/self/fd"].includes(path);
627
+ const virtualDirectory = this.procEntry(path)?.kind === "directory"
628
+ || ["/proc", "/proc/self", "/proc/self/fd"].includes(path);
584
629
  const entries = directory && !virtualDirectory ? this.directoryEntries(path) : undefined;
585
630
  this.files.set(fd, {
586
631
  path,
@@ -873,7 +918,8 @@ export class WaliFileDescriptorTable {
873
918
  directoryEntries(path) {
874
919
  const fs = this.fs();
875
920
  const entries = [];
876
- const virtual = path === "/proc" ? ["self"] : path === "/proc/self" ? ["fd"]
921
+ const proc = this.procEntry(path);
922
+ const virtual = proc?.kind === "directory" ? proc.entries : path === "/proc" ? ["self"] : path === "/proc/self" ? ["fd"]
877
923
  : path === "/proc/self/fd" ? this.descriptors.entries.flatMap((entry, fd) => entry ? [String(fd)] : []) : undefined;
878
924
  for (const name of [".", "..", ...(virtual ?? fs.readdirSync(path))]) {
879
925
  const entryPath = name === "." ? path : name === ".."
@@ -1551,8 +1597,11 @@ export class WaliFileDescriptorTable {
1551
1597
  const target = this.virtualLink(candidate, false);
1552
1598
  if (target !== undefined)
1553
1599
  return { directory: false, target };
1554
- if (["/proc", "/proc/self", "/proc/self/fd"].includes(candidate))
1600
+ const proc = this.procEntry(candidate);
1601
+ if (proc?.kind === "directory" || ["/proc", "/proc/self", "/proc/self/fd"].includes(candidate))
1555
1602
  return { directory: true };
1603
+ if (proc?.kind === "file")
1604
+ return { directory: false };
1556
1605
  const fd = this.procDescriptor(candidate);
1557
1606
  if (fd === undefined || !this.hasFd(fd))
1558
1607
  return;
@@ -1569,8 +1618,23 @@ export class WaliFileDescriptorTable {
1569
1618
  return resolved;
1570
1619
  }
1571
1620
  procDescriptor(path) {
1572
- const match = /^\/proc\/self\/fd\/(\d+)$/u.exec(path);
1573
- return match ? Number(match[1]) : undefined;
1621
+ const match = /^\/proc\/(self|\d+)\/fd\/(\d+)$/u.exec(path);
1622
+ return match && (match[1] === "self" || Number(match[1]) === this.options.pid) ? Number(match[2]) : undefined;
1623
+ }
1624
+ procEntry(path) {
1625
+ if (path !== "/proc" && !path.startsWith("/proc/"))
1626
+ return;
1627
+ if (path === `/proc/${this.options.pid}/fd` || path === "/proc/self/fd")
1628
+ return {
1629
+ kind: "directory", entries: this.descriptors.entries.flatMap((entry, fd) => entry ? [String(fd)] : []),
1630
+ };
1631
+ return this.options.proc?.(path, this.options.pid ?? 1);
1632
+ }
1633
+ procStat(path, kind) {
1634
+ const pid = Number(/^\/proc\/(\d+)/u.exec(path)?.[1] ?? 0);
1635
+ const tag = ["comm", "cmdline", "stat", "status", "exe", "fd"].indexOf(path.split("/").pop() ?? "") + 1;
1636
+ return { isFile: () => kind === "file", isDirectory: () => kind === "directory", size: 0,
1637
+ mode: kind === "directory" ? 0o040555 : 0o100444, uid: 1000, gid: 1000, ino: 1 + pid * 16 + tag };
1574
1638
  }
1575
1639
  virtualLink(path, descriptors = true) {
1576
1640
  if (path === "/dev/fd")
@@ -1581,6 +1645,9 @@ export class WaliFileDescriptorTable {
1581
1645
  return "/proc/self/fd/1";
1582
1646
  if (path === "/dev/stderr")
1583
1647
  return "/proc/self/fd/2";
1648
+ const proc = this.procEntry(path);
1649
+ if (proc?.kind === "symlink")
1650
+ return proc.target;
1584
1651
  if (!descriptors)
1585
1652
  return;
1586
1653
  const fd = this.procDescriptor(path);
@@ -1614,6 +1681,9 @@ export class WaliFileDescriptorTable {
1614
1681
  return {
1615
1682
  isFile: () => false, isDirectory: () => true, size: 0, mode: 0o040555,
1616
1683
  };
1684
+ const proc = this.procEntry(path);
1685
+ if (proc?.kind === "directory" || proc?.kind === "file")
1686
+ return this.procStat(path, proc.kind);
1617
1687
  const fd = this.procDescriptor(path);
1618
1688
  if (fd === undefined)
1619
1689
  return;