From df10c37122cc3e6565d13aeefb9466dc6c0dc780 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 06:17:47 -0300 Subject: Grep and Find pass over a directory they may not open and keep every other hit, saying in one line how many they skipped One `chmod 000` directory anywhere under a pane made every Grep say `pattern not found` and every Find `access denied`: the walk's `try w.enter`/`try w.next` ended it at the first refusal. Each is now counted and passed over, and the +Search ends `N directories skipped: permission denied` under the hits. Co-Authored-By: Claude Opus 5.5 --- src/look.zig | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/look.zig') diff --git a/src/look.zig b/src/look.zig index f208c1fb..21148b37 100644 --- a/src/look.zig +++ b/src/look.zig @@ -593,6 +593,7 @@ pub fn runSearch(p: *Pardes, id: usize, pat_raw: []const u8, kind: Search, start var out_len: usize = 0; var nrows: usize = 0; var anchor: ?usize = null; + var skipped: usize = 0; if (kind == .grep) { var roots: [MAX_PANES][]const u8 = undefined; var nroots: usize = 0; @@ -625,13 +626,13 @@ pub fn runSearch(p: *Pardes, id: usize, pat_raw: []const u8, kind: Search, start // not made yet, a peer's) has nothing to grep: passed over, not the // search's failure. for (roots[0..nroots]) |r| - out_len += filesystem.grep(arena, p.gpa, r, dir, pat, out[out_len..]) catch |err| switch (err) { + out_len += filesystem.grep(arena, p.gpa, r, dir, pat, out[out_len..], &skipped) catch |err| switch (err) { error.FileNotFound, error.NotDir, error.AccessDenied => continue, else => return err, }; nrows = std.mem.count(u8, out[0..out_len], "\n"); } else if (kind == .find) { - out_len = try filesystem.find(arena, dir, pat, out); + out_len = try filesystem.find(arena, dir, pat, out, &skipped); nrows = std.mem.count(u8, out[0..out_len], "\n"); } else if (pane.hasPdf()) { if (comptime pdf_enabled) { @@ -672,6 +673,13 @@ pub fn runSearch(p: *Pardes, id: usize, pat_raw: []const u8, kind: Search, start nrows += 1; } } + // What the walk could not open is said in one line under the hits, so + // a locked directory reads as passed over, not as nothing there. + if (skipped > 0) { + const note = std.fmt.bufPrint(out[out_len..], "{d} director{s} skipped: permission denied\n", .{ skipped, if (skipped == 1) "y" else "ies" }) catch ""; + out_len += note.len; + nrows += @intFromBool(note.len > 0); + } // A Find or Grep that finds nothing empties its directory's +Search, if // there is one, rather than leave the last search's rows looking like // this one's. -- cgit v1.3