The threaded external sorter silently swallowed I/O errors from
temporary file writes, causing truncated or missing spill data to
go unnoticed. Propagate the write error to abort the sort with a
proper diagnostic.
Also add a regression test covering the spill write failure path.
Use C-style quoting for invalid mode errors when stderr is not a terminal. Escape control characters in rich mode diagnostics while preserving the highlighted span.
install -D opened the deepest existing ancestor read-only, so it failed
with EACCES when that directory had write and execute but not read
permission, while GNU install succeeds. Open it with DirFd::open_anchor.
Open a directory readable, and on EACCES retry with O_PATH or O_SEARCH,
which anchor *at calls without read access. The targets with either flag
are named by the has_o_path and has_o_search cfg aliases. If the retry
fails, its own error is returned.
openpty doesn't set close-on-exec, so every command that another test
started while a terminal was simulated inherited its PTYs, up to six
descriptors. Tests that run under a low descriptor limit then failed.
Open the PTY close-on-exec through rustix where the OS supports it
(Linux, Android, FreeBSD, NetBSD), and set it right after openpty
elsewhere, which leaves a short window.
The stdin PTY stayed open only through the copy the child inherited.
Read its echo in a thread, as a terminal would, which keeps it open until
the child closes it; macOS also waits at exit for an unread echo.