add opendir alias
[minix.git] / commands / grep / file.c
blob9a6ae8ebcd420be3b74674b84eae8bb47266ddc9
1 /* $OpenBSD: file.c,v 1.9 2006/02/09 09:54:46 otto Exp $ */
3 /*-
4 * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
5 * All rights reserved.
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.
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.
29 #include <sys/param.h>
31 #include <err.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
36 #include "grep.h"
38 static char fname[MAXPATHLEN];
39 #ifndef NOZ
40 static char *lnbuf;
41 static size_t lnbuflen;
42 #endif
44 #define FILE_STDIO 0
45 #ifndef __minix
46 #define FILE_MMAP 1
47 #endif
48 #define FILE_GZIP 2
50 struct file {
51 int type;
52 int noseek;
53 FILE *f;
54 mmf_t *mmf;
55 #ifndef NOZ
56 gzFile *gzf;
57 #endif
60 #ifndef NOZ
61 static char *
62 gzfgetln(gzFile *f, size_t *len)
64 size_t n;
65 int c;
67 for (n = 0; ; ++n) {
68 c = gzgetc(f);
69 if (c == -1) {
70 const char *gzerrstr;
71 int gzerr;
73 if (gzeof(f))
74 break;
76 gzerrstr = gzerror(f, &gzerr);
77 if (gzerr == Z_ERRNO)
78 err(2, "%s", fname);
79 else
80 errx(2, "%s: %s", fname, gzerrstr);
82 if (n >= lnbuflen) {
83 lnbuflen *= 2;
84 lnbuf = grep_realloc(lnbuf, ++lnbuflen);
86 if (c == '\n')
87 break;
88 lnbuf[n] = c;
91 if (gzeof(f) && n == 0)
92 return NULL;
93 *len = n;
94 return lnbuf;
96 #endif
98 file_t *
99 grep_fdopen(int fd, char *mode)
101 file_t *f;
103 if (fd == STDIN_FILENO)
104 snprintf(fname, sizeof fname, "(standard input)");
105 else
106 snprintf(fname, sizeof fname, "(fd %d)", fd);
108 f = grep_malloc(sizeof *f);
110 #ifndef NOZ
111 if (Zflag) {
112 f->type = FILE_GZIP;
113 f->noseek = lseek(fd, 0L, SEEK_SET) == -1;
114 if ((f->gzf = gzdopen(fd, mode)) != NULL)
115 return f;
116 } else
117 #endif
119 f->type = FILE_STDIO;
120 f->noseek = isatty(fd);
121 if ((f->f = fdopen(fd, mode)) != NULL)
122 return f;
125 free(f);
126 return NULL;
129 file_t *
130 grep_open(char *path, char *mode)
132 file_t *f;
134 snprintf(fname, sizeof fname, "%s", path);
136 f = grep_malloc(sizeof *f);
137 f->noseek = 0;
139 #ifndef NOZ
140 if (Zflag) {
141 f->type = FILE_GZIP;
142 if ((f->gzf = gzopen(fname, mode)) != NULL)
143 return f;
144 } else
145 #endif
147 #ifdef FILE_MMAP
148 /* try mmap first; if it fails, try stdio */
149 if ((f->mmf = mmopen(fname, mode)) != NULL) {
150 f->type = FILE_MMAP;
151 return f;
153 #endif
154 f->type = FILE_STDIO;
155 if ((f->f = fopen(path, mode)) != NULL)
156 return f;
159 free(f);
160 return NULL;
164 grep_bin_file(file_t *f)
166 if (f->noseek)
167 return 0;
169 switch (f->type) {
170 case FILE_STDIO:
171 return bin_file(f->f);
172 #ifdef FILE_MMAP
173 case FILE_MMAP:
174 return mmbin_file(f->mmf);
175 #endif
176 #ifndef NOZ
177 case FILE_GZIP:
178 return gzbin_file(f->gzf);
179 #endif
180 default:
181 /* can't happen */
182 errx(2, "invalid file type");
186 char *
187 grep_fgetln(file_t *f, size_t *l)
189 switch (f->type) {
190 case FILE_STDIO:
191 return fgetln(f->f, l);
192 #ifdef FILE_MMAP
193 case FILE_MMAP:
194 return mmfgetln(f->mmf, l);
195 #endif
196 #ifndef NOZ
197 case FILE_GZIP:
198 return gzfgetln(f->gzf, l);
199 #endif
200 default:
201 /* can't happen */
202 errx(2, "invalid file type");
206 void
207 grep_close(file_t *f)
209 switch (f->type) {
210 case FILE_STDIO:
211 fclose(f->f);
212 break;
213 #ifdef FILE_MMAP
214 case FILE_MMAP:
215 mmclose(f->mmf);
216 break;
217 #endif
218 #ifndef NOZ
219 case FILE_GZIP:
220 gzclose(f->gzf);
221 break;
222 #endif
223 default:
224 /* can't happen */
225 errx(2, "invalid file type");
227 free(f);