summaryrefslogtreecommitdiff
path: root/src/ninep/addr.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 18:20:33 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitafc72ac3db0840d8571dcfb8e2e182a241bdecaf (patch)
tree287d4e2cc74839e668f3afba4d13873923a40d89 /src/ninep/addr.zig
parent4354669aa560c5504b046413f771d02c4216dd45 (diff)
downloadpardes-afc72ac3db0840d8571dcfb8e2e182a241bdecaf.tar.gz
pardes-afc72ac3db0840d8571dcfb8e2e182a241bdecaf.zip
A shell's > on addr no longer resets it, so echo /re/ > addr searches on
Truncating addr reset it to #0, so a shell's find-and-replace loop matched the first hit for ever, .+#1 read 1 1 each time, and foo x foo y foo became foobarbarbar... acme resets addr on the first open (xfid.c:105-108), for clients that hold the fid; a shell cannot. Here neither an open nor a truncation resets it: the address written is evaluated from the last one, and 0 or , starts over. Documented as a departure from acme. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/addr.zig')
-rw-r--r--src/ninep/addr.zig25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/ninep/addr.zig b/src/ninep/addr.zig
index 0537c17a..ccb08924 100644
--- a/src/ninep/addr.zig
+++ b/src/ninep/addr.zig
@@ -340,13 +340,34 @@ test "a failed address leaves none, so data refuses rather than act at the last
try testing.expectEqualStrings(pane_files.e_addr_failed, th.rd(p, addr, 0, 64).reply.ename);
try testing.expectEqual(E.INVAL, th.call(p, .{ .tag = 1, .op = .setattr, .node = Node.of(serial, .xdata), .truncate = true }).errno());
try testing.expectEqualStrings("one\ntwo\n", p.panes[0].?.file.?.content);
- // A good address, or a truncated addr, gives it one again.
+ // A good address gives it one again; truncating addr does not.
_ = th.wr(p, addr, "#0,#3");
try testing.expectEqual(Status.ok, th.wr(p, data, "ONE").reply.status);
try testing.expectEqualStrings("ONE\ntwo\n", p.panes[0].?.file.?.content);
_ = th.wr(p, addr, "99");
_ = th.call(p, .{ .tag = 1, .op = .setattr, .node = addr, .truncate = true });
- try testing.expectEqual(Status.ok, th.wr(p, data, "0").reply.status);
+ try testing.expectEqualStrings(pane_files.e_addr_failed, th.wr(p, data, "0").reply.ename);
+}
+
+test "a shell's > on addr searches on from the last address, and 0 starts over" {
+ const p = try th.withFile(testing.allocator, "foo x foo y foo\n");
+ defer p.deinit();
+ const serial = th.serialOf(p);
+ const addr = Node.of(serial, .addr);
+ const data = Node.of(serial, .data);
+ // echo /foo/ > addr; printf foobar > data -- twice over, as a loop does.
+ for (0..3) |_| {
+ _ = th.call(p, .{ .tag = 1, .op = .setattr, .node = addr, .truncate = true });
+ try testing.expectEqual(Status.ok, th.wr(p, addr, "/foo/").reply.status);
+ _ = th.call(p, .{ .tag = 1, .op = .setattr, .node = data, .truncate = true });
+ try testing.expectEqual(Status.ok, th.wr(p, data, "foobar").reply.status);
+ }
+ try testing.expectEqualStrings("foobar x foobar y foobar\n", p.panes[0].?.file.?.content);
+ // .+#1 moves on from where the last write left the address.
+ _ = th.wr(p, addr, "0");
+ _ = th.call(p, .{ .tag = 1, .op = .setattr, .node = addr, .truncate = true });
+ try testing.expectEqual(Status.ok, th.wr(p, addr, ".+#1").reply.status);
+ try testing.expectEqualStrings(" 1 1 ", th.rd(p, addr, 0, 64).bytes);
}
test "the address language, form by form" {