1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-16 10:20:30 +00:00

Added builtin decompression using zlib library, option -Z.

Enabled this new feature with the makefile variable GREP_LIBZ. If
you don't like it, compile with `make GREP_LIBZ='.

grep + zlib has several advantages:

- the shell script zgrep(1) will be basically a one line
  exec grep -Z "$@"

- no shell script, no bugs. The current zgrep implementations
  have many bugs and some grep options are no supported.

- no shell script, no security risks.

- it is a magnitude faster than a shell script

Also fixed:
0 -> STDIN_FILENO
Close a file descriptor only if the open call was successfully. It does
not hurt for the open(2) function, but the gzclose(3) function
died in free() to free up (not) allocated memory.
This commit is contained in:
Wolfram Schneider 1997-12-20 18:46:09 +00:00
parent 09d64da3a4
commit a6f4e3c4dc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=31900
3 changed files with 131 additions and 67 deletions

View File

@ -1,8 +1,13 @@
# $Id$
GREP_LIBZ= YES
GREP_FTS= YES
PROG= grep
SRCS= dfa.c grep.c getopt.c kwset.c obstack.c search.c
CFLAGS+=-DGREP -DHAVE_STRING_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_UNISTD_H=1 \
-DHAVE_GETPAGESIZE=1 -DHAVE_MEMCHR=1 -DHAVE_STRERROR=1 \
-DHAVE_VALLOC=1 -DHAVE_MMAP=1 -DHAVE_FTS=1
-DHAVE_VALLOC=1
LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \
${BINDIR}/grep ${BINDIR}/fgrep
@ -11,6 +16,15 @@ MLINKS= grep.1 egrep.1 grep.1 fgrep.1
DPADD+= ${LIBGNUREGEX}
LDADD+= -lgnuregex
.if defined(GREP_LIBZ) && !empty(GREP_LIBZ)
LDADD+= -lz
DPADD+= ${LIBZ}
CFLAGS+= -DHAVE_LIBZ=1
.endif
.if defined(GREP_FTS) && !empty(GREP_FTS)
CFLAGS+= -DHAVE_FTS=1
.endif
check: all
sh ${.CURDIR}/tests/check.sh ${.CURDIR}/tests

View File

@ -161,7 +161,7 @@ characters are letters, digits, and the underscore.
Select only those matches that exactly match the whole line.
.PP
Following options only available if compiled with FTS library:
Following options are only available if compiled with FTS library:
.PD 0
.TP
.BI \-H
@ -171,24 +171,30 @@ option is specified, symbolic links on the command line
are followed. (Symbolic links encountered in the tree traversal
are not followed.)
.TP
.BI \-L
If the
.I \-R
option is specified, all symbolic links are followed.
.TP
.BI \-P
If the
.I \-R
option is specified, no symbolic links are followed.
.TP
.BI \-R
Search in the file hierarchies
rooted in the files instead of just the files themselves.
.TP
.LP
Following option is only available if compiled with zlib library:
.PD 0
.TP
.BI \-Z
If the
.I \-Z
option is specified, the input data will be
decompressed before searching.
.TP
.PD
.SH "REGULAR EXPRESSIONS"
.PP

View File

