Annotation of src/usr.bin/grep/file.c, Revision 1.17
1.17 ! tb 1: /* $OpenBSD: file.c,v 1.16 2021/03/10 21:55:22 millert 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.17 ! tb 33: #include <limits.h>
1.1 deraadt 34: #include <stdio.h>
35: #include <stdlib.h>
1.17 ! tb 36: #include <unistd.h>
1.1 deraadt 37: #include <zlib.h>
38:
39: #include "grep.h"
40:
1.12 deraadt 41: static char fname[PATH_MAX];
1.1 deraadt 42: static char *lnbuf;
1.15 tedu 43: static size_t lnbufsize;
1.1 deraadt 44:
45: #define FILE_STDIO 0
46: #define FILE_MMAP 1
47: #define FILE_GZIP 2
48:
49: struct file {
50: int type;
1.7 otto 51: int noseek;
1.1 deraadt 52: FILE *f;
53: mmf_t *mmf;
1.16 millert 54: gzFile gzf;
1.1 deraadt 55: };
56:
1.2 deraadt 57: #ifndef NOZ
1.1 deraadt 58: static char *
1.16 millert 59: gzfgetln(gzFile f, size_t *len)
1.1 deraadt 60: {
61: size_t n;
62: int c;
63:
64: for (n = 0; ; ++n) {
65: c = gzgetc(f);
66: if (c == -1) {
67: const char *gzerrstr;
68: int gzerr;
69:
70: if (gzeof(f))
71: break;
1.2 deraadt 72:
1.1 deraadt 73: gzerrstr = gzerror(f, &gzerr);
74: if (gzerr == Z_ERRNO)
1.4 millert 75: err(2, "%s", fname);
1.1 deraadt 76: else
1.4 millert 77: errx(2, "%s: %s", fname, gzerrstr);
1.1 deraadt 78: }
1.15 tedu 79: if (n >= lnbufsize) {
80: lnbufsize *= 2;
81: lnbuf = grep_realloc(lnbuf, ++lnbufsize);
1.1 deraadt 82: }
1.5 canacar 83: if (c == '\n')
84: break;
1.1 deraadt 85: lnbuf[n] = c;
86: }
87:
88: if (gzeof(f) && n == 0)
89: return NULL;
90: *len = n;
91: return lnbuf;
92: }
1.2 deraadt 93: #endif
1.1 deraadt 94:
95: file_t *
1.14 tedu 96: grep_fdopen(int fd)
1.1 deraadt 97: {
98: file_t *f;
1.14 tedu 99: struct stat sb;
1.1 deraadt 100:
1.6 tedu 101: if (fd == STDIN_FILENO)
1.2 deraadt 102: snprintf(fname, sizeof fname, "(standard input)");
1.14 tedu 103: else if (fname[0] == '\0')
1.2 deraadt 104: snprintf(fname, sizeof fname, "(fd %d)", fd);
105:
1.14 tedu 106: if (fstat(fd, &sb) == -1)
107: return NULL;
108: if (S_ISDIR(sb.st_mode)) {
109: errno = EISDIR;
110: return NULL;
111: }
112:
1.1 deraadt 113: f = grep_malloc(sizeof *f);
1.2 deraadt 114:
115: #ifndef NOZ
1.1 deraadt 116: if (Zflag) {
117: f->type = FILE_GZIP;
1.7 otto 118: f->noseek = lseek(fd, 0L, SEEK_SET) == -1;
1.14 tedu 119: if ((f->gzf = gzdopen(fd, "r")) != NULL)
1.1 deraadt 120: return f;
1.14 tedu 121: }
1.2 deraadt 122: #endif
1.14 tedu 123: f->noseek = isatty(fd);
124: #ifndef SMALL
125: /* try mmap first; if it fails, try stdio */
126: if (!f->noseek && (f->mmf = mmopen(fd, &sb)) != NULL) {
127: f->type = FILE_MMAP;
128: return f;
1.1 deraadt 129: }
1.14 tedu 130: #endif
131: f->type = FILE_STDIO;
132: if ((f->f = fdopen(fd, "r")) != NULL)
133: return f;
1.2 deraadt 134:
1.1 deraadt 135: free(f);
136: return NULL;
137: }
138:
139: file_t *
1.14 tedu 140: grep_open(char *path)
1.1 deraadt 141: {
142: file_t *f;
1.14 tedu 143: int fd;
1.1 deraadt 144:
1.2 deraadt 145: snprintf(fname, sizeof fname, "%s", path);
146:
1.14 tedu 147: if ((fd = open(fname, O_RDONLY)) == -1)
148: return NULL;
1.2 deraadt 149:
1.14 tedu 150: f = grep_fdopen(fd);
151: if (f == NULL)
152: close(fd);
153: return f;
1.1 deraadt 154: }
155:
156: int
157: grep_bin_file(file_t *f)
158: {
1.7 otto 159: if (f->noseek)
160: return 0;
161:
1.1 deraadt 162: switch (f->type) {
163: case FILE_STDIO:
164: return bin_file(f->f);
1.11 nicm 165: #ifndef SMALL
1.1 deraadt 166: case FILE_MMAP:
167: return mmbin_file(f->mmf);
1.11 nicm 168: #endif
1.2 deraadt 169: #ifndef NOZ
1.1 deraadt 170: case FILE_GZIP:
171: return gzbin_file(f->gzf);
1.2 deraadt 172: #endif
1.1 deraadt 173: default:
174: /* can't happen */
1.4 millert 175: errx(2, "invalid file type");
1.1 deraadt 176: }
177: }
178:
179: char *
180: grep_fgetln(file_t *f, size_t *l)
181: {
182: switch (f->type) {
183: case FILE_STDIO:
1.15 tedu 184: if ((*l = getline(&lnbuf, &lnbufsize, f->f)) == -1) {
185: if (ferror(f->f))
186: err(2, "%s: getline", fname);
187: else
188: return NULL;
189: }
190: return lnbuf;
1.11 nicm 191: #ifndef SMALL
1.1 deraadt 192: case FILE_MMAP:
193: return mmfgetln(f->mmf, l);
1.11 nicm 194: #endif
1.2 deraadt 195: #ifndef NOZ
1.1 deraadt 196: case FILE_GZIP:
197: return gzfgetln(f->gzf, l);
1.2 deraadt 198: #endif
1.1 deraadt 199: default:
200: /* can't happen */
1.4 millert 201: errx(2, "invalid file type");
1.1 deraadt 202: }
203: }
204:
205: void
206: grep_close(file_t *f)
207: {
208: switch (f->type) {
209: case FILE_STDIO:
210: fclose(f->f);
211: break;
1.11 nicm 212: #ifndef SMALL
1.1 deraadt 213: case FILE_MMAP:
214: mmclose(f->mmf);
215: break;
1.11 nicm 216: #endif
1.2 deraadt 217: #ifndef NOZ
1.1 deraadt 218: case FILE_GZIP:
219: gzclose(f->gzf);
220: break;
1.2 deraadt 221: #endif
1.1 deraadt 222: default:
223: /* can't happen */
1.4 millert 224: errx(2, "invalid file type");
1.1 deraadt 225: }
1.8 otto 226: free(f);
1.1 deraadt 227: }