Annotation of src/usr.bin/grep/file.c, Revision 1.12
1.12 ! deraadt 1: /* $OpenBSD: file.c,v 1.11 2010/07/02 20:48:48 nicm 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>
1.12 ! deraadt 32: #include <limits.h>
1.1 deraadt 33: #include <zlib.h>
34:
35: #include "grep.h"
36:
1.12 ! deraadt 37: static char fname[PATH_MAX];
1.10 deraadt 38: #ifndef NOZ
1.1 deraadt 39: static char *lnbuf;
1.2 deraadt 40: static size_t lnbuflen;
1.10 deraadt 41: #endif
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: }
77: if (n >= lnbuflen) {
78: lnbuflen *= 2;
79: lnbuf = grep_realloc(lnbuf, ++lnbuflen);
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 *
94: grep_fdopen(int fd, char *mode)
95: {
96: file_t *f;
97:
1.6 tedu 98: if (fd == STDIN_FILENO)
1.2 deraadt 99: snprintf(fname, sizeof fname, "(standard input)");
1.1 deraadt 100: else
1.2 deraadt 101: snprintf(fname, sizeof fname, "(fd %d)", fd);
102:
1.1 deraadt 103: f = grep_malloc(sizeof *f);
1.2 deraadt 104:
105: #ifndef NOZ
1.1 deraadt 106: if (Zflag) {
107: f->type = FILE_GZIP;
1.7 otto 108: f->noseek = lseek(fd, 0L, SEEK_SET) == -1;
1.1 deraadt 109: if ((f->gzf = gzdopen(fd, mode)) != NULL)
110: return f;
1.2 deraadt 111: } else
112: #endif
113: {
1.1 deraadt 114: f->type = FILE_STDIO;
1.7 otto 115: f->noseek = isatty(fd);
1.1 deraadt 116: if ((f->f = fdopen(fd, mode)) != NULL)
117: return f;
118: }
1.2 deraadt 119:
1.1 deraadt 120: free(f);
121: return NULL;
122: }
123:
124: file_t *
125: grep_open(char *path, char *mode)
126: {
127: file_t *f;
128:
1.2 deraadt 129: snprintf(fname, sizeof fname, "%s", path);
130:
1.1 deraadt 131: f = grep_malloc(sizeof *f);
1.7 otto 132: f->noseek = 0;
1.2 deraadt 133:
134: #ifndef NOZ
1.1 deraadt 135: if (Zflag) {
136: f->type = FILE_GZIP;
137: if ((f->gzf = gzopen(fname, mode)) != NULL)
138: return f;
1.2 deraadt 139: } else
140: #endif
141: {
1.11 nicm 142: #ifndef SMALL
1.1 deraadt 143: /* try mmap first; if it fails, try stdio */
144: if ((f->mmf = mmopen(fname, mode)) != NULL) {
145: f->type = FILE_MMAP;
146: return f;
147: }
1.11 nicm 148: #endif
1.1 deraadt 149: f->type = FILE_STDIO;
150: if ((f->f = fopen(path, mode)) != NULL)
151: return f;
152: }
1.2 deraadt 153:
1.1 deraadt 154: free(f);
155: return NULL;
156: }
157:
158: int
159: grep_bin_file(file_t *f)
160: {
1.7 otto 161: if (f->noseek)
162: return 0;
163:
1.1 deraadt 164: switch (f->type) {
165: case FILE_STDIO:
166: return bin_file(f->f);
1.11 nicm 167: #ifndef SMALL
1.1 deraadt 168: case FILE_MMAP:
169: return mmbin_file(f->mmf);
1.11 nicm 170: #endif
1.2 deraadt 171: #ifndef NOZ
1.1 deraadt 172: case FILE_GZIP:
173: return gzbin_file(f->gzf);
1.2 deraadt 174: #endif
1.1 deraadt 175: default:
176: /* can't happen */
1.4 millert 177: errx(2, "invalid file type");
1.1 deraadt 178: }
179: }
180:
181: char *
182: grep_fgetln(file_t *f, size_t *l)
183: {
184: switch (f->type) {
185: case FILE_STDIO:
186: return fgetln(f->f, l);
1.11 nicm 187: #ifndef SMALL
1.1 deraadt 188: case FILE_MMAP:
189: return mmfgetln(f->mmf, l);
1.11 nicm 190: #endif
1.2 deraadt 191: #ifndef NOZ
1.1 deraadt 192: case FILE_GZIP:
193: return gzfgetln(f->gzf, l);
1.2 deraadt 194: #endif
1.1 deraadt 195: default:
196: /* can't happen */
1.4 millert 197: errx(2, "invalid file type");
1.1 deraadt 198: }
199: }
200:
201: void
202: grep_close(file_t *f)
203: {
204: switch (f->type) {
205: case FILE_STDIO:
206: fclose(f->f);
207: break;
1.11 nicm 208: #ifndef SMALL
1.1 deraadt 209: case FILE_MMAP:
210: mmclose(f->mmf);
211: break;
1.11 nicm 212: #endif
1.2 deraadt 213: #ifndef NOZ
1.1 deraadt 214: case FILE_GZIP:
215: gzclose(f->gzf);
216: break;
1.2 deraadt 217: #endif
1.1 deraadt 218: default:
219: /* can't happen */
1.4 millert 220: errx(2, "invalid file type");
1.1 deraadt 221: }
1.8 otto 222: free(f);
1.1 deraadt 223: }