=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/read.c,v retrieving revision 1.73 retrieving revision 1.74 diff -c -r1.73 -r1.74 *** src/usr.bin/mandoc/read.c 2014/11/26 21:40:11 1.73 --- src/usr.bin/mandoc/read.c 2014/11/26 23:27:13 1.74 *************** *** 1,4 **** ! /* $OpenBSD: read.c,v 1.73 2014/11/26 21:40:11 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: read.c,v 1.74 2014/11/26 23:27:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze *************** *** 759,787 **** curp->file = svfile; } enum mandoclevel mparse_readfd(struct mparse *curp, int fd, const char *file) { struct buf blk; int with_mmap; int save_filenc; ! if (-1 == fd && -1 == (fd = open(file, O_RDONLY, 0))) { ! curp->file_status = MANDOCLEVEL_SYSERR; ! if (curp->mmsg) ! (*curp->mmsg)(MANDOCERR_SYSOPEN, ! curp->file_status, ! file, 0, 0, strerror(errno)); ! return(curp->file_status); ! } - /* - * Run for each opened file; may be called more than once for - * each full parse sequence if the opened file is nested (i.e., - * from `so'). Simply sucks in the whole file and moves into - * the parse phase for the file. - */ - if (read_whole_file(curp, file, fd, &blk, &with_mmap)) { save_filenc = curp->filenc; curp->filenc = curp->options & --- 759,784 ---- curp->file = svfile; } + /* + * If a file descriptor is given, use it and assume it points + * to the named file. Otherwise, open the named file. + * Read the whole file into memory and call the parsers. + * Called recursively when an .so request is encountered. + */ enum mandoclevel mparse_readfd(struct mparse *curp, int fd, const char *file) { struct buf blk; int with_mmap; int save_filenc; + pid_t save_child; ! save_child = curp->child; ! if (fd != -1) ! curp->child = 0; ! else if (mparse_open(curp, &fd, file) >= MANDOCLEVEL_SYSERR) ! goto out; if (read_whole_file(curp, file, fd, &blk, &with_mmap)) { save_filenc = curp->filenc; curp->filenc = curp->options & *************** *** 794,802 **** free(blk.buf); } ! if (STDIN_FILENO != fd && -1 == close(fd)) perror(file); return(curp->file_status); } --- 791,802 ---- free(blk.buf); } ! if (fd != STDIN_FILENO && close(fd) == -1) perror(file); + mparse_wait(curp); + out: + curp->child = save_child; return(curp->file_status); } *************** *** 804,824 **** mparse_open(struct mparse *curp, int *fd, const char *file) { int pfd[2]; char *cp; enum mandocerr err; pfd[1] = -1; curp->file = file; if ((cp = strrchr(file, '.')) == NULL || strcmp(cp + 1, "gz")) { curp->child = 0; ! if ((*fd = open(file, O_RDONLY)) == -1) { ! err = MANDOCERR_SYSOPEN; ! goto out; ! } ! return(MANDOCLEVEL_OK); } if (pipe(pfd) == -1) { err = MANDOCERR_SYSPIPE; goto out; --- 804,843 ---- mparse_open(struct mparse *curp, int *fd, const char *file) { int pfd[2]; + int save_errno; char *cp; enum mandocerr err; pfd[1] = -1; curp->file = file; + + /* Unless zipped, try to just open the file. */ + if ((cp = strrchr(file, '.')) == NULL || strcmp(cp + 1, "gz")) { curp->child = 0; ! if ((*fd = open(file, O_RDONLY)) != -1) ! return(MANDOCLEVEL_OK); ! ! /* Open failed; try to append ".gz". */ ! ! mandoc_asprintf(&cp, "%s.gz", file); ! file = cp; ! } else ! cp = NULL; ! ! /* Before forking, make sure the file can be read. */ ! ! save_errno = errno; ! if (access(file, R_OK) == -1) { ! if (cp != NULL) ! errno = save_errno; ! err = MANDOCERR_SYSOPEN; ! goto out; } + /* Run gunzip(1). */ + if (pipe(pfd) == -1) { err = MANDOCERR_SYSPIPE; goto out; *************** *** 847,857 **** } out: *fd = -1; curp->child = 0; curp->file_status = MANDOCLEVEL_SYSERR; if (curp->mmsg) ! (*curp->mmsg)(err, curp->file_status, file, 0, 0, strerror(errno)); if (pfd[1] != -1) exit(1); --- 866,877 ---- } out: + free(cp); *fd = -1; curp->child = 0; curp->file_status = MANDOCLEVEL_SYSERR; if (curp->mmsg) ! (*curp->mmsg)(err, curp->file_status, curp->file, 0, 0, strerror(errno)); if (pfd[1] != -1) exit(1);