Reorganize to be more like the BSD version + KNF
authormillert <millert@openbsd.org>
Thu, 2 Mar 2000 15:51:36 +0000 (15:51 +0000)
committermillert <millert@openbsd.org>
Thu, 2 Mar 2000 15:51:36 +0000 (15:51 +0000)
usr.bin/mg/ttyio.c

index 236c26e..166e9a8 100644 (file)
 #include       <termios.h>
 #include       <term.h>
 
-#define        NOBUF   512                     /* Output buffer size.          */
+#define NOBUF  512                     /* Output buffer size.          */
 
 #ifndef TCSASOFT
 #define TCSASOFT       0
 #endif
 
 char   obuf[NOBUF];                    /* Output buffer.               */
-int    nobuf;                          /* buffer count                 */
-
-static struct termios  ot;             /* entry state of the terminal  */
-static struct termios  nt;             /* editor's terminal state      */
-
-static int ttyactivep = FALSE;         /* terminal in editor mode?     */
-static int ttysavedp = FALSE;          /* terminal state saved?        */
-
+int    nobuf;                          /* Buffer count.                */
+struct termios oldtty;                 /* POSIX tty settings.          */
+struct termios newtty;
 int    nrow;                           /* Terminal size, rows.         */
 int    ncol;                           /* Terminal size, columns.      */
 
+/* XXX - move most of these to def.h? */
+void ttopen __P((void));
+int ttraw __P((void));
+void ttclose __P((void));
+int ttcooked __P((void));
+void ttputc __P((int));
+void ttflush __P((void));
+int ttgetc __P((void));
+void setttysize __P((void));
+int typeahead __P((void));
+void panic __P((char *));
+int ttwait __P((void));
+
 /*
- * This function gets called once, to set up
- * the terminal channel.  This version turns off flow
- * control.  This may be wrong for your system, but no
- * good solution has really been found (daveb).
+ * This function gets called once, to set up the terminal
+ * On systems w/o TCSASOFT we turn off off flow control,
+ * which isn't really the right thing to do.
  */
