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