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