root/kern/tty.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ttyopen
  2. ttyclose
  3. ttyinput
  4. ttyoutput
  5. ttioctl
  6. ttpoll
  7. ttkqfilter
  8. filt_ttyrdetach
  9. filt_ttyread
  10. filt_ttywdetach
  11. filt_ttywrite
  12. ttnread
  13. ttywait
  14. ttywflush
  15. ttyflush
  16. ttychars
  17. ttyblock
  18. ttrstrt
  19. ttstart
  20. ttylclose
  21. ttymodem
  22. nullmodem
  23. ttypend
  24. ttvtimeout
  25. ttread
  26. ttyunblock
  27. ttycheckoutq
  28. ttwrite
  29. ttyrub
  30. ttyrubo
  31. ttyretype
  32. ttyecho
  33. ttwakeup
  34. ttspeedtab
  35. ttsetwater
  36. ttyinfo
  37. proc_compare
  38. tputchar
  39. ttysleep
  40. tty_init
  41. ttymalloc
  42. ttyfree
  43. ttystats_init
  44. sysctl_tty
  45. ttytstamp

    1 /*      $OpenBSD: tty.c,v 1.72 2007/03/15 10:22:30 art Exp $    */
    2 /*      $NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $     */
    3 
    4 /*-
    5  * Copyright (c) 1982, 1986, 1990, 1991, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  *      @(#)tty.c       8.8 (Berkeley) 1/21/94
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/ioctl.h>
   43 #include <sys/proc.h>
   44 #define TTYDEFCHARS
   45 #include <sys/tty.h>
   46 #undef  TTYDEFCHARS
   47 #include <sys/file.h>
   48 #include <sys/conf.h>
   49 #include <sys/dkstat.h>
   50 #include <sys/uio.h>
   51 #include <sys/kernel.h>
   52 #include <sys/vnode.h>
   53 #include <sys/syslog.h>
   54 #include <sys/malloc.h>
   55 #include <sys/signalvar.h>
   56 #include <sys/resourcevar.h>
   57 #include <sys/sysctl.h>
   58 #include <sys/pool.h>
   59 #include <sys/poll.h>
   60 
   61 #include <sys/namei.h>
   62 
   63 #include <uvm/uvm_extern.h>
   64 #include <dev/rndvar.h>
   65 
   66 #include "pty.h"
   67 
   68 static int ttnread(struct tty *);
   69 static void ttyblock(struct tty *);
   70 void ttyunblock(struct tty *);
   71 static void ttyecho(int, struct tty *);
   72 static void ttyrubo(struct tty *, int);
   73 static int proc_compare(struct proc *, struct proc *);
   74 int     filt_ttyread(struct knote *kn, long hint);
   75 void    filt_ttyrdetach(struct knote *kn);
   76 int     filt_ttywrite(struct knote *kn, long hint);
   77 void    filt_ttywdetach(struct knote *kn);
   78 int     ttystats_init(void);
   79 
   80 /* Symbolic sleep message strings. */
   81 char ttclos[]   = "ttycls";
   82 char ttopen[]   = "ttyopn";
   83 char ttybg[]    = "ttybg";
   84 char ttyin[]    = "ttyin";
   85 char ttyout[]   = "ttyout";
   86 
   87 /*
   88  * Table with character classes and parity. The 8th bit indicates parity,
   89  * the 7th bit indicates the character is an alphameric or underscore (for
   90  * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
   91  * are 0 then the character needs no special processing on output; classes
   92  * other than 0 might be translated or (not currently) require delays.
   93  */
   94 #define E       0x00    /* Even parity. */
   95 #define O       0x80    /* Odd parity. */
   96 #define PARITY(c)       (char_type[c] & O)
   97 
   98 #define ALPHA   0x40    /* Alpha or underscore. */
   99 #define ISALPHA(c)      (char_type[(c) & TTY_CHARMASK] & ALPHA)
  100 
  101 #define CCLASSMASK      0x3f
  102 #define CCLASS(c)       (char_type[c] & CCLASSMASK)
  103 
  104 #define BS      BACKSPACE
  105 #define CC      CONTROL
  106 #define CR      RETURN
  107 #define NA      ORDINARY | ALPHA
  108 #define NL      NEWLINE
  109 #define NO      ORDINARY
  110 #define TB      TAB
  111 #define VT      VTAB
  112 
  113 u_char const char_type[] = {
  114         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
  115         O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
  116         O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
  117         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
  118         O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
  119         E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
  120         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
  121         O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
  122         O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
  123         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
  124         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
  125         O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
  126         E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
  127         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
  128         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
  129         E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
  130         /*
  131          * Meta chars; should be settable per character set;
  132          * for now, treat them all as normal characters.
  133          */
  134         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  135         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  136         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  137         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  138         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  139         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  140         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  141         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  142         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  143         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  144         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  145         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  146         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  147         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  148         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  149         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  150 };
  151 #undef  BS
  152 #undef  CC
  153 #undef  CR
  154 #undef  NA
  155 #undef  NL
  156 #undef  NO
  157 #undef  TB
  158 #undef  VT
  159 
  160 #define islower(c)      ((c) >= 'a' && (c) <= 'z')
  161 #define isupper(c)      ((c) >= 'A' && (c) <= 'Z')
  162 
  163 #define tolower(c)      ((c) - 'A' + 'a')
  164 #define toupper(c)      ((c) - 'a' + 'A')
  165 
  166 struct ttylist_head ttylist;    /* TAILQ_HEAD */
  167 int tty_count;
  168 
  169 int64_t tk_cancc, tk_nin, tk_nout, tk_rawcc;
  170 
  171 /*
  172  * Initial open of tty, or (re)entry to standard tty line discipline.
  173  */
  174 int
  175 ttyopen(dev_t device, struct tty *tp)
  176 {
  177         int s;
  178 
  179         s = spltty();
  180         tp->t_dev = device;
  181         if (!ISSET(tp->t_state, TS_ISOPEN)) {
  182                 SET(tp->t_state, TS_ISOPEN);
  183                 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
  184 #ifdef COMPAT_OLDTTY
  185                 tp->t_flags = 0;
  186 #endif
  187         }
  188         CLR(tp->t_state, TS_WOPEN);
  189         splx(s);
  190         return (0);
  191 }
  192 
  193 /*
  194  * Handle close() on a tty line: flush and set to initial state,
  195  * bumping generation number so that pending read/write calls
  196  * can detect recycling of the tty.
  197  */
  198 int
  199 ttyclose(struct tty *tp)
  200 {
  201         extern struct tty *constty;     /* Temporary virtual console. */
  202 
  203         if (constty == tp)
  204                 constty = NULL;
  205 
  206         ttyflush(tp, FREAD | FWRITE);
  207 
  208         tp->t_gen++;
  209         tp->t_pgrp = NULL;
  210         if (tp->t_session)
  211                 SESSRELE(tp->t_session);
  212         tp->t_session = NULL;
  213         tp->t_state = 0;
  214         return (0);
  215 }
  216 
  217 #define FLUSHQ(q) {                                                     \
  218         if ((q)->c_cc)                                                  \
  219                 ndflush(q, (q)->c_cc);                                  \
  220 }
  221 
  222 /* Is 'c' a line delimiter ("break" character)? */
  223 #define TTBREAKC(c, lflag)                                              \
  224         ((c) == '\n' || (((c) == cc[VEOF] || (c) == cc[VEOL] ||         \
  225         ((c) == cc[VEOL2] && (lflag & IEXTEN))) && (c) != _POSIX_VDISABLE))
  226 
  227 
  228 /*
  229  * Process input of a single character received on a tty.
  230  */
  231 int
  232 ttyinput(int c, struct tty *tp)
  233 {
  234         int iflag, lflag;
  235         u_char *cc;
  236         int i, error;
  237         int s;
  238 
  239         add_tty_randomness(tp->t_dev << 8 | c);
  240         /*
  241          * If receiver is not enabled, drop it.
  242          */
  243         if (!ISSET(tp->t_cflag, CREAD))
  244                 return (0);
  245 
  246         /*
  247          * If input is pending take it first.
  248          */
  249         lflag = tp->t_lflag;
  250         s = spltty();
  251         if (ISSET(lflag, PENDIN))
  252                 ttypend(tp);
  253         splx(s);
  254         /*
  255          * Gather stats.
  256          */
  257         if (ISSET(lflag, ICANON)) {
  258                 ++tk_cancc;
  259                 ++tp->t_cancc;
  260         } else {
  261                 ++tk_rawcc;
  262                 ++tp->t_rawcc;
  263         }
  264         ++tk_nin;
  265 
  266         /* Handle exceptional conditions (break, parity, framing). */
  267         cc = tp->t_cc;
  268         iflag = tp->t_iflag;
  269         if ((error = (ISSET(c, TTY_ERRORMASK))) != 0) {
  270                 CLR(c, TTY_ERRORMASK);
  271                 if (ISSET(error, TTY_FE) && !c) {       /* Break. */
  272                         if (ISSET(iflag, IGNBRK))
  273                                 return (0);
  274                         ttyflush(tp, FREAD | FWRITE);
  275                         if (ISSET(iflag, BRKINT)) {
  276                             pgsignal(tp->t_pgrp, SIGINT, 1);
  277                             goto endcase;
  278                         }
  279                         else if (ISSET(iflag, PARMRK))
  280                                 goto parmrk;
  281                 } else if ((ISSET(error, TTY_PE) && ISSET(iflag, INPCK)) ||
  282                     ISSET(error, TTY_FE)) {
  283                         if (ISSET(iflag, IGNPAR))
  284                                 goto endcase;
  285                         else if (ISSET(iflag, PARMRK)) {
  286 parmrk:                         (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
  287                                 if (ISSET(iflag, ISTRIP) || c != 0377)
  288                                         (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
  289                                 (void)putc(c | TTY_QUOTE, &tp->t_rawq);
  290                                 goto endcase;
  291                         } else
  292                                 c = 0;
  293                 }
  294         }
  295         if (c == 0377 && !ISSET(iflag, ISTRIP) && ISSET(iflag, PARMRK))
  296                 goto parmrk;
  297 
  298         /*
  299          * In tandem mode, check high water mark.
  300          */
  301         if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW))
  302                 ttyblock(tp);
  303         if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
  304                 CLR(c, 0x80);
  305         if (!ISSET(lflag, EXTPROC)) {
  306                 /*
  307                  * Check for literal nexting very first
  308                  */
  309                 if (ISSET(tp->t_state, TS_LNCH)) {
  310                         SET(c, TTY_QUOTE);
  311                         CLR(tp->t_state, TS_LNCH);
  312                 }
  313                 /*
  314                  * Scan for special characters.  This code
  315                  * is really just a big case statement with
  316                  * non-constant cases.  The bottom of the
  317                  * case statement is labeled ``endcase'', so goto
  318                  * it after a case match, or similar.
  319                  */
  320 
  321                 /*
  322                  * Control chars which aren't controlled
  323                  * by ICANON, ISIG, or IXON.
  324                  */
  325                 if (ISSET(lflag, IEXTEN)) {
  326                         if (CCEQ(cc[VLNEXT], c)) {
  327                                 if (ISSET(lflag, ECHO)) {
  328                                         if (ISSET(lflag, ECHOE)) {
  329                                                 (void)ttyoutput('^', tp);
  330                                                 (void)ttyoutput('\b', tp);
  331                                         } else
  332                                                 ttyecho(c, tp);
  333                                 }
  334                                 SET(tp->t_state, TS_LNCH);
  335                                 goto endcase;
  336                         }
  337                         if (CCEQ(cc[VDISCARD], c)) {
  338                                 if (ISSET(lflag, FLUSHO))
  339                                         CLR(tp->t_lflag, FLUSHO);
  340                                 else {
  341                                         ttyflush(tp, FWRITE);
  342                                         ttyecho(c, tp);
  343                                         if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
  344                                                 ttyretype(tp);
  345                                         SET(tp->t_lflag, FLUSHO);
  346                                 }
  347                                 goto startoutput;
  348                         }
  349                 }
  350                 /*
  351                  * Signals.
  352                  */
  353                 if (ISSET(lflag, ISIG)) {
  354                         if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
  355                                 if (!ISSET(lflag, NOFLSH))
  356                                         ttyflush(tp, FREAD | FWRITE);
  357                                 ttyecho(c, tp);
  358                                 pgsignal(tp->t_pgrp,
  359                                     CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
  360                                 goto endcase;
  361                         }
  362                         if (CCEQ(cc[VSUSP], c)) {
  363                                 if (!ISSET(lflag, NOFLSH))
  364                                         ttyflush(tp, FREAD);
  365                                 ttyecho(c, tp);
  366                                 pgsignal(tp->t_pgrp, SIGTSTP, 1);
  367                                 goto endcase;
  368                         }
  369                 }
  370                 /*
  371                  * Handle start/stop characters.
  372                  */
  373                 if (ISSET(iflag, IXON)) {
  374                         if (CCEQ(cc[VSTOP], c)) {
  375                                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
  376                                         SET(tp->t_state, TS_TTSTOP);
  377                                         (*cdevsw[major(tp->t_dev)].d_stop)(tp,
  378                                            0);
  379                                         return (0);
  380                                 }
  381                                 if (!CCEQ(cc[VSTART], c))
  382                                         return (0);
  383                                 /*
  384                                  * if VSTART == VSTOP then toggle
  385                                  */
  386                                 goto endcase;
  387                         }
  388                         if (CCEQ(cc[VSTART], c))
  389                                 goto restartoutput;
  390                 }
  391                 /*
  392                  * IGNCR, ICRNL, & INLCR
  393                  */
  394                 if (c == '\r') {
  395                         if (ISSET(iflag, IGNCR))
  396                                 goto endcase;
  397                         else if (ISSET(iflag, ICRNL))
  398                                 c = '\n';
  399                 } else if (c == '\n' && ISSET(iflag, INLCR))
  400                         c = '\r';
  401         }
  402         if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
  403                 /*
  404                  * From here on down canonical mode character
  405                  * processing takes place.
  406                  */
  407                 /*
  408                  * upper case or specials with IUCLC and XCASE
  409                  */
  410                 if (ISSET(lflag, XCASE) && ISSET(iflag, IUCLC)) {
  411                         if (ISSET(tp->t_state, TS_BKSL)) {
  412                                 CLR(tp->t_state, TS_BKSL);
  413                                 switch (c) {
  414                                 case '\'':
  415                                         c = '`';
  416                                         break;
  417                                 case '!':
  418                                         c = '|';
  419                                         break;
  420                                 case '^':
  421                                         c = '~';
  422                                         break;
  423                                 case '(':
  424                                         c = '{';
  425                                         break;
  426                                 case ')':
  427                                         c = '}';
  428                                         break;
  429                                 }
  430                         }
  431                         else if (c == '\\') {
  432                                 SET(tp->t_state, TS_BKSL);
  433                                 goto endcase;
  434                         }
  435                         else if (isupper(c))
  436                                 c = tolower(c);
  437                 }
  438                 else if (ISSET(iflag, IUCLC) && isupper(c))
  439                         c = tolower(c);
  440                 /*
  441                  * erase (^H / ^?)
  442                  */
  443                 if (CCEQ(cc[VERASE], c)) {
  444                         if (tp->t_rawq.c_cc)
  445                                 ttyrub(unputc(&tp->t_rawq), tp);
  446                         goto endcase;
  447                 }
  448                 /*
  449                  * kill (^U)
  450                  */
  451                 if (CCEQ(cc[VKILL], c)) {
  452                         if (ISSET(lflag, ECHOKE) &&
  453                             tp->t_rawq.c_cc == tp->t_rocount &&
  454                             !ISSET(lflag, ECHOPRT))
  455                                 while (tp->t_rawq.c_cc)
  456                                         ttyrub(unputc(&tp->t_rawq), tp);
  457                         else {
  458                                 ttyecho(c, tp);
  459                                 if (ISSET(lflag, ECHOK) ||
  460                                     ISSET(lflag, ECHOKE))
  461                                         ttyecho('\n', tp);
  462                                 FLUSHQ(&tp->t_rawq);
  463                                 tp->t_rocount = 0;
  464                         }
  465                         CLR(tp->t_state, TS_LOCAL);
  466                         goto endcase;
  467                 }
  468                 /*
  469                  * word erase (^W)
  470                  */
  471                 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
  472                         int alt = ISSET(lflag, ALTWERASE);
  473                         int ctype;
  474 
  475                         /*
  476                          * erase whitespace
  477                          */
  478                         while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
  479                                 ttyrub(c, tp);
  480                         if (c == -1)
  481                                 goto endcase;
  482                         /*
  483                          * erase last char of word and remember the
  484                          * next chars type (for ALTWERASE)
  485                          */
  486                         ttyrub(c, tp);
  487                         c = unputc(&tp->t_rawq);
  488                         if (c == -1)
  489                                 goto endcase;
  490                         if (c == ' ' || c == '\t') {
  491                                 (void)putc(c, &tp->t_rawq);
  492                                 goto endcase;
  493                         }
  494                         ctype = ISALPHA(c);
  495                         /*
  496                          * erase rest of word
  497                          */
  498                         do {
  499                                 ttyrub(c, tp);
  500                                 c = unputc(&tp->t_rawq);
  501                                 if (c == -1)
  502                                         goto endcase;
  503                         } while (c != ' ' && c != '\t' &&
  504                             (alt == 0 || ISALPHA(c) == ctype));
  505                         (void)putc(c, &tp->t_rawq);
  506                         goto endcase;
  507                 }
  508                 /*
  509                  * reprint line (^R)
  510                  */
  511                 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
  512                         ttyretype(tp);
  513                         goto endcase;
  514                 }
  515                 /*
  516                  * ^T - kernel info and generate SIGINFO
  517                  */
  518                 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
  519                         if (ISSET(lflag, ISIG))
  520                                 pgsignal(tp->t_pgrp, SIGINFO, 1);
  521                         if (!ISSET(lflag, NOKERNINFO))
  522                                 ttyinfo(tp);
  523                         goto endcase;
  524                 }
  525         }
  526         /*
  527          * Check for input buffer overflow
  528          */
  529         if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
  530                 if (ISSET(iflag, IMAXBEL)) {
  531                         if (tp->t_outq.c_cc < tp->t_hiwat)
  532                                 (void)ttyoutput(CTRL('g'), tp);
  533                 } else
  534                         ttyflush(tp, FREAD | FWRITE);
  535                 goto endcase;
  536         }
  537         /*
  538          * Put data char in q for user and
  539          * wakeup on seeing a line delimiter.
  540          */
  541         if (putc(c, &tp->t_rawq) >= 0) {
  542                 if (!ISSET(lflag, ICANON)) {
  543                         ttwakeup(tp);
  544                         ttyecho(c, tp);
  545                         goto endcase;
  546                 }
  547                 if (TTBREAKC(c, lflag)) {
  548                         tp->t_rocount = 0;
  549                         catq(&tp->t_rawq, &tp->t_canq);
  550                         ttwakeup(tp);
  551                 } else if (tp->t_rocount++ == 0)
  552                         tp->t_rocol = tp->t_column;
  553                 if (ISSET(tp->t_state, TS_ERASE)) {
  554                         /*
  555                          * end of prterase \.../
  556                          */
  557                         CLR(tp->t_state, TS_ERASE);
  558                         (void)ttyoutput('/', tp);
  559                 }
  560                 i = tp->t_column;
  561                 ttyecho(c, tp);
  562                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
  563                         /*
  564                          * Place the cursor over the '^' of the ^D.
  565                          */
  566                         i = min(2, tp->t_column - i);
  567                         while (i > 0) {
  568                                 (void)ttyoutput('\b', tp);
  569                                 i--;
  570                         }
  571                 }
  572         }
  573 endcase:
  574         /*
  575          * IXANY means allow any character to restart output.
  576          */
  577         if (ISSET(tp->t_state, TS_TTSTOP) &&
  578             !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
  579                 return (0);
  580 restartoutput:
  581         CLR(tp->t_lflag, FLUSHO);
  582         CLR(tp->t_state, TS_TTSTOP);
  583 startoutput:
  584         return (ttstart(tp));
  585 }
  586 
  587 /*
  588  * Output a single character on a tty, doing output processing
  589  * as needed (expanding tabs, newline processing, etc.).
  590  * Returns < 0 if succeeds, otherwise returns char to resend.
  591  * Must be recursive.
  592  */
  593 int
  594 ttyoutput(int c, struct tty *tp)
  595 {
  596         long oflag;
  597         int col, notout, s, c2;
  598 
  599         oflag = tp->t_oflag;
  600         if (!ISSET(oflag, OPOST)) {
  601                 tk_nout++;
  602                 tp->t_outcc++;
  603                 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
  604                         return (c);
  605                 return (-1);
  606         }
  607         /*
  608          * Do tab expansion if OXTABS is set.  Special case if we external
  609          * processing, we don't do the tab expansion because we'll probably
  610          * get it wrong.  If tab expansion needs to be done, let it happen
  611          * externally.
  612          */
  613         CLR(c, ~TTY_CHARMASK);
  614         if (c == '\t' &&
  615             ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
  616                 c = 8 - (tp->t_column & 7);
  617                 if (ISSET(tp->t_lflag, FLUSHO)) {
  618                         notout = 0;
  619                 } else {
  620                         s = spltty();           /* Don't interrupt tabs. */
  621                         notout = b_to_q("        ", c, &tp->t_outq);
  622                         c -= notout;
  623                         tk_nout += c;
  624                         tp->t_outcc += c;
  625                         splx(s);
  626                 }
  627                 tp->t_column += c;
  628                 return (notout ? '\t' : -1);
  629         }
  630         if (c == CEOT && ISSET(oflag, ONOEOT))
  631                 return (-1);
  632 
  633         /*
  634          * Newline translation: if ONLCR is set,
  635          * translate newline into "\r\n".  If OCRNL
  636          * is set, translate '\r' into '\n'.
  637          */
  638         if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
  639                 tk_nout++;
  640                 tp->t_outcc++;
  641                 if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
  642                         return (c);
  643                 tp->t_column = 0;
  644         }
  645         else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
  646                 c = '\n';
  647 
  648         if (ISSET(tp->t_oflag, OLCUC) && islower(c))
  649                 c = toupper(c);
  650         else if (ISSET(tp->t_oflag, OLCUC) && ISSET(tp->t_lflag, XCASE)) {
  651                 c2 = c;
  652                 switch (c) {
  653                 case '`':
  654                         c2 = '\'';
  655                         break;
  656                 case '|':
  657                         c2 = '!';
  658                         break;
  659                 case '~':
  660                         c2 = '^';
  661                         break;
  662                 case '{':
  663                         c2 = '(';
  664                         break;
  665                 case '}':
  666                         c2 = ')';
  667                         break;
  668                 }
  669                 if (c == '\\' || isupper(c) || c != c2) {
  670                         tk_nout++;
  671                         tp->t_outcc++;
  672                         if (putc('\\', &tp->t_outq))
  673                                 return (c);
  674                         c = c2;
  675                 }
  676         }
  677         if (ISSET(tp->t_oflag, ONOCR) && c == '\r' && tp->t_column == 0)
  678                 return (-1);
  679 
  680         tk_nout++;
  681         tp->t_outcc++;
  682         if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
  683                 return (c);
  684 
  685         col = tp->t_column;
  686         switch (CCLASS(c)) {
  687         case BACKSPACE:
  688                 if (col > 0)
  689                         --col;
  690                 break;
  691         case CONTROL:
  692                 break;
  693         case NEWLINE:
  694                 if (ISSET(tp->t_oflag, ONLRET) || ISSET(tp->t_oflag, OCRNL))
  695                         col = 0;
  696                 break;
  697         case RETURN:
  698                 col = 0;
  699                 break;
  700         case ORDINARY:
  701                 ++col;
  702                 break;
  703         case TAB:
  704                 col = (col + 8) & ~7;
  705                 break;
  706         }
  707         tp->t_column = col;
  708         return (-1);
  709 }
  710 
  711 /*
  712  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
  713  * has been called to do discipline-specific functions and/or reject any
  714  * of these ioctl commands.
  715  */
  716 /* ARGSUSED */
  717 int
  718 ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
  719 {
  720         extern struct tty *constty;     /* Temporary virtual console. */
  721         extern int nlinesw;
  722         int s, error;
  723 
  724         /* If the ioctl involves modification, hang if in the background. */
  725         switch (cmd) {
  726         case  TIOCFLUSH:
  727         case  TIOCDRAIN:
  728         case  TIOCSBRK:
  729         case  TIOCCBRK:
  730         case  TIOCSETA:
  731         case  TIOCSETD:
  732         case  TIOCSETAF:
  733         case  TIOCSETAW:
  734 #ifdef notdef
  735         case  TIOCSPGRP:
  736 #endif
  737         case  TIOCSTAT:
  738         case  TIOCSTI:
  739         case  TIOCSWINSZ:
  740 #ifdef COMPAT_OLDTTY
  741         case  TIOCLBIC:
  742         case  TIOCLBIS:
  743         case  TIOCLSET:
  744         case  TIOCSETC:
  745         case OTIOCSETD:
  746         case  TIOCSETN:
  747         case  TIOCSETP:
  748         case  TIOCSLTC:
  749 #endif
  750                 while (isbackground(p, tp) &&
  751                     (p->p_flag & P_PPWAIT) == 0 &&
  752                     (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
  753                     (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
  754                         if (p->p_pgrp->pg_jobc == 0)
  755                                 return (EIO);
  756                         pgsignal(p->p_pgrp, SIGTTOU, 1);
  757                         error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
  758                             ttybg, 0);
  759                         if (error)
  760                                 return (error);
  761                 }
  762                 break;
  763         }
  764 
  765         switch (cmd) {                  /* Process the ioctl. */
  766         case FIOASYNC:                  /* set/clear async i/o */
  767                 s = spltty();
  768                 if (*(int *)data)
  769                         SET(tp->t_state, TS_ASYNC);
  770                 else
  771                         CLR(tp->t_state, TS_ASYNC);
  772                 splx(s);
  773                 break;
  774         case FIONBIO:                   /* set/clear non-blocking i/o */
  775                 break;                  /* XXX: delete. */
  776         case FIONREAD:                  /* get # bytes to read */
  777                 s = spltty();
  778                 *(int *)data = ttnread(tp);
  779                 splx(s);
  780                 break;
  781         case TIOCEXCL:                  /* set exclusive use of tty */
  782                 s = spltty();
  783                 SET(tp->t_state, TS_XCLUDE);
  784                 splx(s);
  785                 break;
  786         case TIOCFLUSH: {               /* flush buffers */
  787                 int flags = *(int *)data;
  788 
  789                 if (flags == 0)
  790                         flags = FREAD | FWRITE;
  791                 else
  792                         flags &= FREAD | FWRITE;
  793                 ttyflush(tp, flags);
  794                 break;
  795         }
  796         case TIOCCONS: {                /* become virtual console */
  797                 if (*(int *)data) {
  798                         struct nameidata nid;
  799 
  800                         if (constty != NULL && constty != tp &&
  801                             ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
  802                             (TS_CARR_ON | TS_ISOPEN))
  803                                 return (EBUSY);
  804 
  805                         /* ensure user can open the real console */
  806                         NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
  807                         error = namei(&nid);
  808                         if (error)
  809                                 return (error);
  810                         vn_lock(nid.ni_vp, LK_EXCLUSIVE | LK_RETRY, p);
  811                         error = VOP_ACCESS(nid.ni_vp, VREAD, p->p_ucred, p);
  812                         VOP_UNLOCK(nid.ni_vp, 0, p);
  813                         vrele(nid.ni_vp);
  814                         if (error)
  815                                 return (error);
  816 
  817                         constty = tp;
  818                 } else if (tp == constty)
  819                         constty = NULL;
  820                 break;
  821         }
  822         case TIOCDRAIN:                 /* wait till output drained */
  823                 if ((error = ttywait(tp)) != 0)
  824                         return (error);
  825                 break;
  826         case TIOCGETA: {                /* get termios struct */
  827                 struct termios *t = (struct termios *)data;
  828 
  829                 bcopy(&tp->t_termios, t, sizeof(struct termios));
  830                 break;
  831         }
  832         case TIOCGETD:                  /* get line discipline */
  833                 *(int *)data = tp->t_line;
  834                 break;
  835         case TIOCGWINSZ:                /* get window size */
  836                 *(struct winsize *)data = tp->t_winsize;
  837                 break;
  838         case TIOCGTSTAMP:
  839                 s = spltty();
  840                 *(struct timeval *)data = tp->t_tv;
  841                 splx(s);
  842                 break;
  843         case TIOCGPGRP:                 /* get pgrp of tty */
  844                 if (!isctty(p, tp) && suser(p, 0))
  845                         return (ENOTTY);
  846                 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
  847                 break;
  848 #ifdef TIOCHPCL
  849         case TIOCHPCL:                  /* hang up on last close */
  850                 s = spltty();
  851                 SET(tp->t_cflag, HUPCL);
  852                 splx(s);
  853                 break;
  854 #endif
  855         case TIOCNXCL:                  /* reset exclusive use of tty */
  856                 s = spltty();
  857                 CLR(tp->t_state, TS_XCLUDE);
  858                 splx(s);
  859                 break;
  860         case TIOCOUTQ:                  /* output queue size */
  861                 *(int *)data = tp->t_outq.c_cc;
  862                 break;
  863         case TIOCSETA:                  /* set termios struct */
  864         case TIOCSETAW:                 /* drain output, set */
  865         case TIOCSETAF: {               /* drn out, fls in, set */
  866                 struct termios *t = (struct termios *)data;
  867 
  868                 s = spltty();
  869                 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
  870                         if ((error = ttywait(tp)) != 0) {
  871                                 splx(s);
  872                                 return (error);
  873                         }
  874                         if (cmd == TIOCSETAF)
  875                                 ttyflush(tp, FREAD);
  876                 }
  877                 if (!ISSET(t->c_cflag, CIGNORE)) {
  878                         /*
  879                          * Set device hardware.
  880                          */
  881                         if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
  882                                 splx(s);
  883                                 return (error);
  884                         } else {
  885                                 if (!ISSET(tp->t_state, TS_CARR_ON) &&
  886                                     ISSET(tp->t_cflag, CLOCAL) &&
  887                                     !ISSET(t->c_cflag, CLOCAL)) {
  888                                         CLR(tp->t_state, TS_ISOPEN);
  889                                         SET(tp->t_state, TS_WOPEN);
  890                                         ttwakeup(tp);
  891                                 }
  892                                 tp->t_cflag = t->c_cflag;
  893                                 tp->t_ispeed = t->c_ispeed;
  894                                 tp->t_ospeed = t->c_ospeed;
  895                                 if (t->c_ospeed == 0 && tp->t_session &&
  896                                     tp->t_session->s_leader)
  897                                         psignal(tp->t_session->s_leader,
  898                                             SIGHUP);
  899                         }
  900                         ttsetwater(tp);
  901                 }
  902                 if (cmd != TIOCSETAF) {
  903                         if (ISSET(t->c_lflag, ICANON) !=
  904                             ISSET(tp->t_lflag, ICANON)) {
  905                                 if (ISSET(t->c_lflag, ICANON)) {
  906                                         SET(tp->t_lflag, PENDIN);
  907                                         ttwakeup(tp);
  908                                 } else {
  909                                         struct clist tq;
  910 
  911                                         catq(&tp->t_rawq, &tp->t_canq);
  912                                         tq = tp->t_rawq;
  913                                         tp->t_rawq = tp->t_canq;
  914                                         tp->t_canq = tq;
  915                                         CLR(tp->t_lflag, PENDIN);
  916                                 }
  917                         }
  918                 }
  919                 tp->t_iflag = t->c_iflag;
  920                 tp->t_oflag = t->c_oflag;
  921                 /*
  922                  * Make the EXTPROC bit read only.
  923                  */
  924                 if (ISSET(tp->t_lflag, EXTPROC))
  925                         SET(t->c_lflag, EXTPROC);
  926                 else
  927                         CLR(t->c_lflag, EXTPROC);
  928                 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
  929                 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
  930                 splx(s);
  931                 break;
  932         }
  933         case TIOCSETD: {                /* set line discipline */
  934                 int t = *(int *)data;
  935                 dev_t device = tp->t_dev;
  936 
  937                 if ((u_int)t >= nlinesw)
  938                         return (ENXIO);
  939                 if (t != tp->t_line) {
  940                         s = spltty();
  941                         (*linesw[tp->t_line].l_close)(tp, flag);
  942                         error = (*linesw[t].l_open)(device, tp);
  943                         if (error) {
  944                                 (void)(*linesw[tp->t_line].l_open)(device, tp);
  945                                 splx(s);
  946                                 return (error);
  947                         }
  948                         tp->t_line = t;
  949                         splx(s);
  950                 }
  951                 break;
  952         }
  953         case TIOCSTART:                 /* start output, like ^Q */
  954                 s = spltty();
  955                 if (ISSET(tp->t_state, TS_TTSTOP) ||
  956                     ISSET(tp->t_lflag, FLUSHO)) {
  957                         CLR(tp->t_lflag, FLUSHO);
  958                         CLR(tp->t_state, TS_TTSTOP);
  959                         ttstart(tp);
  960                 }
  961                 splx(s);
  962                 break;
  963         case TIOCSTI:                   /* simulate terminal input */
  964                 if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
  965                         return (EPERM);
  966                 if (p->p_ucred->cr_uid && !isctty(p, tp))
  967                         return (EACCES);
  968                 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
  969                 break;
  970         case TIOCSTOP:                  /* stop output, like ^S */
  971                 s = spltty();
  972                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
  973                         SET(tp->t_state, TS_TTSTOP);
  974                         (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
  975                 }
  976                 splx(s);
  977                 break;
  978         case TIOCSCTTY:                 /* become controlling tty */
  979                 /* Session ctty vnode pointer set in vnode layer. */
  980                 if (!SESS_LEADER(p) ||
  981                     ((p->p_session->s_ttyvp || tp->t_session) &&
  982                      (tp->t_session != p->p_session)))
  983                         return (EPERM);
  984                 if (tp->t_session)
  985                         SESSRELE(tp->t_session);
  986                 SESSHOLD(p->p_session);
  987                 tp->t_session = p->p_session;
  988                 tp->t_pgrp = p->p_pgrp;
  989                 p->p_session->s_ttyp = tp;
  990                 atomic_setbits_int(&p->p_flag, P_CONTROLT);
  991                 break;
  992         case TIOCSPGRP: {               /* set pgrp of tty */
  993                 struct pgrp *pgrp = pgfind(*(int *)data);
  994 
  995                 if (!isctty(p, tp))
  996                         return (ENOTTY);
  997                 else if (pgrp == NULL)
  998                         return (EINVAL);
  999                 else if (pgrp->pg_session != p->p_session)
 1000                         return (EPERM);
 1001                 tp->t_pgrp = pgrp;
 1002                 break;
 1003         }
 1004         case TIOCSTAT:                  /* get load avg stats */
 1005                 ttyinfo(tp);
 1006                 break;
 1007         case TIOCSWINSZ:                /* set window size */
 1008                 if (bcmp((caddr_t)&tp->t_winsize, data,
 1009                     sizeof (struct winsize))) {
 1010                         tp->t_winsize = *(struct winsize *)data;
 1011                         pgsignal(tp->t_pgrp, SIGWINCH, 1);
 1012                 }
 1013                 break;
 1014         case TIOCSTSTAMP: {
 1015                 struct tstamps *ts = (struct tstamps *)data;
 1016 
 1017                 s = spltty();
 1018                 CLR(tp->t_flags, TS_TSTAMPDCDSET);
 1019                 CLR(tp->t_flags, TS_TSTAMPCTSSET);
 1020                 CLR(tp->t_flags, TS_TSTAMPDCDCLR);
 1021                 CLR(tp->t_flags, TS_TSTAMPCTSCLR);
 1022                 if (ISSET(ts->ts_set, TIOCM_CAR))
 1023                         SET(tp->t_flags, TS_TSTAMPDCDSET);
 1024                 if (ISSET(ts->ts_set, TIOCM_CTS))
 1025                         SET(tp->t_flags, TS_TSTAMPCTSSET);
 1026                 if (ISSET(ts->ts_clr, TIOCM_CAR))
 1027                         SET(tp->t_flags, TS_TSTAMPDCDCLR);
 1028                 if (ISSET(ts->ts_clr, TIOCM_CTS))
 1029                         SET(tp->t_flags, TS_TSTAMPCTSCLR);
 1030                 splx(s);
 1031                 break;
 1032         }
 1033         default:
 1034 #ifdef COMPAT_OLDTTY
 1035                 return (ttcompat(tp, cmd, data, flag, p));
 1036 #else
 1037                 return (-1);
 1038 #endif
 1039         }
 1040         return (0);
 1041 }
 1042 
 1043 int
 1044 ttpoll(dev_t device, int events, struct proc *p)
 1045 {
 1046         struct tty *tp;
 1047         int revents, s;
 1048 
 1049         tp = (*cdevsw[major(device)].d_tty)(device);
 1050 
 1051         revents = 0;
 1052         s = spltty();
 1053         if (events & (POLLIN | POLLRDNORM)) {
 1054                 if (ttnread(tp) > 0 || (!ISSET(tp->t_cflag, CLOCAL) &&
 1055                     !ISSET(tp->t_state, TS_CARR_ON)))
 1056                         revents |= events & (POLLIN | POLLRDNORM);
 1057         }
 1058         if (events & (POLLOUT | POLLWRNORM)) {
 1059                 if (tp->t_outq.c_cc <= tp->t_lowat)
 1060                         revents |= events & (POLLOUT | POLLWRNORM);
 1061         }
 1062         if (revents == 0) {
 1063                 if (events & (POLLIN | POLLRDNORM))
 1064                         selrecord(p, &tp->t_rsel);
 1065                 if (events & (POLLOUT | POLLWRNORM))
 1066                         selrecord(p, &tp->t_wsel);
 1067         }
 1068         splx(s);
 1069         return (revents);
 1070 }
 1071 
 1072 struct filterops ttyread_filtops =
 1073         { 1, NULL, filt_ttyrdetach, filt_ttyread };
 1074 struct filterops ttywrite_filtops =
 1075         { 1, NULL, filt_ttywdetach, filt_ttywrite };
 1076 
 1077 int
 1078 ttkqfilter(dev_t dev, struct knote *kn)
 1079 {
 1080         struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
 1081         struct klist *klist;
 1082         int s;
 1083 
 1084         switch (kn->kn_filter) {
 1085         case EVFILT_READ:
 1086                 klist = &tp->t_rsel.si_note;
 1087                 kn->kn_fop = &ttyread_filtops;
 1088                 break;
 1089         case EVFILT_WRITE:
 1090                 klist = &tp->t_wsel.si_note;
 1091                 kn->kn_fop = &ttywrite_filtops;
 1092                 break;
 1093         default:
 1094                 return (1);
 1095         }
 1096 
 1097         kn->kn_hook = (caddr_t)((u_long)dev);
 1098 
 1099         s = spltty();
 1100         SLIST_INSERT_HEAD(klist, kn, kn_selnext);
 1101         splx(s);
 1102 
 1103         return (0);
 1104 }
 1105 
 1106 void
 1107 filt_ttyrdetach(struct knote *kn)
 1108 {
 1109         dev_t dev = (dev_t)((u_long)kn->kn_hook);
 1110         struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
 1111         int s = spltty();
 1112 
 1113         SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext);
 1114         splx(s);
 1115 }
 1116 
 1117 int
 1118 filt_ttyread(struct knote *kn, long hint)
 1119 {
 1120         dev_t dev = (dev_t)((u_long)kn->kn_hook);
 1121         struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
 1122         int s;
 1123 
 1124         s = spltty();
 1125         kn->kn_data = ttnread(tp);
 1126         splx(s);
 1127         if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
 1128                 kn->kn_flags |= EV_EOF;
 1129                 return (1);
 1130         }
 1131         return (kn->kn_data > 0);
 1132 }
 1133 
 1134 void
 1135 filt_ttywdetach(struct knote *kn)
 1136 {
 1137         dev_t dev = (dev_t)((u_long)kn->kn_hook);
 1138         struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
 1139         int s = spltty();
 1140 
 1141         SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext);
 1142         splx(s);
 1143 }
 1144 
 1145 int
 1146 filt_ttywrite(struct knote *kn, long hint)
 1147 {
 1148         dev_t dev = (dev_t)((u_long)kn->kn_hook);
 1149         struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
 1150 
 1151         kn->kn_data = tp->t_outq.c_cc;
 1152         return (kn->kn_data <= tp->t_lowat);
 1153 }
 1154 
 1155 static int
 1156 ttnread(struct tty *tp)
 1157 {
 1158         int nread;
 1159 
 1160         splassert(IPL_TTY);
 1161 
 1162         if (ISSET(tp->t_lflag, PENDIN))
 1163                 ttypend(tp);
 1164         nread = tp->t_canq.c_cc;
 1165         if (!ISSET(tp->t_lflag, ICANON)) {
 1166                 nread += tp->t_rawq.c_cc;
 1167                 if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
 1168                         nread = 0;
 1169         }
 1170         return (nread);
 1171 }
 1172 
 1173 /*
 1174  * Wait for output to drain.
 1175  */
 1176 int
 1177 ttywait(struct tty *tp)
 1178 {
 1179         int error, s;
 1180 
 1181         error = 0;
 1182         s = spltty();
 1183         while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
 1184             (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL)) &&
 1185             tp->t_oproc) {
 1186                 (*tp->t_oproc)(tp);
 1187                 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
 1188                     (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
 1189                     && tp->t_oproc) {
 1190                         SET(tp->t_state, TS_ASLEEP);
 1191                         error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
 1192                         if (error)
 1193                                 break;
 1194                 } else
 1195                         break;
 1196         }
 1197         splx(s);
 1198         return (error);
 1199 }
 1200 
 1201 /*
 1202  * Flush if successfully wait.
 1203  */
 1204 int
 1205 ttywflush(struct tty *tp)
 1206 {
 1207         int error;
 1208 
 1209         if ((error = ttywait(tp)) == 0)
 1210                 ttyflush(tp, FREAD);
 1211         return (error);
 1212 }
 1213 
 1214 /*
 1215  * Flush tty read and/or write queues, notifying anyone waiting.
 1216  */
 1217 void
 1218 ttyflush(struct tty *tp, int rw)
 1219 {
 1220         int s;
 1221 
 1222         s = spltty();
 1223         if (rw & FREAD) {
 1224                 FLUSHQ(&tp->t_canq);
 1225                 FLUSHQ(&tp->t_rawq);
 1226                 tp->t_rocount = 0;
 1227                 tp->t_rocol = 0;
 1228                 CLR(tp->t_state, TS_LOCAL);
 1229                 ttyunblock(tp);
 1230                 ttwakeup(tp);
 1231         }
 1232         if (rw & FWRITE) {
 1233                 CLR(tp->t_state, TS_TTSTOP);
 1234                 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
 1235                 FLUSHQ(&tp->t_outq);
 1236                 wakeup((caddr_t)&tp->t_outq);
 1237                 selwakeup(&tp->t_wsel);
 1238         }
 1239         splx(s);
 1240 }
 1241 
 1242 /*
 1243  * Copy in the default termios characters.
 1244  */
 1245 void
 1246 ttychars(struct tty *tp)
 1247 {
 1248 
 1249         bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
 1250 }
 1251 
 1252 /*
 1253  * Send stop character on input overflow.
 1254  */
 1255 static void
 1256 ttyblock(struct tty *tp)
 1257 {
 1258         int total;
 1259 
 1260         total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
 1261         if (tp->t_rawq.c_cc > TTYHOG) {
 1262                 ttyflush(tp, FREAD | FWRITE);
 1263                 CLR(tp->t_state, TS_TBLOCK);
 1264         }
 1265         /*
 1266          * Block further input iff: current input > threshold
 1267          * AND input is available to user program.
 1268          */
 1269         if ((total >= TTYHOG / 2 &&
 1270              !ISSET(tp->t_state, TS_TBLOCK) &&
 1271              !ISSET(tp->t_lflag, ICANON)) || tp->t_canq.c_cc > 0) {
 1272                 if (ISSET(tp->t_iflag, IXOFF) &&
 1273                     tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
 1274                     putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
 1275                         SET(tp->t_state, TS_TBLOCK);
 1276                         ttstart(tp);
 1277                 }
 1278                 /* Try to block remote output via hardware flow control. */
 1279                 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
 1280                     (*tp->t_hwiflow)(tp, 1) != 0)
 1281                         SET(tp->t_state, TS_TBLOCK);
 1282         }
 1283 }
 1284 
 1285 void
 1286 ttrstrt(void *tp_arg)
 1287 {
 1288         struct tty *tp;
 1289         int s;
 1290 
 1291 #ifdef DIAGNOSTIC
 1292         if (tp_arg == NULL)
 1293                 panic("ttrstrt");
 1294 #endif
 1295         tp = tp_arg;
 1296         s = spltty();
 1297 
 1298         CLR(tp->t_state, TS_TIMEOUT);
 1299         ttstart(tp);
 1300 
 1301         splx(s);
 1302 }
 1303 
 1304 int
 1305 ttstart(struct tty *tp)
 1306 {
 1307 
 1308         if (tp->t_oproc != NULL)        /* XXX: Kludge for pty. */
 1309                 (*tp->t_oproc)(tp);
 1310         return (0);
 1311 }
 1312 
 1313 /*
 1314  * "close" a line discipline
 1315  */
 1316 int
 1317 ttylclose(struct tty *tp, int flag)
 1318 {
 1319 
 1320         if (flag & FNONBLOCK)
 1321                 ttyflush(tp, FREAD | FWRITE);
 1322         else
 1323                 ttywflush(tp);
 1324         return (0);
 1325 }
 1326 
 1327 /*
 1328  * Handle modem control transition on a tty.
 1329  * Flag indicates new state of carrier.
 1330  * Returns 0 if the line should be turned off, otherwise 1.
 1331  */
 1332 int
 1333 ttymodem(struct tty *tp, int flag)
 1334 {
 1335 
 1336         if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
 1337                 /*
 1338                  * MDMBUF: do flow control according to carrier flag
 1339                  */
 1340                 if (flag) {
 1341                         CLR(tp->t_state, TS_TTSTOP);
 1342                         ttstart(tp);
 1343                 } else if (!ISSET(tp->t_state, TS_TTSTOP)) {
 1344                         SET(tp->t_state, TS_TTSTOP);
 1345                         (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
 1346                 }
 1347         } else if (flag == 0) {
 1348                 /*
 1349                  * Lost carrier.
 1350                  */
 1351                 CLR(tp->t_state, TS_CARR_ON);
 1352                 if (ISSET(tp->t_state, TS_ISOPEN) &&
 1353                     !ISSET(tp->t_cflag, CLOCAL)) {
 1354                         if (tp->t_session && tp->t_session->s_leader)
 1355                                 psignal(tp->t_session->s_leader, SIGHUP);
 1356                         ttyflush(tp, FREAD | FWRITE);
 1357                         return (0);
 1358                 }
 1359         } else {
 1360                 /*
 1361                  * Carrier now on.
 1362                  */
 1363                 SET(tp->t_state, TS_CARR_ON);
 1364                 ttwakeup(tp);
 1365         }
 1366         return (1);
 1367 }
 1368 
 1369 /*
 1370  * Default modem control routine (for other line disciplines).
 1371  * Return argument flag, to turn off device on carrier drop.
 1372  */
 1373 int
 1374 nullmodem(struct tty *tp, int flag)
 1375 {
 1376 
 1377         if (flag)
 1378                 SET(tp->t_state, TS_CARR_ON);
 1379         else {
 1380                 CLR(tp->t_state, TS_CARR_ON);
 1381                 if (ISSET(tp->t_state, TS_ISOPEN) &&
 1382                     !ISSET(tp->t_cflag, CLOCAL)) {
 1383                         if (tp->t_session && tp->t_session->s_leader)
 1384                                 psignal(tp->t_session->s_leader, SIGHUP);
 1385                         ttyflush(tp, FREAD | FWRITE);
 1386                         return (0);
 1387                 }
 1388         }
 1389         return (1);
 1390 }
 1391 
 1392 /*
 1393  * Reinput pending characters after state switch
 1394  * call at spltty().
 1395  */
 1396 void
 1397 ttypend(struct tty *tp)
 1398 {
 1399         struct clist tq;
 1400         int c;
 1401 
 1402         splassert(IPL_TTY);
 1403 
 1404         CLR(tp->t_lflag, PENDIN);
 1405         SET(tp->t_state, TS_TYPEN);
 1406         tq = tp->t_rawq;
 1407         tp->t_rawq.c_cc = 0;
 1408         tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
 1409         while ((c = getc(&tq)) >= 0)
 1410                 ttyinput(c, tp);
 1411         CLR(tp->t_state, TS_TYPEN);
 1412 }
 1413 
 1414 void ttvtimeout(void *);
 1415 
 1416 void
 1417 ttvtimeout(void *arg)
 1418 {
 1419         struct tty *tp = (struct tty *)arg;
 1420 
 1421         wakeup(&tp->t_rawq);
 1422 }
 1423 
 1424 /*
 1425  * Process a read call on a tty device.
 1426  */
 1427 int
 1428 ttread(struct tty *tp, struct uio *uio, int flag)
 1429 {
 1430         struct timeout *stime = NULL;
 1431         struct proc *p = curproc;
 1432         int s, first, error = 0;
 1433         u_char *cc = tp->t_cc;
 1434         struct clist *qp;
 1435         int last_cc = 0;
 1436         long lflag;
 1437         int c;
 1438 
 1439 loop:   lflag = tp->t_lflag;
 1440         s = spltty();
 1441         /*
 1442          * take pending input first
 1443          */
 1444         if (ISSET(lflag, PENDIN))
 1445                 ttypend(tp);
 1446         splx(s);
 1447 
 1448         /*
 1449          * Hang process if it's in the background.
 1450          */
 1451         if (isbackground(p, tp)) {
 1452                 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
 1453                    (p->p_sigmask & sigmask(SIGTTIN)) ||
 1454                     p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0) {
 1455                         error = EIO;
 1456                         goto out;
 1457                 }
 1458                 pgsignal(p->p_pgrp, SIGTTIN, 1);
 1459                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
 1460                 if (error)
 1461                         goto out;
 1462                 goto loop;
 1463         }
 1464 
 1465         s = spltty();
 1466         if (!ISSET(lflag, ICANON)) {
 1467                 int m = cc[VMIN];
 1468                 long t;
 1469 
 1470                 /*
 1471                  * Note - since cc[VTIME] is a u_char, this won't overflow
 1472                  * until we have 32-bit longs and a hz > 8388608.
 1473                  * Hopefully this code and 32-bit longs are obsolete by then.
 1474                  */
 1475                 t = cc[VTIME] * hz / 10;
 1476 
 1477                 qp = &tp->t_rawq;
 1478                 /*
 1479                  * Check each of the four combinations.
 1480                  * (m > 0 && t == 0) is the normal read case.
 1481                  * It should be fairly efficient, so we check that and its
 1482                  * companion case (m == 0 && t == 0) first.
 1483                  */
 1484                 if (t == 0) {
 1485                         if (qp->c_cc < m)
 1486                                 goto sleep;
 1487                         goto read;
 1488                 }
 1489                 if (m > 0) {
 1490                         if (qp->c_cc <= 0)
 1491                                 goto sleep;
 1492                         if (qp->c_cc >= m)
 1493                                 goto read;
 1494                         if (stime == NULL) {
 1495 alloc_timer:
 1496                                 stime = malloc(sizeof(*stime), M_TEMP, M_WAITOK);
 1497                                 timeout_set(stime, ttvtimeout, tp);
 1498                                 timeout_add(stime, t);
 1499                         } else if (qp->c_cc > last_cc) {
 1500                                 /* got a character, restart timer */
 1501                                 timeout_add(stime, t);
 1502                         }
 1503                 } else {        /* m == 0 */
 1504                         if (qp->c_cc > 0)
 1505                                 goto read;
 1506                         if (stime == NULL) {
 1507                                 goto alloc_timer;
 1508                         }
 1509                 }
 1510                 last_cc = qp->c_cc;
 1511                 if (stime && !timeout_triggered(stime)) {
 1512                         goto sleep;
 1513                 }
 1514         } else if ((qp = &tp->t_canq)->c_cc <= 0) {
 1515                 int carrier;
 1516 
 1517 sleep:
 1518                 /*
 1519                  * If there is no input, sleep on rawq
 1520                  * awaiting hardware receipt and notification.
 1521                  * If we have data, we don't need to check for carrier.
 1522                  */
 1523                 carrier = ISSET(tp->t_state, TS_CARR_ON) ||
 1524                     ISSET(tp->t_cflag, CLOCAL);
 1525                 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
 1526                         splx(s);
 1527                         error = 0;
 1528                         goto out;
 1529                 }
 1530                 if (flag & IO_NDELAY) {
 1531                         splx(s);
 1532                         error = EWOULDBLOCK;
 1533                         goto out;
 1534                 }
 1535                 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
 1536                     carrier ? ttyin : ttopen, 0);
 1537                 splx(s);
 1538                 if (stime && timeout_triggered(stime))
 1539                         error = EWOULDBLOCK;
 1540                 if (cc[VMIN] == 0 && error == EWOULDBLOCK) {
 1541                         error = 0;
 1542                         goto out;
 1543                 }
 1544                 if (error && error != EWOULDBLOCK)
 1545                         goto out;
 1546                 error = 0;
 1547                 goto loop;
 1548         }
 1549 read:
 1550         splx(s);
 1551 
 1552         /*
 1553          * Input present, check for input mapping and processing.
 1554          */
 1555         first = 1;
 1556         while ((c = getc(qp)) >= 0) {
 1557                 /*
 1558                  * delayed suspend (^Y)
 1559                  */
 1560                 if (CCEQ(cc[VDSUSP], c) &&
 1561                     ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
 1562                         pgsignal(tp->t_pgrp, SIGTSTP, 1);
 1563                         if (first) {
 1564                                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
 1565                                     ttybg, 0);
 1566                                 if (error)
 1567                                         break;
 1568                                 goto loop;
 1569                         }
 1570                         break;
 1571                 }
 1572                 /*
 1573                  * Interpret EOF only in canonical mode.
 1574                  */
 1575                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
 1576                         break;
 1577                 /*
 1578                  * Give user character.
 1579                  */
 1580                 error = ureadc(c, uio);
 1581                 if (error)
 1582                         break;
 1583                 if (uio->uio_resid == 0)
 1584                         break;
 1585                 /*
 1586                  * In canonical mode check for a "break character"
 1587                  * marking the end of a "line of input".
 1588                  */
 1589                 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
 1590                         break;
 1591                 first = 0;
 1592         }
 1593         /*
 1594          * Look to unblock output now that (presumably)
 1595          * the input queue has gone down.
 1596          */
 1597         s = spltty();
 1598         if (tp->t_rawq.c_cc < TTYHOG/5)
 1599                 ttyunblock(tp);
 1600         splx(s);
 1601 
 1602 out:
 1603         if (stime) {
 1604                 timeout_del(stime);
 1605                 free(stime, M_TEMP);
 1606         }
 1607         return (error);
 1608 }
 1609 
 1610 /* Call at spltty */
 1611 void
 1612 ttyunblock(struct tty *tp)
 1613 {
 1614         u_char *cc = tp->t_cc;
 1615 
 1616         splassert(IPL_TTY);
 1617 
 1618         if (ISSET(tp->t_state, TS_TBLOCK)) {
 1619                 if (ISSET(tp->t_iflag, IXOFF) &&
 1620                     cc[VSTART] != _POSIX_VDISABLE &&
 1621                     putc(cc[VSTART], &tp->t_outq) == 0) {
 1622                         CLR(tp->t_state, TS_TBLOCK);
 1623                         ttstart(tp);
 1624                 }
 1625                 /* Try to unblock remote output via hardware flow control. */
 1626                 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
 1627                     (*tp->t_hwiflow)(tp, 0) != 0)
 1628                         CLR(tp->t_state, TS_TBLOCK);
 1629         }
 1630 }
 1631 
 1632 /*
 1633  * Check the output queue on tp for space for a kernel message (from uprintf
 1634  * or tprintf).  Allow some space over the normal hiwater mark so we don't
 1635  * lose messages due to normal flow control, but don't let the tty run amok.
 1636  * Sleeps here are not interruptible, but we return prematurely if new signals
 1637  * arrive.
 1638  */
 1639 int
 1640 ttycheckoutq(struct tty *tp, int wait)
 1641 {
 1642         int hiwat, s, oldsig;
 1643 
 1644         hiwat = tp->t_hiwat;
 1645         s = spltty();
 1646         oldsig = wait ? curproc->p_siglist : 0;
 1647         if (tp->t_outq.c_cc > hiwat + 200)
 1648                 while (tp->t_outq.c_cc > hiwat) {
 1649                         ttstart(tp);
 1650                         if (wait == 0 || curproc->p_siglist != oldsig) {
 1651                                 splx(s);
 1652                                 return (0);
 1653                         }
 1654                         SET(tp->t_state, TS_ASLEEP);
 1655                         tsleep(&tp->t_outq, PZERO - 1, "ttckoutq", hz);
 1656                 }
 1657         splx(s);
 1658         return (1);
 1659 }
 1660 
 1661 /*
 1662  * Process a write call on a tty device.
 1663  */
 1664 int
 1665 ttwrite(struct tty *tp, struct uio *uio, int flag)
 1666 {
 1667         u_char *cp = NULL;
 1668         int cc, ce;
 1669         struct proc *p;
 1670         int i, hiwat, cnt, error, s;
 1671         u_char obuf[OBUFSIZ];
 1672 
 1673         hiwat = tp->t_hiwat;
 1674         cnt = uio->uio_resid;
 1675         error = 0;
 1676         cc = 0;
 1677 loop:
 1678         s = spltty();
 1679         if (!ISSET(tp->t_state, TS_CARR_ON) &&
 1680             !ISSET(tp->t_cflag, CLOCAL)) {
 1681                 if (ISSET(tp->t_state, TS_ISOPEN)) {
 1682                         splx(s);
 1683                         return (EIO);
 1684                 } else if (flag & IO_NDELAY) {
 1685                         splx(s);
 1686                         error = EWOULDBLOCK;
 1687                         goto out;
 1688                 } else {
 1689                         /* Sleep awaiting carrier. */
 1690                         error = ttysleep(tp,
 1691                             &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
 1692                         splx(s);
 1693                         if (error)
 1694                                 goto out;
 1695                         goto loop;
 1696                 }
 1697         }
 1698         splx(s);
 1699         /*
 1700          * Hang the process if it's in the background.
 1701          */
 1702         p = curproc;
 1703         if (isbackground(p, tp) &&
 1704             ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
 1705             (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
 1706             (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
 1707                 if (p->p_pgrp->pg_jobc == 0) {
 1708                         error = EIO;
 1709                         goto out;
 1710                 }
 1711                 pgsignal(p->p_pgrp, SIGTTOU, 1);
 1712                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
 1713                 if (error)
 1714                         goto out;
 1715                 goto loop;
 1716         }
 1717         /*
 1718          * Process the user's data in at most OBUFSIZ chunks.  Perform any
 1719          * output translation.  Keep track of high water mark, sleep on
 1720          * overflow awaiting device aid in acquiring new space.
 1721          */
 1722         while (uio->uio_resid > 0 || cc > 0) {
 1723                 if (ISSET(tp->t_lflag, FLUSHO)) {
 1724                         uio->uio_resid = 0;
 1725                         return (0);
 1726                 }
 1727                 if (tp->t_outq.c_cc > hiwat)
 1728                         goto ovhiwat;
 1729                 /*
 1730                  * Grab a hunk of data from the user, unless we have some
 1731                  * leftover from last time.
 1732                  */
 1733                 if (cc == 0) {
 1734                         cc = min(uio->uio_resid, OBUFSIZ);
 1735                         cp = obuf;
 1736                         error = uiomove(cp, cc, uio);
 1737                         if (error) {
 1738                                 cc = 0;
 1739                                 break;
 1740                         }
 1741                 }
 1742                 /*
 1743                  * If nothing fancy need be done, grab those characters we
 1744                  * can handle without any of ttyoutput's processing and
 1745                  * just transfer them to the output q.  For those chars
 1746                  * which require special processing (as indicated by the
 1747                  * bits in char_type), call ttyoutput.  After processing
 1748                  * a hunk of data, look for FLUSHO so ^O's will take effect
 1749                  * immediately.
 1750                  */
 1751                 while (cc > 0) {
 1752                         if (!ISSET(tp->t_oflag, OPOST))
 1753                                 ce = cc;
 1754                         else {
 1755                                 ce = cc - scanc((u_int)cc, cp, char_type,
 1756                                     CCLASSMASK);
 1757                                 /*
 1758                                  * If ce is zero, then we're processing
 1759                                  * a special character through ttyoutput.
 1760                                  */
 1761                                 if (ce == 0) {
 1762                                         tp->t_rocount = 0;
 1763                                         if (ttyoutput(*cp, tp) >= 0) {
 1764                                                 /* out of space */
 1765                                                 goto overfull;
 1766                                         }
 1767                                         cp++;
 1768                                         cc--;
 1769                                         if (ISSET(tp->t_lflag, FLUSHO) ||
 1770                                             tp->t_outq.c_cc > hiwat)
 1771                                                 goto ovhiwat;
 1772                                         continue;
 1773                                 }
 1774                         }
 1775                         /*
 1776                          * A bunch of normal characters have been found.
 1777                          * Transfer them en masse to the output queue and
 1778                          * continue processing at the top of the loop.
 1779                          * If there are any further characters in this
 1780                          * <= OBUFSIZ chunk, the first should be a character
 1781                          * requiring special handling by ttyoutput.
 1782                          */
 1783                         tp->t_rocount = 0;
 1784                         i = b_to_q(cp, ce, &tp->t_outq);
 1785                         ce -= i;
 1786                         tp->t_column += ce;
 1787                         cp += ce, cc -= ce, tk_nout += ce;
 1788                         tp->t_outcc += ce;
 1789                         if (i > 0) {
 1790                                 /* out of space */
 1791                                 goto overfull;
 1792                         }
 1793                         if (ISSET(tp->t_lflag, FLUSHO) ||
 1794                             tp->t_outq.c_cc > hiwat)
 1795                                 break;
 1796                 }
 1797                 ttstart(tp);
 1798         }
 1799 out:
 1800         /*
 1801          * If cc is nonzero, we leave the uio structure inconsistent, as the
 1802          * offset and iov pointers have moved forward, but it doesn't matter
 1803          * (the call will either return short or restart with a new uio).
 1804          */
 1805         uio->uio_resid += cc;
 1806         return (error);
 1807 
 1808 overfull:
 1809         /*
 1810          * Since we are using ring buffers, if we can't insert any more into
 1811          * the output queue, we can assume the ring is full and that someone
 1812          * forgot to set the high water mark correctly.  We set it and then
 1813          * proceed as normal.
 1814          */
 1815         hiwat = tp->t_outq.c_cc - 1;
 1816 
 1817 ovhiwat:
 1818         ttstart(tp);
 1819         s = spltty();
 1820         /*
 1821          * This can only occur if FLUSHO is set in t_lflag,
 1822          * or if ttstart/oproc is synchronous (or very fast).
 1823          */
 1824         if (tp->t_outq.c_cc <= hiwat) {
 1825                 splx(s);
 1826                 goto loop;
 1827         }
 1828         if (flag & IO_NDELAY) {
 1829                 splx(s);
 1830                 uio->uio_resid += cc;
 1831                 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
 1832         }
 1833         SET(tp->t_state, TS_ASLEEP);
 1834         error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
 1835         splx(s);
 1836         if (error)
 1837                 goto out;
 1838         goto loop;
 1839 }
 1840 
 1841 /*
 1842  * Rubout one character from the rawq of tp
 1843  * as cleanly as possible.
 1844  */
 1845 void
 1846 ttyrub(int c, struct tty *tp)
 1847 {
 1848         u_char *cp;
 1849         int savecol;
 1850         int tabc, s;
 1851 
 1852         if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
 1853                 return;
 1854         CLR(tp->t_lflag, FLUSHO);
 1855         if (ISSET(tp->t_lflag, ECHOE)) {
 1856                 if (tp->t_rocount == 0) {
 1857                         /*
 1858                          * Screwed by ttwrite; retype
 1859                          */
 1860                         ttyretype(tp);
 1861                         return;
 1862                 }
 1863                 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
 1864                         ttyrubo(tp, 2);
 1865                 else {
 1866                         CLR(c, ~TTY_CHARMASK);
 1867                         switch (CCLASS(c)) {
 1868                         case ORDINARY:
 1869                                 ttyrubo(tp, 1);
 1870                                 break;
 1871                         case BACKSPACE:
 1872                         case CONTROL:
 1873                         case NEWLINE:
 1874                         case RETURN:
 1875                         case VTAB:
 1876                                 if (ISSET(tp->t_lflag, ECHOCTL))
 1877                                         ttyrubo(tp, 2);
 1878                                 break;
 1879                         case TAB:
 1880                                 if (tp->t_rocount < tp->t_rawq.c_cc) {
 1881                                         ttyretype(tp);
 1882                                         return;
 1883                                 }
 1884                                 s = spltty();
 1885                                 savecol = tp->t_column;
 1886                                 SET(tp->t_state, TS_CNTTB);
 1887                                 SET(tp->t_lflag, FLUSHO);
 1888                                 tp->t_column = tp->t_rocol;
 1889                                 for (cp = firstc(&tp->t_rawq, &tabc); cp;
 1890                                     cp = nextc(&tp->t_rawq, cp, &tabc))
 1891                                         ttyecho(tabc, tp);
 1892                                 CLR(tp->t_lflag, FLUSHO);
 1893                                 CLR(tp->t_state, TS_CNTTB);
 1894                                 splx(s);
 1895 
 1896                                 /* savecol will now be length of the tab. */
 1897                                 savecol -= tp->t_column;
 1898                                 tp->t_column += savecol;
 1899                                 if (savecol > 8)
 1900                                         savecol = 8;    /* overflow screw */
 1901                                 while (--savecol >= 0)
 1902                                         (void)ttyoutput('\b', tp);
 1903                                 break;
 1904                         default:                        /* XXX */
 1905 #define PANICSTR        "ttyrub: would panic c = %d, val = %d\n"
 1906                                 (void)printf(PANICSTR, c, CCLASS(c));
 1907 #ifdef notdef
 1908                                 panic(PANICSTR, c, CCLASS(c));
 1909 #endif
 1910                         }
 1911                 }
 1912         } else if (ISSET(tp->t_lflag, ECHOPRT)) {
 1913                 if (!ISSET(tp->t_state, TS_ERASE)) {
 1914                         SET(tp->t_state, TS_ERASE);
 1915                         (void)ttyoutput('\\', tp);
 1916                 }
 1917                 ttyecho(c, tp);
 1918         } else
 1919                 ttyecho(tp->t_cc[VERASE], tp);
 1920         --tp->t_rocount;
 1921 }
 1922 
 1923 /*
 1924  * Back over cnt characters, erasing them.
 1925  */
 1926 static void
 1927 ttyrubo(struct tty *tp, int cnt)
 1928 {
 1929 
 1930         while (cnt-- > 0) {
 1931                 (void)ttyoutput('\b', tp);
 1932                 (void)ttyoutput(' ', tp);
 1933                 (void)ttyoutput('\b', tp);
 1934         }
 1935 }
 1936 
 1937 /*
 1938  * ttyretype --
 1939  *      Reprint the rawq line.  Note, it is assumed that c_cc has already
 1940  *      been checked.
 1941  */
 1942 void
 1943 ttyretype(struct tty *tp)
 1944 {
 1945         u_char *cp;
 1946         int s, c;
 1947 
 1948         /* Echo the reprint character. */
 1949         if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
 1950                 ttyecho(tp->t_cc[VREPRINT], tp);
 1951 
 1952         (void)ttyoutput('\n', tp);
 1953 
 1954         s = spltty();
 1955         for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
 1956                 ttyecho(c, tp);
 1957         for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
 1958                 ttyecho(c, tp);
 1959         CLR(tp->t_state, TS_ERASE);
 1960         splx(s);
 1961 
 1962         tp->t_rocount = tp->t_rawq.c_cc;
 1963         tp->t_rocol = 0;
 1964 }
 1965 
 1966 /*
 1967  * Echo a typed character to the terminal.
 1968  */
 1969 static void
 1970 ttyecho(int c, struct tty *tp)
 1971 {
 1972 
 1973         if (!ISSET(tp->t_state, TS_CNTTB))
 1974                 CLR(tp->t_lflag, FLUSHO);
 1975         if ((!ISSET(tp->t_lflag, ECHO) &&
 1976             (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
 1977             ISSET(tp->t_lflag, EXTPROC))
 1978                 return;
 1979         if (((ISSET(tp->t_lflag, ECHOCTL) &&
 1980              (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
 1981             ISSET(c, TTY_CHARMASK) == 0177)) {
 1982                 (void)ttyoutput('^', tp);
 1983                 CLR(c, ~TTY_CHARMASK);
 1984                 if (c == 0177)
 1985                         c = '?';
 1986                 else
 1987                         c += 'A' - 1;
 1988         }
 1989         (void)ttyoutput(c, tp);
 1990 }
 1991 
 1992 /*
 1993  * Wake up any readers on a tty.
 1994  */
 1995 void
 1996 ttwakeup(struct tty *tp)
 1997 {
 1998 
 1999         selwakeup(&tp->t_rsel);
 2000         if (ISSET(tp->t_state, TS_ASYNC))
 2001                 pgsignal(tp->t_pgrp, SIGIO, 1);
 2002         wakeup((caddr_t)&tp->t_rawq);
 2003         KNOTE(&tp->t_rsel.si_note, 0);
 2004 }
 2005 
 2006 /*
 2007  * Look up a code for a specified speed in a conversion table;
 2008  * used by drivers to map software speed values to hardware parameters.
 2009  */
 2010 int
 2011 ttspeedtab(int speed, const struct speedtab *table)
 2012 {
 2013 
 2014         for ( ; table->sp_speed != -1; table++)
 2015                 if (table->sp_speed == speed)
 2016                         return (table->sp_code);
 2017         return (-1);
 2018 }
 2019 
 2020 /*
 2021  * Set tty hi and low water marks.
 2022  *
 2023  * Try to arrange the dynamics so there's about one second
 2024  * from hi to low water.
 2025  */
 2026 void
 2027 ttsetwater(struct tty *tp)
 2028 {
 2029         int cps, x;
 2030 
 2031 #define CLAMP(x, h, l)  ((x) > h ? h : ((x) < l) ? l : (x))
 2032 
 2033         cps = tp->t_ospeed / 10;
 2034         tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
 2035         x += cps;
 2036         x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
 2037         tp->t_hiwat = roundup(x, CBSIZE);
 2038 #undef  CLAMP
 2039 }
 2040 
 2041 /*
 2042  * Report on state of foreground process group.
 2043  */
 2044 void
 2045 ttyinfo(struct tty *tp)
 2046 {
 2047         struct proc *p, *pick;
 2048         struct timeval utime, stime;
 2049         int tmp;
 2050 
 2051         if (ttycheckoutq(tp,0) == 0)
 2052                 return;
 2053 
 2054         /* Print load average. */
 2055         tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
 2056         ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
 2057 
 2058         if (tp->t_session == NULL)
 2059                 ttyprintf(tp, "not a controlling terminal\n");
 2060         else if (tp->t_pgrp == NULL)
 2061                 ttyprintf(tp, "no foreground process group\n");
 2062         else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL)
 2063                 ttyprintf(tp, "empty foreground process group\n");
 2064         else {
 2065                 /* Pick interesting process. */
 2066                 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
 2067                         if (proc_compare(pick, p))
 2068                                 pick = p;
 2069 
 2070                 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
 2071                     pick->p_stat == SONPROC ? "running" :
 2072                     pick->p_stat == SRUN ? "runnable" :
 2073                     pick->p_wmesg ? pick->p_wmesg : "iowait");
 2074 
 2075                 calcru(pick, &utime, &stime, NULL);
 2076 
 2077                 /* Round up and print user time. */
 2078                 utime.tv_usec += 5000;
 2079                 if (utime.tv_usec >= 1000000) {
 2080                         utime.tv_sec += 1;
 2081                         utime.tv_usec -= 1000000;
 2082                 }
 2083                 ttyprintf(tp, "%ld.%02ldu ", utime.tv_sec,
 2084                     utime.tv_usec / 10000);
 2085 
 2086                 /* Round up and print system time. */
 2087                 stime.tv_usec += 5000;
 2088                 if (stime.tv_usec >= 1000000) {
 2089                         stime.tv_sec += 1;
 2090                         stime.tv_usec -= 1000000;
 2091                 }
 2092                 ttyprintf(tp, "%ld.%02lds ", stime.tv_sec,
 2093                     stime.tv_usec / 10000);
 2094 
 2095 #define pgtok(a)        (((u_long) ((a) * PAGE_SIZE) / 1024))
 2096                 /* Print percentage cpu, resident set size. */
 2097                 tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
 2098                 ttyprintf(tp, "%d%% %ldk\n",
 2099                     tmp / 100,
 2100                     pick->p_stat == SIDL || P_ZOMBIE(pick) ? 0 :
 2101                         vm_resident_count(pick->p_vmspace));
 2102         }
 2103         tp->t_rocount = 0;      /* so pending input will be retyped if BS */
 2104 }
 2105 
 2106 /*
 2107  * Returns 1 if p2 is "better" than p1
 2108  *
 2109  * The algorithm for picking the "interesting" process is thus:
 2110  *
 2111  *      1) Only foreground processes are eligible - implied.
 2112  *      2) Runnable processes are favored over anything else.  The runner
 2113  *         with the highest cpu utilization is picked (p_estcpu).  Ties are
 2114  *         broken by picking the highest pid.
 2115  *      3) The sleeper with the shortest sleep time is next.  With ties,
 2116  *         we pick out just "short-term" sleepers (P_SINTR == 0).
 2117  *      4) Further ties are broken by picking the highest pid.
 2118  */
 2119 #define ISRUN(p)        (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL) || \
 2120                          ((p)->p_stat == SONPROC))
 2121 #define TESTAB(a, b)    ((a)<<1 | (b))
 2122 #define ONLYA   2
 2123 #define ONLYB   1
 2124 #define BOTH    3
 2125 
 2126 static int
 2127 proc_compare(struct proc *p1, struct proc *p2)
 2128 {
 2129 
 2130         if (p1 == NULL)
 2131                 return (1);
 2132         /*
 2133          * see if at least one of them is runnable
 2134          */
 2135         switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
 2136         case ONLYA:
 2137                 return (0);
 2138         case ONLYB:
 2139                 return (1);
 2140         case BOTH:
 2141                 /*
 2142                  * tie - favor one with highest recent cpu utilization
 2143                  */
 2144                 if (p2->p_estcpu > p1->p_estcpu)
 2145                         return (1);
 2146                 if (p1->p_estcpu > p2->p_estcpu)
 2147                         return (0);
 2148                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2149         }
 2150         /*
 2151          * weed out zombies
 2152          */
 2153         switch (TESTAB(P_ZOMBIE(p1), P_ZOMBIE(p2))) {
 2154         case ONLYA:
 2155                 return (1);
 2156         case ONLYB:
 2157                 return (0);
 2158         case BOTH:
 2159                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2160         }
 2161         /*
 2162          * pick the one with the smallest sleep time
 2163          */
 2164         if (p2->p_slptime > p1->p_slptime)
 2165                 return (0);
 2166         if (p1->p_slptime > p2->p_slptime)
 2167                 return (1);
 2168         /*
 2169          * favor one sleeping in a non-interruptible sleep
 2170          */
 2171         if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
 2172                 return (1);
 2173         if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
 2174                 return (0);
 2175         return (p2->p_pid > p1->p_pid);         /* tie - return highest pid */
 2176 }
 2177 
 2178 /*
 2179  * Output char to tty; console putchar style.
 2180  */
 2181 int
 2182 tputchar(int c, struct tty *tp)
 2183 {
 2184         int s;
 2185 
 2186         s = spltty();
 2187         if (ISSET(tp->t_state,
 2188             TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
 2189                 splx(s);
 2190                 return (-1);
 2191         }
 2192         if (c == '\n')
 2193                 (void)ttyoutput('\r', tp);
 2194         (void)ttyoutput(c, tp);
 2195         ttstart(tp);
 2196         splx(s);
 2197         return (0);
 2198 }
 2199 
 2200 /*
 2201  * Sleep on chan, returning ERESTART if tty changed while we napped and
 2202  * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep.  If
 2203  * the tty is revoked, restarting a pending call will redo validation done
 2204  * at the start of the call.
 2205  */
 2206 int
 2207 ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo)
 2208 {
 2209         int error;
 2210         short gen;
 2211 
 2212         gen = tp->t_gen;
 2213         if ((error = tsleep(chan, pri, wmesg, timo)) != 0)
 2214                 return (error);
 2215         return (tp->t_gen == gen ? 0 : ERESTART);
 2216 }
 2217 
 2218 /*
 2219  * Initialise the global tty list.
 2220  */
 2221 void
 2222 tty_init(void)
 2223 {
 2224 
 2225         TAILQ_INIT(&ttylist);
 2226         tty_count = 0;
 2227 }
 2228 
 2229 /*
 2230  * Allocate a tty structure and its associated buffers, and attach it to the
 2231  * tty list.
 2232  */
 2233 struct tty *
 2234 ttymalloc(void)
 2235 {
 2236         struct tty *tp;
 2237 
 2238         MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
 2239         bzero(tp, sizeof *tp);
 2240         /* XXX: default to 1024 chars for now */
 2241         clalloc(&tp->t_rawq, 1024, 1);
 2242         clalloc(&tp->t_canq, 1024, 1);
 2243         /* output queue doesn't need quoting */
 2244         clalloc(&tp->t_outq, 1024, 0);
 2245 
 2246         TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
 2247         ++tty_count;
 2248         timeout_set(&tp->t_rstrt_to, ttrstrt, tp);
 2249 
 2250         return(tp);
 2251 }
 2252 
 2253 
 2254 /*
 2255  * Free a tty structure and its buffers, after removing it from the tty list.
 2256  */
 2257 void
 2258 ttyfree(struct tty *tp)
 2259 {
 2260 
 2261         --tty_count;
 2262 #ifdef DIAGNOSTIC
 2263         if (tty_count < 0)
 2264                 panic("ttyfree: tty_count < 0");
 2265 #endif
 2266         TAILQ_REMOVE(&ttylist, tp, tty_link);
 2267 
 2268         clfree(&tp->t_rawq);
 2269         clfree(&tp->t_canq);
 2270         clfree(&tp->t_outq);
 2271         FREE(tp, M_TTYS);
 2272 }
 2273 
 2274 struct itty *ttystats;
 2275 
 2276 int
 2277 ttystats_init(void)
 2278 {
 2279         struct itty *itp;
 2280         struct tty *tp;
 2281 
 2282         ttystats = malloc(tty_count * sizeof(struct itty),
 2283             M_SYSCTL, M_WAITOK);
 2284         for (tp = TAILQ_FIRST(&ttylist), itp = ttystats; tp;
 2285             tp = TAILQ_NEXT(tp, tty_link), itp++) {
 2286                 itp->t_dev = tp->t_dev;
 2287                 itp->t_rawq_c_cc = tp->t_rawq.c_cc;
 2288                 itp->t_canq_c_cc = tp->t_canq.c_cc;
 2289                 itp->t_outq_c_cc = tp->t_outq.c_cc;
 2290                 itp->t_hiwat = tp->t_hiwat;
 2291                 itp->t_lowat = tp->t_lowat;
 2292                 itp->t_column = tp->t_column;
 2293                 itp->t_state = tp->t_state;
 2294                 itp->t_session = tp->t_session;
 2295                 if (tp->t_pgrp)
 2296                         itp->t_pgrp_pg_id = tp->t_pgrp->pg_id;
 2297                 else
 2298                         itp->t_pgrp_pg_id = 0;
 2299                 itp->t_line = tp->t_line;
 2300         }
 2301         return (0);
 2302 }
 2303 
 2304 /*
 2305  * Return tty-related information.
 2306  */
 2307 int
 2308 sysctl_tty(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
 2309     size_t newlen)
 2310 {
 2311         int err;
 2312 
 2313         if (namelen != 1)
 2314                 return (ENOTDIR);
 2315 
 2316         switch (name[0]) {
 2317         case KERN_TTY_TKNIN:
 2318                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_nin));
 2319         case KERN_TTY_TKNOUT:
 2320                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_nout));
 2321         case KERN_TTY_TKRAWCC:
 2322                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_rawcc));
 2323         case KERN_TTY_TKCANCC:
 2324                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_cancc));
 2325         case KERN_TTY_INFO:
 2326                 err = ttystats_init();
 2327                 if (err)
 2328                         return (err);
 2329                 err = sysctl_rdstruct(oldp, oldlenp, newp, ttystats,
 2330                     tty_count * sizeof(struct itty));
 2331                 free(ttystats, M_SYSCTL);
 2332                 return (err);
 2333         default:
 2334 #if NPTY > 0
 2335                 return (sysctl_pty(name, namelen, oldp, oldlenp, newp, newlen));
 2336 #else
 2337                 return (EOPNOTSUPP);
 2338 #endif
 2339         }
 2340         /* NOTREACHED */
 2341 }
 2342 
 2343 void
 2344 ttytstamp(struct tty *tp, int octs, int ncts, int odcd, int ndcd)
 2345 {
 2346         int doit = 0;
 2347 
 2348         if (ncts ^ octs)
 2349                 doit |= ncts ? ISSET(tp->t_flags, TS_TSTAMPCTSSET) :
 2350                     ISSET(tp->t_flags, TS_TSTAMPCTSCLR);
 2351         if (ndcd ^ odcd)
 2352                 doit |= ndcd ? ISSET(tp->t_flags, TS_TSTAMPDCDSET) :
 2353                     ISSET(tp->t_flags, TS_TSTAMPDCDCLR);
 2354 
 2355         if (doit)
 2356                 microtime(&tp->t_tv);
 2357 }

/* [<][>][^][v][top][bottom][index][help] */