From 97c939b981bc7fbf1a58511a9d83d9f1e12a8f16 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Fri, 2 Oct 2026 00:50:41 -0300 Subject: An Edit filter that can never be reaped no longer holds the Edit's answer: at the limit the command's group is killed and reaped off the answer's path, the stdin writer owning its input, so a filter writing its own ctl with > or >> answers EIO at 10 s instead of hanging; a running Edit keeps its own copies of the names it reports, and the panes it changes refuse Del, delete, rmdir, Undo, Redo, Get and Zerox (busy, EBUSY); e and r say unreadable files in Get's words; the reference says both sides of a filter's own ctl write need <> Co-Authored-By: Claude Opus 5.5 --- src/ninep/ctl.zig | 1 + src/ninep/tree.zig | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src/ninep') diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index c9ce41e1..105de07c 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -1003,6 +1003,7 @@ pub fn writePane(p: *Pardes, req: Req, pane: *Pane) Reply { } if (std.mem.eql(u8, line, "get")) { if (!apply) continue; + if (@import("../edit_cmd.zig").busyOn(p, p.paneBySerial(serial).?)) return tree.failText(req.tag, E.BUSY, "get: " ++ @import("../edit_cmd.zig").e_busy); // Quoting the line, as a builtin's refusal (Save's) does. if (getRefused(p, pane, "get")) |said_in_ename| { // refuse writes ename, where the words are: copy them out. diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig index c78a1aa2..8d3c599f 100644 --- a/src/ninep/tree.zig +++ b/src/ninep/tree.zig @@ -937,6 +937,8 @@ fn remove(p: *Pardes, req: Req) Reply { }; if (t.file != .dir) return Reply.fail(req.tag, E.PERM); const id = p.paneBySerial(t.serial) orelse return Reply.fail(req.tag, E.NOENT); + // A pane an Edit's running commands will change stays until they end. + if (@import("../edit_cmd.zig").busyOn(p, id)) return failText(req.tag, E.BUSY, @import("../edit_cmd.zig").e_busy); p.removePane(id, null) catch return Reply.fail(req.tag, E.IO); return .{ .tag = req.tag }; } -- cgit v1.3