+void
 ttopen()
 {
-       register char   *cp;
-
-       if (ttyactivep)
-               return;
-
-       if( !ttysavedp )
-       {
-               if (tcgetattr(0, &ot) < 0)
-                       abort();
-               nt = ot;                /* save entry state             */
-               /* Set terminal to 'raw' mode and ignore a 'break' */
-               nt.c_cc[VMIN] = 1;
-               nt.c_cc[VTIME] = 0;
-               nt.c_iflag |= IGNBRK;
-               nt.c_iflag &= ~(BRKINT|PARMRK|INLCR|IGNCR|ICRNL|IXON);
-               nt.c_oflag &= ~OPOST;
-               nt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
 
-#if !TCSASOFT
-               /*
-                * If we don't have TCSASOFT, force terminal to
-                * 8 bits, no parity.
-                */
-               nt.c_iflag &= ~ISTRIP;
-               nt.c_cflag &= ~(CSIZE|PARENB);
-               nt.c_cflag |= CS8;
-#endif
+       if (ttraw() == FALSE)
+               panic("aborting due to terminal initialize failure");
+}
+
+/*
+ * This function sets the terminal to RAW mode, as defined for the current
+ * shell.  This is called both by ttopen() above and by spawncli() to
+ * get the current terminal settings and then change them to what
+ * mg expects. Thus, tty changes done while spawncli() is in effect
+ * will be reflected in mg.
+ */
+int
+ttraw()
+{
 
-               ttysavedp = TRUE;
+       if (tcgetattr(0, &oldtty) < 0) {
+               ewprintf("ttopen can't get terminal attributes");
+               return(FALSE);
        }
-       
-       if (tcsetattr(0, TCSASOFT | TCSADRAIN, &nt) < 0)
-               abort();
+       (void)memcpy(&newtty, &oldtty, sizeof(newtty));
+       /* Set terminal to 'raw' mode and ignore a 'break' */
+       newtty.c_cc[VMIN] = 1;
+       newtty.c_cc[VTIME] = 0;
+       newtty.c_iflag |= IGNBRK;
+       newtty.c_iflag &= ~(BRKINT | PARMRK | INLCR | IGNCR | ICRNL | IXON);
+       newtty.c_oflag &= ~OPOST;
+       newtty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
 
-       ttyactivep = TRUE;
+#if !TCSASOFT
+       /*
+        * If we don't have TCSASOFT, force terminal to
+        * 8 bits, no parity.
+        */
+       newtty.c_iflag &= ~ISTRIP;
+       newtty.c_cflag &= ~(CSIZE | PARENB);
+       newtty.c_cflag |= CS8;
+#endif
+       if (tcsetattr(0, TCSASOFT | TCSADRAIN, &newtty) < 0) {
+               ewprintf("ttopen can't tcsetattr");
+               return(FALSE);
+       }
 }
 
 /*
- * This function gets called just
- * before we go back home to the shell. Put all of
- * the terminal parameters back.
+ * This function gets called just before we go back home to the shell.
+ * Put all of the terminal parameters back.
+ * Under UN*X this just calls ttcooked(), but the ttclose() hook is in
+ * because vttidy() in display.c expects it for portability reasons.
  */
+void
 ttclose()
 {
-       if(!ttysavedp || !ttyactivep)
-               return;
+
+       if (ttcooked() == FALSE)
+               panic("");              /* ttcooked() already printf'd */
+}
+
+/*
+ * This function restores all terminal settings to their default values,
+ * in anticipation of exiting or suspending the editor.
+ */
+int
+ttcooked()
+{
+
        ttflush();
-       if (tcsetattr(0, TCSASOFT | TCSADRAIN, &ot) < 0)
-               abort();
-       ttyactivep = FALSE;
+       if (tcsetattr(0, TCSASOFT | TCSADRAIN, &oldtty) < 0) {
+               ewprintf("ttclose can't tcsetattr");
+               return(FALSE);
+       }
+       return(TRUE);
 }
 
 /*
- * Write character to the display.
- * Characters are buffered up, to make things
- * a little bit more efficient.
+ * Write character to the display.  Characters are buffered up,
+ * to make things a little bit more efficient.
  */
+void
 ttputc(c)
+       int c;
 {
 
        if (nobuf >= NOBUF)
@@ -109,11 +140,13 @@ ttputc(c)
 /*
  * Flush output.
  */
+void
 ttflush()
 {
 
        if (nobuf != 0) {
-               write(1, obuf, nobuf);
+               if (write(1, obuf, nobuf) != nobuf)
+                       panic("ttflush write failed");
                nobuf = 0;
        }
 }
@@ -122,61 +155,34 @@ ttflush()
  * Read character from terminal.
  * All 8 bits are returned, so that you can use
  * a multi-national terminal.
- *
- * If keyboard 'queue' already has typeahead from a typeahead() call,
- * just return it.  Otherwise, make sure we are in blocking i/o mode
- * and read a character.
  */
+int
 ttgetc()
 {
-       int    c;
+       char    buf[1];
 
-       while (read(0, &c, 1) != 1)
+       while (read(0, &buf[0], 1) != 1)
                ;
-       return (c & 0xFF);
-}
-
-/*
- * Return TRUE if there are characters waiting to be read.
- */
-typeahead()
-{
-       int x;
-
-       return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
+       return (buf[0] & 0xFF);
 }
 
-
 /*
- * panic:  print error and die, leaving core file.
- * Don't know why this is needed (daveb).
+ * Set the tty size.
+ * XXX - belongs in tty.c since it uses terminfo vars.
  */
-panic(s)
-char *s;
-{
-
-       (void) fputs("panic: ", stderr);
-       (void) fputs(s, stderr);
-       (void) fputc('\n', stderr);
-       abort();                /* To leave a core image. */
-}
-
-
-/*
-** This should check the size of the window, and reset if needed.
-*/
-
+void
 setttysize()
 {
 #ifdef TIOCGWINSZ
-        struct winsize winsize;
+       struct  winsize winsize;
 
        if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
                nrow = winsize.ws_row;
                ncol = winsize.ws_col;
-       } else
+       } else nrow = 0;
 #endif
-       if ((nrow = lines) <= 0 || (ncol = columns) <= 0) {
+       if ((nrow <= 0 || ncol <= 0) &&
+           ((nrow = lines) <= 0 || (ncol = columns) <= 0)) {
                nrow = 24;
                ncol = 80;
        }
@@ -188,23 +194,50 @@ setttysize()
                ncol = NCOL;
 }
 
+/*
+ * Returns TRUE if there are characters waiting to be read.
+ */
+int
+typeahead()
+{
+       int     x;
+
+       return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
+}
+
+/*
+ * panic - just exit, as quickly as we can.
+ */
+void
+panic(s)
+       char *s;
+{
+
+       (void) fputs("panic: ", stderr);
+       (void) fputs(s, stderr);
+       (void) fputc('\n', stderr);
+       abort();                /* To leave a core image. */
+}
+
 #ifndef NO_DPROMPT
 /*
- * Return TRUE if we wait without doing anything, else return FALSE.
+ * A program to return TRUE if we wait for 2 seconds without anything
+ * happening, else return FALSE.  Cribbed from mod.sources xmodem.
  */
+int
 ttwait()
 {
-       fd_set readfds;
-       struct timeval tmout;
+       fd_set          readfds;
+       struct timeval  tmout;
 
-       FD_ZERO(&readfds);
+       FD_ZERO(&readfds);   
        FD_SET(0, &readfds);
 
        tmout.tv_sec = 2;
        tmout.tv_usec = 0;
 
        if ((select(1, &readfds, NULL, NULL, &tmout)) == 0)
-               return(TRUE);
-       return(FALSE);
+               return (TRUE);
+       return (FALSE);
 }
-#endif NO_DPROMPT
+#endif /* NO_DPROMPT */