summaryrefslogtreecommitdiff
path: root/src/ninep
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 10:10:50 -0300
committerGabriel Schneider <[email protected]>2026-10-01 10:36:27 -0300
commit13c5f281ae0264e42e04bce527b83159fa75466c (patch)
tree9658e26f977523bd8bc539011e805a3ca04a47ed /src/ninep
parent1f2653d96656ab55956b5798bf637372ce337e29 (diff)
downloadpardes-13c5f281ae0264e42e04bce527b83159fa75466c.tar.gz
pardes-13c5f281ae0264e42e04bce527b83159fa75466c.zip
/pager takes one directory an open, as pty/run takes one line: a second line, in the same write or the next, is refused EINVAL
Through a mount `printf 'a\nb\n' > pager` arrives a line a write, so the second asked for another +Pager on the same open, its answer replacing the first. An open that asked already refuses another. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep')
-rw-r--r--src/ninep/ctl.zig18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 554333bb..4fb5bf41 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -656,8 +656,11 @@ pub fn writePager(p: *Pardes, req: Req) Reply {
p.fs.results_len = 0;
var it = Messages.init(p, req.data);
const line = it.next() orelse "";
- // 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");
+ // Words 9ns maps back to EINVAL (`invalid`), as every refusal here. One
+ // directory an open, as pty/run takes one line: through a mount
+ // `printf 'a\nb\n'` comes a line a write, and the second is refused.
+ const asked_before = if (tree.openOf(p, req)) |o| o.results.wrote else false;
+ if (it.next() != null or asked_before) return tree.failText(req.tag, E.INVAL, "pager: invalid write: one directory an open");
// `~` is home, and `/tmp/../etc` is `/etc`: the +Pager is named in the
// directory it is, as any other pane's name is.
var home_buf: [4096]u8 = undefined;
@@ -4071,12 +4074,19 @@ test "pager answers its +Pager on the open that asked, whatever another client e
try testing.expectEqual(E.INVAL, call(p, .{ .tag = 6, .op = .write, .node = pager, .handle = asked, .data = "relative\n" }).errno());
try testing.expectEqualStrings("", call(p, .{ .tag = 7, .op = .read, .node = pager, .handle = asked, .size = 64 }).bytes);
// Resolved: `/tmp/../tmp/.` is /tmp's +Pager, the one made above.
- try testing.expectEqual(Status.ok, call(p, .{ .tag = 8, .op = .write, .node = pager, .handle = asked, .data = "/tmp/../tmp/.\n" }).reply.status);
- try testing.expectEqualStrings(want, call(p, .{ .tag = 9, .op = .read, .node = pager, .handle = asked, .size = 64 }).bytes);
+ const again = call(p, .{ .tag = 8, .op = .open, .node = pager, .omode = 2 }).reply.handle;
+ try testing.expectEqual(Status.ok, call(p, .{ .tag = 8, .op = .write, .node = pager, .handle = again, .data = "/tmp/../tmp/.\n" }).reply.status);
+ try testing.expectEqualStrings(want, call(p, .{ .tag = 9, .op = .read, .node = pager, .handle = again, .size = 64 }).bytes);
+ _ = call(p, .{ .tag = 9, .op = .release, .node = pager, .handle = again });
// One that may not be written is refused, permission denied.
try testing.expectEqual(E.PERM, wr(p, pager, "/proc/1\n").errno());
// One directory a write, absolute, and there.
try testing.expectEqual(E.INVAL, wr(p, pager, "/a\n/b\n").errno());
+ // A second line on an open that asked already, as a mount sends two.
+ const twice = call(p, .{ .tag = 20, .op = .open, .node = pager, .omode = 2 }).reply.handle;
+ try testing.expectEqual(Status.ok, call(p, .{ .tag = 21, .op = .write, .node = pager, .handle = twice, .data = "/tmp\n" }).reply.status);
+ try testing.expectEqual(E.INVAL, call(p, .{ .tag = 22, .op = .write, .node = pager, .handle = twice, .data = "/tmp\n" }).errno());
+ _ = call(p, .{ .tag = 23, .op = .release, .node = pager, .handle = twice });
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);