summaryrefslogtreecommitdiffstats
path: root/usr.bin/grep/file.c
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/file.c
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/file.c')
-rw-r--r--usr.bin/grep/file.c25
1 files changed, 19 insertions, 6 deletions
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);
-
}
OpenPOWER on IntegriCloud