Annotation of src/usr.bin/grep/file.c, Revision 1.15
1.15 ! tedu 1: /* $OpenBSD: file.c,v 1.14 2019/01/23 23:00:54 tedu Exp $ */
1.3 deraadt 2:
1.1 deraadt 3: /*-
4: * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26: * SUCH DAMAGE.
27: */
28:
1.14 tedu 29: #include <sys/stat.h>
1.1 deraadt 30: #include <err.h>
1.14 tedu 31: #include <errno.h>
32: #include <fcntl.h>
1.1 deraadt 33: #include <stdio.h>
34: #include <stdlib.h>
35: #include <zlib.h>
36:
37: #include "grep.h"
38:
1.12 deraadt 39: static char fname[PATH_MAX];
1.1 deraadt 40: static char *lnbuf;
1.15 ! tedu 41: static size_t lnbufsize;
1.1 deraadt 42:
43: #define FILE_STDIO 0
44: #define FILE_MMAP 1
45: #define FILE_GZIP 2
46:
47: struct file {
48: int type;
1.7 otto 49: int noseek;
1.1 deraadt 50: FILE *f;
51: mmf_t *mmf;
52: gzFile *gzf;
53: };
54:
1.2 deraadt 55: #ifndef NOZ
1.1 deraadt 56: static char *
57: gzfgetln(gzFile *f, size_t *len)
58: {
59: size_t n;
60: int c;
61:
62: for (n = 0; ; ++n) {
63: c = gzgetc(f);
64: if (c == -1) {
65: const char *gzerrstr;
66: int gzerr;
67:
68: if (gzeof(f))
69: break;
1.2 deraadt 70:
1.1 deraadt 71: gzerrstr = gzerror(f, &gzerr);
72: if (gzerr == Z_ERRNO)
1.4 millert 73: err(2, "%s", fname);
1.1 deraadt 74: else
1.4 millert 75: errx(2, "%s: %s", fname, gzerrstr);
1.1 deraadt 76: }
1.15 ! tedu 77: if (n >= lnbufsize) {
! 78: lnbufsize *= 2;
! 79: lnbuf = grep_realloc(lnbuf, ++lnbufsize);
1.1 deraadt 80: }
1.5 canacar 81: if (c == '\n')
82: break;
1.1 deraadt 83: lnbuf[n] = c;
84: }
85:
86: if (gzeof(f) && n == 0)
87: return NULL;
88: *len = n;
89: return lnbuf;
90: }
1.2 deraadt 91: #endif
1.1 deraadt 92:
93: file_t *
1.14 tedu 94: grep_fdopen(int fd)
1.1 deraadt 95: {
96: file_t *f;
1.14 tedu 97: struct stat sb;
1.1 deraadt 98:
1.6 tedu 99: if (fd == STDIN_FILENO)
1.2 deraadt 100: snprintf(fname, sizeof fname, "(standard input)");
1.14 tedu 101: else if (fname[0] == '\0')
1.2 deraadt 102: snprintf(fname, sizeof fname, "(fd %d)", fd);
103:
1.14 tedu 104: if (fstat(fd, &sb) == -1)
105: return NULL;
106: if (S_ISDIR(sb.st_mode)) {
107: errno = EISDIR;
108: return NULL;
109: }
110:
1.1 deraadt 111: f = grep_malloc(sizeof *f);
1.2 deraadt 112:
113: #ifndef NOZ
1.1 deraadt 114: if (Zflag) {
115: f->type = FILE_GZIP;
1.7 otto 116: f->noseek = lseek(fd, 0L, SEEK_SET) == -1;
1.14 tedu 117: if ((f->gzf = gzdopen(fd, "r")) != NULL)
1.1 deraadt 118: return f;
1.14 tedu 119: }
1.2 deraadt 120: #endif
1.14 tedu 121: f->noseek = isatty(fd);
122: #ifndef SMALL
123: /* try mmap first; if it fails, try stdio */
124: if (!f->noseek && (f->mmf = mmopen(fd, &sb)) != NULL) {
125: f->type = FILE_MMAP;
126: return f;
1.1 deraadt 127: }
1.14 tedu 128: #endif
129: f->type = FILE_STDIO;
130: if ((f->f = fdopen(fd, "r")) != NULL)
131: return f;
1.2 deraadt 132:
1.1 deraadt 133: free(f);
134: return NULL;
135: }
136:
137: file_t *
1.14 tedu 138: grep_open(char *path)
1.1 deraadt 139: {
140: file_t *f;
1.14 tedu 141: int fd;
1.1 deraadt 142:
1.2 deraadt 143: snprintf(fname, sizeof fname, "%s", path);
144:
1.14 tedu 145: if ((fd = open(fname, O_RDONLY)) == -1)
146: return NULL;
1.2 deraadt 147:
1.14 tedu 148: f = grep_fdopen(fd);
149: if (f == NULL)
150: close(fd);
151: return f;
1.1 deraadt 152: }
153:
154: int
155: grep_bin_file(file_t *f)
156: {
1.7 otto 157: if (f->noseek)
158: return 0;
159:
1.1 deraadt 160: switch (f->type) {
161: case FILE_STDIO:
162: return bin_file(f->f);
1.11 nicm 163: #ifndef SMALL
1.1 deraadt 164: case FILE_MMAP:
165: return mmbin_file(f->mmf);
1.11 nicm 166: #endif
1.2 deraadt 167: #ifndef NOZ
1.1 deraadt 168: case FILE_GZIP:
169: return gzbin_file(f->gzf);
1.2 deraadt 170: #endif
1.1 deraadt 171: default:
172: /* can't happen */
1.4 millert 173: errx(2, "invalid file type");
1.1 deraadt 174: }
175: }
176:
177: char *
178: grep_fgetln(file_t *f, size_t *l)
179: {
180: switch (f->type) {
181: case FILE_STDIO:
1.15 ! tedu 182: if ((*l = getline(&lnbuf, &lnbufsize, f->f)) == -1) {
! 183: if (ferror(f->f))
! 184: err(2, "%s: getline", fname);
! 185: else
! 186: return NULL;
! 187: }
! 188: return lnbuf;
1.11 nicm 189: #ifndef SMALL
1.1 deraadt 190: case FILE_MMAP:
191: return mmfgetln(f->mmf, l);
1.11 nicm 192: #endif
1.2 deraadt 193: #ifndef NOZ
1.1 deraadt 194: case FILE_GZIP:
195: return gzfgetln(f->gzf, l);
1.2 deraadt 196: #endif
1.1 deraadt 197: default:
198: /* can't happen */
1.4 millert 199: errx(2, "invalid file type");
1.1 deraadt 200: }
201: }
202:
203: void
204: grep_close(file_t *f)
205: {
206: switch (f->type) {
207: case FILE_STDIO:
208: fclose(f->f);
209: break;
1.11 nicm 210: #ifndef SMALL
1.1 deraadt 211: case FILE_MMAP:
212: mmclose(f->mmf);
213: break;
1.11 nicm 214: #endif
1.2 deraadt 215: #ifndef NOZ
1.1 deraadt 216: case FILE_GZIP:
217: gzclose(f->gzf);
218: break;
1.2 deraadt 219: #endif
1.1 deraadt 220: default:
221: /* can't happen */
1.4 millert 222: errx(2, "invalid file type");
1.1 deraadt 223: }
1.8 otto 224: free(f);
1.1 deraadt 225: }