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

Diff for /mandoc/term_tag.c between version 1.1 and 1.6

version 1.1, 2020/03/13 15:32:29 version 1.6, 2021/03/30 17:16:55
Line 22 
Line 22 
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <errno.h>  #include <errno.h>
   #include <fcntl.h>
 #include <signal.h>  #include <signal.h>
 #include <stddef.h>  #include <stddef.h>
 #include <stdio.h>  #include <stdio.h>
Line 31 
Line 32 
   
 #include "mandoc.h"  #include "mandoc.h"
 #include "roff.h"  #include "roff.h"
   #include "roff_int.h"
 #include "tag.h"  #include "tag.h"
 #include "term_tag.h"  #include "term_tag.h"
   
Line 45  static struct tag_files tag_files;
Line 47  static struct tag_files tag_files;
  * but for simplicity, create it anyway.   * but for simplicity, create it anyway.
  */   */
 struct tag_files *  struct tag_files *
 term_tag_init(char *tagname)  term_tag_init(const char *outfilename, const char *suffix,
       const char *tagfilename)
 {  {
         struct sigaction         sa;          struct sigaction         sa;
         int                      ofd;   /* In /tmp/, dup(2)ed to stdout. */          int                      ofd;   /* In /tmp/, dup(2)ed to stdout. */
Line 54  term_tag_init(char *tagname)
Line 57  term_tag_init(char *tagname)
         ofd = tfd = -1;          ofd = tfd = -1;
         tag_files.tfs = NULL;          tag_files.tfs = NULL;
         tag_files.tcpgid = -1;          tag_files.tcpgid = -1;
         tag_files.tagname = tagname;  
   
         /* Clean up when dying from a signal. */          /* Clean up when dying from a signal. */
   
Line 83  term_tag_init(char *tagname)
Line 85  term_tag_init(char *tagname)
   
         /* Create both temporary output files. */          /* Create both temporary output files. */
   
         (void)strlcpy(tag_files.ofn, "/tmp/man.XXXXXXXXXX",          if (outfilename == NULL) {
             sizeof(tag_files.ofn));                  (void)snprintf(tag_files.ofn, sizeof(tag_files.ofn),
         (void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",                      "/tmp/man.XXXXXXXXXX%s", suffix);
             sizeof(tag_files.tfn));                  if ((ofd = mkstemps(tag_files.ofn, strlen(suffix))) == -1) {
         if ((ofd = mkstemp(tag_files.ofn)) == -1) {                          mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
                 mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,                              "%s: %s", tag_files.ofn, strerror(errno));
                     "%s: %s", tag_files.ofn, strerror(errno));                          goto fail;
                 goto fail;                  }
           } else {
                   (void)strlcpy(tag_files.ofn, outfilename,
                      sizeof(tag_files.ofn));
                   unlink(outfilename);
                   ofd = open(outfilename, O_WRONLY | O_CREAT | O_EXCL, 0644);
                   if (ofd == -1) {
                           mandoc_msg(MANDOCERR_OPEN, 0, 0,
                               "%s: %s", outfilename, strerror(errno));
                           goto fail;
                   }
         }          }
         if ((tfd = mkstemp(tag_files.tfn)) == -1) {          if (tagfilename == NULL) {
                 mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,                  (void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX",
                     "%s: %s", tag_files.tfn, strerror(errno));                      sizeof(tag_files.tfn));
                 goto fail;                  if ((tfd = mkstemp(tag_files.tfn)) == -1) {
                           mandoc_msg(MANDOCERR_MKSTEMP, 0, 0,
                               "%s: %s", tag_files.tfn, strerror(errno));
                           goto fail;
                   }
           } else {
                   (void)strlcpy(tag_files.tfn, tagfilename,
                       sizeof(tag_files.tfn));
                   unlink(tagfilename);
                   tfd = open(tagfilename, O_WRONLY | O_CREAT | O_EXCL, 0644);
                   if (tfd == -1) {
                           mandoc_msg(MANDOCERR_OPEN, 0, 0,
                               "%s: %s", tagfilename, strerror(errno));
                           goto fail;
                   }
         }          }
         if ((tag_files.tfs = fdopen(tfd, "w")) == NULL) {          if ((tag_files.tfs = fdopen(tfd, "w")) == NULL) {
                 mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));                  mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno));
