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);