diff options
-rw-r--r-- | mandoc.h | 10 | ||||
-rw-r--r-- | read.c | 56 |
2 files changed, 49 insertions, 17 deletions
@@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -152,6 +152,7 @@ enum mandocerr { MANDOCERR_FATAL, /* ===== start of fatal errors ===== */ + MANDOCERR_TOOLARGE, /* input too large */ MANDOCERR_NOTMANUAL, /* manual isn't really a manual */ MANDOCERR_COLUMNS, /* column syntax is inconsistent */ MANDOCERR_BADDISP, /* NOT IMPLEMENTED: .Bd -file */ @@ -162,6 +163,13 @@ enum mandocerr { MANDOCERR_NODOCBODY, /* no document body */ MANDOCERR_NODOCPROLOG, /* no document prologue */ MANDOCERR_MEM, /* static buffer exhausted */ + + /* ===== system errors ===== */ + + MANDOCERR_SYSOPEN, /* cannot open file */ + MANDOCERR_SYSSTAT, /* cannot stat file */ + MANDOCERR_SYSREAD, /* cannot read file */ + MANDOCERR_MAX }; @@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -26,6 +26,7 @@ #include <assert.h> #include <ctype.h> +#include <errno.h> #include <fcntl.h> #include <stdarg.h> #include <stdint.h> @@ -68,7 +69,8 @@ struct mparse { static void resize_buf(struct buf *, size_t); static void mparse_buf_r(struct mparse *, struct buf, int); static void pset(const char *, int, struct mparse *); -static int read_whole_file(const char *, int, struct buf *, int *); +static int read_whole_file(struct mparse *, const char *, int, + struct buf *, int *); static void mparse_end(struct mparse *); static void mparse_parse_buffer(struct mparse *, struct buf, const char *); @@ -192,6 +194,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "generic fatal error", + "input too large", "not a manual", "column syntax is inconsistent", "NOT IMPLEMENTED: .Bd -file", @@ -202,6 +205,11 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "no document body", "no document prologue", "static buffer exhausted", + + /* system errors */ + "cannot open file", + "cannot stat file", + "cannot read file", }; static const char * const mandoclevels[MANDOCLEVEL_MAX] = { @@ -568,7 +576,8 @@ rerun: } static int -read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) +read_whole_file(struct mparse *curp, const char *file, int fd, + struct buf *fb, int *with_mmap) { size_t off; ssize_t ssz; @@ -576,7 +585,10 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) #ifdef HAVE_MMAP struct stat st; if (-1 == fstat(fd, &st)) { - perror(file); + curp->file_status = MANDOCLEVEL_SYSERR; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_SYSSTAT, curp->file_status, + file, 0, 0, strerror(errno)); return(0); } @@ -589,7 +601,10 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) if (S_ISREG(st.st_mode)) { if (st.st_size >= (1U << 31)) { - fprintf(stderr, "%s: input too large\n", file); + curp->file_status = MANDOCLEVEL_FATAL; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_TOOLARGE, + curp->file_status, file, 0, 0, NULL); return(0); } *with_mmap = 1; @@ -612,7 +627,11 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) for (;;) { if (off == fb->sz) { if (fb->sz == (1U << 31)) { - fprintf(stderr, "%s: input too large\n", file); + curp->file_status = MANDOCLEVEL_FATAL; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_TOOLARGE, + curp->file_status, + file, 0, 0, NULL); break; } resize_buf(fb, 65536); @@ -623,7 +642,11 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) return(1); } if (ssz == -1) { - perror(file); + curp->file_status = MANDOCLEVEL_SYSERR; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_SYSREAD, + curp->file_status, file, 0, 0, + strerror(errno)); break; } off += (size_t)ssz; @@ -704,12 +727,15 @@ mparse_readfd(struct mparse *curp, int fd, const char *file) struct buf blk; int with_mmap; - if (-1 == fd) - if (-1 == (fd = open(file, O_RDONLY, 0))) { - perror(file); - curp->file_status = MANDOCLEVEL_SYSERR; - goto out; - } + 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)); + goto out; + } + /* * Run for each opened file; may be called more than once for * each full parse sequence if the opened file is nested (i.e., @@ -717,10 +743,8 @@ mparse_readfd(struct mparse *curp, int fd, const char *file) * the parse phase for the file. */ - if ( ! read_whole_file(file, fd, &blk, &with_mmap)) { - curp->file_status = MANDOCLEVEL_SYSERR; + if ( ! read_whole_file(curp, file, fd, &blk, &with_mmap)) goto out; - } mparse_parse_buffer(curp, blk, file); |