diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 18:23:04 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | 1db5ba2b267f030e2de54a2cb4de9fb155c4139d (patch) | |
| tree | 11d20f29b4773b92e492d2035e103e38d083007e /src/pardes.zig | |
| parent | 09ef40318a3a3d1b9494e2a5fa41f71363929676 (diff) | |
| download | pardes-1db5ba2b267f030e2de54a2cb4de9fb155c4139d.tar.gz pardes-1db5ba2b267f030e2de54a2cb4de9fb155c4139d.zip | |
Only a write logs an err: a refused open or truncation, create or remove, or a write to pane/new, is its error alone, and every refusal is said in words
The one-failure rule is a write's. A refused remove, pane/new's open refused for want of a slot, and an OTRUNC open's refused truncation (data's after a failed addr) also logged an err, and a reply carrying only an errno reached the client as the C library's text (Operation not permitted). tree.handle now gives such a reply Plan 9's words, chosen so 9ns maps each back to its errno (EPERM's to EACCES, as Plan 9's does), and serveFs logs errs for writes only, not a write to pane/new, which is only read. docs/fs.md and the 9P skill say so, and that a look miss quotes what was written.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/pardes.zig')
| -rw-r--r-- | src/pardes.zig | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index cb39b5d1..19fe51d1 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -5729,7 +5729,11 @@ pub const Pardes = struct { p.fs.lsp_answer_at = null; const reply = ctlfs.handle(p, req); p.fs.serving = false; - if (reply.status == .err and (req.op == .write or req.op == .setattr or (req.op == .open and reply.errno == ctlfs.E.NOSPC) or (req.op == .release and req.remove))) ctlfs.events.noteError(p, req, reply); + // The one-failure rule is a write's: a refused open (its OTRUNC's + // truncation, a setattr, too), create or remove is its Rerror alone, + // no err, as is a write to pane/new, which is only ever read. + const ruled = req.op == .write and req.node != @intFromEnum(ctlfs.TopFile.new); + if (reply.status == .err and ruled) ctlfs.events.noteError(p, req, reply); // The request was a whole step of its own, so it settles the way a // step does: the cursor and scroll reconciled, the scripted panes // told, and the panes it made announced to /log now rather than at |
