Skip to content

Fish integration: deterministic EINTR test; markers survive repeated interrupted writes (#443) - #449

Merged
raiseCatError merged 2 commits into
release/v0.22.0from
fix/v022-fish-marker-attempts
Oct 19, 2026
Merged

raiseCatError merged 2 commits into
release/v0.22.0from
fix/v022-fish-marker-attempts

Conversation

@raiseCatError

Copy link
Copy Markdown
Owner

Part of #443. Work in progress: the first commit is the fault-injection test alone, so CI's Ubuntu/Fish 3.7 job can show it failing before the fix. Description follows with the fix.

#443)

#443's evidence so far was timing: a CI loop and an strace that saw two
real interrupted marker writes retried. This test makes write() fail with
EINTR a set number of times through a preloaded shim (Linux, Fish 3.7 on
CI), so nothing depends on when SIGWINCH lands. It also characterises the
residual: Fish 3 drops its own interrupted output; Fish 4 retries.

The marker function moves to an exported constant so the test runs the
bootstrap's own text. Expected to fail on CI before the next commit: two
interruptions in a row, and a write that never succeeds (the retry prints
"write: Interrupted system call").
…d write never loses one (#443)

The fault-injection test (f909e77) failed on CI's Ubuntu Fish 3.7.0 as
expected for two interruptions in a row, and showed more: even when #445's
single retry saved the marker, Fish 3 printed "write: Interrupted system
call" into the transcript. Fish 3 reports a failed builtin write from its
own output layer on its own stderr, so the builtin's 2>/dev/null never
silenced it (#443's strace shows the same).

On Fish 3 a marker is now printf'd into a pipe (a few bytes, never
blocked, so never interrupted) and written to the terminal by cat, which
ignores SIGWINCH and retries an interrupted write. The marker travels on
stdin, never in arguments. Fish 4 retries by itself and keeps the builtin.
The cost is one short cat per marker, on Fish 3 only.

The test now runs Fish in a real terminal and fails only terminal writes,
as the real signal does (a pipe write of a few bytes never waits). A
characterisation test runs #445's helper under the same faults: on Fish 3
it shows the error and loses a marker interrupted twice. Command output
from Fish's own builtins is still lost on Fish 3 (the shim test documents
it); NMSh cannot retry a person's command for them.
@raiseCatError
raiseCatError merged commit 99e0d1e into release/v0.22.0 Oct 19, 2026
12 checks passed
raiseCatError added a commit that referenced this pull request Oct 19, 2026
…, recorded QA, targeted retests

- CHANGELOG [0.22.0]: HTML in /view (#454); Ask shell tasks and
  suggestions (#446); mixed NMSh/shell pastes (#450); the queue while a
  program waits (#452); the Markdown wrap fix; Security: a reply entered
  before an unseen read never runs as a command (#426) and an older
  session service says its protections are off. Known limitations
  reworded to what the code now does: the #426 residual is a reply that
  is itself a command name; on Fish 3 NMSh's markers are no longer lost
  (#449), Fish's own builtin output still can be (#443); suggestion
  quality depends on the model; /view's HTML subset.
- docs/testing/v022-physical-qa.md: results as reported on 68c1cbb
  (sitting A PASS except A12 FAIL; B1, B3 PASS; B5, B8, B9, B10, C2, C7,
  C9, C10, D11 NOT RUN, user waived/deferred); what the reduced coverage
  does and does not prove; A9 steps 6-7 updated for #448; retests R1-R4
  on a separate build, so 68c1cbb's QA build stays as it was.
- scripts/qa/v022-retest-fixtures.sh: adds work/retest/ and nmsh2 to the
  existing QA folder, never changing what is there.
- Ledger: findings, root causes, evidence, integration and decisions.
@raiseCatError

Copy link
Copy Markdown
Owner Author

Integrated into release/v0.22.0 at fa7ec665 (merge commits, in the order #448, #449, #456, #447, #451, #453, #455). Dispatched CI on that exact head: all 13 jobs green (run 39257608055).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant