GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/grep/file.c Lines: 37 76 48.7 %
Date: 2016-12-06 Branches: 14 44 31.8 %

Line Branch Exec Source
1
/*	$OpenBSD: file.c,v 1.13 2015/03/16 13:27:59 millert Exp $	*/
2
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
36
static char	 fname[PATH_MAX];
37
#ifndef NOZ
38
static char	*lnbuf;
39
static size_t	 lnbuflen;
40
#endif
41
42
#define FILE_STDIO	0
43
#define FILE_MMAP	1
44
#define FILE_GZIP	2
45
46
struct file {
47
	int	 type;
48
	int	 noseek;
49
	FILE	*f;
50
	mmf_t	*mmf;
51
	gzFile	*gzf;
52
};
53
54
#ifndef NOZ
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;
69
70
			gzerrstr = gzerror(f, &gzerr);
71
			if (gzerr == Z_ERRNO)
72
				err(2, "%s", fname);
73
			else
74
				errx(2, "%s: %s", fname, gzerrstr);
75
		}
76
		if (n >= lnbuflen) {
77
			lnbuflen *= 2;
78
			lnbuf = grep_realloc(lnbuf, ++lnbuflen);
79
		}
80
		if (c == '\n')
81
			break;
82
		lnbuf[n] = c;
83
	}
84
85
	if (gzeof(f) && n == 0)
86
		return NULL;
87
	*len = n;
88
	return lnbuf;
89
}
90
#endif
91
92
file_t *
93
grep_fdopen(int fd, char *mode)
94
82
{
95
	file_t *f;
96
97
82
	if (fd == STDIN_FILENO)
98
82
		snprintf(fname, sizeof fname, "(standard input)");
99
	else
100
		snprintf(fname, sizeof fname, "(fd %d)", fd);
101
102
82
	f = grep_malloc(sizeof *f);
103
104
#ifndef NOZ
105
82
	if (Zflag) {
106
		f->type = FILE_GZIP;
107
		f->noseek = lseek(fd, 0L, SEEK_SET) == -1;
108
		if ((f->gzf = gzdopen(fd, mode)) != NULL)
109
			return f;
110
	} else
111
#endif
112
	{
113
82
		f->type = FILE_STDIO;
114
82
		f->noseek = isatty(fd);
115
82
		if ((f->f = fdopen(fd, mode)) != NULL)
116
82
			return f;
117
	}
118
119
	free(f);
120
	return NULL;
121
}
122
123
file_t *
124
grep_open(char *path, char *mode)
125
267
{
126
	file_t *f;
127
128
267
	snprintf(fname, sizeof fname, "%s", path);
129
130
267
	f = grep_malloc(sizeof *f);
131
267
	f->noseek = 0;
132
133
#ifndef NOZ
134
267
	if (Zflag) {
135
		f->type = FILE_GZIP;
136
		if ((f->gzf = gzopen(fname, mode)) != NULL)
137
			return f;
138
	} else
139
#endif
140
	{
141
#ifndef SMALL
142
		/* try mmap first; if it fails, try stdio */
143
267
		if ((f->mmf = mmopen(fname, mode)) != NULL) {
144
266
			f->type = FILE_MMAP;
145
266
			return f;
146
		}
147
#endif
148
1
		f->type = FILE_STDIO;
149
1
		if ((f->f = fopen(path, mode)) != NULL)
150
1
			return f;
151
	}
152
153
	free(f);
154
	return NULL;
155
}
156
157
int
158
grep_bin_file(file_t *f)
159
349
{
160
349
	if (f->noseek)
161
		return 0;
162
163

349
	switch (f->type) {
164
	case FILE_STDIO:
165
83
		return bin_file(f->f);
166
#ifndef SMALL
167
	case FILE_MMAP:
168
266
		return mmbin_file(f->mmf);
169
#endif
170
#ifndef NOZ
171
	case FILE_GZIP:
172
		return gzbin_file(f->gzf);
173
#endif
174
	default:
175
		/* can't happen */
176
		errx(2, "invalid file type");
177
	}
178
}
179
180
char *
181
grep_fgetln(file_t *f, size_t *l)
182
21322
{
183

21322
	switch (f->type) {
184
	case FILE_STDIO:
185
18697
		return fgetln(f->f, l);
186
#ifndef SMALL
187
	case FILE_MMAP:
188
2625
		return mmfgetln(f->mmf, l);
189
#endif
190
#ifndef NOZ
191
	case FILE_GZIP:
192
		return gzfgetln(f->gzf, l);
193
#endif
194
	default:
195
		/* can't happen */
196
		errx(2, "invalid file type");
197
	}
198
}
199
200
void
201
grep_close(file_t *f)
202
349
{
203

349
	switch (f->type) {
204
	case FILE_STDIO:
205
83
		fclose(f->f);
206
83
		break;
207
#ifndef SMALL
208
	case FILE_MMAP:
209
266
		mmclose(f->mmf);
210
266
		break;
211
#endif
212
#ifndef NOZ
213
	case FILE_GZIP:
214
		gzclose(f->gzf);
215
		break;
216
#endif
217
	default:
218
		/* can't happen */
219
		errx(2, "invalid file type");
220
	}
221
349
	free(f);
222
349
}