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