[BACK]Return to tty.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mail

Diff for /src/usr.bin/mail/tty.c between version 1.12 and 1.13

version 1.12, 2001/06/23 23:04:23 version 1.13, 2001/11/20 20:50:00
Line 51 
Line 51 
 #include "rcv.h"  #include "rcv.h"
 #include "extern.h"  #include "extern.h"
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
   #include <errno.h>
   
 static  cc_t            c_erase;        /* Current erase char */  static  cc_t            c_erase;        /* Current erase char */
 static  cc_t            c_kill;         /* Current kill char */  static  cc_t            c_kill;         /* Current kill char */
 static  sigjmp_buf      rewrite;        /* Place to go when continued */  
 static  sigjmp_buf      intjmp;         /* Place to go when interrupted */  
 #ifndef TIOCSTI  #ifndef TIOCSTI
 static  int             ttyset;         /* We must now do erase/kill */  static  int             ttyset;         /* We must now do erase/kill */
 #endif  #endif
   static  volatile sig_atomic_t   ttysignal;      /* Interrupted by a signal? */
   
 /*  /*
  * Read all relevant header fields.   * Read all relevant header fields.
Line 70 
Line 70 
         int gflags;          int gflags;
 {  {
         struct termios ttybuf;          struct termios ttybuf;
         volatile sig_t saveint;  
 #ifndef TIOCSTI  #ifndef TIOCSTI
         sig_t savequit;          struct sigaction savequit;
 #else  #else
 # ifdef TIOCEXT  # ifdef TIOCEXT
         volatile int extproc;          int extproc;
         int flag;          int flag;
 # endif /* TIOCEXT */  # endif /* TIOCEXT */
 #endif  #endif
         sig_t savetstp;          struct sigaction savetstp;
         sig_t savettou;          struct sigaction savettou;
         sig_t savettin;          struct sigaction savettin;
         volatile int errs = 0;          struct sigaction act;
           char *s;
           int error;
   
         savetstp = signal(SIGTSTP, SIG_DFL);          sigemptyset(&act.sa_mask);
         savettou = signal(SIGTTOU, SIG_DFL);          act.sa_flags = SA_RESTART;
         savettin = signal(SIGTTIN, SIG_DFL);          act.sa_handler = SIG_DFL;
         errs = 0;          (void)sigaction(SIGTSTP, &act, &savetstp);
           (void)sigaction(SIGTTOU, &act, &savettou);
           (void)sigaction(SIGTTIN, &act, &savettin);
           error = 1;
 #ifndef TIOCSTI  #ifndef TIOCSTI
         ttyset = 0;          ttyset = 0;
 #endif  #endif
Line 100 
Line 104 
 #ifndef TIOCSTI  #ifndef TIOCSTI
         ttybuf.c_cc[VERASE] = 0;          ttybuf.c_cc[VERASE] = 0;
         ttybuf.c_cc[VKILL] = 0;          ttybuf.c_cc[VKILL] = 0;
         if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL)          act.sa_handler = SIG_IGN;
                 (void)signal(SIGINT, SIG_DFL);          if (sigaction(SIGQUIT, &act, &savequit) == 0 &&
         if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)              savequit.sa_handler == SIG_DFL)
                 (void)signal(SIGQUIT, SIG_DFL);                  (void)sigaction(SIGQUIT, &savequit, NULL);
 #else  #else
 # ifdef TIOCEXT  # ifdef TIOCEXT
         extproc = ((ttybuf.c_lflag & EXTPROC) ? 1 : 0);          extproc = ((ttybuf.c_lflag & EXTPROC) ? 1 : 0);
