I noticed this today while grepping through a very long kdump output and
using something like:
$ fgrep -n -m2 -C2 'kevent -1' dump.txt
641- 31513 vmd RET sendmsg 1848/0x738
642- 31513 vmd CALL kevent(5,0x90d4c2e4000,1,0x90d8004a000,2048,0)
643: 31513 vmd RET kevent -1 errno 4 Interrupted system call
644- 31513 vmd CALL sigreturn(0x7f7ffffd6430)
645- 31513 vmd RET sigreturn JUSTRETURN
--
661- 31513 vmd RET sendmsg 44/0x2c
662- 31513 vmd CALL kevent(5,0x90d4c2e4000,1,0x90d8004a000,2048,0)
663: 31513 vmd RET kevent -1 errno 4 Interrupted system call
Notice how grep(1) isn't printing anything after the last requested
match even though I've specified -C2. (I assure you...there're a lot
more lines after that match. ;)
The below patch changes the logic to avoid bailing out of the loop in
util.c:procfile() even after the match count is hit but we still have
some after-context lines to print.
In procline(), it will skip attempting matches after hitting the match
count. (This does mean that when using -n, a line within the
after-context that may match will not get printed with the matched
prefix ":".)
With the diff:
$ fgrep -n -m2 -C2 'kevent -1' dump.txt
641- 31513 vmd RET sendmsg 1848/0x738
642- 31513 vmd CALL kevent(5,0x90d4c2e4000,1,0x90d8004a000,2048,0)
643: 31513 vmd RET kevent -1 errno 4 Interrupted system call
644- 31513 vmd CALL sigreturn(0x7f7ffffd6430)
645- 31513 vmd RET sigreturn JUSTRETURN
--
661- 31513 vmd RET sendmsg 44/0x2c
662- 31513 vmd CALL kevent(5,0x90d4c2e4000,1,0x90d8004a000,2048,0)
663: 31513 vmd RET kevent -1 errno 4 Interrupted system call
664- 31513 vmd CALL sigreturn(0x7f7ffffd6430)
665- 31513 vmd RET sigreturn JUSTRETURN
FWIW: GNU grep (v3.3) seems to do my proposed behavior including not
marking possible matches in the after-context of a final match. Busybox
grep (v1.33.1) acts like our current grep and fails to print the
after-context of the final match when using -m.
ok?
-dv
diff 9dabd3f978a6a46c3c1b3a472234e5d2c0d11206 /usr/src
blob - bcef0897881eb7890ab3e568a92a77ae5fe1f4a7
file + usr.bin/grep/util.c
--- usr.bin/grep/util.c
+++ usr.bin/grep/util.c
@@ -163,7 +163,7 @@ procfile(char *fn)
overflow = 1;
else
c += t;
- if (mflag && mcount <= 0)
+ if (mflag && mcount <= 0 && tail <= 0)
break;
}
if (Bflag > 0)
@@ -212,6 +212,8 @@ procline(str_t *l, int nottext)
c = 1;
goto print;
}
+ if (mflag && mcount <=0)
+ goto print;
for (i = 0; i < patterns; i++) {
offset = 0;