Subject: bug#24941: Early termination bug in grep 2.26

From: Jim Meyering <[email-masked]>
Date: Tue, 15 Nov 2016 11:35:15 -0800

On Tue, Nov 15, 2016 at 12:17 AM, Paul Eggert <[email-masked]> wrote:
> Jim Meyering wrote:
>>
>> Paul, what do you think about making your heuristic apply only for
>> non-pipes?
>
> I'm a bit dubious, as grep exits early for other reasons, and did so before
> the patch in question. For example, here:
>
> seq 10000000000 | grep -q .
>
> This is as of grep 2.19 (2014), due to a bug report where grep performed
> badly by not exiting early <https://bugs.gnu.org/17427>. Which suggests that
> we'll get bug reports in this area no matter what grep does....

The issue of -q is separate, because anyone who has invoked grep with
-q has long been exposed to this behavior already. And behavior could
even be inferred based on the POSIX description. I think it is fine
for grep -q to terminate early in all cases.

My concern is when no "exit-early"-implying option (none of at least
-l, -q, -m) is specified, say within some script that has always
worked, yet grep-2.26 makes OP's example fail most surprisingly when
at a distance (i.e., the invocation of grep was hidden) someone
unwittingly redirects standard output to /dev/null.

> Looking at other implementations, Solaris 11 grep is similar with -q. And
> FreeBSD-current grep exits early for this case:
>
> seq 10000000000 | grep -f /dev/null
>
> Come to think of it, perhaps GNU grep should do a similar optimization for
> -f /dev/null, if only to keep up with FreeBSD.
>
> All the above being said, I am sympathetic to the bug report. Perhaps we can
> eliminate the optimization if there are no file arguments and only options
> in the set -EFivx are specified. Something like that anyway. The idea is to
> catch common cases in old (and really, broken) scripts, without hurting
> performance in general.

I suppose you mean in addition to the S_ISFIFO test? That sounds good.
We should retain the optimization when reading from stdin that is a
non-pipe.