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

Cache object: 3bbd137b4e5000ce36039016c4e40c15


[ 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.