Print this page
9718 update mandoc to 1.14.4

*** 1,9 **** ! /* $Id: main.c,v 1.301 2017/07/26 10:21:55 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> ! * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. --- 1,9 ---- ! /* $Id: main.c,v 1.306 2018/05/14 14:10:23 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> ! * Copyright (c) 2010-2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies.
*** 17,27 **** --- 17,29 ---- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "config.h" #include <sys/types.h> + #include <sys/ioctl.h> #include <sys/param.h> /* MACHINE */ + #include <sys/termios.h> #include <sys/wait.h> #include <assert.h> #include <ctype.h> #if HAVE_ERR
*** 118,137 **** main(int argc, char *argv[]) { struct manconf conf; struct mansearch search; struct curparse curp; struct tag_files *tag_files; struct manpage *res, *resp; const char *progname, *sec, *thisarg; char *conf_file, *defpaths, *auxpaths; char *oarg; unsigned char *uc; size_t i, sz; int prio, best_prio; enum outmode outmode; ! int fd; int show_usage; int options; int use_pager; int status, signum; int c; --- 120,140 ---- main(int argc, char *argv[]) { struct manconf conf; struct mansearch search; struct curparse curp; + struct winsize ws; struct tag_files *tag_files; struct manpage *res, *resp; const char *progname, *sec, *thisarg; char *conf_file, *defpaths, *auxpaths; char *oarg; unsigned char *uc; size_t i, sz; int prio, best_prio; enum outmode outmode; ! int fd, startdir; int show_usage; int options; int use_pager; int status, signum; int c;
*** 314,323 **** --- 317,336 ---- if (outmode == OUTMODE_FLN || outmode == OUTMODE_LST || !isatty(STDOUT_FILENO)) use_pager = 0; + if (use_pager && + (conf.output.width == 0 || conf.output.indent == 0) && + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && + ws.ws_col > 1) { + if (conf.output.width == 0 && ws.ws_col < 79) + conf.output.width = ws.ws_col - 1; + if (conf.output.indent == 0 && ws.ws_col < 66) + conf.output.indent = 3; + } + #if HAVE_PLEDGE if (!use_pager) if (pledge("stdio rpath", NULL) == -1) err((int)MANDOCLEVEL_SYSERR, "pledge"); #endif
*** 372,390 **** manconf_parse(&conf, conf_file, defpaths, auxpaths); if ( ! mansearch(&search, &conf.manpath, argc, argv, &res, &sz)) usage(search.argmode); ! if (sz == 0) { ! if (search.argmode == ARG_NAME) fs_search(&search, &conf.manpath, argc, argv, &res, &sz); ! else ! warnx("nothing appropriate"); } if (sz == 0) { rc = MANDOCLEVEL_BADARG; goto out; } /* --- 385,422 ---- manconf_parse(&conf, conf_file, defpaths, auxpaths); if ( ! mansearch(&search, &conf.manpath, argc, argv, &res, &sz)) usage(search.argmode); ! if (sz == 0 && search.argmode == ARG_NAME) fs_search(&search, &conf.manpath, argc, argv, &res, &sz); ! ! if (search.argmode == ARG_NAME) { ! for (c = 0; c < argc; c++) { ! if (strchr(argv[c], '/') == NULL) ! continue; ! if (access(argv[c], R_OK) == -1) { ! warn("%s", argv[c]); ! continue; } + res = mandoc_reallocarray(res, + sz + 1, sizeof(*res)); + res[sz].file = mandoc_strdup(argv[c]); + res[sz].names = NULL; + res[sz].output = NULL; + res[sz].ipath = SIZE_MAX; + res[sz].bits = 0; + res[sz].sec = 10; + res[sz].form = FORM_SRC; + sz++; + } + } if (sz == 0) { + if (search.argmode != ARG_NAME) + warnx("nothing appropriate"); rc = MANDOCLEVEL_BADARG; goto out; } /*
*** 464,491 **** if (use_pager) tag_files = tag_init(); parse(&curp, STDIN_FILENO, "<stdin>"); } while (argc > 0) { fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv); if (fd != -1) { if (use_pager) { tag_files = tag_init(); use_pager = 0; } if (resp == NULL) parse(&curp, fd, *argv); ! else if (resp->form == FORM_SRC) { ! /* For .so only; ignore failure. */ ! (void)chdir(conf.manpath.paths[resp->ipath]); parse(&curp, fd, resp->file); ! } else passthrough(resp->file, fd, conf.output.synopsisonly); if (argc > 1 && curp.outtype <= OUTT_UTF8) { if (curp.outdata == NULL) outdata_alloc(&curp); terminal_sepline(curp.outdata); } --- 496,554 ---- if (use_pager) tag_files = tag_init(); parse(&curp, STDIN_FILENO, "<stdin>"); } + /* + * Remember the original working directory, if possible. + * This will be needed if some names on the command line + * are page names and some are relative file names. + * Do not error out if the current directory is not + * readable: Maybe it won't be needed after all. + */ + startdir = open(".", O_RDONLY | O_DIRECTORY); + while (argc > 0) { + + /* + * Changing directories is not needed in ARG_FILE mode. + * Do it on a best-effort basis. Even in case of + * failure, some functionality may still work. + */ + if (resp != NULL) { + if (resp->ipath != SIZE_MAX) + (void)chdir(conf.manpath.paths[resp->ipath]); + else if (startdir != -1) + (void)fchdir(startdir); + } + fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv); if (fd != -1) { if (use_pager) { tag_files = tag_init(); use_pager = 0; } if (resp == NULL) parse(&curp, fd, *argv); ! else if (resp->form == FORM_SRC) parse(&curp, fd, resp->file); ! else passthrough(resp->file, fd, conf.output.synopsisonly); + if (ferror(stdout)) { + if (tag_files != NULL) { + warn("%s", tag_files->ofn); + tag_unlink(); + tag_files = NULL; + } else + warn("stdout"); + rc = MANDOCLEVEL_SYSERR; + break; + } + if (argc > 1 && curp.outtype <= OUTT_UTF8) { if (curp.outdata == NULL) outdata_alloc(&curp); terminal_sepline(curp.outdata); }
*** 500,509 **** --- 563,576 ---- else argv++; if (--argc) mparse_reset(curp.mp); } + if (startdir != -1) { + (void)fchdir(startdir); + close(startdir); + } if (curp.outdata != NULL) { switch (curp.outtype) { case OUTT_HTML: html_free(curp.outdata);
*** 720,730 **** if (fs_lookup(paths, ipath, sections[isec], cfg->arch, *argv, res, ressz) && cfg->firstmatch) return 1; } ! if (res != NULL && *ressz == lastsz) warnx("No entry for %s in the manual.", *argv); lastsz = *ressz; argv++; argc--; } --- 787,798 ---- if (fs_lookup(paths, ipath, sections[isec], cfg->arch, *argv, res, ressz) && cfg->firstmatch) return 1; } ! if (res != NULL && *ressz == lastsz && ! strchr(*argv, '/') == NULL) warnx("No entry for %s in the manual.", *argv); lastsz = *ressz; argv++; argc--; }
*** 1171,1181 **** /* The child process becomes the pager. */ if (dup2(tag_files->ofd, STDOUT_FILENO) == -1) err((int)MANDOCLEVEL_SYSERR, "pager stdout"); close(tag_files->ofd); ! close(tag_files->tfd); /* Do not start the pager before controlling the terminal. */ while (tcgetpgrp(STDOUT_FILENO) != getpid()) nanosleep(&timeout, NULL); --- 1239,1249 ---- /* The child process becomes the pager. */ if (dup2(tag_files->ofd, STDOUT_FILENO) == -1) err((int)MANDOCLEVEL_SYSERR, "pager stdout"); close(tag_files->ofd); ! assert(tag_files->tfd == -1); /* Do not start the pager before controlling the terminal. */ while (tcgetpgrp(STDOUT_FILENO) != getpid()) nanosleep(&timeout, NULL);