Line 113 
Line 117 
                         warn("TIOCEXT: off");                          warn("TIOCEXT: off");
         }          }
 # endif /* TIOCEXT */  # endif /* TIOCEXT */
         if (sigsetjmp(intjmp, 1)) {  
                 errs = SIGINT;  
                 goto out;  
         }  
         saveint = signal(SIGINT, ttyint);  
 #endif  #endif
         if (gflags & GTO) {          if (gflags & GTO) {
 #ifndef TIOCSTI  #ifndef TIOCSTI
                 if (!ttyset && hp->h_to != NIL)                  if (!ttyset && hp->h_to != NIL)
                         ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);                          ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
 #endif  #endif
                 hp->h_to =                  s = readtty("To: ", detract(hp->h_to, 0));
                         extract(readtty("To: ", detract(hp->h_to, 0)), GTO);                  if (s == NULL)
                           goto out;
                   hp->h_to = extract(s, GTO);
         }          }
         if (gflags & GSUBJECT) {          if (gflags & GSUBJECT) {
 #ifndef TIOCSTI  #ifndef TIOCSTI
                 if (!ttyset && hp->h_subject != NULL)                  if (!ttyset && hp->h_subject != NULL)
                         ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);                          ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
 #endif  #endif
                 hp->h_subject = readtty("Subject: ", hp->h_subject);                  s = readtty("Subject: ", hp->h_subject);
                   if (s == NULL)
                           goto out;
                   hp->h_subject = s;
         }          }
         if (gflags & GCC) {          if (gflags & GCC) {
 #ifndef TIOCSTI  #ifndef TIOCSTI
                 if (!ttyset && hp->h_cc != NIL)                  if (!ttyset && hp->h_cc != NIL)
                         ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);                          ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
 #endif  #endif
                 hp->h_cc =                  s = readtty("Cc: ", detract(hp->h_cc, 0));
                         extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);                  if (s == NULL)
                           goto out;
                   hp->h_cc = extract(s, GCC);
         }          }
         if (gflags & GBCC) {          if (gflags & GBCC) {
 #ifndef TIOCSTI  #ifndef TIOCSTI
                 if (!ttyset && hp->h_bcc != NIL)                  if (!ttyset && hp->h_bcc != NIL)
                         ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);                          ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
 #endif  #endif
                 hp->h_bcc =                  s = readtty("Bcc: ", detract(hp->h_bcc, 0));
                         extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);                  if (s == NULL)
                           goto out;
                   hp->h_bcc = extract(s, GBCC);
         }          }
           error = 0;
 out:  out:
         (void)signal(SIGTSTP, savetstp);          (void)sigaction(SIGTSTP, &savetstp, NULL);
         (void)signal(SIGTTOU, savettou);          (void)sigaction(SIGTTOU, &savettou, NULL);
         (void)signal(SIGTTIN, savettin);          (void)sigaction(SIGTTIN, &savettin, NULL);
 #ifndef TIOCSTI  #ifndef TIOCSTI
         ttybuf.c_cc[VERASE] = c_erase;          ttybuf.c_cc[VERASE] = c_erase;
         ttybuf.c_cc[VKILL] = c_kill;          ttybuf.c_cc[VKILL] = c_kill;
         if (ttyset)          if (ttyset)
                 tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);                  tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
         (void)signal(SIGQUIT, savequit);          (void)sigaction(SIGQUIT, &savequit, NULL);
 #else  #else
 # ifdef TIOCEXT  # ifdef TIOCEXT
         if (extproc) {          if (extproc) {
Line 169 
Line 178 
         }          }
 # endif /* TIOCEXT */  # endif /* TIOCEXT */
 #endif  #endif
         (void)signal(SIGINT, saveint);          return(error);
         return(errs);  
 }  }
   
 /*  /*
Line 184 
Line 192 
 readtty(pr, src)  readtty(pr, src)
         char pr[], src[];          char pr[], src[];
 {  {
           struct sigaction act, oact;
           sigset_t oset;
         char ch, canonb[BUFSIZ];          char ch, canonb[BUFSIZ];
         volatile int c;          char *cp, *cp2;
         char *cp, * volatile cp2;          int c;
   
         fputs(pr, stdout);          fputs(pr, stdout);
         fflush(stdout);          fflush(stdout);
Line 219 
Line 229 
         while (cp2 < canonb + BUFSIZ)          while (cp2 < canonb + BUFSIZ)
                 *cp2++ = 0;                  *cp2++ = 0;
         cp2 = cp;          cp2 = cp;
         if (sigsetjmp(rewrite, 1))          sigemptyset(&act.sa_mask);
                 goto redo;          act.sa_flags = 0;               /* Note: will not restart syscalls */
         (void)signal(SIGTSTP, ttystop);          act.sa_handler = ttyint;
         (void)signal(SIGTTOU, ttystop);          (void)sigaction(SIGINT, &act, &oact);
         (void)signal(SIGTTIN, ttystop);          act.sa_handler = ttystop;
           (void)sigaction(SIGTSTP, &act, NULL);
           (void)sigaction(SIGTTOU, &act, NULL);
           (void)sigaction(SIGTTIN, &act, NULL);
           (void)sigprocmask(SIG_UNBLOCK, &intset, &oset);
         clearerr(stdin);          clearerr(stdin);
         while (cp2 < canonb + BUFSIZ) {          while (cp2 < canonb + BUFSIZ) {
                 c = getc(stdin);                  c = getc(stdin);
                   switch (ttysignal) {
                           case SIGINT:
                                   ttysignal = 0;
                                   cp2 = NULL;
                                   c = EOF;
                                   /* FALLTHROUGH */
                           case 0:
                                   break;
                           default:
                                   ttysignal = 0;
                                   goto redo;
                   }
                 if (c == EOF || c == '\n')                  if (c == EOF || c == '\n')
                         break;                          break;
                 *cp2++ = c;                  *cp2++ = c;
         }          }
         *cp2 = 0;          act.sa_handler = SIG_DFL;
         (void)signal(SIGTSTP, SIG_DFL);          sigemptyset(&act.sa_mask);
         (void)signal(SIGTTOU, SIG_DFL);          act.sa_flags = SA_RESTART;
         (void)signal(SIGTTIN, SIG_DFL);          (void)sigprocmask(SIG_SETMASK, &oset, NULL);
           (void)sigaction(SIGTSTP, &act, NULL);
           (void)sigaction(SIGTTOU, &act, NULL);
           (void)sigaction(SIGTTIN, &act, NULL);
           (void)sigaction(SIGTTIN, &oact, NULL);
           if (cp2 == NULL)
                   return(NULL);                   /* user hit ^C */
           *cp2 = '\0';
         if (c == EOF && ferror(stdin)) {          if (c == EOF && ferror(stdin)) {
 redo:  redo:
                 cp = strlen(canonb) > 0 ? canonb : NULL;                  cp = strlen(canonb) > 0 ? canonb : NULL;
                 clearerr(stdin);                  clearerr(stdin);
                   /* XXX - make iterative, not recursive */
                 return(readtty(pr, cp));                  return(readtty(pr, cp));
         }          }
 #ifndef TIOCSTI  #ifndef TIOCSTI
