summaryrefslogtreecommitdiff
path: root/src/ninep/ctl.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 17:58:05 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitc5fcbc0cb9c1e76bb01283e9ccfa00ed5bc4bef8 (patch)
tree967ca08153c0385d5fc3e05a69468bee45dfa7b0 /src/ninep/ctl.zig
parent08c4a01f799ae250577d99a61f23eef7d66e439a (diff)
downloadpardes-c5fcbc0cb9c1e76bb01283e9ccfa00ed5bc4bef8.tar.gz
pardes-c5fcbc0cb9c1e76bb01283e9ccfa00ed5bc4bef8.zip
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 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
-rw-r--r--src/ninep/ctl.zig17
1 files changed, 17 insertions, 0 deletions
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");