Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Aug 2010 13:48:40 -0700
From:      mdf@FreeBSD.org
To:        Gabor Kovesdan <gabor@freebsd.org>, src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r211463 - head/usr.bin/grep
Message-ID:  <AANLkTimjHt9NZa0-vU%2Bm2dkY2pTciUDLGd0Qut=uhFTq@mail.gmail.com>
In-Reply-To: <201008181740.o7IHeA4c075984@svn.freebsd.org>
References:  <201008181740.o7IHeA4c075984@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Aug 18, 2010 at 10:40 AM, Gabor Kovesdan <gabor@freebsd.org> wrote:
> Author: gabor
> Date: Wed Aug 18 17:40:10 2010
> New Revision: 211463
> URL: http://svn.freebsd.org/changeset/base/211463
>
> Log:
> =A0- Refactor file reading code to use pure syscalls and an internal buff=
er
> =A0 =A0instead of stdio. =A0This gives BSD grep a very big performance bo=
ost,
> =A0 =A0its speed is now almost comparable to GNU grep.

I didn't read all of the details in the profiling mails in the thread,
but does this mean that work on stdio would give a performance boost
to many apps?  Or is there something specific about how grep(1) is
using its input that makes it a horse of a different color?

Thanks,
matthew


>
> =A0Submitted by: Dimitry Andric <dimitry@andric.com>
> =A0Approved by: =A0delphij (mentor)
>
> Modified:
> =A0head/usr.bin/grep/fastgrep.c
> =A0head/usr.bin/grep/file.c
> =A0head/usr.bin/grep/grep.h
> =A0head/usr.bin/grep/util.c
>
> Modified: head/usr.bin/grep/fastgrep.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/usr.bin/grep/fastgrep.c =A0 =A0 =A0 =A0Wed Aug 18 17:39:47 2010 =
=A0 =A0 =A0 =A0(r211462)
> +++ head/usr.bin/grep/fastgrep.c =A0 =A0 =A0 =A0Wed Aug 18 17:40:10 2010 =
=A0 =A0 =A0 =A0(r211463)
> @@ -198,7 +198,7 @@ fastcomp(fastgrep_t *fg, const char *pat
> =A0}
>
> =A0int
> -grep_search(fastgrep_t *fg, unsigned char *data, size_t len, regmatch_t =
*pmatch)
> +grep_search(fastgrep_t *fg, const unsigned char *data, size_t len, regma=
tch_t *pmatch)
> =A0{
> =A0 =A0 =A0 =A0unsigned int j;
> =A0 =A0 =A0 =A0int ret =3D REG_NOMATCH;
>
> Modified: head/usr.bin/grep/file.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/usr.bin/grep/file.c =A0 =A0Wed Aug 18 17:39:47 2010 =A0 =A0 =A0 =
=A0(r211462)
> +++ head/usr.bin/grep/file.c =A0 =A0Wed Aug 18 17:40:10 2010 =A0 =A0 =A0 =
=A0(r211463)
> @@ -2,7 +2,8 @@
>
> =A0/*-
> =A0* Copyright (c) 1999 James Howard and Dag-Erling Co=EFdan Sm=F8rgrav
> - * Copyright (C) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
> + * Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
> + * Copyright (C) 2010 Dimitry Andric <dimitry@andric.com>
> =A0* All rights reserved.
> =A0*
> =A0* Redistribution and use in source and binary forms, with or without
> @@ -37,7 +38,8 @@ __FBSDID("$FreeBSD$");
> =A0#include <bzlib.h>
> =A0#include <err.h>
> =A0#include <errno.h>
> -#include <stdio.h>
> +#include <fcntl.h>
> +#include <stddef.h>
> =A0#include <stdlib.h>
> =A0#include <string.h>
> =A0#include <unistd.h>
> @@ -47,222 +49,204 @@ __FBSDID("$FreeBSD$");
>
> =A0#include "grep.h"
>
> -static char =A0 =A0 fname[MAXPATHLEN]; =A0 =A0 /* file name */
> +#define =A0 =A0 =A0 =A0MAXBUFSIZ =A0 =A0 =A0 (32 * 1024)
> +#define =A0 =A0 =A0 =A0LNBUFBUMP =A0 =A0 =A0 80
>
> -#define =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 MAXBUFSIZ =A0 =A0 =A0(16 * 1024)
> -#define =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 PREREAD_M =A0 =A0 =A00.2
> +static gzFile gzbufdesc;
> +static BZFILE* bzbufdesc;
>
> -/* Some global variables for the buffering and reading. */
> -static char =A0 =A0*lnbuf;
> -static size_t =A0 lnbuflen;
> -static unsigned char *binbuf;
> -static int =A0 =A0 =A0binbufsiz;
> -unsigned char =A0*binbufptr;
> -static int =A0 =A0 =A0bzerr;
> +static unsigned char buffer[MAXBUFSIZ];
> +static unsigned char *bufpos;
> +static size_t bufrem;
>
> -#define iswbinary(ch) =A0(!iswspace((ch)) && iswcntrl((ch)) && \
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (ch !=3D L'\b') && =
(ch !=3D L'\0'))
> +static unsigned char *lnbuf;
> +static size_t lnbuflen;
>
> -/*
> - * Returns a single character according to the file type.
> - * Returns -1 on failure.
> - */
> =A0static inline int
> -grep_fgetc(struct file *f)
> +grep_refill(struct file *f)
> =A0{
> - =A0 =A0 =A0 unsigned char c;
> + =A0 =A0 =A0 ssize_t nr;
> + =A0 =A0 =A0 int bzerr;
>
> - =A0 =A0 =A0 switch (filebehave) {
> - =A0 =A0 =A0 case FILE_STDIO:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (getc_unlocked(f->f));
> - =A0 =A0 =A0 case FILE_GZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (gzgetc(f->gzf));
> - =A0 =A0 =A0 case FILE_BZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 BZ2_bzRead(&bzerr, f->bzf, &c, 1);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (bzerr =3D=3D BZ_STREAM_END)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (-1);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 else if (bzerr !=3D BZ_SEQUENCE_ERROR && bz=
err !=3D BZ_OK)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 errx(2, "%s", getstr(2));
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (c);
> - =A0 =A0 =A0 }
> - =A0 =A0 =A0 return (-1);
> + =A0 =A0 =A0 bufpos =3D buffer;
> + =A0 =A0 =A0 bufrem =3D 0;
> +
> + =A0 =A0 =A0 if (filebehave =3D=3D FILE_GZIP)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 nr =3D gzread(gzbufdesc, buffer, MAXBUFSIZ)=
;
> + =A0 =A0 =A0 else if (filebehave =3D=3D FILE_BZIP && bzbufdesc !=3D NULL=
) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 nr =3D BZ2_bzRead(&bzerr, bzbufdesc, buffer=
, MAXBUFSIZ);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 switch (bzerr) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 case BZ_OK:
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 case BZ_STREAM_END:
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* No problem, nr will be o=
kay */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 case BZ_DATA_ERROR_MAGIC:
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* As opposed to gzread()=
, which simply returns the
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* plain file data, if it=
 is not in the correct
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* compressed format, BZ2=
_bzRead() instead aborts.
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* So, just restart at th=
e beginning of the file again,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* and use plain reads fr=
om now on.
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 BZ2_bzReadClose(&bzerr, bzb=
ufdesc);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bzbufdesc =3D NULL;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (lseek(f->fd, 0, SEEK_SE=
T) =3D=3D -1)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (-1)=
;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nr =3D read(f->fd, buffer, =
MAXBUFSIZ);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 default:
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Make sure we exit with a=
n error */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 nr =3D -1;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> + =A0 =A0 =A0 } else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 nr =3D read(f->fd, buffer, MAXBUFSIZ);
> +
> + =A0 =A0 =A0 if (nr < 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (-1);
> +
> + =A0 =A0 =A0 bufrem =3D nr;
> + =A0 =A0 =A0 return (0);
> =A0}
>
> -/*
> - * Returns true if the file position is a EOF, returns false
> - * otherwise.
> - */
> =A0static inline int
> -grep_feof(struct file *f)
> +grep_lnbufgrow(size_t newlen)
> =A0{
>
> - =A0 =A0 =A0 switch (filebehave) {
> - =A0 =A0 =A0 case FILE_STDIO:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (feof_unlocked(f->f));
> - =A0 =A0 =A0 case FILE_GZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (gzeof(f->gzf));
> - =A0 =A0 =A0 case FILE_BZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (bzerr =3D=3D BZ_STREAM_END);
> + =A0 =A0 =A0 if (lnbuflen < newlen) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lnbuf =3D grep_realloc(lnbuf, newlen);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lnbuflen =3D newlen;
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 return (1);
> +
> + =A0 =A0 =A0 return (0);
> =A0}
>
> -/*
> - * At the first call, fills in an internal buffer and checks if the give=
n
> - * file is a binary file and sets the binary flag accordingly. =A0Then r=
eturns
> - * a single line and sets len to the length of the returned line.
> - * At any other call returns a single line either from the internal buff=
er
> - * or from the file if the buffer is exhausted and sets len to the lengt=
h
> - * of the line.
> - */
> =A0char *
> -grep_fgetln(struct file *f, size_t *len)
> +grep_fgetln(struct file *f, size_t *lenp)
> =A0{
> - =A0 =A0 =A0 struct stat st;
> - =A0 =A0 =A0 size_t bufsiz, i =3D 0;
> - =A0 =A0 =A0 int ch =3D 0;
> -
> - =A0 =A0 =A0 /* Fill in the buffer if it is empty. */
> - =A0 =A0 =A0 if (binbufptr =3D=3D NULL) {
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Only pre-read to the buffer if we need t=
he binary check. */
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (binbehave !=3D BINFILE_TEXT) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (f->stdin)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 st.st_size =
=3D MAXBUFSIZ;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else if (stat(fname, &st) !=
=3D 0)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 err(2, NULL=
);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* no need to allocate buff=
er. */
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (st.st_size =3D=3D 0)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (NUL=
L);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bufsiz =3D (MAXBUFSIZ > (st=
.st_size * PREREAD_M)) ?
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (st.st_size / 2) : =
MAXBUFSIZ;
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 binbuf =3D grep_malloc(size=
of(char) * bufsiz);
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 while (i < bufsiz) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ch =3D grep=
_fgetc(f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (ch =3D=
=3D EOF)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 break;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 binbuf[i++]=
 =3D ch;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((ch =3D=
=3D '\n') && lbflag)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 break;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 f->binary =3D memchr(binbuf=
, (filebehave !=3D FILE_GZIP) ?
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 '\0' : '\200', i - =
1) !=3D NULL;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 binbufsiz =3D i;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 binbufptr =3D binbuf;
> - =A0 =A0 =A0 }
> -
> - =A0 =A0 =A0 /* Read a line whether from the buffer or from the file its=
elf. */
> - =A0 =A0 =A0 for (i =3D 0; !(grep_feof(f) &&
> - =A0 =A0 =A0 =A0 =A0 (binbufptr =3D=3D &binbuf[binbufsiz])); i++) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (binbufptr =3D=3D &binbuf[binbufsiz]) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ch =3D grep_fgetc(f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 } else {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ch =3D binbufptr[0];
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 binbufptr++;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (i >=3D lnbuflen) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lnbuflen *=3D 2;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lnbuf =3D grep_realloc(lnbu=
f, ++lnbuflen);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((ch =3D=3D '\n') || (ch =3D=3D EOF)) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lnbuf[i] =3D '\0';
> + =A0 =A0 =A0 unsigned char *p;
> + =A0 =A0 =A0 char *ret;
> + =A0 =A0 =A0 size_t len;
> + =A0 =A0 =A0 size_t off;
> + =A0 =A0 =A0 ptrdiff_t diff;
> +
> + =A0 =A0 =A0 /* Fill the buffer, if necessary */
> + =A0 =A0 =A0 if (bufrem =3D=3D 0 && grep_refill(f) !=3D 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> +
> + =A0 =A0 =A0 if (bufrem =3D=3D 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Return zero length to indicate EOF */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 *lenp =3D 0;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (bufpos);
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 /* Look for a newline in the remaining part of the buffer *=
/
> + =A0 =A0 =A0 if ((p =3D memchr(bufpos, '\n', bufrem)) !=3D NULL) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++p; /* advance over newline */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ret =3D bufpos;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 len =3D p - bufpos;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 bufrem -=3D len;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 bufpos =3D p;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 *lenp =3D len;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (ret);
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 /* We have to copy the current buffered data to the line bu=
ffer */
> + =A0 =A0 =A0 for (len =3D bufrem, off =3D 0; ; len +=3D bufrem) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Make sure there is room for more data */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (grep_lnbufgrow(len + LNBUFBUMP))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 memcpy(lnbuf + off, bufpos, len - off);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 off =3D len;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (grep_refill(f) !=3D 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (bufrem =3D=3D 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* EOF: return partial line=
 */
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 } else
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lnbuf[i] =3D ch;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((p =3D memchr(bufpos, '\n', bufrem)) =
=3D=3D NULL)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* got it: finish up the line (like code ab=
ove) */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++p;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 diff =3D p - bufpos;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 len +=3D diff;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (grep_lnbufgrow(len))
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 memcpy(lnbuf + off, bufpos, diff);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 bufrem -=3D diff;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 bufpos =3D p;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 if (grep_feof(f) && (i =3D=3D 0) && (ch !=3D '\n'))
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (NULL);
> - =A0 =A0 =A0 *len =3D i;
> + =A0 =A0 =A0 *lenp =3D len;
> =A0 =A0 =A0 =A0return (lnbuf);
> +
> +error:
> + =A0 =A0 =A0 *lenp =3D 0;
> + =A0 =A0 =A0 return (NULL);
> =A0}
>
> -/*
> - * Opens the standard input for processing.
> - */
> -struct file *
> -grep_stdin_open(void)
> +static inline struct file *
> +grep_file_init(struct file *f)
> =A0{
> - =A0 =A0 =A0 struct file *f;
>
> - =A0 =A0 =A0 /* Processing stdin implies --line-buffered for tail -f to =
work. */
> - =A0 =A0 =A0 lbflag =3D true;
> + =A0 =A0 =A0 if (filebehave =3D=3D FILE_GZIP &&
> + =A0 =A0 =A0 =A0 =A0 (gzbufdesc =3D gzdopen(f->fd, "r")) =3D=3D NULL)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
>
> - =A0 =A0 =A0 snprintf(fname, sizeof fname, "%s", getstr(1));
> + =A0 =A0 =A0 if (filebehave =3D=3D FILE_BZIP &&
> + =A0 =A0 =A0 =A0 =A0 (bzbufdesc =3D BZ2_bzdopen(f->fd, "r")) =3D=3D NULL=
)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
>
> - =A0 =A0 =A0 f =3D grep_malloc(sizeof *f);
> + =A0 =A0 =A0 /* Fill read buffer, also catches errors early */
> + =A0 =A0 =A0 if (grep_refill(f) !=3D 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto error;
>
> - =A0 =A0 =A0 binbuf =3D NULL;
> - =A0 =A0 =A0 if ((f->f =3D fdopen(STDIN_FILENO, "r")) !=3D NULL) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 flockfile(f->f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 f->stdin =3D true;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (f);
> - =A0 =A0 =A0 }
> + =A0 =A0 =A0 /* Check for binary stuff, if necessary */
> + =A0 =A0 =A0 if (binbehave !=3D BINFILE_TEXT && memchr(bufpos, '\0', buf=
rem) !=3D NULL)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 f->binary =3D true;
>
> + =A0 =A0 =A0 return (f);
> +error:
> + =A0 =A0 =A0 close(f->fd);
> =A0 =A0 =A0 =A0free(f);
> =A0 =A0 =A0 =A0return (NULL);
> =A0}
>
> =A0/*
> - * Opens a normal, a gzipped or a bzip2 compressed file for processing.
> + * Opens a file for processing.
> =A0*/
> =A0struct file *
> =A0grep_open(const char *path)
> =A0{
> =A0 =A0 =A0 =A0struct file *f;
>
> - =A0 =A0 =A0 snprintf(fname, sizeof fname, "%s", path);
> -
> =A0 =A0 =A0 =A0f =3D grep_malloc(sizeof *f);
> -
> - =A0 =A0 =A0 binbuf =3D NULL;
> - =A0 =A0 =A0 f->stdin =3D false;
> - =A0 =A0 =A0 switch (filebehave) {
> - =A0 =A0 =A0 case FILE_STDIO:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((f->f =3D fopen(path, "r")) !=3D NULL) =
{
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 flockfile(f->f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 case FILE_GZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((f->gzf =3D gzopen(fname, "r")) !=3D NU=
LL)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 case FILE_BZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((f->bzf =3D BZ2_bzopen(fname, "r")) !=
=3D NULL)
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> + =A0 =A0 =A0 memset(f, 0, sizeof *f);
> + =A0 =A0 =A0 if (path =3D=3D NULL) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Processing stdin implies --line-buffered=
. */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lbflag =3D true;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 f->fd =3D STDIN_FILENO;
> + =A0 =A0 =A0 } else if ((f->fd =3D open(path, O_RDONLY)) =3D=3D -1) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 free(f);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (NULL);
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 free(f);
> - =A0 =A0 =A0 return (NULL);
> + =A0 =A0 =A0 return (grep_file_init(f));
> =A0}
>
> =A0/*
> - * Closes a normal, a gzipped or a bzip2 compressed file.
> + * Closes a file.
> =A0*/
> =A0void
> =A0grep_close(struct file *f)
> =A0{
>
> - =A0 =A0 =A0 switch (filebehave) {
> - =A0 =A0 =A0 case FILE_STDIO:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 funlockfile(f->f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 fclose(f->f);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 case FILE_GZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 gzclose(f->gzf);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 case FILE_BZIP:
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 BZ2_bzclose(f->bzf);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 }
> + =A0 =A0 =A0 close(f->fd);
>
> - =A0 =A0 =A0 /* Reset read buffer for the file we are closing */
> - =A0 =A0 =A0 binbufptr =3D NULL;
> - =A0 =A0 =A0 free(binbuf);
> + =A0 =A0 =A0 /* Reset read buffer and line buffer */
> + =A0 =A0 =A0 bufpos =3D buffer;
> + =A0 =A0 =A0 bufrem =3D 0;
> +
> + =A0 =A0 =A0 free(lnbuf);
> + =A0 =A0 =A0 lnbuf =3D NULL;
> + =A0 =A0 =A0 lnbuflen =3D 0;
> =A0}
>
> Modified: head/usr.bin/grep/grep.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/usr.bin/grep/grep.h =A0 =A0Wed Aug 18 17:39:47 2010 =A0 =A0 =A0 =
=A0(r211462)
> +++ head/usr.bin/grep/grep.h =A0 =A0Wed Aug 18 17:40:10 2010 =A0 =A0 =A0 =
=A0(r211463)
> @@ -77,12 +77,8 @@ extern const char =A0 =A0 =A0 =A0 =A0 =A0*errstr[];
> =A0#define MAX_LINE_MATCHES =A0 =A0 =A0 32
>
> =A0struct file {
> - =A0 =A0 =A0 struct mmfile =A0 *mmf;
> - =A0 =A0 =A0 BZFILE =A0 =A0 =A0 =A0 =A0*bzf;
> - =A0 =A0 =A0 FILE =A0 =A0 =A0 =A0 =A0 =A0*f;
> - =A0 =A0 =A0 gzFile =A0 =A0 =A0 =A0 =A0*gzf;
> + =A0 =A0 =A0 int =A0 =A0 =A0 =A0 =A0 =A0 =A0fd;
> =A0 =A0 =A0 =A0bool =A0 =A0 =A0 =A0 =A0 =A0 binary;
> - =A0 =A0 =A0 bool =A0 =A0 =A0 =A0 =A0 =A0 stdin;
> =A0};
>
> =A0struct str {
> @@ -150,11 +146,10 @@ void =A0 =A0 =A0 clearqueue(void);
>
> =A0/* file.c */
> =A0void =A0 =A0 =A0 =A0 =A0 =A0grep_close(struct file *f);
> -struct file =A0 =A0*grep_stdin_open(void);
> =A0struct file =A0 =A0*grep_open(const char *path);
> =A0char =A0 =A0 =A0 =A0 =A0 *grep_fgetln(struct file *f, size_t *len);
>
> =A0/* fastgrep.c */
> =A0int =A0 =A0 =A0 =A0 =A0 =A0 fastcomp(fastgrep_t *, const char *);
> =A0void =A0 =A0 =A0 =A0 =A0 =A0fgrepcomp(fastgrep_t *, const char *);
> -int =A0 =A0 =A0 =A0 =A0 =A0 grep_search(fastgrep_t *, unsigned char *, s=
ize_t, regmatch_t *);
> +int =A0 =A0 =A0 =A0 =A0 =A0 grep_search(fastgrep_t *, const unsigned cha=
r *, size_t, regmatch_t *);
>
> Modified: head/usr.bin/grep/util.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/usr.bin/grep/util.c =A0 =A0Wed Aug 18 17:39:47 2010 =A0 =A0 =A0 =
=A0(r211462)
> +++ head/usr.bin/grep/util.c =A0 =A0Wed Aug 18 17:40:10 2010 =A0 =A0 =A0 =
=A0(r211463)
> @@ -184,7 +184,7 @@ procfile(const char *fn)
>
> =A0 =A0 =A0 =A0if (strcmp(fn, "-") =3D=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0fn =3D label !=3D NULL ? label : getstr(1)=
;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 f =3D grep_stdin_open();
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 f =3D grep_open(NULL);
> =A0 =A0 =A0 =A0} else {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (!stat(fn, &sb)) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Check if we need to pro=
cess the file */
> @@ -215,7 +215,7 @@ procfile(const char *fn)
>
> =A0 =A0 =A0 =A0for (c =3D 0; =A0c =3D=3D 0 || !(lflag || qflag); ) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ln.off +=3D ln.len + 1;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((ln.dat =3D grep_fgetln(f, &ln.len)) =
=3D=3D NULL) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((ln.dat =3D grep_fgetln(f, &ln.len)) =
=3D=3D NULL || ln.len =3D=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (ln.line_no =3D=3D 0 &&=
 matchall)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0exit(0);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0else
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTimjHt9NZa0-vU%2Bm2dkY2pTciUDLGd0Qut=uhFTq>