4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / usr.bin / mail / tty.c
index 5b7aded..6a77724 100644 (file)
@@ -1,6 +1,13 @@
+/*
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)tty.c      2.7 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)tty.c      8.1 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * Mail -- a mail program
 
 /*
  * Mail -- a mail program
@@ -9,11 +16,12 @@ static char sccsid[] = "@(#)tty.c    2.7 (Berkeley) %G%";
  */
 
 #include "rcv.h"
  */
 
 #include "rcv.h"
+#include "extern.h"
 
 static int     c_erase;                /* Current erase char */
 static int     c_kill;                 /* Current kill char */
 
 static int     c_erase;                /* Current erase char */
 static int     c_kill;                 /* Current kill char */
-static int     hadcont;                /* Saw continue signal */
 static jmp_buf rewrite;                /* Place to go when continued */
 static jmp_buf rewrite;                /* Place to go when continued */
+static jmp_buf intjmp;                 /* Place to go when interrupted */
 #ifndef TIOCSTI
 static int     ttyset;                 /* We must now do erase/kill */
 #endif
 #ifndef TIOCSTI
 static int     ttyset;                 /* We must now do erase/kill */
 #endif
@@ -22,26 +30,30 @@ static      int     ttyset;                 /* We must now do erase/kill */
  * Read all relevant header fields.
  */
 
  * Read all relevant header fields.
  */
 
+int
 grabh(hp, gflags)
        struct header *hp;
 grabh(hp, gflags)
        struct header *hp;
+       int gflags;
 {
        struct sgttyb ttybuf;
 {
        struct sgttyb ttybuf;
-       int ttycont(), signull();
+       sig_t saveint;
 #ifndef TIOCSTI
 #ifndef TIOCSTI
-       int (*savesigs[2])();
+       sig_t savequit;
 #endif
 #endif
-       int (*savecont)();
-       register int s;
+       sig_t savetstp;
+       sig_t savettou;
+       sig_t savettin;
        int errs;
        int errs;
+       void ttyint();
 
 
-# ifdef VMUNIX
-       savecont = sigset(SIGCONT, signull);
-# endif VMUNIX
+       savetstp = signal(SIGTSTP, SIG_DFL);
+       savettou = signal(SIGTTOU, SIG_DFL);
+       savettin = signal(SIGTTIN, SIG_DFL);
        errs = 0;
 #ifndef TIOCSTI
        ttyset = 0;
 #endif
        errs = 0;
 #ifndef TIOCSTI
        ttyset = 0;
 #endif
-       if (gtty(fileno(stdin), &ttybuf) < 0) {
+       if (ioctl(fileno(stdin), TIOCGETP, &ttybuf) < 0) {
                perror("gtty");
                return(-1);
        }
                perror("gtty");
                return(-1);
        }
@@ -50,18 +62,22 @@ grabh(hp, gflags)
 #ifndef TIOCSTI
        ttybuf.sg_erase = 0;
        ttybuf.sg_kill = 0;
 #ifndef TIOCSTI
        ttybuf.sg_erase = 0;
        ttybuf.sg_kill = 0;
-       for (s = SIGINT; s <= SIGQUIT; s++)
-               if ((savesigs[s-SIGINT] = sigset(s, SIG_IGN)) == SIG_DFL)
-                       sigset(s, SIG_DFL);
+       if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL)
+               signal(SIGINT, SIG_DFL);
+       if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
+               signal(SIGQUIT, SIG_DFL);
+#else
+       if (setjmp(intjmp))
+               goto out;
+       saveint = signal(SIGINT, ttyint);
 #endif
        if (gflags & GTO) {
 #ifndef TIOCSTI
 #endif
        if (gflags & GTO) {
 #ifndef TIOCSTI
-               if (!ttyset && hp->h_to != NOSTR)
+               if (!ttyset && hp->h_to != NIL)
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
-               hp->h_to = readtty("To: ", hp->h_to);
-               if (hp->h_to != NOSTR)
-                       hp->h_seq++;
+               hp->h_to =
+                       extract(readtty("To: ", detract(hp->h_to, 0)), GTO);
        }
        if (gflags & GSUBJECT) {
 #ifndef TIOCSTI
        }
        if (gflags & GSUBJECT) {
 #ifndef TIOCSTI
@@ -69,38 +85,35 @@ grabh(hp, gflags)
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
                hp->h_subject = readtty("Subject: ", hp->h_subject);
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
                hp->h_subject = readtty("Subject: ", hp->h_subject);
-               if (hp->h_subject != NOSTR)
-                       hp->h_seq++;
        }
        if (gflags & GCC) {
 #ifndef TIOCSTI
        }
        if (gflags & GCC) {
 #ifndef TIOCSTI
-               if (!ttyset && hp->h_cc != NOSTR)
+               if (!ttyset && hp->h_cc != NIL)
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
-               hp->h_cc = readtty("Cc: ", hp->h_cc);
-               if (hp->h_cc != NOSTR)
-                       hp->h_seq++;
+               hp->h_cc =
+                       extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);
        }
        if (gflags & GBCC) {
 #ifndef TIOCSTI
        }
        if (gflags & GBCC) {
 #ifndef TIOCSTI
-               if (!ttyset && hp->h_bcc != NOSTR)
+               if (!ttyset && hp->h_bcc != NIL)
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
                        ttyset++, stty(fileno(stdin), &ttybuf);
 #endif
-               hp->h_bcc = readtty("Bcc: ", hp->h_bcc);
-               if (hp->h_bcc != NOSTR)
-                       hp->h_seq++;
+               hp->h_bcc =
+                       extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);
        }
        }
