From 84b3bb51d7009902659e05f94c53c82d109ba8f6 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 08:37:39 -0300 Subject: DumpDir refuses a relative directory and one that may not be written, up front, and a Dump that could not make its directory says permission denied A relative DumpDir was resolved from wherever pardes started, and one under a directory that may not be written was taken, the Dump failing later as `no such directory`. DumpDir now takes an absolute or `~` path whose nearest directory there may be written, and refuses any other with what it takes; a Dump refused by a directory above says permission denied (fs.deniedAbove), as a Save does. Co-Authored-By: Claude Opus 5.5 --- src/ninep/ctl.zig | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/ninep/ctl.zig') diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 89c2e5dd..d4d09e0b 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -2332,8 +2332,9 @@ test "a Restore of a file that is no dump fails the write before any warning, an try testing.expect(p.panes[0].?.discard_warned == null); p.fs.late_failure_len = 0; - p.dumpFailed("/nowhere/pardes.dump.zon", error.FileNotFound); - try testing.expectEqualStrings("Dump /nowhere/pardes.dump.zon: no such directory", p.fs.late_failure[0..p.fs.late_failure_len]); + // (Under /tmp: under / a user's Dump is refused permission, not missing.) + p.dumpFailed("/tmp/pardes-nowhere-zz/pardes.dump.zon", error.FileNotFound); + try testing.expectEqualStrings("Dump /tmp/pardes-nowhere-zz/pardes.dump.zon: no such directory", p.fs.late_failure[0..p.fs.late_failure_len]); // A DumpDir that is there but no directory says that. p.fs.late_failure_len = 0; p.dumpFailed("/dev/null/pardes.dump.zon", error.NotDir); @@ -4357,3 +4358,16 @@ test "a ctl line over 1 MiB is refused once, EINVAL, and its tail is not run as try testing.expectEqualStrings("", pane_files.fileOf(p.panes[0].?).?.content); _ = call(p, .{ .tag = 4, .op = .release, .node = node, .handle = h }); } + +test "DumpDir refuses a relative directory and one that may not be written, up front; a Dump there says permission denied" { + if (comptime !pardes.hosted) return; + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const root_ctl = @intFromEnum(tree.TopFile.ctl); + try testing.expectEqual(E.INVAL, wr(p, root_ctl, "DumpDir dumps\n").errno()); + try testing.expectEqual(E.INVAL, wr(p, root_ctl, "DumpDir /proc/1/root/dumps\n").errno()); + try testing.expectEqual(Status.ok, wr(p, root_ctl, "DumpDir /tmp/pardes-dumps-test\n").reply.status); + p.fs.late_failure_len = 0; + p.dumpFailed("/proc/1/root/x/pardes.dump.zon", error.FileNotFound); + try testing.expect(std.mem.endsWith(u8, p.fs.late_failure[0..p.fs.late_failure_len], ": permission denied")); +} -- cgit v1.3