zsh: two more cache answers that claimed capabilities SchOS lacks

Checking the rest of ZSH_CACHE after the killesrch fix, on the principle that
one wrong answer in a hand-written block is rarely the only one. Two more, both
`yes`, both measurable on the running system in a line each.

**zsh_cv_sys_path_dev_fd=/dev/fd.** Neither /dev/fd nor /proc/self/fd exists --
/proc/self does not exist at all. So `<(cmd)` failed at the point of use with

    cat: /dev/fd/11: No such file or directory

which reads as a broken command rather than as a feature the system does not
have.

**zsh_cv_sys_fifo=yes.** mkfifo() does not fail here. It *succeeds*, and
produces a character device: mknod() turns S_IFIFO into a T_DEV and keeps the
major/minor, so `ls -l` shows `crw-rw-rw- 438, 0` where a `p` belongs, and
nothing written to it comes back out. Succeeding wrongly is what made `yes`
look defensible.

Both `no` now. `<(cmd)` says "doesn't look like your system supports FIFOs",
which names the missing thing instead of blaming cat, and `$( )` is unaffected.

The two gaps are recorded in docs/architecture/filesystem.md rather than left
implied by a build flag -- named pipes and a path to one's own descriptors are
both real features, and neither exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Nexoniarz 2026-09-22 00:36:48 +02:00
commit fdbd9bcf95
3 changed files with 50 additions and 2 deletions

View file

@ -269,6 +269,16 @@ both need the `..` fixup and the ancestor-loop check that are not written.
a deadlock rather than a wrong answer. a deadlock rather than a wrong answer.
- **`rename()` does not move directories**, and will not replace one. `EISDIR` - **`rename()` does not move directories**, and will not replace one. `EISDIR`
either way. either way.
- **No named pipes.** `mkfifo()` does not fail — it *succeeds* and produces a
character device, because `mknod()` turns `S_IFIFO` into a `T_DEV` and keeps
the major/minor. `ls -l` shows `crw-rw-rw- 438, 0` where a `p` belongs, and
nothing written to it comes back out. Succeeding wrongly is worse than
refusing: the zsh port was configured with `zsh_cv_sys_fifo=yes` on the
strength of it, and process substitution failed at the point of use rather
than being reported as unavailable.
- **No `/dev/fd`, and no `/proc/self`.** A process cannot reach its own open
descriptors by path. `<(cmd)` needs one or the other — zsh now knows it has
neither and says so.
- **No `AF_UNIX` socket inodes.** Socket names live in a table in - **No `AF_UNIX` socket inodes.** Socket names live in a table in
`kernel/net/unix.c`, so `bind()` creates nothing that can be `stat()`ed or `kernel/net/unix.c`, so `bind()` creates nothing that can be `stat()`ed or
`unlink()`ed. `unlink()`ed.

View file

@ -505,6 +505,25 @@ The lesson is narrow and worth stating: when a probe that reproduces a
program's exact syscall sequence behaves correctly and the program does not, program's exact syscall sequence behaves correctly and the program does not,
stop looking under the syscalls and start looking at the build. stop looking under the syscalls and start looking at the build.
#### Two more in the same block
Checking the rest of `ZSH_CACHE` after fixing that one found two more answers
claiming capabilities SchOS does not have, both `yes`, both measurable on the
running system in one line each:
- `zsh_cv_sys_path_dev_fd=/dev/fd` — neither `/dev/fd` nor `/proc/self/fd`
exists. `<(cmd)` therefore failed at the point of use with `cat:
/dev/fd/11: No such file or directory`, which reads as a broken command
rather than an unimplemented feature.
- `zsh_cv_sys_fifo=yes` — `mkfifo()` does not fail, it *succeeds* and produces
a character device: `mknod()` turns `S_IFIFO` into a `T_DEV`, so `ls -l`
shows `crw-rw-rw- 438, 0` and nothing written comes back out.
Both are `no` now, and `<(cmd)` says *"doesn't look like your system supports
FIFOs"* — which names the missing feature instead of blaming `cat`. The gaps
themselves are recorded in
[../architecture/filesystem.md](../architecture/filesystem.md).
--- ---
This was left here deliberately rather than continuing to iterate blind: This was left here deliberately rather than continuing to iterate blind:

View file

@ -113,6 +113,25 @@ ZSH_LIBS := -lncursesw $(MUSL)/lib/libc.a $(LIBGCC) $(MUSL)/lib/libc.a \
# #
# The cruel part: autoconf's own cross-compilation default for this one is # The cruel part: autoconf's own cross-compilation default for this one is
# `yes`. Leaving the line out entirely would have been correct. # `yes`. Leaving the line out entirely would have been correct.
#
# Two more in this block claimed capabilities SchOS does not have, found by
# checking the rest after the one above. Both were `yes`, and both are facts
# that can simply be measured on the running system:
#
# zsh_cv_sys_path_dev_fd /dev/fd and /proc/self/fd do not exist. Telling
# zsh otherwise made `<(cmd)` fail at the point of
# use with `cat: /dev/fd/11: No such file or
# directory`, which reads as a broken command
# rather than an unimplemented feature.
#
# zsh_cv_sys_fifo mkfifo() "succeeds" and produces a *character
# device*: the kernel's mknod turns S_IFIFO into a
# T_DEV, so `ls -l` shows `crw-rw-rw- 438, 0`, and
# nothing written to it comes back out. Named pipes
# are not implemented.
#
# With both `no`, zsh knows it cannot do process substitution and says so,
# which is the honest state until FIFOs exist.
ZSH_CACHE := \ ZSH_CACHE := \
zsh_cv_shared_environ=yes \ zsh_cv_shared_environ=yes \
zsh_cv_shared_tgetent=no \ zsh_cv_shared_tgetent=no \
@ -120,8 +139,8 @@ ZSH_CACHE := \
zsh_cv_sys_nis=no \ zsh_cv_sys_nis=no \
zsh_cv_sys_nss=no \ zsh_cv_sys_nss=no \
zsh_cv_func_realpath_accepts_null=yes \ zsh_cv_func_realpath_accepts_null=yes \
zsh_cv_sys_path_dev_fd=/dev/fd \ zsh_cv_sys_path_dev_fd=no \
zsh_cv_sys_fifo=yes \ zsh_cv_sys_fifo=no \
zsh_cv_sys_killesrch=yes \ zsh_cv_sys_killesrch=yes \
zsh_cv_sys_signal_handler=void \ zsh_cv_sys_signal_handler=void \
zsh_cv_prog_tcsetpgrp=yes \ zsh_cv_prog_tcsetpgrp=yes \