Line 119  fail:
Line 145  fail:
                 close(tag_files.ofd);                  close(tag_files.ofd);
                 tag_files.ofd = -1;                  tag_files.ofd = -1;
         }          }
         tag_files.tagname = NULL;  
         return NULL;          return NULL;
 }  }
   
Line 131  term_tag_write(struct roff_node *n, size_t line)
Line 156  term_tag_write(struct roff_node *n, size_t line)
   
         if (tag_files.tfs == NULL)          if (tag_files.tfs == NULL)
                 return;                  return;
         if (n->string == NULL)          cp = n->tag == NULL ? n->child->string : n->tag;
                 n = n->child;  
         cp = n->string;  
         if (cp[0] == '\\' && (cp[1] == '&' || cp[1] == 'e'))          if (cp[0] == '\\' && (cp[1] == '&' || cp[1] == 'e'))
                 cp += 2;                  cp += 2;
         len = strcspn(cp, " \t\\");          len = strcspn(cp, " \t\\");
Line 141  term_tag_write(struct roff_node *n, size_t line)
Line 164  term_tag_write(struct roff_node *n, size_t line)
             len, cp, tag_files.ofn, line);              len, cp, tag_files.ofn, line);
 }  }
   
 void  /*
 term_tag_finish(void)   * Close both output files and restore the original standard output
    * to the terminal.  In the unlikely case that the latter fails,
    * trying to start a pager would be useless, so report the failure
    * to the main program.
    */
   int
   term_tag_close(void)
 {  {
         if (tag_files.tfs == NULL)          int irc = 0;
                 return;  
         fclose(tag_files.tfs);          if (tag_files.tfs != NULL) {
         tag_files.tfs = NULL;                  fclose(tag_files.tfs);
         switch (tag_check(tag_files.tagname)) {                  tag_files.tfs = NULL;
         case TAG_EMPTY:  
                 unlink(tag_files.tfn);  
                 *tag_files.tfn = '\0';  
                 /* FALLTHROUGH */  
         case TAG_MISS:  
                 if (tag_files.tagname == NULL)  
                         break;  
                 mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", tag_files.tagname);  
                 tag_files.tagname = NULL;  
                 break;  
         case TAG_OK:  
                 break;  
         }          }
           if (tag_files.ofd != -1) {
                   fflush(stdout);
                   if ((irc = dup2(tag_files.ofd, STDOUT_FILENO)) == -1)
                           mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
                   close(tag_files.ofd);
                   tag_files.ofd = -1;
           }
           return irc;
 }  }
   
 void  void
Line 170  term_tag_unlink(void)
Line 195  term_tag_unlink(void)
         pid_t    tc_pgid;          pid_t    tc_pgid;
   
         if (tag_files.tcpgid != -1) {          if (tag_files.tcpgid != -1) {
                 tc_pgid = tcgetpgrp(tag_files.ofd);                  tc_pgid = tcgetpgrp(STDOUT_FILENO);
                 if (tc_pgid == tag_files.pager_pid ||                  if (tc_pgid == tag_files.pager_pid ||
                     tc_pgid == getpgid(0) ||                      tc_pgid == getpgid(0) ||
                     getpgid(tc_pgid) == -1)                      getpgid(tc_pgid) == -1)
                         (void)tcsetpgrp(tag_files.ofd, tag_files.tcpgid);                          (void)tcsetpgrp(STDOUT_FILENO, tag_files.tcpgid);
         }          }
         if (*tag_files.ofn != '\0') {          if (strncmp(tag_files.ofn, "/tmp/man.", 9) == 0) {
                 unlink(tag_files.ofn);                  unlink(tag_files.ofn);
                 *tag_files.ofn = '\0';                  *tag_files.ofn = '\0';
         }          }
         if (*tag_files.tfn != '\0') {          if (strncmp(tag_files.tfn, "/tmp/man.", 9) == 0) {
                 unlink(tag_files.tfn);                  unlink(tag_files.tfn);
                 *tag_files.tfn = '\0';                  *tag_files.tfn = '\0';
         }  
         if (tag_files.tfs != NULL) {  
                 fclose(tag_files.tfs);  
                 tag_files.tfs = NULL;  
         }          }
 }  }
   

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.6

CVSweb