summaryrefslogtreecommitdiff
path: root/src/ninep
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep')
-rw-r--r--src/ninep/pane.zig18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index de7f7cd4..6a0fbba5 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -867,6 +867,11 @@ fn writeName(p: *Pardes, req: Req, id: usize, pane: *Pane) Reply {
error.OutOfMemory => E.NOMEM,
else => E.INVAL,
});
+ // A name into a directory not there yet asks for it, as Config's pane
+ // does: its Save makes the directories (`pardes new/dir/f` forwarded).
+ if (comptime pardes.hosted) if (fs.localPath(std.fs.path.dirname(full) orelse "/")) |local| {
+ if (!exec.isDirectory(local)) fileOf(pane).?.make_dirs = true;
+ };
return .{ .tag = req.tag, .written = @intCast(req.data.len) };
}
@@ -1387,6 +1392,19 @@ test "a name with a component over 255 bytes is refused, and a long path's faile
try testing.expect(std.mem.endsWith(u8, late, "/f.txt: no such directory"));
}
+test "a name into a directory not there has Save make it; one into a directory there does not" {
+ if (comptime !pardes.hosted) return error.SkipZigTest;
+ const p = try withFile(testing.allocator, "x\n");
+ defer p.deinit();
+ const serial = serialOf(p);
+ const f = fileOf(p.panes[p.paneBySerial(serial).?].?).?;
+ try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .name), "/tmp/pardes-no-such-dir-mk/sub/f.txt\n").reply.status);
+ try testing.expect(f.make_dirs);
+ f.make_dirs = false;
+ try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .name), "/tmp/f.txt\n").reply.status);
+ try testing.expect(!f.make_dirs);
+}
+
test "a name cut across writes is one name, applied once at its newline or its close" {
const p = try withFile(testing.allocator, "x\n");
defer p.deinit();