summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 09:58:17 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit8bc8bc2289e3e33903f9008b3513d0bd9c3f7311 (patch)
tree7f336cbb09ea312e248a465ba5e2ac180466a5d9
parent4d413c812db9ec8783471700c09ac270e16d097f (diff)
downloadpardes-8bc8bc2289e3e33903f9008b3513d0bd9c3f7311.tar.gz
pardes-8bc8bc2289e3e33903f9008b3513d0bd9c3f7311.zip
A bad event record says what is wrong with it
`bad event syntax` said nothing of which: now it says a report record (I D i d) is not written back, a range ends before it starts, or what a record looks like when the line is not one. Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--src/ninep/ctl.zig18
-rw-r--r--src/ninep/events.zig6
2 files changed, 21 insertions, 3 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index c0695c76..5f26a181 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -2061,6 +2061,24 @@ test "a malformed address is bad address syntax, on a terminal as on a text" {
}
}
+test "a bad event record says what is wrong with it" {
+ const p = try withFile(testing.allocator, "one\n");
+ defer p.deinit();
+ const event = Node.of(serialOf(p), .event);
+ const h = call(p, .{ .tag = 1, .op = .open, .node = event, .omode = 2 }).reply.handle;
+ for ([_][2][]const u8{
+ .{ "MI0 1 0 1 x\n", "only a look or exec" },
+ .{ "MX3 1 0 0 \n", "ends before it starts" },
+ .{ "MX9 9 0 0 \n", "range past end" },
+ .{ "garbage\n", "a record is" },
+ }) |c| {
+ const refused = call(p, .{ .tag = 2, .op = .write, .node = event, .handle = h, .data = c[0] });
+ try testing.expectEqual(E.INVAL, refused.errno());
+ try testing.expect(std.mem.indexOf(u8, refused.reply.ename, c[1]) != null);
+ }
+ _ = call(p, .{ .tag = 3, .op = .release, .node = event, .handle = h });
+}
+
test "size is monotonic: growing is never refused, and a size once taken is taken again" {
const p = try Pardes.init(testing.allocator, .{ .tty_only = true, .cols = 160, .rows = 60 });
defer p.deinit();
diff --git a/src/ninep/events.zig b/src/ninep/events.zig
index 8b8f8637..868364a6 100644
--- a/src/ninep/events.zig
+++ b/src/ninep/events.zig
@@ -726,14 +726,14 @@ pub fn writeEvent(p: *Pardes, req: Req, id: usize) Reply {
while (check.next()) |r| {
switch (r.action) {
.body_look, .tag_look, .body_exec, .tag_exec => {},
- else => return tree.failText(req.tag, E.INVAL, tree.e_bad_event),
+ else => return tree.failText(req.tag, E.INVAL, tree.e_bad_event ++ ": only a look or exec (L l X x) is written back"),
}
const n = if (r.action.onTag()) tag.len else body.len;
- if (r.q0 > r.q1) return tree.failText(req.tag, E.INVAL, tree.e_bad_event);
+ if (r.q0 > r.q1) return tree.failText(req.tag, E.INVAL, tree.e_bad_event ++ ": its range ends before it starts");
// Well formed, but not a range of this text: say which.
if (r.q1 > n) return tree.failText(req.tag, E.INVAL, if (r.action.onTag()) "range past end of tag" else "range past end of body");
}
- if (check.i != req.data.len) return tree.failText(req.tag, E.INVAL, tree.e_bad_event);
+ if (check.i != req.data.len) return tree.failText(req.tag, E.INVAL, tree.e_bad_event ++ ": a record is <origin><action><q0> <q1> <flag> <count> <text>, a line each");
}
var run: EventReader = .{ .data = req.data };
while (run.next()) |r| {