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/ninep/cols.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/ninep/cols.zig')
| -rw-r--r-- | src/ninep/cols.zig | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/src/ninep/cols.zig b/src/ninep/cols.zig index 6b59f9e5..cc583c93 100644 --- a/src/ninep/cols.zig +++ b/src/ninep/cols.zig @@ -368,10 +368,11 @@ test "a column's ctl and exec act on it as its tag would, and rmdir closes it on try testing.expectEqual(E.INVAL, th.wr(p, Node.ofCol(empty, .ctl), "Exit\n").errno()); var rec: [64]u8 = undefined; try testing.expect(th.logHas(p, try std.fmt.bufPrint(&rec, "err - col/{d}/ctl: unknown control message \"Exit\"", .{empty}))); - // rmdir refuses a column with a pane, and says why. + // rmdir refuses a column with a pane, and says why, in its error alone. const full = th.call(p, .{ .tag = 1, .op = .release, .node = Node.ofCol(empty, .dir), .remove = true }); try testing.expectEqual(E.NOTEMPTY, full.errno()); - try testing.expect(th.logHas(p, try std.fmt.bufPrint(&rec, "err - col/{d}: column not empty", .{empty}))); + try testing.expect(std.mem.startsWith(u8, full.reply.ename, "column not empty")); + try testing.expect(!th.logHas(p, try std.fmt.bufPrint(&rec, "err - col/{d}: column not empty", .{empty}))); // exec runs a word as a click in that column's tag: Delcol closes it. try testing.expectEqual(tree.Status.ok, th.wr(p, Node.ofCol(empty, .exec), "Delcol\n").reply.status); try testing.expectEqual(@as(?usize, null), layout.columnBySerial(p, empty)); |
