summaryrefslogtreecommitdiffstats
path: root/usr.bin/grep
diff options
context:
space:
mode:
authorgabor <gabor@FreeBSD.org>2010-08-15 22:15:04 +0000
committergabor <gabor@FreeBSD.org>2010-08-15 22:15:04 +0000
commit5ee11c8783defc30e3f53ba6ba6004cae0574e8b (patch)
tree44ced6cc8e38528f9ae4294c0509d9f40b61a7c7 /usr.bin/grep
parent257a18ba177d6257c87a07ccb72fc9908650db8c (diff)
downloadFreeBSD-src-5ee11c8783defc30e3f53ba6ba6004cae0574e8b.zip
FreeBSD-src-5ee11c8783defc30e3f53ba6ba6004cae0574e8b.tar.gz
- Revert strlcpy() changes to memcpy() because it's more efficient and
former may be safer but in this case it doesn't add extra safety [1] - Fix -w option [2] - Fix handling of GREP_OPTIONS [3] - Fix --line-buffered - Make stdin input imply --line-buffered so that tail -f can be piped to grep [4] - Imply -h if single file is grepped, this is the GNU behaviour - Reduce locking overhead to gain some more performance [5] - Inline some functions to help the compiler better optimize the code - Use shortcut for empty files [6] PR: bin/149425 [6] Prodded by: jilles [1] Reported by: Alex Kozlov <spam@rm-rf.kiev.ua> [2] [3], swell.k@gmail.com [2], poyopoyo@puripuri.plala.or.jp [4] Submitted by: scf [5], Shuichi KITAGUCHI <ki@hh.iij4u.or.jp> [6] Approved by: delphij (mentor)
Diffstat (limited to 'usr.bin/grep')
-rw-r--r--usr.bin/grep/fastgrep.c8
-rw-r--r--usr.bin/grep/file.c25
-rw-r--r--usr.bin/grep/grep.c49
-rw-r--r--usr.bin/grep/grep.h5
-rw-r--r--usr.bin/grep/queue.c2
-rw-r--r--usr.bin/grep/util.c43
6 files changed, 66 insertions, 66 deletions
diff --git a/usr.bin/grep/fastgrep.c b/usr.bin/grep/fastgrep.c
index 5239a0e1..c66f0a7 100644
--- a/usr.bin/grep/fastgrep.c
+++ b/usr.bin/grep/fastgrep.c
@@ -46,8 +46,8 @@ __FBSDID("$FreeBSD$");
#include "grep.h"
-static int grep_cmp(const unsigned char *, const unsigned char *, size_t);
-static void grep_revstr(unsigned char *, int);
+static inline int grep_cmp(const unsigned char *, const unsigned char *, size_t);
+static inline void grep_revstr(unsigned char *, int);
void
fgrepcomp(fastgrep_t *fg, const char *pat)
@@ -273,7 +273,7 @@ grep_search(fastgrep_t *fg, unsigned char *data, size_t len, regmatch_t *pmatch)
* Returns: i >= 0 on failure (position that it failed)
* -1 on success
*/
-static int
+static inline int
grep_cmp(const unsigned char *pat, const unsigned char *data, size_t len)
{
size_t size;
@@ -318,7 +318,7 @@ grep_cmp(const unsigned char *pat, const unsigned char *data, size_t len)
return (-1);
}
-static void
+static inline void
grep_revstr(unsigned char *str, int len)
{
int i;
diff --git a/usr.bin/grep/file.c b/usr.bin/grep/file.c
index c4de7db..1872d0e 100644
--- a/usr.bin/grep/file.c
+++ b/usr.bin/grep/file.c
@@ -67,14 +67,14 @@ static int bzerr;
* Returns a single character according to the file type.
* Returns -1 on failure.
*/
-int
+static inline int
grep_fgetc(struct file *f)
{
unsigned char c;
switch (filebehave) {
case FILE_STDIO:
- return (fgetc(f->f));
+ return (getc_unlocked(f->f));
case FILE_GZIP:
return (gzgetc(f->gzf));
case FILE_BZIP:
@@ -92,13 +92,13 @@ grep_fgetc(struct file *f)
* Returns true if the file position is a EOF, returns false
* otherwise.
*/
-int
+static inline int
grep_feof(struct file *f)
{
switch (filebehave) {
case FILE_STDIO:
- return (feof(f->f));
+ return (feof_unlocked(f->f));
case FILE_GZIP:
return (gzeof(f->gzf));
case FILE_BZIP:
@@ -131,6 +131,9 @@ grep_fgetln(struct file *f, size_t *len)
st.st_size = MAXBUFSIZ;
else if (stat(fname, &st) != 0)
err(2, NULL);
+ /* no need to allocate buffer. */
+ if (st.st_size == 0)
+ return (NULL);
bufsiz = (MAXBUFSIZ > (st.st_size * PREREAD_M)) ?
(st.st_size / 2) : MAXBUFSIZ;
@@ -142,6 +145,8 @@ grep_fgetln(struct file *f, size_t *len)
if (ch == EOF)
break;
binbuf[i++] = ch;
+ if ((ch == '\n') && lbflag)
+ break;
}
f->binary = memchr(binbuf, (filebehave != FILE_GZIP) ?
@@ -184,11 +189,16 @@ grep_stdin_open(void)
{
struct file *f;
+ /* Processing stdin implies --line-buffered for tail -f to work. */
+ lbflag = true;
+
snprintf(fname, sizeof fname, "%s", getstr(1));
f = grep_malloc(sizeof *f);
+ binbuf = NULL;
if ((f->f = fdopen(STDIN_FILENO, "r")) != NULL) {
+ flockfile(f->f);
f->stdin = true;
return (f);
}
@@ -209,11 +219,14 @@ grep_open(const char *path)
f = grep_malloc(sizeof *f);
+ binbuf = NULL;
f->stdin = false;
switch (filebehave) {
case FILE_STDIO:
- if ((f->f = fopen(path, "r")) != NULL)
+ if ((f->f = fopen(path, "r")) != NULL) {
+ flockfile(f->f);
return (f);
+ }
break;
case FILE_GZIP:
if ((f->gzf = gzopen(fname, "r")) != NULL)
@@ -238,6 +251,7 @@ grep_close(struct file *f)
switch (filebehave) {
case FILE_STDIO:
+ funlockfile(f->f);
fclose(f->f);
break;
case FILE_GZIP:
@@ -251,5 +265,4 @@ grep_close(struct file *f)
/* Reset read buffer for the file we are closing */
binbufptr = NULL;
free(binbuf);
-
}
diff --git a/usr.bin/grep/grep.c b/usr.bin/grep/grep.c
index 3dc1a1c..1221785 100644
--- a/usr.bin/grep/grep.c
+++ b/usr.bin/grep/grep.c
@@ -121,8 +121,8 @@ int devbehave = DEV_READ; /* -D: handling of devices */
int dirbehave = DIR_READ; /* -dRr: handling of directories */
int linkbehave = LINK_READ; /* -OpS: handling of symlinks */
-bool dexclude, dinclude; /* --exclude amd --include */
-bool fexclude, finclude; /* --exclude-dir and --include-dir */
+bool dexclude, dinclude; /* --exclude-dir and --include-dir */
+bool fexclude, finclude; /* --exclude and --include */
enum {
BIN_OPT = CHAR_MAX + 1,
@@ -236,7 +236,8 @@ add_pattern(char *pat, size_t len)
--len;
/* pat may not be NUL-terminated */
pattern[patterns] = grep_malloc(len + 1);
- strlcpy(pattern[patterns], pat, len + 1);
+ memcpy(pattern[patterns], pat, len);
+ pattern[patterns][len] = '\0';
++patterns;
}
@@ -355,38 +356,33 @@ main(int argc, char *argv[])
eopts = getenv("GREP_OPTIONS");
- eargc = 1;
+ /* support for extra arguments in GREP_OPTIONS */
+ eargc = 0;
if (eopts != NULL) {
char *str;
- for(i = 0; i < strlen(eopts); i++)
- if (eopts[i] == ' ')
+ /* make an estimation of how many extra arguments we have */
+ for (unsigned int j = 0; j < strlen(eopts); j++)
+ if (eopts[j] == ' ')
eargc++;
eargv = (char **)grep_malloc(sizeof(char *) * (eargc + 1));
- str = strtok(eopts, " ");
eargc = 0;
-
- while(str != NULL) {
- eargv[++eargc] = (char *)grep_malloc(sizeof(char) *
- (strlen(str) + 1));
- strlcpy(eargv[eargc], str, strlen(str) + 1);
- str = strtok(NULL, " ");
- }
- eargv[++eargc] = NULL;
+ /* parse extra arguments */
+ while ((str = strsep(&eopts, " ")) != NULL)
+ eargv[eargc++] = grep_strdup(str);
aargv = (char **)grep_calloc(eargc + argc + 1,
sizeof(char *));
- aargv[0] = argv[0];
- for(i = 1; i < eargc; i++)
- aargv[i] = eargv[i];
- for(int j = 1; j < argc; j++)
- aargv[i++] = argv[j];
-
- aargc = eargc + argc - 1;
+ aargv[0] = argv[0];
+ for (i = 0; i < eargc; i++)
+ aargv[i + 1] = eargv[i];
+ for (int j = 1; j < argc; j++, i++)
+ aargv[i + 1] = argv[j];
+ aargc = eargc + argc;
} else {
aargv = argv;
aargc = argc;
@@ -609,11 +605,11 @@ main(int argc, char *argv[])
add_fpattern(optarg, EXCL_PAT);
break;
case R_DINCLUDE_OPT:
- dexclude = true;
+ dinclude = true;
add_dpattern(optarg, INCL_PAT);
break;
case R_DEXCLUDE_OPT:
- dinclude = true;
+ dexclude = true;
add_dpattern(optarg, EXCL_PAT);
break;
case HELP_OPT:
@@ -685,12 +681,15 @@ main(int argc, char *argv[])
if (dirbehave == DIR_RECURSE)
c = grep_tree(aargv);
- else
+ else {
+ if (aargc == 1)
+ hflag = true;
for (c = 0; aargc--; ++aargv) {
if ((finclude || fexclude) && !file_matching(*aargv))
continue;
c+= procfile(*aargv);
}
+ }
#ifndef WITHOUT_NLS
catclose(catalog);
diff --git a/usr.bin/grep/grep.h b/usr.bin/grep/grep.h
index bb5e5f9..2f743e4 100644
--- a/usr.bin/grep/grep.h
+++ b/usr.bin/grep/grep.h
@@ -115,7 +115,7 @@ extern int cflags, eflags;
extern bool Eflag, Fflag, Gflag, Hflag, Lflag,
bflag, cflag, hflag, iflag, lflag, mflag, nflag, oflag,
qflag, sflag, vflag, wflag, xflag;
-extern bool dexclude, dinclude, fexclude, finclude, nullflag;
+extern bool dexclude, dinclude, fexclude, finclude, lbflag, nullflag;
extern unsigned long long Aflag, Bflag, mcount;
extern char *label;
extern const char *color;
@@ -134,7 +134,6 @@ extern fastgrep_t *fg_pattern;
extern char re_error[RE_ERROR_BUF + 1]; /* Seems big enough */
/* util.c */
-bool dir_matching(const char *dname);
bool file_matching(const char *fname);
int procfile(const char *fn);
int grep_tree(char **argv);
@@ -153,8 +152,6 @@ void clearqueue(void);
void grep_close(struct file *f);
struct file *grep_stdin_open(void);
struct file *grep_open(const char *path);
-int grep_feof(struct file *f);
-int grep_fgetc(struct file *f);
char *grep_fgetln(struct file *f, size_t *len);
/* fastgrep.c */
diff --git a/usr.bin/grep/queue.c b/usr.bin/grep/queue.c
index 29a6c2f..dcef7f8 100644
--- a/usr.bin/grep/queue.c
+++ b/usr.bin/grep/queue.c
@@ -60,7 +60,7 @@ enqueue(struct str *x)
item->data.len = x->len;
item->data.line_no = x->line_no;
item->data.off = x->off;
- strcpy(item->data.dat, x->dat);
+ memcpy(item->data.dat, x->dat, x->len);
item->data.file = x->file;
STAILQ_INSERT_TAIL(&queue, item, list);
diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c
index 9618dea..f084c3d 100644
--- a/usr.bin/grep/util.c
+++ b/usr.bin/grep/util.c
@@ -72,7 +72,7 @@ file_matching(const char *fname)
return (ret);
}
-bool
+static inline bool
dir_matching(const char *dname)
{
bool ret;
@@ -144,9 +144,10 @@ grep_tree(char **argv)
if (dexclude || dinclude) {
if ((d = strrchr(p->fts_path, '/')) != NULL) {
dir = grep_malloc(sizeof(char) *
- (d - p->fts_path + 2));
- strlcpy(dir, p->fts_path,
(d - p->fts_path + 1));
+ memcpy(dir, p->fts_path,
+ d - p->fts_path);
+ dir[d - p->fts_path] = '\0';
}
ok = dir_matching(dir);
free(dir);
@@ -276,7 +277,7 @@ procfile(const char *fn)
* matches. The matching lines are passed to printline() to display the
* appropriate output.
*/
-static int
+static inline int
procline(struct str *l, int nottext)
{
regmatch_t matches[MAX_LINE_MATCHES];
@@ -317,30 +318,20 @@ procline(struct str *l, int nottext)
(size_t)pmatch.rm_eo != l->len)
r = REG_NOMATCH;
/* Check for whole word match */
- if (r == 0 && wflag && pmatch.rm_so != 0 &&
- (size_t)pmatch.rm_eo != l->len) {
- wchar_t *wbegin;
- wint_t wend;
- size_t size;
-
- size = mbstowcs(NULL, l->dat,
- pmatch.rm_so);
+ if (r == 0 && wflag && pmatch.rm_so != 0) {
+ wint_t wbegin, wend;
- if (size == ((size_t) - 1))
+ wbegin = wend = L' ';
+ if (pmatch.rm_so != 0 &&
+ sscanf(&l->dat[pmatch.rm_so - 1],
+ "%lc", &wbegin) != 1)
+ r = REG_NOMATCH;
+ else if ((size_t)pmatch.rm_eo != l->len &&
+ sscanf(&l->dat[pmatch.rm_eo],
+ "%lc", &wend) != 1)
+ r = REG_NOMATCH;
+ else if (iswword(wbegin) || iswword(wend))
r = REG_NOMATCH;
- else {
- wbegin = grep_malloc(size);
- if (mbstowcs(wbegin, l->dat,
- pmatch.rm_so) == ((size_t) - 1))
- r = REG_NOMATCH;
- else if (sscanf(&l->dat[pmatch.rm_eo],
- "%lc", &wend) != 1)
- r = REG_NOMATCH;
- else if (iswword(wbegin[wcslen(wbegin)]) ||
- iswword(wend))
- r = REG_NOMATCH;
- free(wbegin);
- }
}
if (r == 0) {
if (m == 0)
OpenPOWER on IntegriCloud