[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/main.c between version 1.250 and 1.258

version 1.250, 2015/10/19 19:51:22 version 1.258, 2015/11/14 23:57:47
Line 24 
Line 24 
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
   #if HAVE_ERR
 #include <err.h>  #include <err.h>
   #endif
   #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <glob.h>  #include <glob.h>
 #include <signal.h>  #include <signal.h>
Line 101  static int    toptions(struct curparse *, char *);
Line 104  static int    toptions(struct curparse *, char *);
 static  void              usage(enum argmode) __attribute__((noreturn));  static  void              usage(enum argmode) __attribute__((noreturn));
 static  int               woptions(struct curparse *, char *);  static  int               woptions(struct curparse *, char *);
   
 extern  char             *__progname;  
   
 static  const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};  static  const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
 static  char              help_arg[] = "help";  static  char              help_arg[] = "help";
 static  char             *help_argv[] = {help_arg, NULL};  static  char             *help_argv[] = {help_arg, NULL};
Line 116  main(int argc, char *argv[])
Line 117  main(int argc, char *argv[])
         struct curparse  curp;          struct curparse  curp;
         struct mansearch search;          struct mansearch search;
         struct tag_files *tag_files;          struct tag_files *tag_files;
           const char      *progname;
         char            *auxpaths;          char            *auxpaths;
         char            *defos;          char            *defos;
         unsigned char   *uc;          unsigned char   *uc;
Line 130  main(int argc, char *argv[])
Line 132  main(int argc, char *argv[])
         int              show_usage;          int              show_usage;
         int              options;          int              options;
         int              use_pager;          int              use_pager;
           int              status;
         int              c;          int              c;
           pid_t            pager_pid;
   
 #if !HAVE_PROGNAME  #if HAVE_PROGNAME
           progname = getprogname();
   #else
         if (argc < 1)          if (argc < 1)
                 __progname = mandoc_strdup("mandoc");                  progname = mandoc_strdup("mandoc");
         else if ((__progname = strrchr(argv[0], '/')) == NULL)          else if ((progname = strrchr(argv[0], '/')) == NULL)
                 __progname = argv[0];                  progname = argv[0];
         else          else
                 ++__progname;                  ++progname;
           setprogname(progname);
 #endif  #endif
   
 #if HAVE_SQLITE3  #if HAVE_SQLITE3
         if (strcmp(__progname, BINM_MAKEWHATIS) == 0)          if (strncmp(progname, "mandocdb", 8) == 0 ||
               strcmp(progname, BINM_MAKEWHATIS) == 0)
                 return mandocdb(argc, argv);                  return mandocdb(argc, argv);
 #endif  #endif
   
   #if HAVE_PLEDGE
           if (pledge("stdio rpath tmppath tty proc exec flock", NULL) == -1)
                   err((int)MANDOCLEVEL_SYSERR, "pledge");
   #endif
   
         /* Search options. */          /* Search options. */
   
         memset(&conf, 0, sizeof(conf));          memset(&conf, 0, sizeof(conf));
Line 155  main(int argc, char *argv[])
Line 168  main(int argc, char *argv[])
         memset(&search, 0, sizeof(struct mansearch));          memset(&search, 0, sizeof(struct mansearch));
         search.outkey = "Nd";          search.outkey = "Nd";
   
         if (strcmp(__progname, BINM_MAN) == 0)          if (strcmp(progname, BINM_MAN) == 0)
                 search.argmode = ARG_NAME;                  search.argmode = ARG_NAME;
         else if (strcmp(__progname, BINM_APROPOS) == 0)          else if (strcmp(progname, BINM_APROPOS) == 0)
                 search.argmode = ARG_EXPR;                  search.argmode = ARG_EXPR;
         else if (strcmp(__progname, BINM_WHATIS) == 0)          else if (strcmp(progname, BINM_WHATIS) == 0)
                 search.argmode = ARG_WORD;                  search.argmode = ARG_WORD;
         else if (strncmp(__progname, "help", 4) == 0)          else if (strncmp(progname, "help", 4) == 0)
                 search.argmode = ARG_NAME;                  search.argmode = ARG_NAME;
         else          else
                 search.argmode = ARG_FILE;                  search.argmode = ARG_FILE;
