The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/tty.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: tty.c,v 1.78 2008/11/11 15:33:02 deraadt 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, obufcc = 0;
 1669         struct proc *p;
 1670         int i, hiwat, error, s;
 1671         size_t cnt;
 1672         u_char obuf[OBUFSIZ];
 1673 
 1674         hiwat = tp->t_hiwat;
 1675         cnt = uio->uio_resid;
 1676         error = 0;
 1677         cc = 0;
 1678 loop:
 1679         s = spltty();
 1680         if (!ISSET(tp->t_state, TS_CARR_ON) &&
 1681             !ISSET(tp->t_cflag, CLOCAL)) {
 1682                 if (ISSET(tp->t_state, TS_ISOPEN)) {
 1683                         splx(s);
 1684                         error = EIO;
 1685                         goto done;
 1686                 } else if (flag & IO_NDELAY) {
 1687                         splx(s);
 1688                         error = EWOULDBLOCK;
 1689                         goto out;
 1690                 } else {
 1691                         /* Sleep awaiting carrier. */
 1692                         error = ttysleep(tp,
 1693                             &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
 1694                         splx(s);
 1695                         if (error)
 1696                                 goto out;
 1697                         goto loop;
 1698                 }
 1699         }
 1700         splx(s);
 1701         /*
 1702          * Hang the process if it's in the background.
 1703          */
 1704         p = curproc;
 1705         if (isbackground(p, tp) &&
 1706             ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
 1707             (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
 1708             (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
 1709                 if (p->p_pgrp->pg_jobc == 0) {
 1710                         error = EIO;
 1711                         goto out;
 1712                 }
 1713                 pgsignal(p->p_pgrp, SIGTTOU, 1);
 1714                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
 1715                 if (error)
 1716                         goto out;
 1717                 goto loop;
 1718         }
 1719         /*
 1720          * Process the user's data in at most OBUFSIZ chunks.  Perform any
 1721          * output translation.  Keep track of high water mark, sleep on
 1722          * overflow awaiting device aid in acquiring new space.
 1723          */
 1724         while (uio->uio_resid > 0 || cc > 0) {
 1725                 if (ISSET(tp->t_lflag, FLUSHO)) {
 1726                         uio->uio_resid = 0;
 1727                         goto done;
 1728                 }
 1729                 if (tp->t_outq.c_cc > hiwat)
 1730                         goto ovhiwat;
 1731                 /*
 1732                  * Grab a hunk of data from the user, unless we have some
 1733                  * leftover from last time.
 1734                  */
 1735                 if (cc == 0) {
 1736                         cc = MIN(uio->uio_resid, OBUFSIZ);
 1737                         cp = obuf;
 1738                         error = uiomove(cp, cc, uio);
 1739                         if (error) {
 1740                                 cc = 0;
 1741                                 break;
 1742                         }
 1743                         if (cc > obufcc)
 1744                                 obufcc = cc;
 1745                 }
 1746                 /*
 1747                  * If nothing fancy need be done, grab those characters we
 1748                  * can handle without any of ttyoutput's processing and
 1749                  * just transfer them to the output q.  For those chars
 1750                  * which require special processing (as indicated by the
 1751                  * bits in char_type), call ttyoutput.  After processing
 1752                  * a hunk of data, look for FLUSHO so ^O's will take effect
 1753                  * immediately.
 1754                  */
 1755                 while (cc > 0) {
 1756                         if (!ISSET(tp->t_oflag, OPOST))
 1757                                 ce = cc;
 1758                         else {
 1759                                 ce = cc - scanc((u_int)cc, cp, char_type,
 1760                                     CCLASSMASK);
 1761                                 /*
 1762                                  * If ce is zero, then we're processing
 1763                                  * a special character through ttyoutput.
 1764                                  */
 1765                                 if (ce == 0) {
 1766                                         tp->t_rocount = 0;
 1767                                         if (ttyoutput(*cp, tp) >= 0) {
 1768                                                 /* out of space */
 1769                                                 goto overfull;
 1770                                         }
 1771                                         cp++;
 1772                                         cc--;
 1773                                         if (ISSET(tp->t_lflag, FLUSHO) ||
 1774                                             tp->t_outq.c_cc > hiwat)
 1775                                                 goto ovhiwat;
 1776                                         continue;
 1777                                 }
 1778                         }
 1779                         /*
 1780                          * A bunch of normal characters have been found.
 1781                          * Transfer them en masse to the output queue and
 1782                          * continue processing at the top of the loop.
 1783                          * If there are any further characters in this
 1784                          * <= OBUFSIZ chunk, the first should be a character
 1785                          * requiring special handling by ttyoutput.
 1786                          */
 1787                         tp->t_rocount = 0;
 1788                         i = b_to_q(cp, ce, &tp->t_outq);
 1789                         ce -= i;
 1790                         tp->t_column += ce;
 1791                         cp += ce, cc -= ce, tk_nout += ce;
 1792                         tp->t_outcc += ce;
 1793                         if (i > 0) {
 1794                                 /* out of space */
 1795                                 goto overfull;
 1796                         }
 1797                         if (ISSET(tp->t_lflag, FLUSHO) ||
 1798                             tp->t_outq.c_cc > hiwat)
 1799                                 break;
 1800                 }
 1801                 ttstart(tp);
 1802         }
 1803 out:
 1804         /*
 1805          * If cc is nonzero, we leave the uio structure inconsistent, as the
 1806          * offset and iov pointers have moved forward, but it doesn't matter
 1807          * (the call will either return short or restart with a new uio).
 1808          */
 1809         uio->uio_resid += cc;
 1810 done:
 1811         if (obufcc)
 1812                 bzero(obuf, obufcc);
 1813         return (error);
 1814 
 1815 overfull:
 1816         /*
 1817          * Since we are using ring buffers, if we can't insert any more into
 1818          * the output queue, we can assume the ring is full and that someone
 1819          * forgot to set the high water mark correctly.  We set it and then
 1820          * proceed as normal.
 1821          */
 1822         hiwat = tp->t_outq.c_cc - 1;
 1823 
 1824 ovhiwat:
 1825         ttstart(tp);
 1826         s = spltty();
 1827         /*
 1828          * This can only occur if FLUSHO is set in t_lflag,
 1829          * or if ttstart/oproc is synchronous (or very fast).
 1830          */
 1831         if (tp->t_outq.c_cc <= hiwat) {
 1832                 splx(s);
 1833                 goto loop;
 1834         }
 1835         if (flag & IO_NDELAY) {
 1836                 splx(s);
 1837                 uio->uio_resid += cc;
 1838                 if (obufcc)
 1839                         bzero(obuf, obufcc);
 1840                 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
 1841         }
 1842         SET(tp->t_state, TS_ASLEEP);
 1843         error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
 1844         splx(s);
 1845         if (error)
 1846                 goto out;
 1847         goto loop;
 1848 }
 1849 
 1850 /*
 1851  * Rubout one character from the rawq of tp
 1852  * as cleanly as possible.
 1853  */
 1854 void
 1855 ttyrub(int c, struct tty *tp)
 1856 {
 1857         u_char *cp;
 1858         int savecol;
 1859         int tabc, s;
 1860 
 1861         if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
 1862                 return;
 1863         CLR(tp->t_lflag, FLUSHO);
 1864         if (ISSET(tp->t_lflag, ECHOE)) {
 1865                 if (tp->t_rocount == 0) {
 1866                         /*
 1867                          * Screwed by ttwrite; retype
 1868                          */
 1869                         ttyretype(tp);
 1870                         return;
 1871                 }
 1872                 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
 1873                         ttyrubo(tp, 2);
 1874                 else {
 1875                         CLR(c, ~TTY_CHARMASK);
 1876                         switch (CCLASS(c)) {
 1877                         case ORDINARY:
 1878                                 ttyrubo(tp, 1);
 1879                                 break;
 1880                         case BACKSPACE:
 1881                         case CONTROL:
 1882                         case NEWLINE:
 1883                         case RETURN:
 1884                         case VTAB:
 1885                                 if (ISSET(tp->t_lflag, ECHOCTL))
 1886                                         ttyrubo(tp, 2);
 1887                                 break;
 1888                         case TAB:
 1889                                 if (tp->t_rocount < tp->t_rawq.c_cc) {
 1890                                         ttyretype(tp);
 1891                                         return;
 1892                                 }
 1893                                 s = spltty();
 1894                                 savecol = tp->t_column;
 1895                                 SET(tp->t_state, TS_CNTTB);
 1896                                 SET(tp->t_lflag, FLUSHO);
 1897                                 tp->t_column = tp->t_rocol;
 1898                                 for (cp = firstc(&tp->t_rawq, &tabc); cp;
 1899                                     cp = nextc(&tp->t_rawq, cp, &tabc))
 1900                                         ttyecho(tabc, tp);
 1901                                 CLR(tp->t_lflag, FLUSHO);
 1902                                 CLR(tp->t_state, TS_CNTTB);
 1903                                 splx(s);
 1904 
 1905                                 /* savecol will now be length of the tab. */
 1906                                 savecol -= tp->t_column;
 1907                                 tp->t_column += savecol;
 1908                                 if (savecol > 8)
 1909                                         savecol = 8;    /* overflow screw */
 1910                                 while (--savecol >= 0)
 1911                                         (void)ttyoutput('\b', tp);
 1912                                 break;
 1913                         default:                        /* XXX */
 1914 #define PANICSTR        "ttyrub: would panic c = %d, val = %d\n"
 1915                                 (void)printf(PANICSTR, c, CCLASS(c));
 1916 #ifdef notdef
 1917                                 panic(PANICSTR, c, CCLASS(c));
 1918 #endif
 1919                         }
 1920                 }
 1921         } else if (ISSET(tp->t_lflag, ECHOPRT)) {
 1922                 if (!ISSET(tp->t_state, TS_ERASE)) {
 1923                         SET(tp->t_state, TS_ERASE);
 1924                         (void)ttyoutput('\\', tp);
 1925                 }
 1926                 ttyecho(c, tp);
 1927         } else
 1928                 ttyecho(tp->t_cc[VERASE], tp);
 1929         --tp->t_rocount;
 1930 }
 1931 
 1932 /*
 1933  * Back over cnt characters, erasing them.
 1934  */
 1935 static void
 1936 ttyrubo(struct tty *tp, int cnt)
 1937 {
 1938 
 1939         while (cnt-- > 0) {
 1940                 (void)ttyoutput('\b', tp);
 1941                 (void)ttyoutput(' ', tp);
 1942                 (void)ttyoutput('\b', tp);
 1943         }
 1944 }
 1945 
 1946 /*
 1947  * ttyretype --
 1948  *      Reprint the rawq line.  Note, it is assumed that c_cc has already
 1949  *      been checked.
 1950  */
 1951 void
 1952 ttyretype(struct tty *tp)
 1953 {
 1954         u_char *cp;
 1955         int s, c;
 1956 
 1957         /* Echo the reprint character. */
 1958         if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
 1959                 ttyecho(tp->t_cc[VREPRINT], tp);
 1960 
 1961         (void)ttyoutput('\n', tp);
 1962 
 1963         s = spltty();
 1964         for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
 1965                 ttyecho(c, tp);
 1966         for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
 1967                 ttyecho(c, tp);
 1968         CLR(tp->t_state, TS_ERASE);
 1969         splx(s);
 1970 
 1971         tp->t_rocount = tp->t_rawq.c_cc;
 1972         tp->t_rocol = 0;
 1973 }
 1974 
 1975 /*
 1976  * Echo a typed character to the terminal.
 1977  */
 1978 static void
 1979 ttyecho(int c, struct tty *tp)
 1980 {
 1981 
 1982         if (!ISSET(tp->t_state, TS_CNTTB))
 1983                 CLR(tp->t_lflag, FLUSHO);
 1984         if ((!ISSET(tp->t_lflag, ECHO) &&
 1985             (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
 1986             ISSET(tp->t_lflag, EXTPROC))
 1987                 return;
 1988         if (((ISSET(tp->t_lflag, ECHOCTL) &&
 1989              (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
 1990             ISSET(c, TTY_CHARMASK) == 0177)) {
 1991                 (void)ttyoutput('^', tp);
 1992                 CLR(c, ~TTY_CHARMASK);
 1993                 if (c == 0177)
 1994                         c = '?';
 1995                 else
 1996                         c += 'A' - 1;
 1997         }
 1998         (void)ttyoutput(c, tp);
 1999 }
 2000 
 2001 /*
 2002  * Wake up any readers on a tty.
 2003  */
 2004 void
 2005 ttwakeup(struct tty *tp)
 2006 {
 2007 
 2008         selwakeup(&tp->t_rsel);
 2009         if (ISSET(tp->t_state, TS_ASYNC))
 2010                 pgsignal(tp->t_pgrp, SIGIO, 1);
 2011         wakeup((caddr_t)&tp->t_rawq);
 2012         KNOTE(&tp->t_rsel.si_note, 0);
 2013 }
 2014 
 2015 /*
 2016  * Look up a code for a specified speed in a conversion table;
 2017  * used by drivers to map software speed values to hardware parameters.
 2018  */
 2019 int
 2020 ttspeedtab(int speed, const struct speedtab *table)
 2021 {
 2022 
 2023         for ( ; table->sp_speed != -1; table++)
 2024                 if (table->sp_speed == speed)
 2025                         return (table->sp_code);
 2026         return (-1);
 2027 }
 2028 
 2029 /*
 2030  * Set tty hi and low water marks.
 2031  *
 2032  * Try to arrange the dynamics so there's about one second
 2033  * from hi to low water.
 2034  */
 2035 void
 2036 ttsetwater(struct tty *tp)
 2037 {
 2038         int cps, x;
 2039 
 2040 #define CLAMP(x, h, l)  ((x) > h ? h : ((x) < l) ? l : (x))
 2041 
 2042         cps = tp->t_ospeed / 10;
 2043         tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
 2044         x += cps;
 2045         x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
 2046         tp->t_hiwat = roundup(x, CBSIZE);
 2047 #undef  CLAMP
 2048 }
 2049 
 2050 /*
 2051  * Report on state of foreground process group.
 2052  */
 2053 void
 2054 ttyinfo(struct tty *tp)
 2055 {
 2056         struct proc *p, *pick;
 2057         struct timeval utime, stime;
 2058         int tmp;
 2059 
 2060         if (ttycheckoutq(tp,0) == 0)
 2061                 return;
 2062 
 2063         /* Print load average. */
 2064         tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
 2065         ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
 2066 
 2067         if (tp->t_session == NULL)
 2068                 ttyprintf(tp, "not a controlling terminal\n");
 2069         else if (tp->t_pgrp == NULL)
 2070                 ttyprintf(tp, "no foreground process group\n");
 2071         else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL)
 2072                 ttyprintf(tp, "empty foreground process group\n");
 2073         else {
 2074                 int pctcpu;
 2075                 long rss;
 2076 
 2077                 /* Pick interesting process. */
 2078                 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
 2079                         if (proc_compare(pick, p))
 2080                                 pick = p;
 2081 
 2082                 /* Calculate percentage cpu, resident set size. */
 2083                 pctcpu = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
 2084                 rss = pick->p_stat == SIDL || P_ZOMBIE(pick) ? 0 :
 2085                     vm_resident_count(pick->p_vmspace);
 2086 
 2087                 calcru(pick, &utime, &stime, NULL);
 2088 
 2089                 /* Round up and print user time. */
 2090                 utime.tv_usec += 5000;
 2091                 if (utime.tv_usec >= 1000000) {
 2092                         utime.tv_sec += 1;
 2093                         utime.tv_usec -= 1000000;
 2094                 }
 2095 
 2096                 /* Round up and print system time. */
 2097                 stime.tv_usec += 5000;
 2098                 if (stime.tv_usec >= 1000000) {
 2099                         stime.tv_sec += 1;
 2100                         stime.tv_usec -= 1000000;
 2101                 }
 2102 
 2103                 ttyprintf(tp,
 2104                     " cmd: %s %d [%s] %ld.%02ldu %ld.%02lds %d%% %ldk\n",
 2105                     pick->p_comm, pick->p_pid,
 2106                     pick->p_stat == SONPROC ? "running" :
 2107                     pick->p_stat == SRUN ? "runnable" :
 2108                     pick->p_wmesg ? pick->p_wmesg : "iowait",
 2109                     utime.tv_sec, utime.tv_usec / 10000,
 2110                     stime.tv_sec, stime.tv_usec / 10000, pctcpu / 100, rss);
 2111         }
 2112         tp->t_rocount = 0;      /* so pending input will be retyped if BS */
 2113 }
 2114 
 2115 /*
 2116  * Returns 1 if p2 is "better" than p1
 2117  *
 2118  * The algorithm for picking the "interesting" process is thus:
 2119  *
 2120  *      1) Only foreground processes are eligible - implied.
 2121  *      2) Runnable processes are favored over anything else.  The runner
 2122  *         with the highest cpu utilization is picked (p_estcpu).  Ties are
 2123  *         broken by picking the highest pid.
 2124  *      3) The sleeper with the shortest sleep time is next.  With ties,
 2125  *         we pick out just "short-term" sleepers (P_SINTR == 0).
 2126  *      4) Further ties are broken by picking the highest pid.
 2127  */
 2128 #define ISRUN(p)        (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL) || \
 2129                          ((p)->p_stat == SONPROC))
 2130 #define TESTAB(a, b)    ((a)<<1 | (b))
 2131 #define ONLYA   2
 2132 #define ONLYB   1
 2133 #define BOTH    3
 2134 
 2135 static int
 2136 proc_compare(struct proc *p1, struct proc *p2)
 2137 {
 2138 
 2139         if (p1 == NULL)
 2140                 return (1);
 2141         /*
 2142          * see if at least one of them is runnable
 2143          */
 2144         switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
 2145         case ONLYA:
 2146                 return (0);
 2147         case ONLYB:
 2148                 return (1);
 2149         case BOTH:
 2150                 /*
 2151                  * tie - favor one with highest recent cpu utilization
 2152                  */
 2153                 if (p2->p_estcpu > p1->p_estcpu)
 2154                         return (1);
 2155                 if (p1->p_estcpu > p2->p_estcpu)
 2156                         return (0);
 2157                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2158         }
 2159         /*
 2160          * weed out zombies
 2161          */
 2162         switch (TESTAB(P_ZOMBIE(p1), P_ZOMBIE(p2))) {
 2163         case ONLYA:
 2164                 return (1);
 2165         case ONLYB:
 2166                 return (0);
 2167         case BOTH:
 2168                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2169         }
 2170         /*
 2171          * pick the one with the smallest sleep time
 2172          */
 2173         if (p2->p_slptime > p1->p_slptime)
 2174                 return (0);
 2175         if (p1->p_slptime > p2->p_slptime)
 2176                 return (1);
 2177         /*
 2178          * favor one sleeping in a non-interruptible sleep
 2179          */
 2180         if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
 2181                 return (1);
 2182         if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
 2183                 return (0);
 2184         return (p2->p_pid > p1->p_pid);         /* tie - return highest pid */
 2185 }
 2186 
 2187 /*
 2188  * Output char to tty; console putchar style.
 2189  */
 2190 int
 2191 tputchar(int c, struct tty *tp)
 2192 {
 2193         int s;
 2194 
 2195         s = spltty();
 2196         if (ISSET(tp->t_state, TS_ISOPEN) == 0 ||
 2197             !(ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))) {
 2198                 splx(s);
 2199                 return (-1);
 2200         }
 2201         if (c == '\n')
 2202                 (void)ttyoutput('\r', tp);
 2203         (void)ttyoutput(c, tp);
 2204         ttstart(tp);
 2205         splx(s);
 2206         return (0);
 2207 }
 2208 
 2209 /*
 2210  * Sleep on chan, returning ERESTART if tty changed while we napped and
 2211  * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep.  If
 2212  * the tty is revoked, restarting a pending call will redo validation done
 2213  * at the start of the call.
 2214  */
 2215 int
 2216 ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo)
 2217 {
 2218         int error;
 2219         short gen;
 2220 
 2221         gen = tp->t_gen;
 2222         if ((error = tsleep(chan, pri, wmesg, timo)) != 0)
 2223                 return (error);
 2224         return (tp->t_gen == gen ? 0 : ERESTART);
 2225 }
 2226 
 2227 /*
 2228  * Initialise the global tty list.
 2229  */
 2230 void
 2231 tty_init(void)
 2232 {
 2233 
 2234         TAILQ_INIT(&ttylist);
 2235         tty_count = 0;
 2236 }
 2237 
 2238 /*
 2239  * Allocate a tty structure and its associated buffers, and attach it to the
 2240  * tty list.
 2241  */
 2242 struct tty *
 2243 ttymalloc(void)
 2244 {
 2245         struct tty *tp;
 2246 
 2247         tp = malloc(sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO);
 2248 
 2249         /* XXX: default to 1024 chars for now */
 2250         clalloc(&tp->t_rawq, 1024, 1);
 2251         clalloc(&tp->t_canq, 1024, 1);
 2252         /* output queue doesn't need quoting */
 2253         clalloc(&tp->t_outq, 1024, 0);
 2254 
 2255         TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
 2256         ++tty_count;
 2257         timeout_set(&tp->t_rstrt_to, ttrstrt, tp);
 2258 
 2259         return(tp);
 2260 }
 2261 
 2262 
 2263 /*
 2264  * Free a tty structure and its buffers, after removing it from the tty list.
 2265  */
 2266 void
 2267 ttyfree(struct tty *tp)
 2268 {
 2269 
 2270         --tty_count;
 2271 #ifdef DIAGNOSTIC
 2272         if (tty_count < 0)
 2273                 panic("ttyfree: tty_count < 0");
 2274 #endif
 2275         TAILQ_REMOVE(&ttylist, tp, tty_link);
 2276 
 2277         clfree(&tp->t_rawq);
 2278         clfree(&tp->t_canq);
 2279         clfree(&tp->t_outq);
 2280         free(tp, M_TTYS);
 2281 }
 2282 
 2283 struct itty *ttystats;
 2284 
 2285 int
 2286 ttystats_init(void)
 2287 {
 2288         struct itty *itp;
 2289         struct tty *tp;
 2290 
 2291         ttystats = malloc(tty_count * sizeof(struct itty),
 2292             M_SYSCTL, M_WAITOK);
 2293         for (tp = TAILQ_FIRST(&ttylist), itp = ttystats; tp;
 2294             tp = TAILQ_NEXT(tp, tty_link), itp++) {
 2295                 itp->t_dev = tp->t_dev;
 2296                 itp->t_rawq_c_cc = tp->t_rawq.c_cc;
 2297                 itp->t_canq_c_cc = tp->t_canq.c_cc;
 2298                 itp->t_outq_c_cc = tp->t_outq.c_cc;
 2299                 itp->t_hiwat = tp->t_hiwat;
 2300                 itp->t_lowat = tp->t_lowat;
 2301                 itp->t_column = tp->t_column;
 2302                 itp->t_state = tp->t_state;
 2303                 itp->t_session = tp->t_session;
 2304                 if (tp->t_pgrp)
 2305                         itp->t_pgrp_pg_id = tp->t_pgrp->pg_id;
 2306                 else
 2307                         itp->t_pgrp_pg_id = 0;
 2308                 itp->t_line = tp->t_line;
 2309         }
 2310         return (0);
 2311 }
 2312 
 2313 /*
 2314  * Return tty-related information.
 2315  */
 2316 int
 2317 sysctl_tty(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
 2318     size_t newlen)
 2319 {
 2320         int err;
 2321 
 2322         if (namelen != 1)
 2323                 return (ENOTDIR);
 2324 
 2325         switch (name[0]) {
 2326         case KERN_TTY_TKNIN:
 2327                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_nin));
 2328         case KERN_TTY_TKNOUT:
 2329                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_nout));
 2330         case KERN_TTY_TKRAWCC:
 2331                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_rawcc));
 2332         case KERN_TTY_TKCANCC:
 2333                 return (sysctl_rdquad(oldp, oldlenp, newp, tk_cancc));
 2334         case KERN_TTY_INFO:
 2335                 err = ttystats_init();
 2336                 if (err)
 2337                         return (err);
 2338                 err = sysctl_rdstruct(oldp, oldlenp, newp, ttystats,
 2339                     tty_count * sizeof(struct itty));
 2340                 free(ttystats, M_SYSCTL);
 2341                 return (err);
 2342         default:
 2343 #if NPTY > 0
 2344                 return (sysctl_pty(name, namelen, oldp, oldlenp, newp, newlen));
 2345 #else
 2346                 return (EOPNOTSUPP);
 2347 #endif
 2348         }
 2349         /* NOTREACHED */
 2350 }
 2351 
 2352 void
 2353 ttytstamp(struct tty *tp, int octs, int ncts, int odcd, int ndcd)
 2354 {
 2355         int doit = 0;
 2356 
 2357         if (ncts ^ octs)
 2358                 doit |= ncts ? ISSET(tp->t_flags, TS_TSTAMPCTSSET) :
 2359                     ISSET(tp->t_flags, TS_TSTAMPCTSCLR);
 2360         if (ndcd ^ odcd)
 2361                 doit |= ndcd ? ISSET(tp->t_flags, TS_TSTAMPDCDSET) :
 2362                     ISSET(tp->t_flags, TS_TSTAMPDCDCLR);
 2363 
 2364         if (doit)
 2365                 microtime(&tp->t_tv);
 2366 }

Cache object: 0b625d2a80081dba7874ffef906f9307


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.