summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/fs.md4
-rw-r--r--src/ninep/cols.zig12
2 files changed, 15 insertions, 1 deletions
diff --git a/docs/fs.md b/docs/fs.md
index 0ec88876..dacb49ba 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -371,7 +371,9 @@ non-UTF-8 bytes are refused (`invalid tag text`). The editable text is at
most 4096 bytes (`no space: over 4096 bytes`, ENOSPC; the log says `err <serial> tag: no space: ...`). All three kinds
take the same checks, whole or not at all, and a `>` whose write is refused
changes nothing: its truncation is done with the write that fits, or at the
-close (or a read) when none came. A clear is an ordinary edit
+close (or a read) when none came. Each write stands on its own: in a `>`
+cut into several writes, those taken before a refused one stay in the
+tag; only the refused write changes nothing. A clear is an ordinary edit
and `u` in the tag undoes it. [tags.md](tags.md) covers tags on screen.
## Panes
diff --git a/src/ninep/cols.zig b/src/ninep/cols.zig
index 4e497545..a1fe9ecc 100644
--- a/src/ninep/cols.zig
+++ b/src/ninep/cols.zig
@@ -253,6 +253,18 @@ test "pane/new takes rows from a pane in another column before refusing ENOSPC"
try testing.expect(moved);
}
+test "in a > cut into several tag writes, those taken before a refused one stand" {
+ const p = try th.withFile(testing.allocator, "x\n");
+ defer p.deinit();
+ const node = tree.Node.of(th.serialOf(p), .tag);
+ _ = th.call(p, .{ .tag = 1, .op = .setattr, .node = node, .truncate = true });
+ const h = th.call(p, .{ .tag = 2, .op = .open, .node = node, .omode = 1 }).reply.handle;
+ try testing.expectEqual(tree.Status.ok, th.call(p, .{ .tag = 3, .op = .write, .node = node, .handle = h, .data = "Make" }).reply.status);
+ try testing.expectEqual(E.INVAL, th.call(p, .{ .tag = 4, .op = .write, .node = node, .handle = h, .data = " \x01" }).errno());
+ _ = th.call(p, .{ .tag = 5, .op = .release, .node = node, .handle = h, .opened = true });
+ try testing.expect(std.mem.endsWith(u8, th.rd(p, node, 0, 4096).bytes, "Make"));
+}
+
test "exactly 4096 bytes written with echo's newline after a truncation fit every kind of tag" {
const p = try th.withFile(testing.allocator, "x\n");
defer p.deinit();