summaryrefslogtreecommitdiff
path: root/src/ninep/pane.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 23:42:32 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitf842a4026348c65370a973e466c2b4f45063bdaf (patch)
treee6258955563103db1ad76b1324f3971e279afa06 /src/ninep/pane.zig
parent8469def61324feb5e278f88bebad36af7a0d997e (diff)
downloadpardes-f842a4026348c65370a973e466c2b4f45063bdaf.tar.gz
pardes-f842a4026348c65370a973e466c2b4f45063bdaf.zip
A write to a closed pane's file says it is gone, and a terminal says why it takes no name
`echo Del > pane/6/exec` just after pane 6 closed failed EACCES: the shell's lookup failed, it tried to create the file, and the engine refused every Tcreate as a permission error. pardes now takes Tcreate itself: refused as before (acme's fsyscreate refuses it too), ENOENT in a pane that has closed. Renaming a terminal was refused with only EPERM; it now says a terminal is named by its shell's directory, worded so a mount still maps it to EPERM. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/pane.zig')
-rw-r--r--src/ninep/pane.zig9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index 9d20c587..3eafdbce 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -561,7 +561,10 @@ fn writeName(p: *Pardes, req: Req, id: usize, pane: *Pane) Reply {
const name = std.mem.trim(u8, req.data, " \t\r\n");
if (name.len == 0) return Reply.fail(req.tag, E.INVAL);
for (name) |c| if (c < ' ') return Reply.fail(req.tag, E.INVAL);
- if (fileOf(pane) == null) return Reply.fail(req.tag, E.PERM);
+ if (fileOf(pane) == null) return tree.failText(req.tag, E.PERM, if (pane.isTerminal())
+ "rename not allowed: a terminal is named by its shell's directory; cd there, or Tty in another"
+ else
+ "rename not allowed: an image or PDF is named by the file it shows");
const full = std.fs.path.resolvePosix(p.scratch.allocator(), &.{ pardes.Pardes.paneDir(pane), name }) catch
return Reply.fail(req.tag, E.NOMEM);
if (!std.fs.path.isAbsolute(full) or full.len >= 4096) return Reply.fail(req.tag, E.INVAL);
@@ -734,7 +737,9 @@ test "a terminal is listed as term with its directory as name" {
try std.fmt.bufPrint(&want, "{d} term 0 /work/dir\n", .{pane.serial}),
) != null);
try testing.expectEqualStrings("/work/dir\n", rd(p, Node.of(pane.serial, .name), 0, 4096).bytes);
- try testing.expectEqual(E.PERM, wr(p, Node.of(pane.serial, .name), "/elsewhere\n").errno());
+ const refused = wr(p, Node.of(pane.serial, .name), "/elsewhere\n");
+ try testing.expectEqual(E.PERM, refused.errno());
+ try testing.expect(std.mem.startsWith(u8, refused.reply.ename, "rename not allowed: a terminal is named"));
}
test "body reads at any offset and writes append" {