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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 0e349d582ee2fc434f4f51d52f9d4a75


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