summaryrefslogtreecommitdiff
path: root/src/ninep
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep')
-rw-r--r--src/ninep/events.zig22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/ninep/events.zig b/src/ninep/events.zig
index a3f8c278..1067b60e 100644
--- a/src/ninep/events.zig
+++ b/src/ninep/events.zig
@@ -371,7 +371,12 @@ pub fn readLog(p: *Pardes, req: Req) Reply {
/// records instead of ending; closing it is the way back.
pub fn writeLog(p: *Pardes, req: Req) Reply {
const slot = &(tree.openOf(p, req) orelse return Reply.fail(req.tag, E.INVAL)).what.log;
- if (!std.mem.eql(u8, std.mem.trim(u8, req.data, " \t\r\n"), "follow")) return Reply.fail(req.tag, E.INVAL);
+ const word = std.mem.trim(u8, req.data, " \t\r\n");
+ // `follow` reads what the open froze, then waits; `follow new` skips
+ // what was there and waits for what comes after, as tail -n0 -f does.
+ if (std.mem.eql(u8, word, "follow new")) {
+ slot.pos = slot.bytes.len;
+ } else if (!std.mem.eql(u8, word, "follow")) return Reply.fail(req.tag, E.INVAL);
slot.follow = true;
return .{ .tag = req.tag, .written = @intCast(req.data.len) };
}
@@ -1110,3 +1115,18 @@ test "a click in the body reports the offsets of the word it takes, so the recor
_ = call(p, .{ .tag = 3, .op = .release, .node = event, .handle = h });
}
}
+
+test "follow new skips what the log held and waits for what comes after" {
+ const p = try withFile(testing.allocator, "x\n");
+ defer p.deinit();
+ p.update(.tick); // the pane's `new` is logged first
+ while (p.nextEffect()) |_| {}
+ p.setMessage(0, "before the open");
+ const log = @intFromEnum(tree.TopFile.log);
+ const h = call(p, .{ .tag = 1, .op = .open, .node = log }).reply.handle;
+ try testing.expectEqual(Status.ok, call(p, .{ .tag = 2, .op = .write, .node = log, .handle = h, .data = "follow new\n" }).reply.status);
+ try testing.expectEqual(Status.again, call(p, .{ .tag = 3, .op = .read, .node = log, .handle = h, .size = 4096 }).reply.status);
+ p.setMessage(0, "after it");
+ try testing.expect(std.mem.endsWith(u8, call(p, .{ .tag = 4, .op = .read, .node = log, .handle = h, .size = 4096 }).bytes, " after it\n"));
+ _ = call(p, .{ .tag = 5, .op = .release, .node = log, .handle = h });
+}