aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2019-07-10 19:39:01 +0000
committerIngo Schwarze <schwarze@openbsd.org>2019-07-10 19:39:01 +0000
commita597f1a3e2780fed1216f2237e8a276110b0daef (patch)
treee59b39076a9f1141d186002bff45c25d72423539
parent589c83d3597ba6229a69bda10630710c515d2508 (diff)
downloadmandoc-a597f1a3e2780fed1216f2237e8a276110b0daef.tar.gz
mandoc-a597f1a3e2780fed1216f2237e8a276110b0daef.tar.zst
mandoc-a597f1a3e2780fed1216f2237e8a276110b0daef.zip
Some time ago, i simplified mandoc_msg() such that it can be used
everywhere and not only in the parsers. For more uniform messages, use it at more places instead of err(3), in particular in the main program. While here, integrate a few trivial functions called at exactly one place into the main option parser, and let a few more functions use the normal convention of returning 0 for success and -1 for error.
-rw-r--r--Makefile.depend4
-rw-r--r--main.c299
-rw-r--r--mandoc.155
-rw-r--r--mandoc.h34
-rw-r--r--mandoc_msg.c44
-rw-r--r--manpath.c92
-rw-r--r--read.c35
-rw-r--r--tag.c32
8 files changed, 346 insertions, 249 deletions
diff --git a/Makefile.depend b/Makefile.depend
index a02a2dc5..81f632d0 100644
--- a/Makefile.depend
+++ b/Makefile.depend
@@ -46,7 +46,7 @@ mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h
mandoc_xr.o: mandoc_xr.c mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc_xr.h
mandocd.o: mandocd.c config.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h main.h manconf.h
mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h manconf.h mansearch.h dba_array.h dba.h
-manpath.o: manpath.c config.h mandoc_aux.h manconf.h
+manpath.o: manpath.c config.h mandoc_aux.h mandoc.h manconf.h
mansearch.o: mansearch.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
@@ -67,7 +67,7 @@ roff_term.o: roff_term.c mandoc.h roff.h out.h term.h
roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h
soelim.o: soelim.c config.h compat_stringlist.h
st.o: st.c config.h mandoc.h roff.h libmdoc.h
-tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h tag.h
+tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h tag.h
tbl.o: tbl.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_parse.h tbl_int.h
tbl_data.o: tbl_data.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_int.h
tbl_html.o: tbl_html.c config.h mandoc.h roff.h tbl.h out.h html.h
diff --git a/main.c b/main.c
index acd9cd92..09fe8939 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.328 2019/07/06 20:05:27 schwarze Exp $ */
+/* $Id: main.c,v 1.329 2019/07/10 19:39:01 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2012, 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
@@ -98,13 +98,10 @@ static int fs_lookup(const struct manpaths *,
static int fs_search(const struct mansearch *,
const struct manpaths *, int, char**,
struct manpage **, size_t *);
-static int koptions(int *, char *);
-static void moptions(int *, char *);
static void outdata_alloc(struct curparse *);
static void parse(struct curparse *, int, const char *);
-static void passthrough(const char *, int, int);
+static void passthrough(int, int);
static pid_t spawn_pager(struct tag_files *);
-static int toptions(struct curparse *, char *);
static void usage(enum argmode) __attribute__((__noreturn__));
static int woptions(struct curparse *, char *);
@@ -155,10 +152,11 @@ main(int argc, char *argv[])
return mandocdb(argc, argv);
#if HAVE_PLEDGE
- if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1)
- err((int)MANDOCLEVEL_SYSERR, "pledge");
+ if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1) {
+ mandoc_msg(MANDOCERR_PLEDGE, 0, 0, "%s", strerror(errno));
+ return mandoc_msg_getrc();
+ }
#endif
-
#if HAVE_SANDBOX_INIT
if (sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, NULL) == -1)
errx((int)MANDOCLEVEL_SYSERR, "sandbox_init");
@@ -222,19 +220,29 @@ main(int argc, char *argv[])
outmode = OUTMODE_ALL;
break;
case 'I':
- if (strncmp(optarg, "os=", 3)) {
- warnx("-I %s: Bad argument", optarg);
- return (int)MANDOCLEVEL_BADARG;
+ if (strncmp(optarg, "os=", 3) != 0) {
+ mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
+ "-I %s", optarg);
+ return mandoc_msg_getrc();
}
if (curp.os_s != NULL) {
- warnx("-I %s: Duplicate argument", optarg);
- return (int)MANDOCLEVEL_BADARG;
+ mandoc_msg(MANDOCERR_BADARG_DUPE, 0, 0,
+ "-I %s", optarg);
+ return mandoc_msg_getrc();
}
curp.os_s = mandoc_strdup(optarg + 3);
break;
case 'K':
- if ( ! koptions(&options, optarg))
- return (int)MANDOCLEVEL_BADARG;
+ options &= ~(MPARSE_UTF8 | MPARSE_LATIN1);
+ if (strcmp(optarg, "utf-8") == 0)
+ options |= MPARSE_UTF8;
+ else if (strcmp(optarg, "iso-8859-1") == 0)
+ options |= MPARSE_LATIN1;
+ else if (strcmp(optarg, "us-ascii") != 0) {
+ mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
+ "-K %s", optarg);
+ return mandoc_msg_getrc();
+ }
break;
case 'k':
search.argmode = ARG_EXPR;
@@ -259,12 +267,37 @@ main(int argc, char *argv[])
search.sec = optarg;
break;
case 'T':
- if ( ! toptions(&curp, optarg))
- return (int)MANDOCLEVEL_BADARG;
+ if (strcmp(optarg, "ascii") == 0)
+ curp.outtype = OUTT_ASCII;
+ else if (strcmp(optarg, "lint") == 0) {
+ curp.outtype = OUTT_LINT;
+ mandoc_msg_setoutfile(stdout);
+ mandoc_msg_setmin(MANDOCERR_BASE);
+ } else if (strcmp(optarg, "tree") == 0)
+ curp.outtype = OUTT_TREE;
+ else if (strcmp(optarg, "man") == 0)
+ curp.outtype = OUTT_MAN;
+ else if (strcmp(optarg, "html") == 0)
+ curp.outtype = OUTT_HTML;
+ else if (strcmp(optarg, "markdown") == 0)
+ curp.outtype = OUTT_MARKDOWN;
+ else if (strcmp(optarg, "utf8") == 0)
+ curp.outtype = OUTT_UTF8;
+ else if (strcmp(optarg, "locale") == 0)
+ curp.outtype = OUTT_LOCALE;
+ else if (strcmp(optarg, "ps") == 0)
+ curp.outtype = OUTT_PS;
+ else if (strcmp(optarg, "pdf") == 0)
+ curp.outtype = OUTT_PDF;
+ else {
+ mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
+ "-T %s", optarg);
+ return mandoc_msg_getrc();
+ }
break;
case 'W':
- if ( ! woptions(&curp, optarg))
- return (int)MANDOCLEVEL_BADARG;
+ if (woptions(&curp, optarg) == -1)
+ return mandoc_msg_getrc();
break;
case 'w':
outmode = OUTMODE_FLN;
@@ -302,7 +335,7 @@ main(int argc, char *argv[])
while (oarg != NULL) {
if (manconf_output(&conf.output,
strsep(&oarg, ","), 0) == -1)
- return (int)MANDOCLEVEL_BADARG;
+ return mandoc_msg_getrc();
}
}
}
@@ -326,9 +359,13 @@ main(int argc, char *argv[])
}
#if HAVE_PLEDGE
- if (!use_pager)
- if (pledge("stdio rpath", NULL) == -1)
- err((int)MANDOCLEVEL_SYSERR, "pledge");
+ if (use_pager == 0) {
+ if (pledge("stdio rpath", NULL) == -1) {
+ mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
+ "%s", strerror(errno));
+ return mandoc_msg_getrc();
+ }
+ }
#endif
/* Parse arguments. */
@@ -393,7 +430,7 @@ main(int argc, char *argv[])
usage(search.argmode);
if (sz == 0 && search.argmode == ARG_NAME)
- fs_search(&search, &conf.manpath,
+ (void)fs_search(&search, &conf.manpath,
argc, argv, &res, &sz);
if (search.argmode == ARG_NAME) {
@@ -401,7 +438,10 @@ main(int argc, char *argv[])
if (strchr(argv[c], '/') == NULL)
continue;
if (access(argv[c], R_OK) == -1) {
- warn("%s", argv[c]);
+ mandoc_msg_setinfilename(argv[c]);
+ mandoc_msg(MANDOCERR_BADARG_BAD,
+ 0, 0, "%s", strerror(errno));
+ mandoc_msg_setinfilename(NULL);
continue;
}
res = mandoc_reallocarray(res,
@@ -487,16 +527,26 @@ main(int argc, char *argv[])
#if HAVE_PLEDGE
if (use_pager) {
- if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1)
- err((int)MANDOCLEVEL_SYSERR, "pledge");
+ if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1) {
+ mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
+ "%s", strerror(errno));
+ return mandoc_msg_getrc();
+ }
} else {
- if (pledge("stdio rpath", NULL) == -1)
- err((int)MANDOCLEVEL_SYSERR, "pledge");
+ if (pledge("stdio rpath", NULL) == -1) {
+ mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
+ "%s", strerror(errno));
+ return mandoc_msg_getrc();
+ }
}
#endif
- if (search.argmode == ARG_FILE)
- moptions(&options, auxpaths);
+ if (search.argmode == ARG_FILE && auxpaths != NULL) {
+ if (strcmp(auxpaths, "doc") == 0)
+ options |= MPARSE_MDOC;
+ else if (strcmp(auxpaths, "an") == 0)
+ options |= MPARSE_MAN;
+ }
mchars_alloc();
curp.mp = mparse_alloc(options, curp.os_e, curp.os_s);
@@ -538,6 +588,7 @@ main(int argc, char *argv[])
} else
thisarg = *argv;
+ mandoc_msg_setinfilename(thisarg);
fd = mparse_open(curp.mp, thisarg);
if (fd != -1) {
if (use_pager) {
@@ -547,22 +598,21 @@ main(int argc, char *argv[])
tag_files->tagname = conf.output.tag;
}
- mandoc_msg_setinfilename(thisarg);
if (resp == NULL || resp->form == FORM_SRC)
parse(&curp, fd, thisarg);
else
- passthrough(resp->file, fd,
- conf.output.synopsisonly);
- mandoc_msg_setinfilename(NULL);
+ passthrough(fd, conf.output.synopsisonly);
if (ferror(stdout)) {
if (tag_files != NULL) {
- warn("%s", tag_files->ofn);
+ mandoc_msg(MANDOCERR_WRITE, 0, 0,
+ "%s: %s", tag_files->ofn,
+ strerror(errno));
tag_unlink();
tag_files = NULL;
} else
- warn("stdout");
- mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
+ mandoc_msg(MANDOCERR_WRITE, 0, 0,
+ "%s", strerror(errno));
break;
}
@@ -572,8 +622,10 @@ main(int argc, char *argv[])
terminal_sepline(curp.outdata);
}
} else
- mandoc_msg(MANDOCERR_FILE, 0, 0,
- "%s: %s", thisarg, strerror(errno));
+ mandoc_msg(resp == NULL ? MANDOCERR_BADARG_BAD :
+ MANDOCERR_OPEN, 0, 0, "%s", strerror(errno));
+
+ mandoc_msg_setinfilename(NULL);
if (curp.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK)
break;
@@ -665,8 +717,8 @@ out:
continue;
if (pid == -1) {
- warn("wait");
- mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
+ mandoc_msg(MANDOCERR_WAIT, 0, 0,
+ "%s", strerror(errno));
break;
}
if (!WIFSTOPPED(status))
@@ -682,7 +734,6 @@ out:
static void
usage(enum argmode argmode)
{
-
switch (argmode) {
case ARG_FILE:
fputs("usage: mandoc [-ac] [-I os=name] "
@@ -747,7 +798,8 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
paths->paths[ipath], sec, name);
globres = glob(file, 0, NULL, &globinfo);
if (globres != 0 && globres != GLOB_NOMATCH)
- warn("%s: glob", file);
+ mandoc_msg(MANDOCERR_GLOB, 0, 0,
+ "%s: %s", file, strerror(errno));
free(file);
if (globres == 0)
file = mandoc_strdup(*globinfo.gl_pathv);
@@ -758,21 +810,21 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
free(file);
}
if (res != NULL || ipath + 1 != paths->sz)
- return 0;
+ return -1;
mandoc_asprintf(&file, "%s.%s", name, sec);
globres = stat(file, &sb);
free(file);
- return globres != -1;
+ return globres;
found:
warnx("outdated mandoc.db lacks %s(%s) entry, run %s %s",
name, sec, BINM_MAKEWHATIS, paths->paths[ipath]);
if (res == NULL) {
free(file);
- return 1;
+ return 0;
}
- *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
+ *res = mandoc_reallocarray(*res, ++*ressz, sizeof(**res));
page = *res + (*ressz - 1);
page->file = file;
page->names = NULL;
@@ -781,7 +833,7 @@ found:
page->ipath = ipath;
page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10;
page->form = form;
- return 1;
+ return 0;
}
static int
@@ -803,14 +855,14 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
for (ipath = 0; ipath < paths->sz; ipath++) {
if (cfg->sec != NULL) {
if (fs_lookup(paths, ipath, cfg->sec,
- cfg->arch, *argv, res, ressz) &&
+ cfg->arch, *argv, res, ressz) != -1 &&
cfg->firstmatch)
- return 1;
+ return 0;
} else for (isec = 0; isec < nsec; isec++)
if (fs_lookup(paths, ipath, sections[isec],
- cfg->arch, *argv, res, ressz) &&
+ cfg->arch, *argv, res, ressz) != -1 &&
cfg->firstmatch)
- return 1;
+ return 0;
}
if (res != NULL && *ressz == lastsz &&
strchr(*argv, '/') == NULL) {
@@ -829,7 +881,7 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
argv++;
argc--;
}
- return 0;
+ return -1;
}
static void
@@ -936,7 +988,7 @@ check_xr(void)
search.firstmatch = 1;
if (mansearch(&search, &paths, 1, &xr->name, NULL, &sz))
continue;
- if (fs_search(&search, &paths, 1, &xr->name, NULL, &sz))
+ if (fs_search(&search, &paths, 1, &xr->name, NULL, &sz) != -1)
continue;
if (xr->count == 1)
mandoc_msg(MANDOCERR_XR_BAD, xr->line,
@@ -976,34 +1028,34 @@ outdata_alloc(struct curparse *curp)
}
static void
-passthrough(const char *file, int fd, int synopsis_only)
+passthrough(int fd, int synopsis_only)
{
const char synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS";
const char synr[] = "SYNOPSIS";
FILE *stream;
- const char *syscall;
char *line, *cp;
size_t linesz;
ssize_t len, written;
- int print;
+ int lno, print;
+ stream = NULL;
line = NULL;
linesz = 0;
if (fflush(stdout) == EOF) {
- syscall = "fflush";
- goto fail;
+ mandoc_msg(MANDOCERR_FFLUSH, 0, 0, "%s", strerror(errno));
+ goto done;
}
-
if ((stream = fdopen(fd, "r")) == NULL) {
close(fd);
- syscall = "fdopen";
- goto fail;
+ mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
+ goto done;
}
- print = 0;
+ lno = print = 0;
while ((len = getline(&line, &linesz, stream)) != -1) {
+ lno++;
cp = line;
if (synopsis_only) {
if (print) {
@@ -1021,94 +1073,20 @@ passthrough(const char *file, int fd, int synopsis_only)
}
}
for (; len > 0; len -= written) {
- if ((written = write(STDOUT_FILENO, cp, len)) != -1)
- continue;
- fclose(stream);
- syscall = "write";
- goto fail;
+ if ((written = write(STDOUT_FILENO, cp, len)) == -1) {
+ mandoc_msg(MANDOCERR_WRITE, 0, 0,
+ "%s", strerror(errno));
+ goto done;
+ }
}
}
-
- if (ferror(stream)) {
- fclose(stream);
- syscall = "getline";
- goto fail;
- }
+ if (ferror(stream))
+ mandoc_msg(MANDOCERR_GETLINE, lno, 0, "%s", strerror(errno));
done:
free(line);
- fclose(stream);
- return;
-
-fail:
- free(line);
- warn("%s: SYSERR: %s", file, syscall);
- mandoc_msg_setrc(MANDOCLEVEL_SYSERR);
-}
-
-static int
-koptions(int *options, char *arg)
-{
-
- if ( ! strcmp(arg, "utf-8")) {
- *options |= MPARSE_UTF8;
- *options &= ~MPARSE_LATIN1;
- } else if ( ! strcmp(arg, "iso-8859-1")) {
- *options |= MPARSE_LATIN1;
- *options &= ~MPARSE_UTF8;
- } else if ( ! strcmp(arg, "us-ascii")) {
- *options &= ~(MPARSE_UTF8 | MPARSE_LATIN1);
- } else {
- warnx("-K %s: Bad argument", arg);
- return 0;
- }
- return 1;
-}
-
-static void
-moptions(int *options, char *arg)
-{
-
- if (arg == NULL)
- return;
- if (strcmp(arg, "doc") == 0)
- *options |= MPARSE_MDOC;
- else if (strcmp(arg, "an") == 0)
- *options |= MPARSE_MAN;
-}
-
-static int
-toptions(struct curparse *curp, char *arg)
-{
-
- if (0 == strcmp(arg, "ascii"))
- curp->outtype = OUTT_ASCII;
- else if (0 == strcmp(arg, "lint")) {
- curp->outtype = OUTT_LINT;
- mandoc_msg_setoutfile(stdout);
- mandoc_msg_setmin(MANDOCERR_BASE);
- } else if (0 == strcmp(arg, "tree"))
- curp->outtype = OUTT_TREE;
- else if (0 == strcmp(arg, "man"))
- curp->outtype = OUTT_MAN;
- else if (0 == strcmp(arg, "html"))
- curp->outtype = OUTT_HTML;
- else if (0 == strcmp(arg, "markdown"))
- curp->outtype = OUTT_MARKDOWN;
- else if (0 == strcmp(arg, "utf8"))
- curp->outtype = OUTT_UTF8;
- else if (0 == strcmp(arg, "locale"))
- curp->outtype = OUTT_LOCALE;
- else if (0 == strcmp(arg, "ps"))
- curp->outtype = OUTT_PS;
- else if (0 == strcmp(arg, "pdf"))
- curp->outtype = OUTT_PDF;
- else {
- warnx("-T %s: Bad argument", arg);
- return 0;
- }
-
- return 1;
+ if (stream != NULL)
+ fclose(stream);
}
static int
@@ -1152,7 +1130,7 @@ woptions(struct curparse *curp, char *arg)
mandoc_msg_setmin(MANDOCERR_UNSUPP);
break;
case 7:
- mandoc_msg_setmin(MANDOCERR_MAX);
+ mandoc_msg_setmin(MANDOCERR_BADARG);
break;
case 8:
mandoc_msg_setmin(MANDOCERR_BASE);
@@ -1163,11 +1141,11 @@ woptions(struct curparse *curp, char *arg)
curp->os_e = MANDOC_OS_NETBSD;
break;
default:
- warnx("-W %s: Bad argument", o);
- return 0;
+ mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0, "-W %s", o);
+ return -1;
}
}
- return 1;
+ return 0;
}
static pid_t
@@ -1232,15 +1210,19 @@ spawn_pager(struct tag_files *tag_files)
switch (pager_pid = fork()) {
case -1:
- err((int)MANDOCLEVEL_SYSERR, "fork");
+ mandoc_msg(MANDOCERR_FORK, 0, 0, "%s", strerror(errno));
+ exit(mandoc_msg_getrc());
case 0:
break;
default:
(void)setpgid(pager_pid, 0);
(void)tcsetpgrp(tag_files->ofd, pager_pid);
#if HAVE_PLEDGE
- if (pledge("stdio rpath tmppath tty proc", NULL) == -1)
- err((int)MANDOCLEVEL_SYSERR, "pledge");
+ if (pledge("stdio rpath tmppath tty proc", NULL) == -1) {
+ mandoc_msg(MANDOCERR_PLEDGE, 0, 0,
+ "%s", strerror(errno));
+ exit(mandoc_msg_getrc());
+ }
#endif
tag_files->pager_pid = pager_pid;
return pager_pid;
@@ -1248,8 +1230,10 @@ spawn_pager(struct tag_files *tag_files)
/* The child process becomes the pager. */
- if (dup2(tag_files->ofd, STDOUT_FILENO) == -1)
- err((int)MANDOCLEVEL_SYSERR, "pager stdout");
+ if (dup2(tag_files->ofd, STDOUT_FILENO) == -1) {
+ mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
+ _exit(mandoc_msg_getrc());
+ }
close(tag_files->ofd);
assert(tag_files->tfd == -1);
@@ -1259,5 +1243,6 @@ spawn_pager(struct tag_files *tag_files)
nanosleep(&timeout, NULL);
execvp(argv[0], argv);
- err((int)MANDOCLEVEL_SYSERR, "exec %s", argv[0]);
+ mandoc_msg(MANDOCERR_EXEC, 0, 0, "%s: %s", argv[0], strerror(errno));
+ _exit(mandoc_msg_getrc());
}
diff --git a/mandoc.1 b/mandoc.1
index 71efdd1b..298d5dc7 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -1,7 +1,7 @@
-.\" $Id: mandoc.1,v 1.239 2019/05/26 01:28:09 schwarze Exp $
+.\" $Id: mandoc.1,v 1.240 2019/07/10 19:39:01 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2012, 2014-2019 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
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 26 2019 $
+.Dd $Mdocdate: July 10 2019 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -698,7 +698,7 @@ No input files have been read.
.It 6
An operating system error occurred, for example exhaustion
of memory, file descriptors, or process table entries.
-Such errors cause
+Such errors may cause
.Nm
to exit at once, possibly in the middle of parsing or formatting a file.
.El
@@ -778,6 +778,13 @@ fields.
.Pp
Message levels have the following meanings:
.Bl -tag -width "warning"
+.It Cm syserr
+An operating system error occurred.
+There isn't necessarily anything wrong with the input files.
+Output may all the same be missing or incomplete.
+.It Cm badarg
+Invalid command line arguments were specified.
+No input files have been read and no output is produced.
.It Cm unsupp
An input file uses unsupported low-level
.Xr roff 7
@@ -826,8 +833,7 @@ Messages of the
.Cm error ,
and
.Cm unsupp
-levels except those about non-existent or unreadable input files
-are hidden unless their level, or a lower level, is requested using a
+levels are hidden unless their level, or a lower level, is requested using a
.Fl W
option or
.Fl T Cm lint
@@ -2242,6 +2248,43 @@ macro or of an undefined macro.
The macro is ignored, and its arguments are handled
as if they were a text line.
.El
+.Ss Bad command line arguments
+.Bl -ohang
+.It Sy "bad command line argument"
+The argument following one of the
+.Fl IKMmOTW
+command line options is invalid, or a
+.Ar file
+given as a command line argument cannot be opened.
+.It Sy "duplicate command line argument"
+The
+.Fl I
+command line option was specified twice.
+.It Sy "option has a superfluous value"
+An argument to the
+.Fl O
+option has a value but does not accept one.
+.It Sy "missing option value"
+An argument to the
+.Fl O
+option has no argument but requires one.
+.It Sy "bad option value"
+An argument to the
+.Fl O
+.Cm indent
+or
+.Cm width
+option has an invalid value.
+.It Sy "duplicate option value"
+The same
+.Fl O
+option is specified more than once.
+.It Sy "no such tag"
+The
+.Fl O Cm tag
+option was specified but the tag was not found in any of the displayed
+manual pages.
+.El
.Sh SEE ALSO
.Xr apropos 1 ,
.Xr man 1 ,
diff --git a/mandoc.h b/mandoc.h
index a44b192e..ac518431 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,7 +1,7 @@
-/* $Id: mandoc.h,v 1.262 2018/12/16 00:17:02 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.263 2019/07/10 19:39:01 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2012-2018 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012-2019 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
@@ -193,7 +193,6 @@ enum mandocerr {
MANDOCERR_TBLDATA_BLK, /* data block open at end of tbl: macro */
/* related to document structure and macros */
- MANDOCERR_FILE, /* cannot open file */
MANDOCERR_PROLOG_REP, /* duplicate prologue macro: macro */
MANDOCERR_DT_LATE, /* skipping late title macro: Dt args */
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
@@ -242,6 +241,35 @@ enum mandocerr {
MANDOCERR_TBLLAYOUT_MOD, /* unsupported tbl layout modifier: m */
MANDOCERR_TBLMACRO, /* ignoring macro in table: macro */
+ MANDOCERR_BADARG, /* ===== start of bad invocations ===== */
+
+ MANDOCERR_BADARG_BAD, /* bad argument */
+ MANDOCERR_BADARG_DUPE, /* duplicate argument */
+ MANDOCERR_BADVAL, /* does not take a value */
+ MANDOCERR_BADVAL_MISS, /* missing argument value */
+ MANDOCERR_BADVAL_BAD, /* bad argument value */
+ MANDOCERR_BADVAL_DUPE, /* duplicate argument value */
+ MANDOCERR_TAG, /* no such tag */
+
+ MANDOCERR_SYSERR, /* ===== start of system errors ===== */
+
+ MANDOCERR_DUP,
+ MANDOCERR_EXEC,
+ MANDOCERR_FDOPEN,
+ MANDOCERR_FFLUSH,
+ MANDOCERR_FORK,
+ MANDOCERR_FSTAT,
+ MANDOCERR_GETLINE,
+ MANDOCERR_GLOB,
+ MANDOCERR_GZCLOSE,
+ MANDOCERR_GZDOPEN,
+ MANDOCERR_MKSTEMP,
+ MANDOCERR_OPEN,
+ MANDOCERR_PLEDGE,
+ MANDOCERR_READ,
+ MANDOCERR_WAIT,
+ MANDOCERR_WRITE,
+
MANDOCERR_MAX
};
diff --git a/mandoc_msg.c b/mandoc_msg.c
index ff4d8031..f3377640 100644
--- a/mandoc_msg.c
+++ b/mandoc_msg.c
@@ -1,7 +1,7 @@
-/* $Id: mandoc_msg.c,v 1.6 2019/03/06 15:55:38 schwarze Exp $ */
+/* $Id: mandoc_msg.c,v 1.7 2019/07/10 19:39:01 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014-2019 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
@@ -29,8 +29,8 @@ static const enum mandocerr lowest_type[MANDOCLEVEL_MAX] = {
MANDOCERR_WARNING,
MANDOCERR_ERROR,
MANDOCERR_UNSUPP,
- MANDOCERR_MAX,
- MANDOCERR_MAX
+ MANDOCERR_BADARG,
+ MANDOCERR_SYSERR
};
static const char *const level_name[MANDOCLEVEL_MAX] = {
@@ -193,7 +193,6 @@ static const char *const type_message[MANDOCERR_MAX] = {
"data block open at end of tbl",
/* related to document structure and macros */
- NULL,
"duplicate prologue macro",
"skipping late title macro",
"input stack limit exceeded, infinite loop?",
@@ -240,11 +239,40 @@ static const char *const type_message[MANDOCERR_MAX] = {
"eqn delim option in tbl",
"unsupported tbl layout modifier",
"ignoring macro in table",
+
+ /* bad command line arguments */
+ NULL,
+ "bad command line argument",
+ "duplicate command line argument",
+ "option has a superfluous value",
+ "missing option value",
+ "bad option value",
+ "duplicate option value",
+ "no such tag",
+
+ /* system errors */
+ NULL,
+ "dup",
+ "exec",
+ "fdopen",
+ "fflush",
+ "fork",
+ "fstat",
+ "getline",
+ "glob",
+ "gzclose",
+ "gzdopen",
+ "mkstemp",
+ "open",
+ "pledge",
+ "read",
+ "wait",
+ "write",
};
static FILE *fileptr = NULL;
static const char *filename = NULL;
-static enum mandocerr min_type = MANDOCERR_MAX;
+static enum mandocerr min_type = MANDOCERR_BADARG;
static enum mandoclevel rc = MANDOCLEVEL_OK;
@@ -297,10 +325,10 @@ mandoc_msg(enum mandocerr t, int line, int col, const char *fmt, ...)
va_list ap;
enum mandoclevel level;
- if (t < min_type && t != MANDOCERR_FILE)
+ if (t < min_type)
return;
- level = MANDOCLEVEL_UNSUPP;
+ level = MANDOCLEVEL_SYSERR;
while (t < lowest_type[level])
level--;
mandoc_msg_setrc(level);
diff --git a/manpath.c b/manpath.c
index 703d6328..e4578cce 100644
--- a/manpath.c
+++ b/manpath.c
@@ -1,6 +1,6 @@
-/* $Id: manpath.c,v 1.39 2019/05/03 18:39:34 schwarze Exp $ */
+/* $Id: manpath.c,v 1.40 2019/07/10 19:39:01 schwarze Exp $ */
/*
- * Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011,2014,2015,2017-2019 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -21,20 +21,19 @@
#include <sys/stat.h>
#include <ctype.h>
-#if HAVE_ERR
-#include <err.h>
-#endif
+#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mandoc_aux.h"
+#include "mandoc.h"
#include "manconf.h"
static void manconf_file(struct manconf *, const char *);
-static void manpath_add(struct manpaths *, const char *, int);
-static void manpath_parseline(struct manpaths *, char *, int);
+static void manpath_add(struct manpaths *, const char *, char);
+static void manpath_parseline(struct manpaths *, char *, char);
void
@@ -44,11 +43,11 @@ manconf_parse(struct manconf *conf, const char *file,
char *insert;
/* Always prepend -m. */
- manpath_parseline(&conf->manpath, auxp, 1);
+ manpath_parseline(&conf->manpath, auxp, 'm');
/* If -M is given, it overrides everything else. */
if (NULL != defp) {
- manpath_parseline(&conf->manpath, defp, 1);
+ manpath_parseline(&conf->manpath, defp, 'M');
return;
}
@@ -66,13 +65,13 @@ manconf_parse(struct manconf *conf, const char *file,
/* Prepend man.conf(5) to MANPATH. */
if (':' == defp[0]) {
manconf_file(conf, file);
- manpath_parseline(&conf->manpath, defp, 0);
+ manpath_parseline(&conf->manpath, defp, '\0');
return;
}
/* Append man.conf(5) to MANPATH. */
if (':' == defp[strlen(defp) - 1]) {
- manpath_parseline(&conf->manpath, defp, 0);
+ manpath_parseline(&conf->manpath, defp, '\0');
manconf_file(conf, file);
return;
}
@@ -81,28 +80,28 @@ manconf_parse(struct manconf *conf, const char *file,
insert = strstr(defp, "::");
if (NULL != insert) {
*insert++ = '\0';
- manpath_parseline(&conf->manpath, defp, 0);
+ manpath_parseline(&conf->manpath, defp, '\0');
manconf_file(conf, file);
- manpath_parseline(&conf->manpath, insert + 1, 0);
+ manpath_parseline(&conf->manpath, insert + 1, '\0');
return;
}
/* MANPATH overrides man.conf(5) completely. */
- manpath_parseline(&conf->manpath, defp, 0);
+ manpath_parseline(&conf->manpath, defp, '\0');
}
void
manpath_base(struct manpaths *dirs)
{
char path_base[] = MANPATH_BASE;
- manpath_parseline(dirs, path_base, 0);
+ manpath_parseline(dirs, path_base, '\0');
}
/*
* Parse a FULL pathname from a colon-separated list of arrays.
*/
static void
-manpath_parseline(struct manpaths *dirs, char *path, int complain)
+manpath_parseline(struct manpaths *dirs, char *path, char option)
{
char *dir;
@@ -110,7 +109,7 @@ manpath_parseline(struct manpaths *dirs, char *path, int complain)
return;
for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":"))
- manpath_add(dirs, dir, complain);
+ manpath_add(dirs, dir, option);
}
/*
@@ -118,33 +117,32 @@ manpath_parseline(struct manpaths *dirs, char *path, int complain)
* Grow the array one-by-one for simplicity's sake.
*/
static void
-manpath_add(struct manpaths *dirs, const char *dir, int complain)
+manpath_add(struct manpaths *dirs, const char *dir, char option)
{
char buf[PATH_MAX];
struct stat sb;
char *cp;
size_t i;
- if (NULL == (cp = realpath(dir, buf))) {
- if (complain)
- warn("manpath: %s", dir);
- return;
- }
+ if ((cp = realpath(dir, buf)) == NULL)
+ goto fail;
for (i = 0; i < dirs->sz; i++)
- if (0 == strcmp(dirs->paths[i], dir))
+ if (strcmp(dirs->paths[i], dir) == 0)
return;
- if (stat(cp, &sb) == -1) {
- if (complain)
- warn("manpath: %s", dir);
- return;
- }
+ if (stat(cp, &sb) == -1)
+ goto fail;
dirs->paths = mandoc_reallocarray(dirs->paths,
- dirs->sz + 1, sizeof(char *));
-
+ dirs->sz + 1, sizeof(*dirs->paths));
dirs->paths[dirs->sz++] = mandoc_strdup(cp);
+ return;
+
+fail:
+ if (option != '\0')
+ mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0,
+ "-%c %s: %s", option, dir, strerror(errno));
}
void
@@ -210,7 +208,7 @@ manconf_file(struct manconf *conf, const char *file)
*ep = '\0';
/* FALLTHROUGH */
case 0: /* manpath */
- manpath_add(&conf->manpath, cp, 0);
+ manpath_add(&conf->manpath, cp, '\0');
*manpath_default = '\0';
break;
case 1: /* output */
@@ -225,7 +223,7 @@ manconf_file(struct manconf *conf, const char *file)
out:
if (*manpath_default != '\0')
- manpath_parseline(&conf->manpath, manpath_default, 0);
+ manpath_parseline(&conf->manpath, manpath_default, '\0');
}
int
@@ -243,7 +241,7 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
for (tok = 0; tok < ntoks; tok++) {
len = strlen(toks[tok]);
- if ( ! strncmp(cp, toks[tok], len) &&
+ if (strncmp(cp, toks[tok], len) == 0 &&
strchr(" = ", cp[len]) != NULL) {
cp += len;
if (*cp == '=')
@@ -255,11 +253,11 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
}
if (tok < 6 && *cp == '\0') {
- warnx("-O %s=?: Missing argument value", toks[tok]);
+ mandoc_msg(MANDOCERR_BADVAL_MISS, 0, 0, "-O %s=?", toks[tok]);
return -1;
}
if (tok > 6 && tok < ntoks && *cp != '\0') {
- warnx("-O %s: Does not take a value: %s", toks[tok], cp);
+ mandoc_msg(MANDOCERR_BADVAL, 0, 0, "-O %s=%s", toks[tok], cp);
return -1;
}
@@ -300,7 +298,8 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
conf->indent = strtonum(cp, 0, 1000, &errstr);
if (errstr == NULL)
return 0;
- warnx("-O indent=%s is %s", cp, errstr);
+ mandoc_msg(MANDOCERR_BADVAL_BAD, 0, 0,
+ "-O indent=%s is %s", cp, errstr);
return -1;
case 5:
if (conf->width) {
@@ -310,7 +309,8 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
conf->width = strtonum(cp, 1, 1000, &errstr);
if (errstr == NULL)
return 0;
- warnx("-O width=%s is %s", cp, errstr);
+ mandoc_msg(MANDOCERR_BADVAL_BAD, 0, 0,
+ "-O width=%s is %s", cp, errstr);
return -1;
case 6:
if (conf->tag != NULL) {
@@ -332,12 +332,16 @@ manconf_output(struct manoutput *conf, const char *cp, int fromfile)
conf->toc = 1;
return 0;
default:
- warnx("-O %s: Bad argument", cp);
+ mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0, "-O %s", cp);
+ return -1;
+ }
+ if (fromfile) {
+ free(oldval);
+ return 0;
+ } else {
+ mandoc_msg(MANDOCERR_BADVAL_DUPE, 0, 0,
+ "-O %s=%s: already set to %s", toks[tok], cp, oldval);
+ free(oldval);
return -1;
}
- if (fromfile == 0)
- warnx("-O %s=%s: Option already set to %s",
- toks[tok], cp, oldval);
- free(oldval);
- return -1;
}
diff --git a/read.c b/read.c
index 6c27a47a..b3858061 100644
--- a/read.c
+++ b/read.c
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.213 2019/06/03 19:58:02 schwarze Exp $ */
+/* $Id: read.c,v 1.214 2019/07/10 19:39:01 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org>
@@ -431,9 +431,8 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
int gzerrnum, retval;
if (fstat(fd, &st) == -1) {
- mandoc_msg(MANDOCERR_FILE, 0, 0,
- "fstat: %s", strerror(errno));
- return 0;
+ mandoc_msg(MANDOCERR_FSTAT, 0, 0, "%s", strerror(errno));
+ return -1;
}
/*
@@ -446,13 +445,13 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
if (curp->gzip == 0 && S_ISREG(st.st_mode)) {
if (st.st_size > 0x7fffffff) {
mandoc_msg(MANDOCERR_TOOLARGE, 0, 0, NULL);
- return 0;
+ return -1;
}
*with_mmap = 1;
fb->sz = (size_t)st.st_size;
fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0);
if (fb->buf != MAP_FAILED)
- return 1;
+ return 0;
}
if (curp->gzip) {
@@ -464,15 +463,15 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
* which this function must not do.
*/
if ((fd = dup(fd)) == -1) {
- mandoc_msg(MANDOCERR_FILE, 0, 0,
- "dup: %s", strerror(errno));
- return 0;
+ mandoc_msg(MANDOCERR_DUP, 0, 0,
+ "%s", strerror(errno));
+ return -1;
}
if ((gz = gzdopen(fd, "rb")) == NULL) {
- mandoc_msg(MANDOCERR_FILE, 0, 0,
- "gzdopen: %s", strerror(errno));
+ mandoc_msg(MANDOCERR_GZDOPEN, 0, 0,
+ "%s", strerror(errno));
close(fd);
- return 0;
+ return -1;
}
} else
gz = NULL;
@@ -484,7 +483,7 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
*with_mmap = 0;
off = 0;
- retval = 0;
+ retval = -1;
fb->sz = 0;
fb->buf = NULL;
for (;;) {
@@ -500,13 +499,13 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
read(fd, fb->buf + (int)off, fb->sz - off);
if (ssz == 0) {
fb->sz = off;
- retval = 1;
+ retval = 0;
break;
}
if (ssz == -1) {
if (curp->gzip)
(void)gzerror(gz, &gzerrnum);
- mandoc_msg(MANDOCERR_FILE, 0, 0, "read: %s",
+ mandoc_msg(MANDOCERR_READ, 0, 0, "%s",
curp->gzip && gzerrnum != Z_ERRNO ?
zError(gzerrnum) : strerror(errno));
break;
@@ -515,10 +514,10 @@ read_whole_file(struct mparse *curp, int fd, struct buf *fb, int *with_mmap)
}
if (curp->gzip && (gzerrnum = gzclose(gz)) != Z_OK)
- mandoc_msg(MANDOCERR_FILE, 0, 0, "gzclose: %s",
+ mandoc_msg(MANDOCERR_GZCLOSE, 0, 0, "%s",
gzerrnum == Z_ERRNO ? strerror(errno) :
zError(gzerrnum));
- if (retval == 0) {
+ if (retval == -1) {
free(fb->buf);
fb->buf = NULL;
}
@@ -557,7 +556,7 @@ mparse_readfd(struct mparse *curp, int fd, const char *filename)
mandoc_msg(MANDOCERR_ROFFLOOP, curp->line, 0, NULL);
return;
}
- if (read_whole_file(curp, fd, &blk, &with_mmap) == 0)
+ if (read_whole_file(curp, fd, &blk, &with_mmap) == -1)
return;
/*
diff --git a/tag.c b/tag.c
index 473ea7b6..4ba38241 100644
--- a/tag.c
+++ b/tag.c
@@ -1,6 +1,6 @@
-/* $Id: tag.c,v 1.21 2018/11/22 11:30:23 schwarze Exp $ */
+/* $Id: tag.c,v 1.22 2019/07/10 19:39:01 schwarze Exp $ */
/*
- * Copyright (c) 2015, 2016, 2018 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2015, 2016, 2018, 2019 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
@@ -18,9 +18,7 @@
#include <sys/types.h>
-#if HAVE_ERR
-#include <err.h>
-#endif
+#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stddef.h>
@@ -32,6 +30,7 @@
#include "mandoc_aux.h"
#include "mandoc_ohash.h"
+#include "mandoc.h"
#include "tag.h"
struct tag_entry {
@@ -83,8 +82,10 @@ tag_init(void)
/* Save the original standard output for use by the pager. */
- if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1)
+ if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1) {
+ mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
goto fail;
+ }
/* Create both temporary output files. */
@@ -92,12 +93,20 @@ tag_init(void)
sizeof(tag_files.ofn));
(void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",
sizeof(tag_files.tfn));
- if ((ofd = mkstemp(tag_files.ofn)) == -1)
+ if ((ofd = mkstemp(tag_files.ofn)) == -1) {
+ mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
+ "%s: %s", tag_files.ofn, strerror(errno));
goto fail;
- if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1)
+ }
+ if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1) {
+ mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
+ "%s: %s", tag_files.tfn, strerror(errno));
goto fail;
- if (dup2(ofd, STDOUT_FILENO) == -1)
+ }
+ if (dup2(ofd, STDOUT_FILENO) == -1) {
+ mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
goto fail;
+ }
close(ofd);
/*
@@ -221,10 +230,11 @@ tag_write(void)
return;
if (tag_files.tagname != NULL && ohash_find(&tag_data,
ohash_qlookup(&tag_data, tag_files.tagname)) == NULL) {
- warnx("%s: no such tag", tag_files.tagname);
+ mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", tag_files.tagname);
tag_files.tagname = NULL;
}
- stream = fdopen(tag_files.tfd, "w");
+ if ((stream = fdopen(tag_files.tfd, "w")) == NULL)
+ mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
entry = ohash_first(&tag_data, &slot);
while (entry != NULL) {
if (stream != NULL && entry->prio >= 0)