grep.c revision 103372
1/* grep.c - main driver file for grep.
2   Copyright (C) 1992, 1997, 1998, 1999 Free Software Foundation, Inc.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17   02111-1307, USA.  */
18
19/* Written July 1992 by Mike Haertel.  */
20/* Builtin decompression 1997 by Wolfram Schneider <wosch@FreeBSD.org>.  */
21
22/* $FreeBSD: head/gnu/usr.bin/grep/grep.c 103372 2002-09-16 04:27:29Z obrien $ */
23
24#ifdef HAVE_CONFIG_H
25# include <config.h>
26#endif
27#include <sys/types.h>
28#include <sys/stat.h>
29#if defined(HAVE_MMAP)
30# include <sys/mman.h>
31#endif
32#if defined(HAVE_SETRLIMIT)
33# include <sys/time.h>
34# include <sys/resource.h>
35#endif
36#include <stdio.h>
37#include "system.h"
38#include "getopt.h"
39#include "getpagesize.h"
40#include "grep.h"
41#include "savedir.h"
42
43#undef MAX
44#define MAX(A,B) ((A) > (B) ? (A) : (B))
45
46struct stats
47{
48  struct stats *parent;
49  struct stat stat;
50};
51
52/* base of chain of stat buffers, used to detect directory loops */
53static struct stats stats_base;
54
55/* if non-zero, display usage information and exit */
56static int show_help;
57
58/* If non-zero, print the version on standard output and exit.  */
59static int show_version;
60
61/* If nonzero, use mmap if possible.  */
62static int mmap_option;
63
64/* If zero, output nulls after filenames.  */
65static int filename_mask;
66
67/* Short options.  */
68static char const short_options[] =
69"0123456789A:B:C::EFGHIRUVX:abcd:e:f:hiLlnqrsuvwxyZz";
70
71/* Non-boolean long options that have no corresponding short equivalents.  */
72enum
73{
74  BINARY_FILES_OPTION = CHAR_MAX + 1
75};
76
77/* Long options equivalences. */
78static struct option long_options[] =
79{
80  {"after-context", required_argument, NULL, 'A'},
81  {"basic-regexp", no_argument, NULL, 'G'},
82  {"before-context", required_argument, NULL, 'B'},
83  {"binary-files", required_argument, NULL, BINARY_FILES_OPTION},
84  {"byte-offset", no_argument, NULL, 'b'},
85  {"context", optional_argument, NULL, 'C'},
86  {"count", no_argument, NULL, 'c'},
87  {"directories", required_argument, NULL, 'd'},
88  {"extended-regexp", no_argument, NULL, 'E'},
89  {"file", required_argument, NULL, 'f'},
90  {"files-with-matches", no_argument, NULL, 'l'},
91  {"files-without-match", no_argument, NULL, 'L'},
92  {"fixed-regexp", no_argument, NULL, 'F'},
93  {"fixed-strings", no_argument, NULL, 'F'},
94  {"help", no_argument, &show_help, 1},
95  {"ignore-case", no_argument, NULL, 'i'},
96  {"line-number", no_argument, NULL, 'n'},
97  {"line-regexp", no_argument, NULL, 'x'},
98  {"mmap", no_argument, &mmap_option, 1},
99  {"no-filename", no_argument, NULL, 'h'},
100  {"no-messages", no_argument, NULL, 's'},
101  {"bz2decompress", no_argument, NULL, 'J'},
102#if HAVE_LIBZ > 0
103  {"decompress", no_argument, NULL, 'Z'},
104  {"null", no_argument, &filename_mask, 0},
105#else
106  {"null", no_argument, NULL, 'Z'},
107#endif
108  {"null-data", no_argument, NULL, 'z'},
109  {"quiet", no_argument, NULL, 'q'},
110  {"recursive", no_argument, NULL, 'r'},
111  {"regexp", required_argument, NULL, 'e'},
112  {"invert-match", no_argument, NULL, 'v'},
113  {"silent", no_argument, NULL, 'q'},
114  {"text", no_argument, NULL, 'a'},
115  {"binary", no_argument, NULL, 'U'},
116  {"unix-byte-offsets", no_argument, NULL, 'u'},
117  {"version", no_argument, NULL, 'V'},
118  {"with-filename", no_argument, NULL, 'H'},
119  {"word-regexp", no_argument, NULL, 'w'},
120  {0, 0, 0, 0}
121};
122
123/* Define flags declared in grep.h. */
124char const *matcher;
125int match_icase;
126int match_words;
127int match_lines;
128unsigned char eolbyte;
129
130/* For error messages. */
131static char *prog;
132static char const *filename;
133static int errseen;
134
135/* How to handle directories.  */
136static enum
137  {
138    READ_DIRECTORIES,
139    RECURSE_DIRECTORIES,
140    SKIP_DIRECTORIES
141  } directories;
142
143static int  ck_atoi PARAMS ((char const *, int *));
144static void usage PARAMS ((int)) __attribute__((noreturn));
145static void error PARAMS ((const char *, int));
146static void setmatcher PARAMS ((char const *));
147static int  install_matcher PARAMS ((char const *));
148static int  prepend_args PARAMS ((char const *, char *, char **));
149static void prepend_default_options PARAMS ((char const *, int *, char ***));
150static char *page_alloc PARAMS ((size_t, char **));
151static int  reset PARAMS ((int, char const *, struct stats *));
152static int  fillbuf PARAMS ((size_t, struct stats *));
153static int  grepbuf PARAMS ((char *, char *));
154static void prtext PARAMS ((char *, char *, int *));
155static void prpending PARAMS ((char *));
156static void prline PARAMS ((char *, char *, int));
157static void print_offset_sep PARAMS ((off_t, int));
158static void nlscan PARAMS ((char *));
159static int  grep PARAMS ((int, char const *, struct stats *));
160static int  grepdir PARAMS ((char const *, struct stats *));
161static int  grepfile PARAMS ((char const *, struct stats *));
162#if O_BINARY
163static inline int undossify_input PARAMS ((register char *, size_t));
164#endif
165
166/* Functions we'll use to search. */
167static void (*compile) PARAMS ((char *, size_t));
168static char *(*execute) PARAMS ((char *, size_t, char **));
169
170/* Print a message and possibly an error string.  Remember
171   that something awful happened. */
172static void
173error (const char *mesg, int errnum)
174{
175  if (errnum)
176    fprintf (stderr, "%s: %s: %s\n", prog, mesg, strerror (errnum));
177  else
178    fprintf (stderr, "%s: %s\n", prog, mesg);
179  errseen = 1;
180}
181
182/* Like error (), but die horribly after printing. */
183void
184fatal (const char *mesg, int errnum)
185{
186  error (mesg, errnum);
187  exit (2);
188}
189
190/* Interface to handle errors and fix library lossage. */
191char *
192xmalloc (size_t size)
193{
194  char *result;
195
196  result = malloc (size);
197  if (size && !result)
198    fatal (_("memory exhausted"), 0);
199  return result;
200}
201
202/* Interface to handle errors and fix some library lossage. */
203char *
204xrealloc (char *ptr, size_t size)
205{
206  char *result;
207
208  if (ptr)
209    result = realloc (ptr, size);
210  else
211    result = malloc (size);
212  if (size && !result)
213    fatal (_("memory exhausted"), 0);
214  return result;
215}
216
217/* Convert STR to a positive integer, storing the result in *OUT.
218   If STR is not a valid integer, return -1 (otherwise 0). */
219static int
220ck_atoi (char const *str, int *out)
221{
222  char const *p;
223  for (p = str; *p; p++)
224    if (*p < '0' || *p > '9')
225      return -1;
226
227  *out = atoi (optarg);
228  return 0;
229}
230
231
232/* Hairy buffering mechanism for grep.  The intent is to keep
233   all reads aligned on a page boundary and multiples of the
234   page size. */
235
236static char *ubuffer;		/* Unaligned base of buffer. */
237static char *buffer;		/* Base of buffer. */
238static size_t bufsalloc;	/* Allocated size of buffer save region. */
239static size_t bufalloc;		/* Total buffer size. */
240#define PREFERRED_SAVE_FACTOR 5	/* Preferred value of bufalloc / bufsalloc.  */
241static int bufdesc;		/* File descriptor. */
242static char *bufbeg;		/* Beginning of user-visible stuff. */
243static char *buflim;		/* Limit of user-visible stuff. */
244static size_t pagesize;		/* alignment of memory pages */
245static off_t bufoffset;		/* Read offset; defined on regular files.  */
246
247#if defined(HAVE_MMAP)
248static int bufmapped;		/* True if buffer is memory-mapped.  */
249static off_t initial_bufoffset;	/* Initial value of bufoffset. */
250#endif
251
252#include <bzlib.h>
253static BZFILE* bzbufdesc;	/* libbz2 file handle. */
254static int BZflag;		/* uncompress before searching. */
255#if HAVE_LIBZ > 0
256#include <zlib.h>
257static gzFile gzbufdesc;	/* zlib file descriptor. */
258static int Zflag;		/* uncompress before searching. */
259#endif
260
261/* Return VAL aligned to the next multiple of ALIGNMENT.  VAL can be
262   an integer or a pointer.  Both args must be free of side effects.  */
263#define ALIGN_TO(val, alignment) \
264  ((size_t) (val) % (alignment) == 0 \
265   ? (val) \
266   : (val) + ((alignment) - (size_t) (val) % (alignment)))
267
268/* Return the address of a page-aligned buffer of size SIZE,
269   reallocating it from *UP.  Set *UP to the newly allocated (but
270   possibly unaligned) buffer used to build the aligned buffer.  To
271   free the buffer, free (*UP).  */
272static char *
273page_alloc (size_t size, char **up)
274{
275  size_t asize = size + pagesize - 1;
276  if (size <= asize)
277    {
278      char *p = *up ? realloc (*up, asize) : malloc (asize);
279      if (p)
280	{
281	  *up = p;
282	  return ALIGN_TO (p, pagesize);
283	}
284    }
285  return NULL;
286}
287
288/* Reset the buffer for a new file, returning zero if we should skip it.
289   Initialize on the first time through. */
290static int
291reset (int fd, char const *file, struct stats *stats)
292{
293  if (pagesize)
294    bufsalloc = ALIGN_TO (bufalloc / PREFERRED_SAVE_FACTOR, pagesize);
295  else
296    {
297      size_t ubufsalloc;
298      pagesize = getpagesize ();
299      if (pagesize == 0)
300	abort ();
301#ifndef BUFSALLOC
302      ubufsalloc = MAX (8192, pagesize);
303#else
304      ubufsalloc = BUFSALLOC;
305#endif
306      bufsalloc = ALIGN_TO (ubufsalloc, pagesize);
307      bufalloc = PREFERRED_SAVE_FACTOR * bufsalloc;
308      /* The 1 byte of overflow is a kludge for dfaexec(), which
309	 inserts a sentinel newline at the end of the buffer
310	 being searched.  There's gotta be a better way... */
311      if (bufsalloc < ubufsalloc
312	  || bufalloc / PREFERRED_SAVE_FACTOR != bufsalloc
313	  || bufalloc + 1 < bufalloc
314	  || ! (buffer = page_alloc (bufalloc + 1, &ubuffer)))
315	fatal (_("memory exhausted"), 0);
316    }
317  if (BZflag)
318    {
319    bzbufdesc = BZ2_bzdopen(fd, "r");
320    if (bzbufdesc == NULL)
321      fatal(_("memory exhausted"), 0);
322    }
323#if HAVE_LIBZ > 0
324  if (Zflag)
325    {
326    gzbufdesc = gzdopen(fd, "r");
327    if (gzbufdesc == NULL)
328      fatal(_("memory exhausted"), 0);
329    }
330#endif
331
332  buflim = buffer;
333  bufdesc = fd;
334
335  if (fstat (fd, &stats->stat) != 0)
336    {
337      error ("fstat", errno);
338      return 0;
339    }
340  if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
341    return 0;
342  if (
343      BZflag ||
344#if HAVE_LIBZ > 0
345      Zflag ||
346#endif
347      S_ISREG (stats->stat.st_mode))
348    {
349      if (file)
350	bufoffset = 0;
351      else
352	{
353	  bufoffset = lseek (fd, 0, SEEK_CUR);
354	  if (bufoffset < 0)
355	    {
356	      error ("lseek", errno);
357	      return 0;
358	    }
359	}
360#ifdef HAVE_MMAP
361      initial_bufoffset = bufoffset;
362      bufmapped = mmap_option && bufoffset % pagesize == 0;
363#endif
364    }
365  else
366    {
367#ifdef HAVE_MMAP
368      bufmapped = 0;
369#endif
370    }
371  return 1;
372}
373
374/* Read new stuff into the buffer, saving the specified
375   amount of old stuff.  When we're done, 'bufbeg' points
376   to the beginning of the buffer contents, and 'buflim'
377   points just after the end.  Return zero if there's an error.  */
378static int
379fillbuf (size_t save, struct stats *stats)
380{
381  size_t fillsize = 0;
382  int cc = 1;
383  size_t readsize;
384
385  /* Offset from start of unaligned buffer to start of old stuff
386     that we want to save.  */
387  size_t saved_offset = buflim - ubuffer - save;
388
389  if (bufsalloc < save)
390    {
391      size_t aligned_save = ALIGN_TO (save, pagesize);
392      size_t maxalloc = (size_t) -1;
393      size_t newalloc;
394
395      if (S_ISREG (stats->stat.st_mode))
396	{
397	  /* Calculate an upper bound on how much memory we should allocate.
398	     We can't use ALIGN_TO here, since off_t might be longer than
399	     size_t.  Watch out for arithmetic overflow.  */
400	  off_t to_be_read = stats->stat.st_size - bufoffset;
401	  size_t slop = to_be_read % pagesize;
402	  off_t aligned_to_be_read = to_be_read + (slop ? pagesize - slop : 0);
403	  off_t maxalloc_off = aligned_save + aligned_to_be_read;
404	  if (0 <= maxalloc_off && maxalloc_off == (size_t) maxalloc_off)
405	    maxalloc = maxalloc_off;
406	}
407
408      /* Grow bufsalloc until it is at least as great as `save'; but
409	 if there is an overflow, just grow it to the next page boundary.  */
410      while (bufsalloc < save)
411	if (bufsalloc < bufsalloc * 2)
412	  bufsalloc *= 2;
413	else
414	  {
415	    bufsalloc = aligned_save;
416	    break;
417	  }
418
419      /* Grow the buffer size to be PREFERRED_SAVE_FACTOR times
420	 bufsalloc....  */
421      newalloc = PREFERRED_SAVE_FACTOR * bufsalloc;
422      if (maxalloc < newalloc)
423	{
424	  /* ... except don't grow it more than a pagesize past the
425	     file size, as that might cause unnecessary memory
426	     exhaustion if the file is large.  */
427	  newalloc = maxalloc;
428	  bufsalloc = aligned_save;
429	}
430
431      /* Check that the above calculations made progress, which might
432         not occur if there is arithmetic overflow.  If there's no
433	 progress, or if the new buffer size is larger than the old
434	 and buffer reallocation fails, report memory exhaustion.  */
435      if (bufsalloc < save || newalloc < save
436	  || (newalloc == save && newalloc != maxalloc)
437	  || (bufalloc < newalloc
438	      && ! (buffer
439		    = page_alloc ((bufalloc = newalloc) + 1, &ubuffer))))
440	fatal (_("memory exhausted"), 0);
441    }
442
443  bufbeg = buffer + bufsalloc - save;
444  memmove (bufbeg, ubuffer + saved_offset, save);
445  readsize = bufalloc - bufsalloc;
446
447#if defined(HAVE_MMAP)
448  if (bufmapped)
449    {
450      size_t mmapsize = readsize;
451
452      /* Don't mmap past the end of the file; some hosts don't allow this.
453	 Use `read' on the last page.  */
454      if (stats->stat.st_size - bufoffset < mmapsize)
455	{
456	  mmapsize = stats->stat.st_size - bufoffset;
457	  mmapsize -= mmapsize % pagesize;
458	}
459
460      if (mmapsize
461	  && (mmap ((caddr_t) (buffer + bufsalloc), mmapsize,
462		    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
463		    bufdesc, bufoffset)
464	      != (caddr_t) -1))
465	{
466	  /* Do not bother to use madvise with MADV_SEQUENTIAL or
467	     MADV_WILLNEED on the mmapped memory.  One might think it
468	     would help, but it slows us down about 30% on SunOS 4.1.  */
469	  fillsize = mmapsize;
470	}
471      else
472	{
473	  /* Stop using mmap on this file.  Synchronize the file
474	     offset.  Do not warn about mmap failures.  On some hosts
475	     (e.g. Solaris 2.5) mmap can fail merely because some
476	     other process has an advisory read lock on the file.
477	     There's no point alarming the user about this misfeature.  */
478	  bufmapped = 0;
479	  if (bufoffset != initial_bufoffset
480	      && lseek (bufdesc, bufoffset, SEEK_SET) < 0)
481	    {
482	      error ("lseek", errno);
483	      cc = 0;
484	    }
485	}
486    }
487#endif /*HAVE_MMAP*/
488
489  if (! fillsize)
490    {
491      ssize_t bytesread;
492      do
493	if (BZflag)
494	  {
495	    bytesread = BZ2_bzread (bzbufdesc, buffer + bufsalloc, readsize);
496	    /* gzread() will return "non-error" when given input that isn't
497	       its type of compression.  So we need to mimic that behavor
498	       for the bzgrep case.  */
499	    if (bytesread == -1)
500	      bytesread = 0;
501	  }
502	else
503#if HAVE_LIBZ > 0
504	if (Zflag)
505	  bytesread = gzread (gzbufdesc, buffer + bufsalloc, readsize);
506	else
507#endif
508	  bytesread = read (bufdesc, buffer + bufsalloc, readsize);
509      while (bytesread < 0 && errno == EINTR);
510      if (bytesread < 0)
511	cc = 0;
512      else
513	fillsize = bytesread;
514    }
515
516  bufoffset += fillsize;
517#if O_BINARY
518  if (fillsize)
519    fillsize = undossify_input (buffer + bufsalloc, fillsize);
520#endif
521  buflim = buffer + bufsalloc + fillsize;
522  return cc;
523}
524
525/* Flags controlling the style of output. */
526static enum
527  {
528    BINARY_BINARY_FILES,
529    TEXT_BINARY_FILES,
530    WITHOUT_MATCH_BINARY_FILES
531  } binary_files;		/* How to handle binary files.  */
532static int out_quiet;		/* Suppress all normal output. */
533static int out_invert;		/* Print nonmatching stuff. */
534static int out_file;		/* Print filenames. */
535static int out_line;		/* Print line numbers. */
536static int out_byte;		/* Print byte offsets. */
537static int out_before;		/* Lines of leading context. */
538static int out_after;		/* Lines of trailing context. */
539static int count_matches;	/* Count matching lines.  */
540static int list_files;		/* List matching files.  */
541static int no_filenames;	/* Suppress file names.  */
542static int suppress_errors;	/* Suppress diagnostics.  */
543
544/* Internal variables to keep track of byte count, context, etc. */
545static off_t totalcc;		/* Total character count before bufbeg. */
546static char *lastnl;		/* Pointer after last newline counted. */
547static char *lastout;		/* Pointer after last character output;
548				   NULL if no character has been output
549				   or if it's conceptually before bufbeg. */
550static off_t totalnl;		/* Total newline count before lastnl. */
551static int pending;		/* Pending lines of output. */
552static int done_on_match;		/* Stop scanning file on first match */
553
554#if O_BINARY
555# include "dosbuf.c"
556#endif
557
558static void
559nlscan (char *lim)
560{
561  char *beg;
562  for (beg = lastnl;  (beg = memchr (beg, eolbyte, lim - beg));  beg++)
563    totalnl++;
564  lastnl = lim;
565}
566
567static void
568print_offset_sep (off_t pos, int sep)
569{
570  /* Do not rely on printf to print pos, since off_t may be longer than long,
571     and long long is not portable.  */
572
573  char buf[sizeof pos * CHAR_BIT];
574  char *p = buf + sizeof buf - 1;
575  *p = sep;
576
577  do
578    *--p = '0' + pos % 10;
579  while ((pos /= 10) != 0);
580
581  fwrite (p, 1, buf + sizeof buf - p, stdout);
582}
583
584static void
585prline (char *beg, char *lim, int sep)
586{
587  if (out_file)
588    printf ("%s%c", filename, sep & filename_mask);
589  if (out_line)
590    {
591      nlscan (beg);
592      print_offset_sep (++totalnl, sep);
593      lastnl = lim;
594    }
595  if (out_byte)
596    {
597      off_t pos = totalcc + (beg - bufbeg);
598#if O_BINARY
599      pos = dossified_pos (pos);
600#endif
601      print_offset_sep (pos, sep);
602    }
603  fwrite (beg, 1, lim - beg, stdout);
604  if (ferror (stdout))
605    error (_("writing output"), errno);
606  lastout = lim;
607}
608
609/* Print pending lines of trailing context prior to LIM. */
610static void
611prpending (char *lim)
612{
613  char *nl;
614
615  if (!lastout)
616    lastout = bufbeg;
617  while (pending > 0 && lastout < lim)
618    {
619      --pending;
620      if ((nl = memchr (lastout, eolbyte, lim - lastout)) != 0)
621	++nl;
622      else
623	nl = lim;
624      prline (lastout, nl, '-');
625    }
626}
627
628/* Print the lines between BEG and LIM.  Deal with context crap.
629   If NLINESP is non-null, store a count of lines between BEG and LIM. */
630static void
631prtext (char *beg, char *lim, int *nlinesp)
632{
633  static int used;		/* avoid printing "--" before any output */
634  char *bp, *p, *nl;
635  char eol = eolbyte;
636  int i, n;
637
638  if (!out_quiet && pending > 0)
639    prpending (beg);
640
641  p = beg;
642
643  if (!out_quiet)
644    {
645      /* Deal with leading context crap. */
646
647      bp = lastout ? lastout : bufbeg;
648      for (i = 0; i < out_before; ++i)
649	if (p > bp)
650	  do
651	    --p;
652	  while (p > bp && p[-1] != eol);
653
654      /* We only print the "--" separator if our output is
655	 discontiguous from the last output in the file. */
656      if ((out_before || out_after) && used && p != lastout)
657	puts ("--");
658
659      while (p < beg)
660	{
661	  nl = memchr (p, eol, beg - p);
662	  prline (p, nl + 1, '-');
663	  p = nl + 1;
664	}
665    }
666
667  if (nlinesp)
668    {
669      /* Caller wants a line count. */
670      for (n = 0; p < lim; ++n)
671	{
672	  if ((nl = memchr (p, eol, lim - p)) != 0)
673	    ++nl;
674	  else
675	    nl = lim;
676	  if (!out_quiet)
677	    prline (p, nl, ':');
678	  p = nl;
679	}
680      *nlinesp = n;
681    }
682  else
683    if (!out_quiet)
684      prline (beg, lim, ':');
685
686  pending = out_quiet ? 0 : out_after;
687  used = 1;
688}
689
690/* Scan the specified portion of the buffer, matching lines (or
691   between matching lines if OUT_INVERT is true).  Return a count of
692   lines printed. */
693static int
694grepbuf (char *beg, char *lim)
695{
696  int nlines, n;
697  register char *p, *b;
698  char *endp;
699  char eol = eolbyte;
700
701  nlines = 0;
702  p = beg;
703  while ((b = (*execute)(p, lim - p, &endp)) != 0)
704    {
705      /* Avoid matching the empty line at the end of the buffer. */
706      if (b == lim && ((b > beg && b[-1] == eol) || b == beg))
707	break;
708      if (!out_invert)
709	{
710	  prtext (b, endp, (int *) 0);
711	  nlines += 1;
712	  if (done_on_match)
713	    return nlines;
714	}
715      else if (p < b)
716	{
717	  prtext (p, b, &n);
718	  nlines += n;
719	}
720      p = endp;
721    }
722  if (out_invert && p < lim)
723    {
724      prtext (p, lim, &n);
725      nlines += n;
726    }
727  return nlines;
728}
729
730/* Search a given file.  Normally, return a count of lines printed;
731   but if the file is a directory and we search it recursively, then
732   return -2 if there was a match, and -1 otherwise.  */
733static int
734grep (int fd, char const *file, struct stats *stats)
735{
736  int nlines, i;
737  int not_text;
738  size_t residue, save;
739  char *beg, *lim;
740  char eol = eolbyte;
741
742  if (!reset (fd, file, stats))
743    return 0;
744
745  if (file && directories == RECURSE_DIRECTORIES
746      && S_ISDIR (stats->stat.st_mode))
747    {
748      /* Close fd now, so that we don't open a lot of file descriptors
749	 when we recurse deeply.  */
750      if (BZflag)
751	BZ2_bzclose(bzbufdesc);
752      else
753#if HAVE_LIBZ > 0
754      if (Zflag)
755	gzclose(gzbufdesc);
756      else
757#endif
758      if (close (fd) != 0)
759	error (file, errno);
760      return grepdir (file, stats) - 2;
761    }
762
763  totalcc = 0;
764  lastout = 0;
765  totalnl = 0;
766  pending = 0;
767
768  nlines = 0;
769  residue = 0;
770  save = 0;
771
772  if (! fillbuf (save, stats))
773    {
774      if (! (is_EISDIR (errno, file) && suppress_errors))
775	error (filename, errno);
776      return 0;
777    }
778
779  not_text = (((binary_files == BINARY_BINARY_FILES && !out_quiet)
780	       || binary_files == WITHOUT_MATCH_BINARY_FILES)
781	      && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg));
782  if (not_text && binary_files == WITHOUT_MATCH_BINARY_FILES)
783    return 0;
784  done_on_match += not_text;
785  out_quiet += not_text;
786
787  for (;;)
788    {
789      lastnl = bufbeg;
790      if (lastout)
791	lastout = bufbeg;
792      if (buflim - bufbeg == save)
793	break;
794      beg = bufbeg + save - residue;
795      for (lim = buflim; lim > beg && lim[-1] != eol; --lim)
796	;
797      residue = buflim - lim;
798      if (beg < lim)
799	{
800	  nlines += grepbuf (beg, lim);
801	  if (pending)
802	    prpending (lim);
803	  if (nlines && done_on_match && !out_invert)
804	    goto finish_grep;
805	}
806      i = 0;
807      beg = lim;
808      while (i < out_before && beg > bufbeg && beg != lastout)
809	{
810	  ++i;
811	  do
812	    --beg;
813	  while (beg > bufbeg && beg[-1] != eol);
814	}
815      if (beg != lastout)
816	lastout = 0;
817      save = residue + lim - beg;
818      totalcc += buflim - bufbeg - save;
819      if (out_line)
820	nlscan (beg);
821      if (! fillbuf (save, stats))
822	{
823	  if (! (is_EISDIR (errno, file) && suppress_errors))
824	    error (filename, errno);
825	  goto finish_grep;
826	}
827    }
828  if (residue)
829    {
830      *buflim++ = eol;
831      nlines += grepbuf (bufbeg + save - residue, buflim);
832      if (pending)
833	prpending (buflim);
834    }
835
836 finish_grep:
837  done_on_match -= not_text;
838  out_quiet -= not_text;
839  if ((not_text & ~out_quiet) && nlines != 0)
840    printf (_("Binary file %s matches\n"), filename);
841  return nlines;
842}
843
844static int
845grepfile (char const *file, struct stats *stats)
846{
847  int desc;
848  int count;
849  int status;
850
851  if (! file)
852    {
853      desc = 0;
854      filename = _("(standard input)");
855    }
856  else
857    {
858      while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)
859	continue;
860
861      if (desc < 0)
862	{
863	  int e = errno;
864
865	  if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
866	    {
867	      if (stat (file, &stats->stat) != 0)
868		{
869		  error (file, errno);
870		  return 1;
871		}
872
873	      return grepdir (file, stats);
874	    }
875
876	  if (!suppress_errors)
877	    {
878	      if (directories == SKIP_DIRECTORIES)
879		switch (e)
880		  {
881#ifdef EISDIR
882		  case EISDIR:
883		    return 1;
884#endif
885		  case EACCES:
886		    /* When skipping directories, don't worry about
887		       directories that can't be opened.  */
888		    if (stat (file, &stats->stat) == 0
889			&& S_ISDIR (stats->stat.st_mode))
890		      return 1;
891		    break;
892		  }
893
894	      error (file, e);
895	    }
896
897	  return 1;
898	}
899
900      filename = file;
901    }
902
903#if O_BINARY
904  /* Set input to binary mode.  Pipes are simulated with files
905     on DOS, so this includes the case of "foo | grep bar".  */
906  if (!isatty (desc))
907    SET_BINARY (desc);
908#endif
909
910  count = grep (desc, file, stats);
911  if (count < 0)
912    status = count + 2;
913  else
914    {
915      if (count_matches)
916	{
917	  if (out_file)
918	    printf ("%s%c", filename, ':' & filename_mask);
919	  printf ("%d\n", count);
920	}
921
922      status = !count;
923      if (list_files == 1 - 2 * status)
924	printf ("%s%c", filename, '\n' & filename_mask);
925
926      if (BZflag)
927	BZ2_bzclose(bzbufdesc);
928      else
929#if HAVE_LIBZ > 0
930      if (Zflag)
931	gzclose(gzbufdesc);
932      else
933#endif
934      if (file)
935	while (close (desc) != 0)
936	  if (errno != EINTR)
937	    {
938	      error (file, errno);
939	      break;
940	    }
941    }
942
943  return status;
944}
945
946static int
947grepdir (char const *dir, struct stats *stats)
948{
949  int status = 1;
950  struct stats *ancestor;
951  char *name_space;
952
953  for (ancestor = stats;  (ancestor = ancestor->parent) != 0;  )
954    if (ancestor->stat.st_ino == stats->stat.st_ino
955	&& ancestor->stat.st_dev == stats->stat.st_dev)
956      {
957	if (!suppress_errors)
958	  fprintf (stderr, _("%s: warning: %s: %s\n"), prog, dir,
959		   _("recursive directory loop"));
960	return 1;
961      }
962
963  name_space = savedir (dir, (unsigned) stats->stat.st_size);
964
965  if (! name_space)
966    {
967      if (errno)
968	{
969	  if (!suppress_errors)
970	    error (dir, errno);
971	}
972      else
973	fatal (_("Memory exhausted"), 0);
974    }
975  else
976    {
977      size_t dirlen = strlen (dir);
978      int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir)
979			   || IS_SLASH (dir[dirlen - 1]));
980      char *file = NULL;
981      char *namep = name_space;
982      struct stats child;
983      child.parent = stats;
984      out_file += !no_filenames;
985      while (*namep)
986	{
987	  size_t namelen = strlen (namep);
988	  file = xrealloc (file, dirlen + 1 + namelen + 1);
989	  strcpy (file, dir);
990	  file[dirlen] = '/';
991	  strcpy (file + dirlen + needs_slash, namep);
992	  namep += namelen + 1;
993	  status &= grepfile (file, &child);
994	}
995      out_file -= !no_filenames;
996      if (file)
997        free (file);
998      free (name_space);
999    }
1000
1001  return status;
1002}
1003
1004static void
1005usage (int status)
1006{
1007  if (status != 0)
1008    {
1009      fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"), prog);
1010      fprintf (stderr, _("Try `%s --help' for more information.\n"), prog);
1011    }
1012  else
1013    {
1014      printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), prog);
1015      printf (_("\
1016Search for PATTERN in each FILE or standard input.\n\
1017Example: %s -i 'hello world' menu.h main.c\n\
1018\n\
1019Regexp selection and interpretation:\n"), prog);
1020      printf (_("\
1021  -E, --extended-regexp     PATTERN is an extended regular expression\n\
1022  -F, --fixed-strings       PATTERN is a set of newline-separated strings\n\
1023  -G, --basic-regexp        PATTERN is a basic regular expression\n"));
1024      printf (_("\
1025  -e, --regexp=PATTERN      use PATTERN as a regular expression\n\
1026  -f, --file=FILE           obtain PATTERN from FILE\n\
1027  -i, --ignore-case         ignore case distinctions\n\
1028  -w, --word-regexp         force PATTERN to match only whole words\n\
1029  -x, --line-regexp         force PATTERN to match only whole lines\n\
1030  -z, --null-data           a data line ends in 0 byte, not newline\n"));
1031      printf (_("\
1032\n\
1033Miscellaneous:\n\
1034  -s, --no-messages         suppress error messages\n\
1035  -v, --invert-match        select non-matching lines\n\
1036  -V, --version             print version information and exit\n\
1037      --help                display this help and exit\n\
1038  -J, --bz2decompress       decompress bzip2'ed input before searching\n\
1039  -Z, --decompress          decompress input before searching (HAVE_LIBZ=1)\n\
1040      --mmap                use memory-mapped input if possible\n"));
1041      printf (_("\
1042\n\
1043Output control:\n\
1044  -b, --byte-offset         print the byte offset with output lines\n\
1045  -n, --line-number         print line number with output lines\n\
1046  -H, --with-filename       print the filename for each match\n\
1047  -h, --no-filename         suppress the prefixing filename on output\n\
1048  -q, --quiet, --silent     suppress all normal output\n\
1049      --binary-files=TYPE   assume that binary files are TYPE\n\
1050                            TYPE is 'binary', 'text', or 'without-match'.\n\
1051  -a, --text                equivalent to --binary-files=text\n\
1052  -I                        equivalent to --binary-files=without-match\n\
1053  -d, --directories=ACTION  how to handle directories\n\
1054                            ACTION is 'read', 'recurse', or 'skip'.\n\
1055  -r, --recursive           equivalent to --directories=recurse.\n\
1056  -L, --files-without-match only print FILE names containing no match\n\
1057  -l, --files-with-matches  only print FILE names containing matches\n\
1058  -c, --count               only print a count of matching lines per FILE\n\
1059      --null                print 0 byte after FILE name\n"));
1060      printf (_("\
1061\n\
1062Context control:\n\
1063  -B, --before-context=NUM  print NUM lines of leading context\n\
1064  -A, --after-context=NUM   print NUM lines of trailing context\n\
1065  -C, --context[=NUM]       print NUM (default 2) lines of output context\n\
1066                            unless overridden by -A or -B\n\
1067  -NUM                      same as --context=NUM\n\
1068  -U, --binary              do not strip CR characters at EOL (MSDOS)\n\
1069  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)\n\
1070\n\
1071`egrep' means `grep -E'.  `fgrep' means `grep -F'.\n\
1072With no FILE, or when FILE is -, read standard input.  If less than\n\
1073two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,\n\
1074and 2 if trouble.\n"));
1075      printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n"));
1076    }
1077  exit (status);
1078}
1079
1080/* Set the matcher to M, reporting any conflicts.  */
1081static void
1082setmatcher (char const *m)
1083{
1084  if (matcher && strcmp (matcher, m) != 0)
1085    fatal (_("conflicting matchers specified"), 0);
1086  matcher = m;
1087}
1088
1089/* Go through the matchers vector and look for the specified matcher.
1090   If we find it, install it in compile and execute, and return 1.  */
1091static int
1092install_matcher (char const *name)
1093{
1094  int i;
1095#ifdef HAVE_SETRLIMIT
1096  struct rlimit rlim;
1097#endif
1098
1099  for (i = 0; matchers[i].name; ++i)
1100    if (strcmp (name, matchers[i].name) == 0)
1101      {
1102	compile = matchers[i].compile;
1103	execute = matchers[i].execute;
1104#if HAVE_SETRLIMIT && defined(RLIMIT_STACK)
1105	/* I think every platform needs to do this, so that regex.c
1106	   doesn't oveflow the stack.  The default value of
1107	   `re_max_failures' is too large for some platforms: it needs
1108	   more than 3MB-large stack.
1109
1110	   The test for HAVE_SETRLIMIT should go into `configure'.  */
1111	if (!getrlimit (RLIMIT_STACK, &rlim))
1112	  {
1113	    long newlim;
1114	    extern long int re_max_failures; /* from regex.c */
1115
1116	    /* Approximate the amount regex.c needs, plus some more.  */
1117	    newlim = re_max_failures * 2 * 20 * sizeof (char *);
1118	    if (newlim > rlim.rlim_max)
1119	      {
1120		newlim = rlim.rlim_max;
1121		re_max_failures = newlim / (2 * 20 * sizeof (char *));
1122	      }
1123	    if (rlim.rlim_cur < newlim)
1124	      rlim.rlim_cur = newlim;
1125
1126	    setrlimit (RLIMIT_STACK, &rlim);
1127	  }
1128#endif
1129	return 1;
1130      }
1131  return 0;
1132}
1133
1134/* Find the white-space-separated options specified by OPTIONS, and
1135   using BUF to store copies of these options, set ARGV[0], ARGV[1],
1136   etc. to the option copies.  Return the number N of options found.
1137   Do not set ARGV[N] to NULL.  If ARGV is NULL, do not store ARGV[0]
1138   etc.  Backslash can be used to escape whitespace (and backslashes).  */
1139static int
1140prepend_args (char const *options, char *buf, char **argv)
1141{
1142  char const *o = options;
1143  char *b = buf;
1144  int n = 0;
1145
1146  for (;;)
1147    {
1148      while (ISSPACE ((unsigned char) *o))
1149	o++;
1150      if (!*o)
1151	return n;
1152      if (argv)
1153	argv[n] = b;
1154      n++;
1155
1156      do
1157	if ((*b++ = *o++) == '\\' && *o)
1158	  b[-1] = *o++;
1159      while (*o && ! ISSPACE ((unsigned char) *o));
1160
1161      *b++ = '\0';
1162    }
1163}
1164
1165/* Prepend the whitespace-separated options in OPTIONS to the argument
1166   vector of a main program with argument count *PARGC and argument
1167   vector *PARGV.  */
1168static void
1169prepend_default_options (char const *options, int *pargc, char ***pargv)
1170{
1171  if (options)
1172    {
1173      char *buf = xmalloc (strlen (options) + 1);
1174      int prepended = prepend_args (options, buf, (char **) NULL);
1175      int argc = *pargc;
1176      char * const *argv = *pargv;
1177      char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
1178      *pargc = prepended + argc;
1179      *pargv = pp;
1180      *pp++ = *argv++;
1181      pp += prepend_args (options, buf, pp);
1182      while ((*pp++ = *argv++))
1183	continue;
1184    }
1185}
1186
1187int
1188main (int argc, char **argv)
1189{
1190  char *keys;
1191  size_t keycc, oldcc, keyalloc;
1192  int with_filenames;
1193  int opt, cc, status;
1194  int default_context;
1195  unsigned digit_args_val;
1196  FILE *fp;
1197  extern char *optarg;
1198  extern int optind;
1199
1200  initialize_main (&argc, &argv);
1201  prog = argv[0];
1202  if (prog && strrchr (prog, '/'))
1203    prog = strrchr (prog, '/') + 1;
1204
1205#if HAVE_LIBZ > 0
1206  if (prog[0] == 'z') {
1207    Zflag = 1;
1208    ++prog;
1209  }
1210#endif
1211  if (prog[0] == 'b') {
1212    BZflag = 1;
1213    ++prog;
1214  }
1215
1216#if defined(__MSDOS__) || defined(_WIN32)
1217  /* DOS and MS-Windows use backslashes as directory separators, and usually
1218     have an .exe suffix.  They also have case-insensitive filesystems.  */
1219  if (prog)
1220    {
1221      char *p = prog;
1222      char *bslash = strrchr (argv[0], '\\');
1223
1224      if (bslash && bslash >= prog) /* for mixed forward/backslash case */
1225	prog = bslash + 1;
1226      else if (prog == argv[0]
1227	       && argv[0][0] && argv[0][1] == ':') /* "c:progname" */
1228	prog = argv[0] + 2;
1229
1230      /* Collapse the letter-case, so `strcmp' could be used hence.  */
1231      for ( ; *p; p++)
1232	if (*p >= 'A' && *p <= 'Z')
1233	  *p += 'a' - 'A';
1234
1235      /* Remove the .exe extension, if any.  */
1236      if ((p = strrchr (prog, '.')) && strcmp (p, ".exe") == 0)
1237	*p = '\0';
1238    }
1239#endif
1240
1241  keys = NULL;
1242  keycc = 0;
1243  with_filenames = 0;
1244  eolbyte = '\n';
1245  filename_mask = ~0;
1246
1247  /* The value -1 means to use DEFAULT_CONTEXT. */
1248  out_after = out_before = -1;
1249  /* Default before/after context: chaged by -C/-NUM options */
1250  default_context = 0;
1251  /* Accumulated value of individual digits in a -NUM option */
1252  digit_args_val = 0;
1253
1254
1255/* Internationalization. */
1256#if HAVE_SETLOCALE
1257  setlocale (LC_ALL, "");
1258#endif
1259#if ENABLE_NLS
1260  bindtextdomain (PACKAGE, LOCALEDIR);
1261  textdomain (PACKAGE);
1262#endif
1263
1264  prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv);
1265
1266  while ((opt = getopt_long (argc, argv, short_options, long_options, NULL))
1267	 != -1)
1268    switch (opt)
1269      {
1270      case '0':
1271      case '1':
1272      case '2':
1273      case '3':
1274      case '4':
1275      case '5':
1276      case '6':
1277      case '7':
1278      case '8':
1279      case '9':
1280	digit_args_val = 10 * digit_args_val + opt - '0';
1281	default_context = digit_args_val;
1282	break;
1283      case 'A':
1284	if (optarg)
1285	  {
1286	    if (ck_atoi (optarg, &out_after))
1287	      fatal (_("invalid context length argument"), 0);
1288	  }
1289	break;
1290      case 'B':
1291	if (optarg)
1292	  {
1293	    if (ck_atoi (optarg, &out_before))
1294	      fatal (_("invalid context length argument"), 0);
1295	  }
1296	break;
1297      case 'C':
1298	/* Set output match context, but let any explicit leading or
1299	   trailing amount specified with -A or -B stand. */
1300	if (optarg)
1301	  {
1302	    if (ck_atoi (optarg, &default_context))
1303	      fatal (_("invalid context length argument"), 0);
1304	  }
1305	else
1306	  default_context = 2;
1307	break;
1308      case 'E':
1309	setmatcher ("egrep");
1310	break;
1311      case 'F':
1312	setmatcher ("fgrep");
1313	break;
1314      case 'G':
1315	setmatcher ("grep");
1316	break;
1317      case 'H':
1318	with_filenames = 1;
1319	break;
1320      case 'I':
1321	binary_files = WITHOUT_MATCH_BINARY_FILES;
1322	break;
1323      case 'J':
1324	BZflag = 1;
1325	break;
1326      case 'U':
1327#if O_BINARY
1328	dos_use_file_type = DOS_BINARY;
1329#endif
1330	break;
1331      case 'u':
1332#if O_BINARY
1333	dos_report_unix_offset = 1;
1334#endif
1335	break;
1336      case 'V':
1337	show_version = 1;
1338	break;
1339      case 'X':
1340	setmatcher (optarg);
1341	break;
1342      case 'a':
1343	binary_files = TEXT_BINARY_FILES;
1344	break;
1345      case 'b':
1346	out_byte = 1;
1347	break;
1348      case 'c':
1349	out_quiet = 1;
1350	count_matches = 1;
1351	break;
1352      case 'd':
1353	if (strcmp (optarg, "read") == 0)
1354	  directories = READ_DIRECTORIES;
1355	else if (strcmp (optarg, "skip") == 0)
1356	  directories = SKIP_DIRECTORIES;
1357	else if (strcmp (optarg, "recurse") == 0)
1358	  directories = RECURSE_DIRECTORIES;
1359	else
1360	  fatal (_("unknown directories method"), 0);
1361	break;
1362      case 'e':
1363	cc = strlen (optarg);
1364	keys = xrealloc (keys, keycc + cc + 1);
1365	strcpy (&keys[keycc], optarg);
1366	keycc += cc;
1367	keys[keycc++] = '\n';
1368	break;
1369      case 'f':
1370	fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin;
1371	if (!fp)
1372	  fatal (optarg, errno);
1373	for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2)
1374	  ;
1375	keys = xrealloc (keys, keyalloc);
1376	oldcc = keycc;
1377	while (!feof (fp)
1378	       && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0)
1379	  {
1380	    keycc += cc;
1381	    if (keycc == keyalloc - 1)
1382	      keys = xrealloc (keys, keyalloc *= 2);
1383	  }
1384	if (fp != stdin)
1385	  fclose(fp);
1386	/* Append final newline if file ended in non-newline. */
1387	if (oldcc != keycc && keys[keycc - 1] != '\n')
1388	  keys[keycc++] = '\n';
1389	break;
1390      case 'h':
1391	no_filenames = 1;
1392	break;
1393      case 'i':
1394      case 'y':			/* For old-timers . . . */
1395	match_icase = 1;
1396	break;
1397      case 'L':
1398	/* Like -l, except list files that don't contain matches.
1399	   Inspired by the same option in Hume's gre. */
1400	out_quiet = 1;
1401	list_files = -1;
1402	done_on_match = 1;
1403	break;
1404      case 'l':
1405	out_quiet = 1;
1406	list_files = 1;
1407	done_on_match = 1;
1408	break;
1409      case 'n':
1410	out_line = 1;
1411	break;
1412      case 'q':
1413	done_on_match = 1;
1414	out_quiet = 1;
1415	break;
1416      case 'R':
1417      case 'r':
1418	directories = RECURSE_DIRECTORIES;
1419	break;
1420      case 's':
1421	suppress_errors = 1;
1422	break;
1423      case 'v':
1424	out_invert = 1;
1425	break;
1426      case 'w':
1427	match_words = 1;
1428	break;
1429      case 'x':
1430	match_lines = 1;
1431	break;
1432      case 'Z':
1433#if HAVE_LIBZ > 0
1434	Zflag = 1;
1435#else
1436	filename_mask = 0;
1437#endif
1438	break;
1439      case 'z':
1440	eolbyte = '\0';
1441	break;
1442      case BINARY_FILES_OPTION:
1443	if (strcmp (optarg, "binary") == 0)
1444	  binary_files = BINARY_BINARY_FILES;
1445	else if (strcmp (optarg, "text") == 0)
1446	  binary_files = TEXT_BINARY_FILES;
1447	else if (strcmp (optarg, "without-match") == 0)
1448	  binary_files = WITHOUT_MATCH_BINARY_FILES;
1449	else
1450	  fatal (_("unknown binary-files type"), 0);
1451	break;
1452      case 0:
1453	/* long options */
1454	break;
1455      default:
1456	usage (2);
1457	break;
1458      }
1459
1460  if (out_after < 0)
1461    out_after = default_context;
1462  if (out_before < 0)
1463    out_before = default_context;
1464
1465  if (! matcher)
1466    matcher = prog;
1467
1468  if (show_version)
1469    {
1470      printf (_("%s (GNU grep) %s\n"), matcher, VERSION);
1471      printf ("\n");
1472      printf (_("\
1473Copyright (C) 1988, 1992-1998, 1999 Free Software Foundation, Inc.\n"));
1474      printf (_("\
1475This is free software; see the source for copying conditions. There is NO\n\
1476warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
1477      printf ("\n");
1478      exit (0);
1479    }
1480
1481  if (show_help)
1482    usage (0);
1483
1484  if (keys)
1485    {
1486      if (keycc == 0)
1487	/* No keys were specified (e.g. -f /dev/null).  Match nothing.  */
1488        out_invert ^= 1;
1489      else
1490	/* Strip trailing newline. */
1491        --keycc;
1492    }
1493  else
1494    if (optind < argc)
1495      {
1496	keys = argv[optind++];
1497	keycc = strlen (keys);
1498      }
1499    else
1500      usage (2);
1501
1502  if (!install_matcher (matcher) && !install_matcher ("default"))
1503    abort ();
1504
1505  (*compile)(keys, keycc);
1506
1507  if ((argc - optind > 1 && !no_filenames) || with_filenames)
1508    out_file = 1;
1509
1510#if O_BINARY
1511  /* Output is set to binary mode because we shouldn't convert
1512     NL to CR-LF pairs, especially when grepping binary files.  */
1513  if (!isatty (1))
1514    SET_BINARY (1);
1515#endif
1516
1517
1518  if (optind < argc)
1519    {
1520	status = 1;
1521	do
1522	{
1523	  char *file = argv[optind];
1524	  status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file,
1525			      &stats_base);
1526	}
1527	while ( ++optind < argc);
1528    }
1529  else
1530    status = grepfile ((char *) NULL, &stats_base);
1531
1532  if (fclose (stdout) == EOF)
1533    error (_("writing output"), errno);
1534
1535  exit (errseen ? 2 : status);
1536}
1537