From owner-svn-src-head@FreeBSD.ORG Wed Aug 18 20:48:43 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 576811065673; Wed, 18 Aug 2010 20:48:43 +0000 (UTC) (envelope-from mdf356@gmail.com) Received: from mail-ew0-f54.google.com (mail-ew0-f54.google.com [209.85.215.54]) by mx1.freebsd.org (Postfix) with ESMTP id 33C818FC15; Wed, 18 Aug 2010 20:48:41 +0000 (UTC) Received: by ewy26 with SMTP id 26so882731ewy.13 for ; Wed, 18 Aug 2010 13:48:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:sender:received :in-reply-to:references:date:x-google-sender-auth:message-id:subject :from:to:content-type:content-transfer-encoding; bh=QRhPZHnignX8FQXzgeixwmAsg2iWfXnf8Owvqgwf5LY=; b=SZE18KSPw1LH9TTwlXaEkj9HGFoAqkV30nyN84CwAu21kVgvdLJ0gMjEVn6nxq6wmm 3oXfN25YvDXZXVBby7cY+98nzYQMp44uehzaexGYTYYniwVVNKsZUNn8Micd3+pt2hhW XFrbUDA/OlD8o2cnfc0yTKC2CpjPjqSw8vMkQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:content-type :content-transfer-encoding; b=m9GUXdzkjR/ExxxwoFMc7wtYBimz5tTXLO9B1ISRAwPegpHrwO8XTKE0CofWuWZ/r1 +7EJZMiqT42xnavJy38uR39YGxZAfW7KPABeiVLYJwy/E1yl4FP/O0LJEN4vQEQAx7Sn 2CbrIjgFDX/JdT8zJdkPDJxHloTaN3R8ZgufU= MIME-Version: 1.0 Received: by 10.213.14.208 with SMTP id h16mr842198eba.14.1282164520704; Wed, 18 Aug 2010 13:48:40 -0700 (PDT) Sender: mdf356@gmail.com Received: by 10.213.108.132 with HTTP; Wed, 18 Aug 2010 13:48:40 -0700 (PDT) In-Reply-To: <201008181740.o7IHeA4c075984@svn.freebsd.org> References: <201008181740.o7IHeA4c075984@svn.freebsd.org> Date: Wed, 18 Aug 2010 13:48:40 -0700 X-Google-Sender-Auth: 05wtm3wIyWRbFmjKHqTUY_Z0Ce8 Message-ID: From: mdf@FreeBSD.org To: Gabor Kovesdan , src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: Subject: Re: svn commit: r211463 - head/usr.bin/grep X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Aug 2010 20:48:43 -0000 On Wed, Aug 18, 2010 at 10:40 AM, Gabor Kovesdan 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 > =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 > + * Copyright (C) 2008-2010 Gabor Kovesdan > + * Copyright (C) 2010 Dimitry Andric > =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 > =A0#include > =A0#include > -#include > +#include > +#include > =A0#include > =A0#include > =A0#include > @@ -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 >