[BACK]Return to file.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / grep

Annotation of src/usr.bin/grep/file.c, Revision 1.15

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