-# ifdef VMUNIX
-       sigset(SIGCONT, savecont);
-# endif VMUNIX
+out:
+       signal(SIGTSTP, savetstp);
+       signal(SIGTTOU, savettou);
+       signal(SIGTTIN, savettin);
 #ifndef TIOCSTI
        ttybuf.sg_erase = c_erase;
        ttybuf.sg_kill = c_kill;
        if (ttyset)
                stty(fileno(stdin), &ttybuf);
 #ifndef TIOCSTI
        ttybuf.sg_erase = c_erase;
        ttybuf.sg_kill = c_kill;
        if (ttyset)
                stty(fileno(stdin), &ttybuf);
-       for (s = SIGINT; s <= SIGQUIT; s++)
-               sigset(s, savesigs[s-SIGINT]);
+       signal(SIGQUIT, savequit);
 #endif
 #endif
+       signal(SIGINT, saveint);
        return(errs);
 }
 
        return(errs);
 }
 
@@ -116,8 +129,9 @@ readtty(pr, src)
        char pr[], src[];
 {
        char ch, canonb[BUFSIZ];
        char pr[], src[];
 {
        char ch, canonb[BUFSIZ];
-       int c, signull();
+       int c;
        register char *cp, *cp2;
        register char *cp, *cp2;
+       void ttystop();
 
        fputs(pr, stdout);
        fflush(stdout);
 
        fputs(pr, stdout);
        fflush(stdout);
@@ -151,9 +165,9 @@ readtty(pr, src)
        cp2 = cp;
        if (setjmp(rewrite))
                goto redo;
        cp2 = cp;
        if (setjmp(rewrite))
                goto redo;
-# ifdef VMUNIX
-       sigset(SIGCONT, ttycont);
-# endif VMUNIX
+       signal(SIGTSTP, ttystop);
+       signal(SIGTTOU, ttystop);
+       signal(SIGTTIN, ttystop);
        clearerr(stdin);
        while (cp2 < canonb + BUFSIZ) {
                c = getc(stdin);
        clearerr(stdin);
        while (cp2 < canonb + BUFSIZ) {
                c = getc(stdin);
@@ -162,12 +176,11 @@ readtty(pr, src)
                *cp2++ = c;
        }
        *cp2 = 0;
                *cp2++ = c;
        }
        *cp2 = 0;
-# ifdef VMUNIX
-       sigset(SIGCONT, signull);
-# endif VMUNIX
-       if (c == EOF && ferror(stdin) && hadcont) {
+       signal(SIGTSTP, SIG_DFL);
+       signal(SIGTTOU, SIG_DFL);
+       signal(SIGTTIN, SIG_DFL);
+       if (c == EOF && ferror(stdin)) {
 redo:
 redo:
-               hadcont = 0;
                cp = strlen(canonb) > 0 ? canonb : NOSTR;
                clearerr(stdin);
                return(readtty(pr, cp));
                cp = strlen(canonb) > 0 ? canonb : NOSTR;
                clearerr(stdin);
                return(readtty(pr, cp));
@@ -209,21 +222,26 @@ redo:
        return(savestr(canonb));
 }
 
        return(savestr(canonb));
 }
 
-# ifdef VMUNIX
 /*
  * Receipt continuation.
  */
 /*
  * Receipt continuation.
  */
-ttycont(s)
+void
+ttystop(s)
+       int s;
 {
 {
+       sig_t old_action = signal(s, SIG_DFL);
 
 
-       hadcont++;
+       sigsetmask(sigblock(0) & ~sigmask(s));
+       kill(0, s);
+       sigblock(sigmask(s));
+       signal(s, old_action);
        longjmp(rewrite, 1);
 }
        longjmp(rewrite, 1);
 }
-# endif VMUNIX
 
 
-/*
- * Null routine to satisfy
- * silly system bug that denies us holding SIGCONT
- */
-signull(s)
-{}
+/*ARGSUSED*/
+void
+ttyint(s)
+       int s;
+{
+       longjmp(intjmp, 1);
+}