From c5fcbc0cb9c1e76bb01283e9ccfa00ed5bc4bef8 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 17:58:05 -0300 Subject: What a root ctl write says is the session's in the log, msg -, not the active pane's A session builtin written to /ctl runs at the active pane, so its messages were logged under that pane's serial, as if the pane had said them. They are now `msg -`, and still shown on the active pane. Co-Authored-By: Claude Opus 5.5 --- src/ninep/ctl.zig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/ninep/ctl.zig') diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 8b73e8f7..bb562672 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -344,6 +344,8 @@ pub fn writeRoot(p: *Pardes, req: Req) Reply { continue; } if (p.panes[p.active] == null) return Reply.fail(req.tag, E.NOENT); + p.fs.session_write = true; + defer p.fs.session_write = false; if (runBuiltin(p, req, p.active, line)) |refusal| return refusal; } } @@ -742,6 +744,21 @@ test "a second lock is refused until the holder unlocks or closes, and binds nob for (p.fs.opens) |o| try testing.expect(o.node == 0); } +test "a message from a root ctl write is the session's in the log" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + p.update(.tick); // the pane's `new` is logged before the log is opened + while (p.nextEffect()) |_| {} + const log = @intFromEnum(tree.TopFile.log); + const f = call(p, .{ .tag = 1, .op = .open, .node = log }).reply.handle; + const frozen = call(p, .{ .tag = 2, .op = .read, .node = log, .handle = f, .size = 8192 }).bytes.len; + _ = call(p, .{ .tag = 3, .op = .write, .node = log, .handle = f, .data = "follow" }); + try testing.expectEqual(Status.ok, wr(p, @intFromEnum(tree.TopFile.ctl), "Kill\n").reply.status); + // The builtin's name, then what it said: both the session's. + try testing.expectEqualStrings("msg - Kill\n", call(p, .{ .tag = 4, .op = .read, .node = log, .handle = f, .off = frozen, .size = 4096 }).bytes); + try testing.expectEqualStrings("msg - Kill: nothing running\n", call(p, .{ .tag = 5, .op = .read, .node = log, .handle = f, .off = frozen, .size = 4096 }).bytes); +} + test "a look takes acme's :addr and file:addr, and a miss changes nothing" { const gpa = testing.allocator; const p = try withFile(gpa, "foo x foo y\nbar\n"); -- cgit v1.3