Line 285  main(int argc, char *argv[])
Line 298  main(int argc, char *argv[])
             !isatty(STDOUT_FILENO))              !isatty(STDOUT_FILENO))
                 use_pager = 0;                  use_pager = 0;
   
   #if HAVE_PLEDGE
           if (!use_pager && pledge("stdio rpath flock", NULL) == -1)
                   err((int)MANDOCLEVEL_SYSERR, "pledge");
   #endif
   
         /* Parse arguments. */          /* Parse arguments. */
   
         if (argc > 0) {          if (argc > 0) {
Line 299  main(int argc, char *argv[])
Line 317  main(int argc, char *argv[])
          */           */
   
         if (search.argmode == ARG_NAME) {          if (search.argmode == ARG_NAME) {
                 if (*__progname == 'h') {                  if (*progname == 'h') {
                         if (argc == 0) {                          if (argc == 0) {
                                 argv = help_argv;                                  argv = help_argv;
                                 argc = 1;                                  argc = 1;
Line 411  main(int argc, char *argv[])
Line 429  main(int argc, char *argv[])
   
         /* mandoc(1) */          /* mandoc(1) */
   
   #if HAVE_PLEDGE
           if (pledge(use_pager ? "stdio rpath tmppath tty proc exec" :
               "stdio rpath", NULL) == -1)
                   err((int)MANDOCLEVEL_SYSERR, "pledge");
   #endif
   
         if (search.argmode == ARG_FILE && ! moptions(&options, auxpaths))          if (search.argmode == ARG_FILE && ! moptions(&options, auxpaths))
                 return (int)MANDOCLEVEL_BADARG;                  return (int)MANDOCLEVEL_BADARG;
   
Line 466  main(int argc, char *argv[])
Line 490  main(int argc, char *argv[])
                         mparse_reset(curp.mp);                          mparse_reset(curp.mp);
         }          }
   
         switch (curp.outtype) {          if (curp.outdata != NULL) {
         case OUTT_HTML:                  switch (curp.outtype) {
                 html_free(curp.outdata);                  case OUTT_HTML:
                 break;                          html_free(curp.outdata);
         case OUTT_UTF8:                          break;
         case OUTT_LOCALE:                  case OUTT_UTF8:
         case OUTT_ASCII:                  case OUTT_LOCALE:
                 ascii_free(curp.outdata);                  case OUTT_ASCII:
                 break;                          ascii_free(curp.outdata);
         case OUTT_PDF:                          break;
         case OUTT_PS:                  case OUTT_PDF:
                 pspdf_free(curp.outdata);                  case OUTT_PS:
                 break;                          pspdf_free(curp.outdata);
         default:                          break;
                 break;                  default:
                           break;
                   }
         }          }
         mparse_free(curp.mp);          mparse_free(curp.mp);
         mchars_free();          mchars_free();
Line 504  out:
Line 530  out:
         if (tag_files != NULL) {          if (tag_files != NULL) {
                 fclose(stdout);                  fclose(stdout);
                 tag_write();                  tag_write();
                 waitpid(spawn_pager(tag_files), NULL, 0);                  pager_pid = spawn_pager(tag_files);
                   for (;;) {
                           if (waitpid(pager_pid, &status, WUNTRACED) == -1) {
                                   if (errno == EINTR)
                                           continue;
                                   warn("wait");
                                   rc = MANDOCLEVEL_SYSERR;
                                   break;
                           }
                           if (!WIFSTOPPED(status))
                                   break;
   
                           (void)tcsetpgrp(STDIN_FILENO, getpgid(0));
                           kill(0, WSTOPSIG(status));
   
                           /*
                            * I'm now stopped.
                            * When getting SIGCONT, continue here:
                            */
   
                           (void)tcsetpgrp(STDIN_FILENO, pager_pid);
                           kill(pager_pid, SIGCONT);
                   }
                 tag_unlink();                  tag_unlink();
         }          }
   
Line 589  fs_lookup(const struct manpaths *paths, size_t ipath,
Line 637  fs_lookup(const struct manpaths *paths, size_t ipath,
   
 found:  found:
 #if HAVE_SQLITE3  #if HAVE_SQLITE3
         warnx("outdated mandoc.db lacks %s(%s) entry, run makewhatis %s\n",          warnx("outdated mandoc.db lacks %s(%s) entry, run makewhatis %s",
             name, sec, paths->paths[ipath]);              name, sec, paths->paths[ipath]);
 #endif  #endif
         *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));          *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
Line 696  parse(struct curparse *curp, int fd, const char *file)
Line 744  parse(struct curparse *curp, int fd, const char *file)
         if (man == NULL)          if (man == NULL)
                 return;                  return;
         if (man->macroset == MACROSET_MDOC) {          if (man->macroset == MACROSET_MDOC) {
                   mdoc_validate(man);
                 switch (curp->outtype) {                  switch (curp->outtype) {
                 case OUTT_HTML:                  case OUTT_HTML:
                         html_mdoc(curp->outdata, man);                          html_mdoc(curp->outdata, man);
Line 718  parse(struct curparse *curp, int fd, const char *file)
Line 767  parse(struct curparse *curp, int fd, const char *file)
                 }                  }
         }          }
         if (man->macroset == MACROSET_MAN) {          if (man->macroset == MACROSET_MAN) {
                   man_validate(man);
                 switch (curp->outtype) {                  switch (curp->outtype) {
                 case OUTT_HTML:                  case OUTT_HTML:
                         html_man(curp->outdata, man);                          html_man(curp->outdata, man);
Line 749  passthrough(const char *file, int fd, int synopsis_onl
Line 799  passthrough(const char *file, int fd, int synopsis_onl
   
         FILE            *stream;          FILE            *stream;
         const char      *syscall;          const char      *syscall;
         char            *line;          char            *line, *cp;
         size_t           len, off;          size_t           linesz;
         ssize_t          nw;  
         int              print;          int              print;
   
         fflush(stdout);          line = NULL;
           linesz = 0;
   
         if ((stream = fdopen(fd, "r")) == NULL) {          if ((stream = fdopen(fd, "r")) == NULL) {
                 close(fd);                  close(fd);
Line 763  passthrough(const char *file, int fd, int synopsis_onl
Line 813  passthrough(const char *file, int fd, int synopsis_onl
         }          }
   
         print = 0;          print = 0;
         while ((line = fgetln(stream, &len)) != NULL) {          while (getline(&line, &linesz, stream) != -1) {
                   cp = line;
                 if (synopsis_only) {                  if (synopsis_only) {
                         if (print) {                          if (print) {
                                 if ( ! isspace((unsigned char)*line))                                  if ( ! isspace((unsigned char)*cp))
                                         goto done;                                          goto done;
                                 while (len &&                                  while (isspace((unsigned char)*cp))
                                     isspace((unsigned char)*line)) {                                          cp++;
                                         line++;  
                                         len--;  
                                 }  
                         } else {                          } else {
                                 if ((len == sizeof(synb) &&                                  if (strcmp(cp, synb) == 0 ||
                                      ! strncmp(line, synb, len - 1)) ||                                      strcmp(cp, synr) == 0)
                                     (len == sizeof(synr) &&  
                                      ! strncmp(line, synr, len - 1)))  
                                         print = 1;                                          print = 1;
                                 continue;                                  continue;
                         }                          }
                 }                  }
                 for (off = 0; off < len; off += nw)                  if (fputs(cp, stdout)) {
                         if ((nw = write(STDOUT_FILENO, line + off,                          fclose(stream);
                             len - off)) == -1 || nw == 0) {                          syscall = "fputs";
                                 fclose(stream);                          goto fail;
                                 syscall = "write";                  }
                                 goto fail;  
                         }  
         }          }
   
         if (ferror(stream)) {          if (ferror(stream)) {
                 fclose(stream);                  fclose(stream);
                 syscall = "fgetln";                  syscall = "getline";
                 goto fail;                  goto fail;
         }          }
   
 done:  done:
           free(line);
         fclose(stream);          fclose(stream);
         return;          return;
   
 fail:  fail:
           free(line);
         warn("%s: SYSERR: %s", file, syscall);          warn("%s: SYSERR: %s", file, syscall);
         if (rc < MANDOCLEVEL_SYSERR)          if (rc < MANDOCLEVEL_SYSERR)
                 rc = MANDOCLEVEL_SYSERR;                  rc = MANDOCLEVEL_SYSERR;
Line 927  mmsg(enum mandocerr t, enum mandoclevel lvl,
Line 973  mmsg(enum mandocerr t, enum mandoclevel lvl,
 {  {
         const char      *mparse_msg;          const char      *mparse_msg;
   
         fprintf(stderr, "%s: %s:", __progname, file);          fprintf(stderr, "%s: %s:", getprogname(), file);
   
         if (line)          if (line)
                 fprintf(stderr, "%d:%d:", line, col + 1);                  fprintf(stderr, "%d:%d:", line, col + 1);
Line 995  spawn_pager(struct tag_files *tag_files)
Line 1041  spawn_pager(struct tag_files *tag_files)
         case -1:          case -1:
                 err((int)MANDOCLEVEL_SYSERR, "fork");                  err((int)MANDOCLEVEL_SYSERR, "fork");
         case 0:          case 0:
                   /* Set pgrp in both parent and child to avoid racing exec. */
                   (void)setpgid(0, 0);
                 break;                  break;
         default:          default:
                   (void)setpgid(pager_pid, 0);
                   if (tcsetpgrp(STDIN_FILENO, pager_pid) == -1)
                           err((int)MANDOCLEVEL_SYSERR, "tcsetpgrp");
   #if HAVE_PLEDGE
                   if (pledge("stdio rpath tmppath tty proc", NULL) == -1)
                           err((int)MANDOCLEVEL_SYSERR, "pledge");
   #endif
                 return pager_pid;                  return pager_pid;
         }          }
   

Legend:
Removed from v.1.250  
changed lines
  Added in v.1.258

CVSweb