Line 274 
Line 308 
         *cp2 = '\0';          *cp2 = '\0';
 #endif  #endif
         if (equal("", canonb))          if (equal("", canonb))
                 return(NULL);                  return("");
         return(savestr(canonb));          return(savestr(canonb));
 }  }
   
Line 285 
Line 319 
 ttystop(s)  ttystop(s)
         int s;          int s;
 {  {
         sig_t old_action = signal(s, SIG_DFL);          struct sigaction act, oact;
         sigset_t nset;          sigset_t nset;
           int save_errno;
   
           /*
            * Save old handler and set to default.
            * Unblock receipt of 's' and then resend it.
            */
           save_errno = errno;
           (void)sigemptyset(&act.sa_mask);
           act.sa_flags = SA_RESTART;
           act.sa_handler = SIG_DFL;
           (void)sigaction(s, &act, &oact);
         (void)sigemptyset(&nset);          (void)sigemptyset(&nset);
         (void)sigaddset(&nset, s);          (void)sigaddset(&nset, s);
         (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);          (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
         (void)kill(0, s);          (void)kill(0, s);
         (void)sigprocmask(SIG_BLOCK, &nset, NULL);          (void)sigprocmask(SIG_BLOCK, &nset, NULL);
         (void)signal(s, old_action);          (void)sigaction(s, &oact, NULL);
         siglongjmp(rewrite, 1);          ttysignal = s;
           errno = save_errno;
 }  }
   
 /*ARGSUSED*/  /*ARGSUSED*/
Line 302 
Line 347 
 ttyint(s)  ttyint(s)
         int s;          int s;
 {  {
         siglongjmp(intjmp, 1);  
           ttysignal = s;
 }  }

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