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