From 60e40675c82efd17aa6bf31bc66c3f8f3f918360 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 10:26:47 -0300 Subject: Addresses search a line at a time as sam does, say why they fail, and a failed addr leaves no address addr's regexps ran mvzr over text[from..hi]: ^ and $ anchored only at the slice's ends, . matched newlines, the search never wrapped, and every failure read as bad address syntax. The regexps stay mvzr's, called the way sam searches (editors/acme/regx.c): one line per haystack, so ^ and $ fall at line boundaries and . never crosses a newline; a pattern naming \\n runs over the whole text with its . made [^\\n]; /re/ wraps unless limit is set, and ?re? takes the last match before the range. The ceiling (mvzr's first alternative, not sam's longest) is documented. A failed address says why (no match for regexp, address out of range, bad regular expression), and a failed write to addr leaves no address, so data and xdata refuse until the next good one instead of writing at the old range. Co-Authored-By: Claude Opus 5.5 --- src/ninep/tree.zig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ninep/tree.zig') diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig index e9c6b8ea..3ce7e758 100644 --- a/src/ninep/tree.zig +++ b/src/ninep/tree.zig @@ -681,6 +681,8 @@ fn setattr(p: *Pardes, req: Req, target: Target) Reply { if (req.truncate) switch (target) { .pane => |t| { const id = p.paneBySerial(t.serial) orelse return Reply.fail(req.tag, E.NOENT); + if ((t.file == .data or t.file == .xdata) and p.panes[id].?.fs.addr_failed) + return failText(req.tag, E.INVAL, pane.e_addr_failed); if (pane.truncate(p, p.panes[id].?, t.file) != .ok) return Reply.fail(req.tag, E.NOMEM); }, .top => {}, -- cgit v1.3