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

Diff for /mandoc/catman.c between version 1.13 and 1.19

version 1.13, 2017/02/04 12:03:07 version 1.19, 2017/02/16 15:12:32
Line 17 
Line 17 
  */   */
 #include "config.h"  #include "config.h"
   
   #if HAVE_CMSG_XPG42
   #define _XPG4_2
   #endif
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/stat.h>  #include <sys/stat.h>
Line 24 
Line 28 
 #if HAVE_ERR  #if HAVE_ERR
 #include <err.h>  #include <err.h>
 #endif  #endif
   #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #if HAVE_FTS  #if HAVE_FTS
 #include <fts.h>  #include <fts.h>
Line 33 
Line 38 
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   #include <time.h>
 #include <unistd.h>  #include <unistd.h>
   
   #ifndef O_DIRECTORY
   #define O_DIRECTORY 0
   #endif
   
 int      process_manpage(int, int, const char *);  int      process_manpage(int, int, const char *);
 int      process_tree(int, int);  int      process_tree(int, int);
 void     run_mandocd(int, const char *) __attribute__((noreturn));  void     run_mandocd(int, const char *, const char *)
                   __attribute__((noreturn));
 ssize_t  sock_fd_write(int, int, int, int);  ssize_t  sock_fd_write(int, int, int, int);
 void     usage(void) __attribute__((noreturn));  void     usage(void) __attribute__((noreturn));
   
   
 void  void
 run_mandocd(int sockfd, const char *outtype)  run_mandocd(int sockfd, const char *outtype, const char* defos)
 {  {
         char     sockfdstr[10];          char     sockfdstr[10];
   
         if (snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd) == -1)          if (snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd) == -1)
                 err(1, "snprintf");                  err(1, "snprintf");
         execlp("mandocd", "mandocd", "-T", outtype, sockfdstr, NULL);          if (defos == NULL)
                   execlp("mandocd", "mandocd", "-T", outtype,
                       sockfdstr, (char *)NULL);
           else
                   execlp("mandocd", "mandocd", "-T", outtype,
                       "-I", defos, sockfdstr, (char *)NULL);
         err(1, "exec");          err(1, "exec");
 }  }
   
 ssize_t  ssize_t
 sock_fd_write(int fd, int fd0, int fd1, int fd2)  sock_fd_write(int fd, int fd0, int fd1, int fd2)
 {  {
           const struct timespec timeout = { 0, 10000000 };  /* 0.01 s */
         struct msghdr    msg;          struct msghdr    msg;
         struct iovec     iov;          struct iovec     iov;
         union {          union {
Line 64  sock_fd_write(int fd, int fd0, int fd1, int fd2)
Line 81  sock_fd_write(int fd, int fd0, int fd1, int fd2)
         } cmsgu;          } cmsgu;
         struct cmsghdr  *cmsg;          struct cmsghdr  *cmsg;
         int             *walk;          int             *walk;
           ssize_t          sz;
         unsigned char    dummy[1] = {'\0'};          unsigned char    dummy[1] = {'\0'};
   
         iov.iov_base = dummy;          iov.iov_base = dummy;
Line 87  sock_fd_write(int fd, int fd0, int fd1, int fd2)
Line 105  sock_fd_write(int fd, int fd0, int fd1, int fd2)
         *(walk++) = fd1;          *(walk++) = fd1;
         *(walk++) = fd2;          *(walk++) = fd2;
   
         return sendmsg(fd, &msg, 0);          /*
            * It appears that on some systems, sendmsg(3)
            * may return EAGAIN even in blocking mode.
            * Seen for example on Oracle Solaris 11.2.
            * The sleeping time was chosen by experimentation,
            * to neither cause more than a handful of retries
            * in normal operation nor unnecessary delays.
            */
           for (;;) {
                   if ((sz = sendmsg(fd, &msg, 0)) != -1 ||
                       errno != EAGAIN)
                           break;
                   nanosleep(&timeout, NULL);
           }
           return sz;
 }  }
   
 int  int
 process_manpage(int srv_fd, int dstdir_fd, const char *path)  process_manpage(int srv_fd, int dstdir_fd, const char *path)
 {  {
         int      in_fd, out_fd;          int      in_fd, out_fd;
           int      irc;
   
         if ((in_fd = open(path, O_RDONLY)) == -1) {          if ((in_fd = open(path, O_RDONLY)) == -1) {
                 warn("open(%s)", path);                  warn("open(%s)", path);
                 return -1;                  return 0;
         }          }
   
         if ((out_fd = openat(dstdir_fd, path,          if ((out_fd = openat(dstdir_fd, path,
             O_WRONLY | O_NOFOLLOW | O_CREAT | O_TRUNC,              O_WRONLY | O_NOFOLLOW | O_CREAT | O_TRUNC,
             S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO)) == -1) {              S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
                 warn("openat(%s)", path);                  warn("openat(%s)", path);
                 close(in_fd);                  close(in_fd);
                 return -1;                  return 0;
         }          }
   
         if (sock_fd_write(srv_fd, in_fd, out_fd, STDERR_FILENO) < 0) {          irc = sock_fd_write(srv_fd, in_fd, out_fd, STDERR_FILENO);
                 warn("sendmsg");  
                 return -1;  
         }  
   
         close(in_fd);          close(in_fd);
         close(out_fd);          close(out_fd);
   
           if (irc < 0) {
                   warn("sendmsg");
                   return -1;
           }
         return 0;          return 0;
 }  }
   
Line 139  process_tree(int srv_fd, int dstdir_fd)
Line 174  process_tree(int srv_fd, int dstdir_fd)
                 path = entry->fts_path + 2;                  path = entry->fts_path + 2;
                 switch (entry->fts_info) {                  switch (entry->fts_info) {
                 case FTS_F:                  case FTS_F:
                         process_manpage(srv_fd, dstdir_fd, path);                          if (process_manpage(srv_fd, dstdir_fd, path) == -1) {
                                   fts_close(ftsp);
                                   return -1;
                           }
                         break;                          break;
                 case FTS_D:                  case FTS_D:
                           if (*path != '\0' &&
                               mkdirat(dstdir_fd, path, S_IRWXU | S_IRGRP |
                                 S_IXGRP | S_IROTH | S_IXOTH) == -1 &&
                               errno != EEXIST) {
                                   warn("mkdirat(%s)", path);
                                   (void)fts_set(ftsp, entry, FTS_SKIP);
                           }
                           break;
                 case FTS_DP:                  case FTS_DP:
                         break;                          break;
                 default:                  default:
Line 157  process_tree(int srv_fd, int dstdir_fd)
Line 203  process_tree(int srv_fd, int dstdir_fd)
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         const char      *outtype;          const char      *defos, *outtype;
         int              srv_fds[2];          int              srv_fds[2];
         int              dstdir_fd;          int              dstdir_fd;
         int              opt;          int              opt;
         pid_t            pid;          pid_t            pid;
   
           defos = NULL;
         outtype = "ascii";          outtype = "ascii";
         while ((opt = getopt(argc, argv, "T:")) != -1) {          while ((opt = getopt(argc, argv, "I:T:")) != -1) {
                 switch (opt) {                  switch (opt) {
                   case 'I':
                           defos = optarg;
                           break;
                 case 'T':                  case 'T':
                         outtype = optarg;                          outtype = optarg;
                         break;                          break;
Line 190  main(int argc, char **argv)
Line 240  main(int argc, char **argv)
                 err(1, "fork");                  err(1, "fork");
         case 0:          case 0:
                 close(srv_fds[0]);                  close(srv_fds[0]);
                 run_mandocd(srv_fds[1], outtype);                  run_mandocd(srv_fds[1], outtype, defos);
         default:          default:
                 break;                  break;
         }          }
Line 208  main(int argc, char **argv)
Line 258  main(int argc, char **argv)
 void  void
 usage(void)  usage(void)
 {  {
         fprintf(stderr, "usage: catman [-T output] srcdir dstdir\n");          fprintf(stderr, "usage: %s [-I os=name] [-T output] "
               "srcdir dstdir\n", BINM_CATMAN);
         exit(1);          exit(1);
 }  }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.19

CVSweb