summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 05:41:15 -0300
committerGabriel Schneider <[email protected]>2026-10-01 05:41:15 -0300
commit56d7f6ee58be6e19b39567ad3e091917acb2fc06 (patch)
tree820feb30721ed3e42ac7c8bf195b5e9b3a118640
parentcda0b279a24e8becc3c2836c42e7321830e2467a (diff)
downloadpardes-56d7f6ee58be6e19b39567ad3e091917acb2fc06.tar.gz
pardes-56d7f6ee58be6e19b39567ad3e091917acb2fc06.zip
/pager's refusals say invalid, so a mount's shell hears EINVAL: `pager: invalid directory "relative": must be absolute`
9ns maps a refusal back to an errno by its words, and "the directory must be absolute" and "one directory a write" held none it knows, so a shell through the mount got EIO for both. They now say `invalid`, as every EINVAL here does, and the reference quotes the new words. Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--docs/typ/reference.typ2
-rw-r--r--src/ninep/ctl.zig12
2 files changed, 10 insertions, 4 deletions
diff --git a/docs/typ/reference.typ b/docs/typ/reference.typ
index 748f6f3c..d9f3012e 100644
--- a/docs/typ/reference.typ
+++ b/docs/typ/reference.typ
@@ -758,7 +758,7 @@ at 200, ending in `…`. Control characters become spaces.
- #file("/status"): `pid`, `version`, `panes`.
- #file("/pager"): write an absolute directory that exists (an empty line
is the session's; one not there is refused `no such directory`, ENOENT,
- a relative one `the directory must be absolute`); a read on
+ a relative one `invalid directory "<dir>": must be absolute`, EINVAL); a read on
the same open answers the serial of that directory's one `+Pager`, made
or emptied for it. It takes one directory a write. This is what
`pardes -` uses.
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index a5a36464..073a5b8a 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -650,11 +650,15 @@ pub fn readRoot(p: *Pardes, req: Req) Reply {
pub fn writePager(p: *Pardes, req: Req) Reply {
var it = Messages.init(p, req.data);
const line = it.next() orelse "";
- if (it.next() != null) return tree.failText(req.tag, E.INVAL, "pager: one directory a write");
+ // Words 9ns maps back to EINVAL (`invalid`), as every refusal here.
+ if (it.next() != null) return tree.failText(req.tag, E.INVAL, "pager: invalid write: one directory a write");
const dir = std.mem.trim(u8, line, " \t");
// A directory that is there, or none (the session's): never a +Pager
// named into one missing, nor a relative one quietly taken for none.
- if (dir.len > 0 and dir[0] != '/') return refuseQuoting(p, req, "pager: the directory must be absolute", dir);
+ if (dir.len > 0 and dir[0] != '/') {
+ var shown: [256]u8 = undefined;
+ return tree.failText(req.tag, E.INVAL, std.fmt.bufPrint(&p.fs.ename, "pager: invalid directory \"{s}\": must be absolute", .{blanked(dir[0..@min(dir.len, shown.len)], &shown)}) catch "pager: invalid directory: must be absolute");
+ }
if (comptime pardes.hosted) if (dir.len > 0) if (pardes.filesystem.localPath(dir)) |local| if (!exec_line.isDirectory(local))
return tree.failText(req.tag, E.NOENT, std.fmt.bufPrint(&p.fs.ename, "pager: {s}: no such directory", .{dir[0..@min(dir.len, 256)]}) catch "pager: no such directory");
p.fs.results_len = 0;
@@ -4043,7 +4047,9 @@ test "pager answers its +Pager on the open that asked, whatever another client e
try testing.expectEqualStrings(want, call(p, .{ .tag = 5, .op = .read, .node = pager, .handle = asked, .size = 64 }).bytes);
// One directory a write, absolute, and there.
try testing.expectEqual(E.INVAL, wr(p, pager, "/a\n/b\n").errno());
- try testing.expectEqual(E.INVAL, wr(p, pager, "relative\n").errno());
+ const relative = wr(p, pager, "relative\n");
+ try testing.expectEqual(E.INVAL, relative.errno());
+ try testing.expectEqualStrings("pager: invalid directory \"relative\": must be absolute", relative.reply.ename);
try testing.expectEqual(E.NOENT, wr(p, pager, "/tmp/pardes-surely-missing-dir\n").errno());
}