@ -15,7 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Written July 1992 by Mike Haertel. */
Written July 1992 by Mike Haertel.
Recursive searching and builtin decompression (libz)
1996/1997 by Wolfram Schneider <wosch@FreeBSD.org>. */
#include <errno.h>
#include <stdio.h>
@ -96,7 +99,7 @@ memchr(vp, c, n)
#endif
/* traverse a file hierarchy library */
#ifdef HAVE_FTS
#if HAVE_FTS > 0
#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>
@ -211,6 +214,12 @@ static struct stat bufstat; /* From fstat(). */
static off_t bufoffset; /* What read() normally remembers. */
#endif
#if HAVE_LIBZ > 0
#include <zlib.h>
static gzFile gzbufdesc; /* zlib file descriptor. */
static int Zflag; /* uncompress before searching */
#endif
/* Reset the buffer for a new file. Initialize
on the first time through. */
void
@ -237,9 +246,20 @@ reset(fd)
bufbeg = buffer;
buflim = buffer;
}
bufdesc = fd;
#if HAVE_LIBZ > 0
if (Zflag) {
gzbufdesc = gzdopen(fd, "r");
if (gzbufdesc == NULL)
fatal("memory exhausted", 0);
}
#endif
bufdesc = fd;
#if defined(HAVE_WORKING_MMAP)
if (fstat(fd, &bufstat) < 0 || !S_ISREG(bufstat.st_mode))
if (
#if HAVE_LIBZ > 0
Zflag ||
#endif
fstat(fd, &bufstat) < 0 || !S_ISREG(bufstat.st_mode))
bufmapped = 0;
else
{
@ -323,10 +343,20 @@ fillbuf(save)
bufmapped = 0;
lseek(bufdesc, bufoffset, 0);
}
cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
#if HAVE_LIBZ > 0
if (Zflag)
cc = gzread(gzbufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
else
#endif
cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
}
#else
cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
#if HAVE_LIBZ > 0
if (Zflag)
cc = gzread(gzbufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
else
#endif
cc = read(bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
#endif
if (cc > 0)
buflim = buffer + bufsalloc + cc;
@ -513,32 +543,22 @@ grepbuf(beg, lim)
/*
* try to guess if fd belong to a binary file
* try to guess if buf belong to a binary file
*/
int isBinaryFile(fd)
int fd;
int isBinaryFile(buf, len)
char *buf;
int len;
{
#define BINARY_BUF_LEN 32
static unsigned char buf[BINARY_BUF_LEN];
int i, n;
int i;
/* pipe, socket, fifo */
if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1)
return(0);
if ((n =(int) read(fd, buf, (size_t)BINARY_BUF_LEN)) == -1)
return(0);
len = (len < BINARY_BUF_LEN ? len : BINARY_BUF_LEN);
/* look for non-printable chars */
for(i = 0; i < n; i++)
if (!isprint((unsigned char)buf[i]) && !isspace((unsigned char)buf[i]))
for(i = 0; i < len; i++, buf++)
if (!isprint(*buf) && !isspace(*buf))
return(1);
/* reset fd to begin of file */
if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1)
return(0);
return(0);
}
@ -553,10 +573,7 @@ grep(fd)
int nlines, i;
size_t residue, save;
char *beg, *lim;
/* skip binary files */
if (aflag && isBinaryFile(fd))
return(0);
int first, cc;
reset(fd);
@ -568,14 +585,22 @@ grep(fd)
nlines = 0;
residue = 0;
save = 0;
first = 0;
cc = 0;
for (;;)
{
if (fillbuf(save) < 0)
if ((cc = fillbuf(save)) < 0)
{
error(filename, errno);
return nlines;
}
/* skip binary files */
if (!first && aflag && isBinaryFile(bufbeg, cc))
return(0);
first++;
lastnl = bufbeg;
if (lastout)
lastout = bufbeg;
@ -620,21 +645,25 @@ grep(fd)
}
static char version[] = "GNU grep version 2.0";
#ifdef HAVE_FTS
#define USAGE \
"usage: %s [-[AB] <num>] [-HRPS] [-CEFGLVabchilnqsvwx]\n\
[-e <expr>] [-f file] [files ...]\n"
#define GETOPT_STD "0123456789A:B:CEFGLVX:abce:f:hilnqsvwxy"
#if HAVE_FTS > 0
#define GETOPT_FTS "HPRS"
#else
#define USAGE \
"usage: %s [-[AB] <num>] [-CEFGLVabchilnqsvwx]\n\
[-e <expr>] [-f file] [files ...]\n"
#define GETOPT_FTS ""
#endif
#if HAVE_LIBZ > 0
#define GETOPT_Z "Z"
#else
#define GETOPT_Z ""
#endif
static void
usage()
{
fprintf(stderr, USAGE, prog);
fprintf(stderr, "usage: %s [-[AB] <num>] [-CEFGLVX%s%s%s",
prog, GETOPT_FTS, GETOPT_Z,
"abchilnqsvwxy]\n [-e <expr>] [-f file] [files ...]\n");
exit(2);
}
@ -656,6 +685,8 @@ setmatcher(name)
return 0;
}
int
main(argc, argv)
int argc;
@ -668,7 +699,7 @@ main(argc, argv)
FILE *fp;
extern char *optarg;
extern int optind;
#ifdef HAVE_FTS
#if HAVE_FTS > 0
int Rflag, Hflag, Pflag, Lflag;
FTS *ftsp;
FTSENT *ftsent;
@ -691,19 +722,12 @@ main(argc, argv)
suppress_errors = 0;
matcher = NULL;
aflag = 0;
#ifdef HAVE_FTS
#if HAVE_FTS > 0
Rflag = Hflag = Pflag = Lflag = 0;
#endif
while ((opt = getopt(argc, argv,
#ifndef HAVE_FTS
"0123456789A:B:CEFGVX:abce:f:hiLlnqsvwxy"
#else
"0123456789A:B:CEFGHLPRSVX:abce:f:hiLlnqsvwxy?"
#endif
)) != EOF)
GETOPT_STD/**/GETOPT_FTS/**/GETOPT_Z)) != -1)
switch (opt)
{
case '0':
@ -755,8 +779,12 @@ main(argc, argv)
fatal("matcher already specified", 0);
matcher = optarg;
break;
#ifdef HAVE_FTS
#if HAVE_LIBZ > 0
case 'Z':
Zflag = 1;
break;
#endif
#if HAVE_FTS > 0
/* symbolic links on the command line are followed */
case 'H':
Hflag = 1;
@ -880,16 +908,16 @@ main(argc, argv)
(*compile)(keys, keycc);
#ifndef HAVE_FTS
if (argc - optind > 1 && !no_filenames)
#else
#if HAVE_FTS > 0
if ((argc - optind > 1 || Rflag) && !no_filenames)
#else
if (argc - optind > 1 && !no_filenames)
#endif
out_file = 1;
status = 1;
#if HAVE_FTS
#if HAVE_FTS > 0
if (Rflag) {
fts_options = FTS_PHYSICAL | FTS_NOCHDIR;
@ -984,8 +1012,14 @@ main(argc, argv)
else if (list_files == -1)
printf("%s\n", filename);
if (desc != STDIN_FILENO)
if (desc != STDIN_FILENO) {
#if HAVE_LIBZ > 0
if (Zflag)
gzclose(gzbufdesc);
else
#endif
close(desc);
}
}
if (fts_close(ftsp) == -1)
@ -1002,7 +1036,8 @@ main(argc, argv)
while (optind < argc)
{
desc = strcmp(argv[optind], "-") ? open(argv[optind], O_RDONLY) : 0;
desc = strcmp(argv[optind], "-") ?
open(argv[optind], O_RDONLY) : STDIN_FILENO;
if (desc < 0)
{
if (!suppress_errors)
@ -1010,7 +1045,8 @@ main(argc, argv)
}
else
{
filename = desc == 0 ? "(standard input)" : argv[optind];
filename = desc == STDIN_FILENO ?
"(standard input)" : argv[optind];
count = grep(desc);
if (count_matches)
{
@ -1026,9 +1062,17 @@ main(argc, argv)
}
else if (list_files == -1)
printf("%s\n", filename);
}
if (desc != 0)
close(desc);
if (desc != STDIN_FILENO) {
#if HAVE_LIBZ > 0
if (Zflag)
gzclose(gzbufdesc);
else
#endif
close(desc);
}
}
++optind;
}
@ -1036,7 +1080,7 @@ main(argc, argv)
else
{
filename = "(standard input)";
count = grep(0);
count = grep(STDIN_FILENO);
if (count_matches)
printf("%d\n", count);
if (count)