diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Messages.zig | 2 | ||||
| -rw-r--r-- | src/fs.zig | 3 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 17 |
3 files changed, 21 insertions, 1 deletions
diff --git a/src/Messages.zig b/src/Messages.zig index ea62041f..cc4b3656 100644 --- a/src/Messages.zig +++ b/src/Messages.zig @@ -407,7 +407,7 @@ pub fn blendRgb(from: [3]u8, to: [3]u8, amount: f32) [3]u8 { fn logMessage(p: *Pardes, id: usize, text: []const u8) void { if (text.len == 0) return; - const serial: u32 = if (id < MAX_PANES) if (p.panes[id]) |pane| pane.serial else 0 else 0; + const serial: u32 = if (p.fs.session_write) 0 else if (id < MAX_PANES) if (p.panes[id]) |pane| pane.serial else 0 else 0; const kept = text[0..@min(text.len, LoggedMessage.cap)]; // /log hears every one: a client that retried and failed the same way // is waiting on that second line. Only the +Messages view collapses. @@ -1260,6 +1260,9 @@ pub const Namespace = struct { /// the first error one reports (`failure`) fails the write, as acme's /// ctl answers a command's error (editors/acme/xfid.c:700). no_prompt: bool = false, + /// The root ctl is running a session builtin: its messages are the + /// session's, logged `msg -`, though shown on the active pane. + session_write: bool = false, refused: bool = false, failure: [256]u8 = undefined, failure_len: u16 = 0, 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"); |
