Hello,
I've encountered a particularly interesting bug in GNU grep yesterday while
hunting some issues with LibreOffice (if you're interested in the whole
post-mortem, it can be read here:
https://grsc.cz/blog/loffice-linux-issues/, but it's mostly not relevant
for this bug).
Whenever the `-q` option is used, grep can exit with a 0, even if no
match has been found and an error has been encountered. In particular,
when the `close_stdout` function is called and the `close` syscall
fails, grep exits with 0, even when it's not supposed to.
While reading the source code, I found out that when the `-q` option is
detected (grep.c:2697), the `exit_failure` variable is set to 0. This
causes any error, when not specially handled, to exit with 0, even
before any match is found. This is also true for the `close_stdout` libc
function, which hard exits using `_exit(exit_failure)` when the syscall
fails.
This, at first glance, (and pardon me if I'm wrong, I haven't looked
into the source code that deeply) seems to me as bad design, since it
makes the code prone to multiple such mistakes – where someone
inadvertently uses the `exit_failure` variable without realising it
makes the program return the wrong code. It would make much more sense
to me (and again, I don't know whether this is possible) to set the
`exit_failure` variable to 0 only *after* the first match is found,
preventing such issues altogether. It also makes more sense semantically
IMO, as the `-q` option states that errors are ignored only when a match
is found, not always.
As I feel this is more of a design decision than a straightforward fix,
I'm not sending a patch, but I'll be glad to assist any efforts to
fix this.
CC'd are my colleagues who helped discover the issue.
Regards,
Jan