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 /*-
    2  * Copyright (c) 1982, 1986, 1990, 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  * (c) UNIX System Laboratories, Inc.
    5  * All or some portions of this file are derived from material licensed
    6  * to the University of California by American Telephone and Telegraph
    7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    8  * the permission of UNIX System Laboratories, Inc.
    9  *
   10  * Copyright (c) 2002 Networks Associates Technologies, Inc.
   11  * All rights reserved.
   12  *
   13  * Portions of this software were developed for the FreeBSD Project by
   14  * ThinkSec AS and NAI Labs, the Security Research Division of Network
   15  * Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
   16  * ("CBOSS"), as part of the DARPA CHATS research program.
   17  *
   18  * Redistribution and use in source and binary forms, with or without
   19  * modification, are permitted provided that the following conditions
   20  * are met:
   21  * 1. Redistributions of source code must retain the above copyright
   22  *    notice, this list of conditions and the following disclaimer.
   23  * 2. Redistributions in binary form must reproduce the above copyright
   24  *    notice, this list of conditions and the following disclaimer in the
   25  *    documentation and/or other materials provided with the distribution.
   26  * 4. Neither the name of the University nor the names of its contributors
   27  *    may be used to endorse or promote products derived from this software
   28  *    without specific prior written permission.
   29  *
   30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   40  * SUCH DAMAGE.
   41  *
   42  *      @(#)tty.c       8.8 (Berkeley) 1/21/94
   43  */
   44 
   45 /*-
   46  * TODO:
   47  *      o Fix races for sending the start char in ttyflush().
   48  *      o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
   49  *        With luck, there will be MIN chars before select() returns().
   50  *      o Handle CLOCAL consistently for ptys.  Perhaps disallow setting it.
   51  *      o Don't allow input in TS_ZOMBIE case.  It would be visible through
   52  *        FIONREAD.
   53  *      o Do the new sio locking stuff here and use it to avoid special
   54  *        case for EXTPROC?
   55  *      o Lock PENDIN too?
   56  *      o Move EXTPROC and/or PENDIN to t_state?
   57  *      o Wrap most of ttioctl in spltty/splx.
   58  *      o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
   59  *      o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
   60  *      o Don't allow certain termios flags to affect disciplines other
   61  *        than TTYDISC.  Cancel their effects before switch disciplines
   62  *        and ignore them if they are set while we are in another
   63  *        discipline.
   64  *      o Now that historical speed conversions are handled here, don't
   65  *        do them in drivers.
   66  *      o Check for TS_CARR_ON being set while everything is closed and not
   67  *        waiting for carrier.  TS_CARR_ON isn't cleared if nothing is open,
   68  *        so it would live until the next open even if carrier drops.
   69  *      o Restore TS_WOPEN since it is useful in pstat.  It must be cleared
   70  *        only when _all_ openers leave open().
   71  */
   72 
   73 #include <sys/cdefs.h>
   74 __FBSDID("$FreeBSD: releng/5.3/sys/kern/tty.c 136588 2004-10-16 08:43:07Z cvs2svn $");
   75 
   76 #include "opt_compat.h"
   77 #include "opt_tty.h"
   78 
   79 #include <sys/param.h>
   80 #include <sys/systm.h>
   81 #include <sys/filio.h>
   82 #include <sys/lock.h>
   83 #include <sys/mutex.h>
   84 #include <sys/namei.h>
   85 #include <sys/sx.h>
   86 #ifndef BURN_BRIDGES
   87 #if defined(COMPAT_43)
   88 #include <sys/ioctl_compat.h>
   89 #endif
   90 #endif
   91 #include <sys/proc.h>
   92 #define TTYDEFCHARS
   93 #include <sys/tty.h>
   94 #undef  TTYDEFCHARS
   95 #include <sys/fcntl.h>
   96 #include <sys/conf.h>
   97 #include <sys/poll.h>
   98 #include <sys/kernel.h>
   99 #include <sys/vnode.h>
  100 #include <sys/serial.h>
  101 #include <sys/signalvar.h>
  102 #include <sys/resourcevar.h>
  103 #include <sys/malloc.h>
  104 #include <sys/filedesc.h>
  105 #include <sys/sched.h>
  106 #include <sys/sysctl.h>
  107 
  108 #include <vm/vm.h>
  109 #include <vm/pmap.h>
  110 #include <vm/vm_map.h>
  111 
  112 MALLOC_DEFINE(M_TTYS, "ttys", "tty data structures");
  113 
  114 long tk_cancc;
  115 long tk_nin;
  116 long tk_nout;
  117 long tk_rawcc;
  118 
  119 static int      proc_compare(struct proc *p1, struct proc *p2);
  120 static int      ttnread(struct tty *tp);
  121 static void     ttyecho(int c, struct tty *tp);
  122 static int      ttyoutput(int c, struct tty *tp);
  123 static void     ttypend(struct tty *tp);
  124 static void     ttyretype(struct tty *tp);
  125 static void     ttyrub(int c, struct tty *tp);
  126 static void     ttyrubo(struct tty *tp, int cnt);
  127 static void     ttyunblock(struct tty *tp);
  128 static int      ttywflush(struct tty *tp);
  129 static int      filt_ttyread(struct knote *kn, long hint);
  130 static void     filt_ttyrdetach(struct knote *kn);
  131 static int      filt_ttywrite(struct knote *kn, long hint);
  132 static void     filt_ttywdetach(struct knote *kn);
  133 
  134 /*
  135  * Table with character classes and parity. The 8th bit indicates parity,
  136  * the 7th bit indicates the character is an alphameric or underscore (for
  137  * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
  138  * are 0 then the character needs no special processing on output; classes
  139  * other than 0 might be translated or (not currently) require delays.
  140  */
  141 #define E       0x00    /* Even parity. */
  142 #define O       0x80    /* Odd parity. */
  143 #define PARITY(c)       (char_type[c] & O)
  144 
  145 #define ALPHA   0x40    /* Alpha or underscore. */
  146 #define ISALPHA(c)      (char_type[(c) & TTY_CHARMASK] & ALPHA)
  147 
  148 #define CCLASSMASK      0x3f
  149 #define CCLASS(c)       (char_type[c] & CCLASSMASK)
  150 
  151 #define BS      BACKSPACE
  152 #define CC      CONTROL
  153 #define CR      RETURN
  154 #define NA      ORDINARY | ALPHA
  155 #define NL      NEWLINE
  156 #define NO      ORDINARY
  157 #define TB      TAB
  158 #define VT      VTAB
  159 
  160 static u_char const char_type[] = {
  161         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
  162         O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
  163         O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
  164         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
  165         O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
  166         E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
  167         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
  168         O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
  169         O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
  170         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
  171         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
  172         O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
  173         E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
  174         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
  175         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
  176         E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
  177         /*
  178          * Meta chars; should be settable per character set;
  179          * for now, treat them all as normal characters.
  180          */
  181         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  182         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  183         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  184         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  185         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  186         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  187         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  188         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  189         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  190         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  191         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  192         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  193         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  194         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  195         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  196         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  197 };
  198 #undef  BS
  199 #undef  CC
  200 #undef  CR
  201 #undef  NA
  202 #undef  NL
  203 #undef  NO
  204 #undef  TB
  205 #undef  VT
  206 
  207 /* Macros to clear/set/test flags. */
  208 #define SET(t, f)       (t) |= (f)
  209 #define CLR(t, f)       (t) &= ~(f)
  210 #define ISSET(t, f)     ((t) & (f))
  211 
  212 #undef MAX_INPUT                /* XXX wrong in <sys/syslimits.h> */
  213 #define MAX_INPUT       TTYHOG  /* XXX limit is usually larger for !ICANON */
  214 
  215 /*
  216  * list of struct tty where pstat(8) can pick it up with sysctl
  217  *
  218  * The lock order is to grab the list mutex before the tty mutex.
  219  * Together with additions going on the tail of the list, this allows
  220  * the sysctl to avoid doing retries.
  221  */
  222 static  TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list);
  223 static struct mtx tty_list_mutex;
  224 
  225 static int  drainwait = 5*60;
  226 SYSCTL_INT(_kern, OID_AUTO, drainwait, CTLFLAG_RW, &drainwait,
  227         0, "Output drain timeout in seconds");
  228 
  229 /*
  230  * Initial open of tty, or (re)entry to standard tty line discipline.
  231  */
  232 int
  233 tty_open(struct cdev *device, struct tty *tp)
  234 {
  235         int s;
  236 
  237         s = spltty();
  238         tp->t_dev = device;
  239         tp->t_hotchar = 0;
  240         if (!ISSET(tp->t_state, TS_ISOPEN)) {
  241                 ttyref(tp);
  242                 SET(tp->t_state, TS_ISOPEN);
  243                 if (ISSET(tp->t_cflag, CLOCAL))
  244                         SET(tp->t_state, TS_CONNECTED);
  245                 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
  246         }
  247         /* XXX don't hang forever on output */
  248         if (tp->t_timeout < 0)
  249                 tp->t_timeout = drainwait*hz;
  250         ttsetwater(tp);
  251         splx(s);
  252         return (0);
  253 }
  254 
  255 /*
  256  * Handle close() on a tty line: flush and set to initial state,
  257  * bumping generation number so that pending read/write calls
  258  * can detect recycling of the tty.
  259  * XXX our caller should have done `spltty(); l_close(); tty_close();'
  260  * and l_close() should have flushed, but we repeat the spltty() and
  261  * the flush in case there are buggy callers.
  262  */
  263 int
  264 tty_close(struct tty *tp)
  265 {
  266         int s;
  267 
  268         funsetown(&tp->t_sigio);
  269         s = spltty();
  270         if (constty == tp)
  271                 constty_clear();
  272 
  273         ttyflush(tp, FREAD | FWRITE);
  274         clist_free_cblocks(&tp->t_canq);
  275         clist_free_cblocks(&tp->t_outq);
  276         clist_free_cblocks(&tp->t_rawq);
  277 
  278         tp->t_gen++;
  279         tp->t_line = TTYDISC;
  280         tp->t_hotchar = 0;
  281         tp->t_pgrp = NULL;
  282         tp->t_session = NULL;
  283         tp->t_state = 0;
  284         knlist_clear(&tp->t_rsel.si_note, 0);
  285         knlist_clear(&tp->t_wsel.si_note, 0);
  286         ttyrel(tp);
  287         splx(s);
  288         return (0);
  289 }
  290 
  291 #define FLUSHQ(q) {                                                     \
  292         if ((q)->c_cc)                                                  \
  293                 ndflush(q, (q)->c_cc);                                  \
  294 }
  295 
  296 /* Is 'c' a line delimiter ("break" character)? */
  297 #define TTBREAKC(c, lflag)                                                      \
  298         ((c) == '\n' || (((c) == cc[VEOF] ||                            \
  299           (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) &&   \
  300          (c) != _POSIX_VDISABLE))
  301 
  302 /*
  303  * Process input of a single character received on a tty.
  304  */
  305 int
  306 ttyinput(int c, struct tty *tp)
  307 {
  308         tcflag_t iflag, lflag;
  309         cc_t *cc;
  310         int i, err;
  311 
  312         /*
  313          * If input is pending take it first.
  314          */
  315         lflag = tp->t_lflag;
  316         if (ISSET(lflag, PENDIN))
  317                 ttypend(tp);
  318         /*
  319          * Gather stats.
  320          */
  321         if (ISSET(lflag, ICANON)) {
  322                 ++tk_cancc;
  323                 ++tp->t_cancc;
  324         } else {
  325                 ++tk_rawcc;
  326                 ++tp->t_rawcc;
  327         }
  328         ++tk_nin;
  329 
  330         /*
  331          * Block further input iff:
  332          * current input > threshold AND input is available to user program
  333          * AND input flow control is enabled and not yet invoked.
  334          * The 3 is slop for PARMRK.
  335          */
  336         iflag = tp->t_iflag;
  337         if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 &&
  338             (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
  339             (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
  340             !ISSET(tp->t_state, TS_TBLOCK))
  341                 ttyblock(tp);
  342 
  343         /* Handle exceptional conditions (break, parity, framing). */
  344         cc = tp->t_cc;
  345         err = (ISSET(c, TTY_ERRORMASK));
  346         if (err) {
  347                 CLR(c, TTY_ERRORMASK);
  348                 if (ISSET(err, TTY_BI)) {
  349                         if (ISSET(iflag, IGNBRK))
  350                                 return (0);
  351                         if (ISSET(iflag, BRKINT)) {
  352                                 ttyflush(tp, FREAD | FWRITE);
  353                                 if (tp->t_pgrp != NULL) {
  354                                         PGRP_LOCK(tp->t_pgrp);
  355                                         pgsignal(tp->t_pgrp, SIGINT, 1);
  356                                         PGRP_UNLOCK(tp->t_pgrp);
  357                                 }
  358                                 goto endcase;
  359                         }
  360                         if (ISSET(iflag, PARMRK))
  361                                 goto parmrk;
  362                 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
  363                         || ISSET(err, TTY_FE)) {
  364                         if (ISSET(iflag, IGNPAR))
  365                                 return (0);
  366                         else if (ISSET(iflag, PARMRK)) {
  367 parmrk:
  368                                 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
  369                                     MAX_INPUT - 3)
  370                                         goto input_overflow;
  371                                 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
  372                                 (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
  373                                 (void)putc(c | TTY_QUOTE, &tp->t_rawq);
  374                                 goto endcase;
  375                         } else
  376                                 c = 0;
  377                 }
  378         }
  379 
  380         if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
  381                 CLR(c, 0x80);
  382         if (!ISSET(lflag, EXTPROC)) {
  383                 /*
  384                  * Check for literal nexting very first
  385                  */
  386                 if (ISSET(tp->t_state, TS_LNCH)) {
  387                         SET(c, TTY_QUOTE);
  388                         CLR(tp->t_state, TS_LNCH);
  389                 }
  390                 /*
  391                  * Scan for special characters.  This code
  392                  * is really just a big case statement with
  393                  * non-constant cases.  The bottom of the
  394                  * case statement is labeled ``endcase'', so goto
  395                  * it after a case match, or similar.
  396                  */
  397 
  398                 /*
  399                  * Control chars which aren't controlled
  400                  * by ICANON, ISIG, or IXON.
  401                  */
  402                 if (ISSET(lflag, IEXTEN)) {
  403                         if (CCEQ(cc[VLNEXT], c)) {
  404                                 if (ISSET(lflag, ECHO)) {
  405                                         if (ISSET(lflag, ECHOE)) {
  406                                                 (void)ttyoutput('^', tp);
  407                                                 (void)ttyoutput('\b', tp);
  408                                         } else
  409                                                 ttyecho(c, tp);
  410                                 }
  411                                 SET(tp->t_state, TS_LNCH);
  412                                 goto endcase;
  413                         }
  414                         if (CCEQ(cc[VDISCARD], c)) {
  415                                 if (ISSET(lflag, FLUSHO))
  416                                         CLR(tp->t_lflag, FLUSHO);
  417                                 else {
  418                                         ttyflush(tp, FWRITE);
  419                                         ttyecho(c, tp);
  420                                         if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
  421                                                 ttyretype(tp);
  422                                         SET(tp->t_lflag, FLUSHO);
  423                                 }
  424                                 goto startoutput;
  425                         }
  426                 }
  427                 /*
  428                  * Signals.
  429                  */
  430                 if (ISSET(lflag, ISIG)) {
  431                         if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
  432                                 if (!ISSET(lflag, NOFLSH))
  433                                         ttyflush(tp, FREAD | FWRITE);
  434                                 ttyecho(c, tp);
  435                                 if (tp->t_pgrp != NULL) {
  436                                         PGRP_LOCK(tp->t_pgrp);
  437                                         pgsignal(tp->t_pgrp,
  438                                             CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
  439                                         PGRP_UNLOCK(tp->t_pgrp);
  440                                 }
  441                                 goto endcase;
  442                         }
  443                         if (CCEQ(cc[VSUSP], c)) {
  444                                 if (!ISSET(lflag, NOFLSH))
  445                                         ttyflush(tp, FREAD);
  446                                 ttyecho(c, tp);
  447                                 if (tp->t_pgrp != NULL) {
  448                                         PGRP_LOCK(tp->t_pgrp);
  449                                         pgsignal(tp->t_pgrp, SIGTSTP, 1);
  450                                         PGRP_UNLOCK(tp->t_pgrp);
  451                                 }
  452                                 goto endcase;
  453                         }
  454                 }
  455                 /*
  456                  * Handle start/stop characters.
  457                  */
  458                 if (ISSET(iflag, IXON)) {
  459                         if (CCEQ(cc[VSTOP], c)) {
  460                                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
  461                                         SET(tp->t_state, TS_TTSTOP);
  462                                         (*tp->t_stop)(tp, 0);
  463                                         return (0);
  464                                 }
  465                                 if (!CCEQ(cc[VSTART], c))
  466                                         return (0);
  467                                 /*
  468                                  * if VSTART == VSTOP then toggle
  469                                  */
  470                                 goto endcase;
  471                         }
  472                         if (CCEQ(cc[VSTART], c))
  473                                 goto restartoutput;
  474                 }
  475                 /*
  476                  * IGNCR, ICRNL, & INLCR
  477                  */
  478                 if (c == '\r') {
  479                         if (ISSET(iflag, IGNCR))
  480                                 return (0);
  481                         else if (ISSET(iflag, ICRNL))
  482                                 c = '\n';
  483                 } else if (c == '\n' && ISSET(iflag, INLCR))
  484                         c = '\r';
  485         }
  486         if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
  487                 /*
  488                  * From here on down canonical mode character
  489                  * processing takes place.
  490                  */
  491                 /*
  492                  * erase or erase2 (^H / ^?)
  493                  */
  494                 if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c) ) {
  495                         if (tp->t_rawq.c_cc)
  496                                 ttyrub(unputc(&tp->t_rawq), tp);
  497                         goto endcase;
  498                 }
  499                 /*
  500                  * kill (^U)
  501                  */
  502                 if (CCEQ(cc[VKILL], c)) {
  503                         if (ISSET(lflag, ECHOKE) &&
  504                             tp->t_rawq.c_cc == tp->t_rocount &&
  505                             !ISSET(lflag, ECHOPRT))
  506                                 while (tp->t_rawq.c_cc)
  507                                         ttyrub(unputc(&tp->t_rawq), tp);
  508                         else {
  509                                 ttyecho(c, tp);
  510                                 if (ISSET(lflag, ECHOK) ||
  511                                     ISSET(lflag, ECHOKE))
  512                                         ttyecho('\n', tp);
  513                                 FLUSHQ(&tp->t_rawq);
  514                                 tp->t_rocount = 0;
  515                         }
  516                         CLR(tp->t_state, TS_LOCAL);
  517                         goto endcase;
  518                 }
  519                 /*
  520                  * word erase (^W)
  521                  */
  522                 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
  523                         int ctype;
  524 
  525                         /*
  526                          * erase whitespace
  527                          */
  528                         while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
  529                                 ttyrub(c, tp);
  530                         if (c == -1)
  531                                 goto endcase;
  532                         /*
  533                          * erase last char of word and remember the
  534                          * next chars type (for ALTWERASE)
  535                          */
  536                         ttyrub(c, tp);
  537                         c = unputc(&tp->t_rawq);
  538                         if (c == -1)
  539                                 goto endcase;
  540                         if (c == ' ' || c == '\t') {
  541                                 (void)putc(c, &tp->t_rawq);
  542                                 goto endcase;
  543                         }
  544                         ctype = ISALPHA(c);
  545                         /*
  546                          * erase rest of word
  547                          */
  548                         do {
  549                                 ttyrub(c, tp);
  550                                 c = unputc(&tp->t_rawq);
  551                                 if (c == -1)
  552                                         goto endcase;
  553                         } while (c != ' ' && c != '\t' &&
  554                             (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
  555                         (void)putc(c, &tp->t_rawq);
  556                         goto endcase;
  557                 }
  558                 /*
  559                  * reprint line (^R)
  560                  */
  561                 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
  562                         ttyretype(tp);
  563                         goto endcase;
  564                 }
  565                 /*
  566                  * ^T - kernel info and generate SIGINFO
  567                  */
  568                 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
  569                         if (ISSET(lflag, ISIG) && tp->t_pgrp != NULL) {
  570                                 PGRP_LOCK(tp->t_pgrp);
  571                                 pgsignal(tp->t_pgrp, SIGINFO, 1);
  572                                 PGRP_UNLOCK(tp->t_pgrp);
  573                         }
  574                         if (!ISSET(lflag, NOKERNINFO))
  575                                 ttyinfo(tp);
  576                         goto endcase;
  577                 }
  578         }
  579         /*
  580          * Check for input buffer overflow
  581          */
  582         if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
  583 input_overflow:
  584                 if (ISSET(iflag, IMAXBEL)) {
  585                         if (tp->t_outq.c_cc < tp->t_ohiwat)
  586                                 (void)ttyoutput(CTRL('g'), tp);
  587                 }
  588                 goto endcase;
  589         }
  590 
  591         if (   c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
  592              && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
  593                 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
  594 
  595         /*
  596          * Put data char in q for user and
  597          * wakeup on seeing a line delimiter.
  598          */
  599         if (putc(c, &tp->t_rawq) >= 0) {
  600                 if (!ISSET(lflag, ICANON)) {
  601                         ttwakeup(tp);
  602                         ttyecho(c, tp);
  603                         goto endcase;
  604                 }
  605                 if (TTBREAKC(c, lflag)) {
  606                         tp->t_rocount = 0;
  607                         catq(&tp->t_rawq, &tp->t_canq);
  608                         ttwakeup(tp);
  609                 } else if (tp->t_rocount++ == 0)
  610                         tp->t_rocol = tp->t_column;
  611                 if (ISSET(tp->t_state, TS_ERASE)) {
  612                         /*
  613                          * end of prterase \.../
  614                          */
  615                         CLR(tp->t_state, TS_ERASE);
  616                         (void)ttyoutput('/', tp);
  617                 }
  618                 i = tp->t_column;
  619                 ttyecho(c, tp);
  620                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
  621                         /*
  622                          * Place the cursor over the '^' of the ^D.
  623                          */
  624                         i = imin(2, tp->t_column - i);
  625                         while (i > 0) {
  626                                 (void)ttyoutput('\b', tp);
  627                                 i--;
  628                         }
  629                 }
  630         }
  631 endcase:
  632         /*
  633          * IXANY means allow any character to restart output.
  634          */
  635         if (ISSET(tp->t_state, TS_TTSTOP) &&
  636             !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
  637                 return (0);
  638 restartoutput:
  639         CLR(tp->t_lflag, FLUSHO);
  640         CLR(tp->t_state, TS_TTSTOP);
  641 startoutput:
  642         return (ttstart(tp));
  643 }
  644 
  645 /*
  646  * Output a single character on a tty, doing output processing
  647  * as needed (expanding tabs, newline processing, etc.).
  648  * Returns < 0 if succeeds, otherwise returns char to resend.
  649  * Must be recursive.
  650  */
  651 static int
  652 ttyoutput(int c, struct tty *tp)
  653 {
  654         tcflag_t oflag;
  655         int col, s;
  656 
  657         oflag = tp->t_oflag;
  658         if (!ISSET(oflag, OPOST)) {
  659                 if (ISSET(tp->t_lflag, FLUSHO))
  660                         return (-1);
  661                 if (putc(c, &tp->t_outq))
  662                         return (c);
  663                 tk_nout++;
  664                 tp->t_outcc++;
  665                 return (-1);
  666         }
  667         /*
  668          * Do tab expansion if OXTABS is set.  Special case if we external
  669          * processing, we don't do the tab expansion because we'll probably
  670          * get it wrong.  If tab expansion needs to be done, let it happen
  671          * externally.
  672          */
  673         CLR(c, ~TTY_CHARMASK);
  674         if (c == '\t' &&
  675             ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
  676                 c = 8 - (tp->t_column & 7);
  677                 if (!ISSET(tp->t_lflag, FLUSHO)) {
  678                         s = spltty();           /* Don't interrupt tabs. */
  679                         c -= b_to_q("        ", c, &tp->t_outq);
  680                         tk_nout += c;
  681                         tp->t_outcc += c;
  682                         splx(s);
  683                 }
  684                 tp->t_column += c;
  685                 return (c ? -1 : '\t');
  686         }
  687         if (c == CEOT && ISSET(oflag, ONOEOT))
  688                 return (-1);
  689 
  690         /*
  691          * Newline translation: if ONLCR is set,
  692          * translate newline into "\r\n".
  693          */
  694         if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
  695                 tk_nout++;
  696                 tp->t_outcc++;
  697                 if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
  698                         return (c);
  699         }
  700         /* If OCRNL is set, translate "\r" into "\n". */
  701         else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
  702                 c = '\n';
  703         /* If ONOCR is set, don't transmit CRs when on column 0. */
  704         else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0)
  705                 return (-1);
  706 
  707         tk_nout++;
  708         tp->t_outcc++;
  709         if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
  710                 return (c);
  711 
  712         col = tp->t_column;
  713         switch (CCLASS(c)) {
  714         case BACKSPACE:
  715                 if (col > 0)
  716                         --col;
  717                 break;
  718         case CONTROL:
  719                 break;
  720         case NEWLINE:
  721                 if (ISSET(tp->t_oflag, ONLCR | ONLRET))
  722                         col = 0;
  723                 break;
  724         case RETURN:
  725                 col = 0;
  726                 break;
  727         case ORDINARY:
  728                 ++col;
  729                 break;
  730         case TAB:
  731                 col = (col + 8) & ~7;
  732                 break;
  733         }
  734         tp->t_column = col;
  735         return (-1);
  736 }
  737 
  738 /*
  739  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
  740  * has been called to do discipline-specific functions and/or reject any
  741  * of these ioctl commands.
  742  */
  743 /* ARGSUSED */
  744 int
  745 ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
  746 {
  747         struct proc *p;
  748         struct thread *td;
  749         struct pgrp *pgrp;
  750         int s, error, bits, sig, sig2;
  751 
  752         td = curthread;                 /* XXX */
  753         p = td->td_proc;
  754 
  755         /* If the ioctl involves modification, hang if in the background. */
  756         switch (cmd) {
  757         case  TIOCCBRK:
  758         case  TIOCCONS:
  759         case  TIOCDRAIN:
  760         case  TIOCEXCL:
  761         case  TIOCFLUSH:
  762 #ifdef TIOCHPCL
  763         case  TIOCHPCL:
  764 #endif
  765         case  TIOCNXCL:
  766         case  TIOCSBRK:
  767         case  TIOCSCTTY:
  768         case  TIOCSDRAINWAIT:
  769         case  TIOCSETA:
  770         case  TIOCSETAF:
  771         case  TIOCSETAW:
  772         case  TIOCSETD:
  773         case  TIOCSPGRP:
  774         case  TIOCSTART:
  775         case  TIOCSTAT:
  776         case  TIOCSTI:
  777         case  TIOCSTOP:
  778         case  TIOCSWINSZ:
  779 #ifndef BURN_BRIDGES
  780 #if defined(COMPAT_43)
  781         case  TIOCLBIC:
  782         case  TIOCLBIS:
  783         case  TIOCLSET:
  784         case  TIOCSETC:
  785         case OTIOCSETD:
  786         case  TIOCSETN:
  787         case  TIOCSETP:
  788         case  TIOCSLTC:
  789 #endif
  790 #endif
  791                 sx_slock(&proctree_lock);
  792                 PROC_LOCK(p);
  793                 while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
  794                     !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) &&
  795                     !SIGISMEMBER(td->td_sigmask, SIGTTOU)) {
  796                         pgrp = p->p_pgrp;
  797                         PROC_UNLOCK(p);
  798                         if (pgrp->pg_jobc == 0) {
  799                                 sx_sunlock(&proctree_lock);
  800                                 return (EIO);
  801                         }
  802                         PGRP_LOCK(pgrp);
  803                         sx_sunlock(&proctree_lock);
  804                         pgsignal(pgrp, SIGTTOU, 1);
  805                         PGRP_UNLOCK(pgrp);
  806                         error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1",
  807                                          0);
  808                         if (error)
  809                                 return (error);
  810                         sx_slock(&proctree_lock);
  811                         PROC_LOCK(p);
  812                 }
  813                 PROC_UNLOCK(p);
  814                 sx_sunlock(&proctree_lock);
  815                 break;
  816         }
  817 
  818         if (tp->t_break != NULL) {
  819                 switch (cmd) {
  820                 case TIOCSBRK:
  821                         tp->t_break(tp, 1);
  822                         return (0);
  823                 case TIOCCBRK:
  824                         tp->t_break(tp, 0);
  825                         return (0);
  826                 default:
  827                         break;
  828                 }
  829         }
  830 
  831         if (tp->t_modem != NULL) {
  832                 switch (cmd) {
  833                 case TIOCSDTR:
  834                         tp->t_modem(tp, SER_DTR, 0);
  835                         return (0);
  836                 case TIOCCDTR:
  837                         tp->t_modem(tp, 0, SER_DTR);
  838                         return (0);
  839                 case TIOCMSET:
  840                         bits = *(int *)data;
  841                         sig = (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1;
  842                         sig2 = ((~bits) & (TIOCM_DTR | TIOCM_RTS)) >> 1;
  843                         tp->t_modem(tp, sig, sig2);
  844                         return (0);
  845                 case TIOCMBIS:
  846                         bits = *(int *)data;
  847                         sig = (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1;
  848                         tp->t_modem(tp, sig, 0);
  849                         return (0);
  850                 case TIOCMBIC:
  851                         bits = *(int *)data;
  852                         sig = (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1;
  853                         tp->t_modem(tp, 0, sig);
  854                         return (0);
  855                 case TIOCMGET:
  856                         sig = tp->t_modem(tp, 0, 0);
  857                         /* See <sys/serial.h. for the "<< 1" stuff */
  858                         bits = TIOCM_LE + (sig << 1);
  859                         *(int *)data = bits;
  860                         return (0);
  861                 default:
  862                         break;
  863                 }
  864         }
  865 
  866         switch (cmd) {                  /* Process the ioctl. */
  867         case FIOASYNC:                  /* set/clear async i/o */
  868                 s = spltty();
  869                 if (*(int *)data)
  870                         SET(tp->t_state, TS_ASYNC);
  871                 else
  872                         CLR(tp->t_state, TS_ASYNC);
  873                 splx(s);
  874                 break;
  875         case FIONBIO:                   /* set/clear non-blocking i/o */
  876                 break;                  /* XXX: delete. */
  877         case FIONREAD:                  /* get # bytes to read */
  878                 s = spltty();
  879                 *(int *)data = ttnread(tp);
  880                 splx(s);
  881                 break;
  882 
  883         case FIOSETOWN:
  884                 /*
  885                  * Policy -- Don't allow FIOSETOWN on someone else's
  886                  *           controlling tty
  887                  */
  888                 if (tp->t_session != NULL && !isctty(p, tp))
  889                         return (ENOTTY);
  890 
  891                 error = fsetown(*(int *)data, &tp->t_sigio);
  892                 if (error)
  893                         return (error);
  894                 break;
  895         case FIOGETOWN:
  896                 if (tp->t_session != NULL && !isctty(p, tp))
  897                         return (ENOTTY);
  898                 *(int *)data = fgetown(&tp->t_sigio);
  899                 break;
  900 
  901         case TIOCEXCL:                  /* set exclusive use of tty */
  902                 s = spltty();
  903                 SET(tp->t_state, TS_XCLUDE);
  904                 splx(s);
  905                 break;
  906         case TIOCFLUSH: {               /* flush buffers */
  907                 int flags = *(int *)data;
  908 
  909                 if (flags == 0)
  910                         flags = FREAD | FWRITE;
  911                 else
  912                         flags &= FREAD | FWRITE;
  913                 ttyflush(tp, flags);
  914                 break;
  915         }
  916         case TIOCCONS:                  /* become virtual console */
  917                 if (*(int *)data) {
  918                         struct nameidata nid;
  919 
  920                         if (constty && constty != tp &&
  921                             ISSET(constty->t_state, TS_CONNECTED))
  922                                 return (EBUSY);
  923 
  924                         /* Ensure user can open the real console. */
  925                         NDINIT(&nid, LOOKUP, LOCKLEAF | FOLLOW, UIO_SYSSPACE,
  926                             "/dev/console", td);
  927                         if ((error = namei(&nid)) != 0)
  928                                 return (error);
  929                         NDFREE(&nid, NDF_ONLY_PNBUF);
  930                         error = VOP_ACCESS(nid.ni_vp, VREAD, td->td_ucred, td);
  931                         vput(nid.ni_vp);
  932                         if (error)
  933                                 return (error);
  934 
  935                         constty_set(tp);
  936                 } else if (tp == constty)
  937                         constty_clear();
  938                 break;
  939         case TIOCDRAIN:                 /* wait till output drained */
  940                 error = ttywait(tp);
  941                 if (error)
  942                         return (error);
  943                 break;
  944         case TIOCGETA: {                /* get termios struct */
  945                 struct termios *t = (struct termios *)data;
  946 
  947                 bcopy(&tp->t_termios, t, sizeof(struct termios));
  948                 break;
  949         }
  950         case TIOCGETD:                  /* get line discipline */
  951                 *(int *)data = tp->t_line;
  952                 break;
  953         case TIOCGWINSZ:                /* get window size */
  954                 *(struct winsize *)data = tp->t_winsize;
  955                 break;
  956         case TIOCGPGRP:                 /* get pgrp of tty */
  957                 if (!isctty(p, tp))
  958                         return (ENOTTY);
  959                 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
  960                 break;
  961 #ifdef TIOCHPCL
  962         case TIOCHPCL:                  /* hang up on last close */
  963                 s = spltty();
  964                 SET(tp->t_cflag, HUPCL);
  965                 splx(s);
  966                 break;
  967 #endif
  968         case TIOCMGDTRWAIT:
  969                 *(int *)data = tp->t_dtr_wait * 100 / hz;
  970                 break;
  971         case TIOCMSDTRWAIT:
  972                 /* must be root since the wait applies to following logins */
  973                 error = suser(td);
  974                 if (error)
  975                         return (error);
  976                 tp->t_dtr_wait = *(int *)data * hz / 100;
  977                 break;
  978         case TIOCNXCL:                  /* reset exclusive use of tty */
  979                 s = spltty();
  980                 CLR(tp->t_state, TS_XCLUDE);
  981                 splx(s);
  982                 break;
  983         case TIOCOUTQ:                  /* output queue size */
  984                 *(int *)data = tp->t_outq.c_cc;
  985                 break;
  986         case TIOCSETA:                  /* set termios struct */
  987         case TIOCSETAW:                 /* drain output, set */
  988         case TIOCSETAF: {               /* drn out, fls in, set */
  989                 struct termios *t = (struct termios *)data;
  990 
  991                 if (t->c_ispeed == 0)
  992                         t->c_ispeed = t->c_ospeed;
  993                 if (t->c_ispeed == 0)
  994                         t->c_ispeed = tp->t_ospeed;
  995                 if (t->c_ispeed == 0)
  996                         return (EINVAL);
  997                 s = spltty();
  998                 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
  999                         error = ttywait(tp);
 1000                         if (error) {
 1001                                 splx(s);
 1002                                 return (error);
 1003                         }
 1004                         if (cmd == TIOCSETAF)
 1005                                 ttyflush(tp, FREAD);
 1006                 }
 1007                 if (!ISSET(t->c_cflag, CIGNORE)) {
 1008                         /*
 1009                          * Set device hardware.
 1010                          */
 1011                         if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
 1012                                 splx(s);
 1013                                 return (error);
 1014                         }
 1015                         if (ISSET(t->c_cflag, CLOCAL) &&
 1016                             !ISSET(tp->t_cflag, CLOCAL)) {
 1017                                 /*
 1018                                  * XXX disconnections would be too hard to
 1019                                  * get rid of without this kludge.  The only
 1020                                  * way to get rid of controlling terminals
 1021                                  * is to exit from the session leader.
 1022                                  */
 1023                                 CLR(tp->t_state, TS_ZOMBIE);
 1024 
 1025                                 wakeup(TSA_CARR_ON(tp));
 1026                                 ttwakeup(tp);
 1027                                 ttwwakeup(tp);
 1028                         }
 1029                         if ((ISSET(tp->t_state, TS_CARR_ON) ||
 1030                              ISSET(t->c_cflag, CLOCAL)) &&
 1031                             !ISSET(tp->t_state, TS_ZOMBIE))
 1032                                 SET(tp->t_state, TS_CONNECTED);
 1033                         else
 1034                                 CLR(tp->t_state, TS_CONNECTED);
 1035                         tp->t_cflag = t->c_cflag;
 1036                         tp->t_ispeed = t->c_ispeed;
 1037                         if (t->c_ospeed != 0)
 1038                                 tp->t_ospeed = t->c_ospeed;
 1039                         ttsetwater(tp);
 1040                 }
 1041                 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
 1042                     cmd != TIOCSETAF) {
 1043                         if (ISSET(t->c_lflag, ICANON))
 1044                                 SET(tp->t_lflag, PENDIN);
 1045                         else {
 1046                                 /*
 1047                                  * XXX we really shouldn't allow toggling
 1048                                  * ICANON while we're in a non-termios line
 1049                                  * discipline.  Now we have to worry about
 1050                                  * panicing for a null queue.
 1051                                  */
 1052                                 if (tp->t_canq.c_cbreserved > 0 &&
 1053                                     tp->t_rawq.c_cbreserved > 0) {
 1054                                         catq(&tp->t_rawq, &tp->t_canq);
 1055                                         /*
 1056                                          * XXX the queue limits may be
 1057                                          * different, so the old queue
 1058                                          * swapping method no longer works.
 1059                                          */
 1060                                         catq(&tp->t_canq, &tp->t_rawq);
 1061                                 }
 1062                                 CLR(tp->t_lflag, PENDIN);
 1063                         }
 1064                         ttwakeup(tp);
 1065                 }
 1066                 tp->t_iflag = t->c_iflag;
 1067                 tp->t_oflag = t->c_oflag;
 1068                 /*
 1069                  * Make the EXTPROC bit read only.
 1070                  */
 1071                 if (ISSET(tp->t_lflag, EXTPROC))
 1072                         SET(t->c_lflag, EXTPROC);
 1073                 else
 1074                         CLR(t->c_lflag, EXTPROC);
 1075                 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
 1076                 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
 1077                     t->c_cc[VTIME] != tp->t_cc[VTIME])
 1078                         ttwakeup(tp);
 1079                 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
 1080                 splx(s);
 1081                 break;
 1082         }
 1083         case TIOCSETD: {                /* set line discipline */
 1084                 int t = *(int *)data;
 1085                 struct cdev *device = tp->t_dev;
 1086 
 1087                 if ((u_int)t >= nlinesw)
 1088                         return (ENXIO);
 1089                 if (t == tp->t_line)
 1090                         return (0);
 1091                 s = spltty();
 1092                 ttyld_close(tp, flag);
 1093                 tp->t_line = t;
 1094                 error = ttyld_open(tp, device);
 1095                 if (error) {
 1096                         /*
 1097                          * If we fail to switch line discipline we cannot
 1098                          * fall back to the previous, because we can not
 1099                          * trust that ldisc to open successfully either.
 1100                          * Fall back to the default ldisc which we know 
 1101                          * will allways succeed.
 1102                          */
 1103                         tp->t_line = TTYDISC;
 1104                         (void)ttyld_open(tp, device);
 1105                 }
 1106                 splx(s);
 1107                 return (error);
 1108                 break;
 1109         }
 1110         case TIOCSTART:                 /* start output, like ^Q */
 1111                 s = spltty();
 1112                 if (ISSET(tp->t_state, TS_TTSTOP) ||
 1113                     ISSET(tp->t_lflag, FLUSHO)) {
 1114                         CLR(tp->t_lflag, FLUSHO);
 1115                         CLR(tp->t_state, TS_TTSTOP);
 1116                         ttstart(tp);
 1117                 }
 1118                 splx(s);
 1119                 break;
 1120         case TIOCSTI:                   /* simulate terminal input */
 1121                 if ((flag & FREAD) == 0 && suser(td))
 1122                         return (EPERM);
 1123                 if (!isctty(p, tp) && suser(td))
 1124                         return (EACCES);
 1125                 s = spltty();
 1126                 ttyld_rint(tp, *(u_char *)data);
 1127                 splx(s);
 1128                 break;
 1129         case TIOCSTOP:                  /* stop output, like ^S */
 1130                 s = spltty();
 1131                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
 1132                         SET(tp->t_state, TS_TTSTOP);
 1133                         (*tp->t_stop)(tp, 0);
 1134                 }
 1135                 splx(s);
 1136                 break;
 1137         case TIOCSCTTY:                 /* become controlling tty */
 1138                 /* Session ctty vnode pointer set in vnode layer. */
 1139                 sx_slock(&proctree_lock);
 1140                 if (!SESS_LEADER(p) ||
 1141                     ((p->p_session->s_ttyvp || tp->t_session) &&
 1142                      (tp->t_session != p->p_session))) {
 1143                         sx_sunlock(&proctree_lock);
 1144                         return (EPERM);
 1145                 }
 1146                 tp->t_session = p->p_session;
 1147                 tp->t_pgrp = p->p_pgrp;
 1148                 SESS_LOCK(p->p_session);
 1149                 ttyref(tp);             /* ttyrel(): kern_proc.c:pgdelete() */
 1150                 p->p_session->s_ttyp = tp;
 1151                 SESS_UNLOCK(p->p_session);
 1152                 PROC_LOCK(p);
 1153                 p->p_flag |= P_CONTROLT;
 1154                 PROC_UNLOCK(p);
 1155                 sx_sunlock(&proctree_lock);
 1156                 break;
 1157         case TIOCSPGRP: {               /* set pgrp of tty */
 1158                 sx_slock(&proctree_lock);
 1159                 pgrp = pgfind(*(int *)data);
 1160                 if (!isctty(p, tp)) {
 1161                         if (pgrp != NULL)
 1162                                 PGRP_UNLOCK(pgrp);
 1163                         sx_sunlock(&proctree_lock);
 1164                         return (ENOTTY);
 1165                 }
 1166                 if (pgrp == NULL) {
 1167                         sx_sunlock(&proctree_lock);
 1168                         return (EPERM);
 1169                 }
 1170                 PGRP_UNLOCK(pgrp);
 1171                 if (pgrp->pg_session != p->p_session) {
 1172                         sx_sunlock(&proctree_lock);
 1173                         return (EPERM);
 1174                 }
 1175                 sx_sunlock(&proctree_lock);
 1176                 tp->t_pgrp = pgrp;
 1177                 break;
 1178         }
 1179         case TIOCSTAT:                  /* simulate control-T */
 1180                 s = spltty();
 1181                 ttyinfo(tp);
 1182                 splx(s);
 1183                 break;
 1184         case TIOCSWINSZ:                /* set window size */
 1185                 if (bcmp((caddr_t)&tp->t_winsize, data,
 1186                     sizeof (struct winsize))) {
 1187                         tp->t_winsize = *(struct winsize *)data;
 1188                         if (tp->t_pgrp != NULL) {
 1189                                 PGRP_LOCK(tp->t_pgrp);
 1190                                 pgsignal(tp->t_pgrp, SIGWINCH, 1);
 1191                                 PGRP_UNLOCK(tp->t_pgrp);
 1192                         }
 1193                 }
 1194                 break;
 1195         case TIOCSDRAINWAIT:
 1196                 error = suser(td);
 1197                 if (error)
 1198                         return (error);
 1199                 tp->t_timeout = *(int *)data * hz;
 1200                 wakeup(TSA_OCOMPLETE(tp));
 1201                 wakeup(TSA_OLOWAT(tp));
 1202                 break;
 1203         case TIOCGDRAINWAIT:
 1204                 *(int *)data = tp->t_timeout / hz;
 1205                 break;
 1206         default:
 1207 #if defined(COMPAT_43)
 1208 #ifndef BURN_BRIDGES
 1209                 return (ttcompat(tp, cmd, data, flag));
 1210 #else
 1211                 return (ENOIOCTL);
 1212 #endif
 1213 #else
 1214                 return (ENOIOCTL);
 1215 #endif
 1216         }
 1217         return (0);
 1218 }
 1219 
 1220 int
 1221 ttypoll(struct cdev *dev, int events, struct thread *td)
 1222 {
 1223         int s;
 1224         int revents = 0;
 1225         struct tty *tp;
 1226 
 1227         KASSERT(devsw(dev)->d_flags & D_TTY,
 1228             ("ttypoll() called on non D_TTY device (%s)", devtoname(dev)));
 1229         tp = dev->si_tty;
 1230         KASSERT(tp != NULL,
 1231             ("ttypoll(): no tty pointer on device (%s)", devtoname(dev)));
 1232         if (tp == NULL) /* XXX used to return ENXIO, but that means true! */
 1233                 return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM))
 1234                         | POLLHUP);
 1235 
 1236         s = spltty();
 1237         if (events & (POLLIN | POLLRDNORM)) {
 1238                 if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
 1239                         revents |= events & (POLLIN | POLLRDNORM);
 1240                 else
 1241                         selrecord(td, &tp->t_rsel);
 1242         }
 1243         if (events & (POLLOUT | POLLWRNORM)) {
 1244                 if ((tp->t_outq.c_cc <= tp->t_olowat &&
 1245                      ISSET(tp->t_state, TS_CONNECTED))
 1246                     || ISSET(tp->t_state, TS_ZOMBIE))
 1247                         revents |= events & (POLLOUT | POLLWRNORM);
 1248                 else
 1249                         selrecord(td, &tp->t_wsel);
 1250         }
 1251         splx(s);
 1252         return (revents);
 1253 }
 1254 
 1255 static struct filterops ttyread_filtops =
 1256         { 1, NULL, filt_ttyrdetach, filt_ttyread };
 1257 static struct filterops ttywrite_filtops =
 1258         { 1, NULL, filt_ttywdetach, filt_ttywrite };
 1259 
 1260 int
 1261 ttykqfilter(struct cdev *dev, struct knote *kn)
 1262 {
 1263         struct tty *tp;
 1264         struct knlist *klist;
 1265         int s;
 1266 
 1267         KASSERT(devsw(dev)->d_flags & D_TTY,
 1268             ("ttykqfilter() called on non D_TTY device (%s)", devtoname(dev)));
 1269         tp = dev->si_tty;
 1270         KASSERT(tp != NULL,
 1271             ("ttykqfilter(): no tty pointer on device (%s)", devtoname(dev)));
 1272         switch (kn->kn_filter) {
 1273         case EVFILT_READ:
 1274                 klist = &tp->t_rsel.si_note;
 1275                 kn->kn_fop = &ttyread_filtops;
 1276                 break;
 1277         case EVFILT_WRITE:
 1278                 klist = &tp->t_wsel.si_note;
 1279                 kn->kn_fop = &ttywrite_filtops;
 1280                 break;
 1281         default:
 1282                 return (EINVAL);
 1283         }
 1284 
 1285         kn->kn_hook = (caddr_t)dev;
 1286 
 1287         s = spltty();
 1288         knlist_add(klist, kn, 0);
 1289         splx(s);
 1290 
 1291         return (0);
 1292 }
 1293 
 1294 static void
 1295 filt_ttyrdetach(struct knote *kn)
 1296 {
 1297         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1298         int s = spltty();
 1299 
 1300         knlist_remove(&tp->t_rsel.si_note, kn, 0);
 1301         splx(s);
 1302 }
 1303 
 1304 static int
 1305 filt_ttyread(struct knote *kn, long hint)
 1306 {
 1307         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1308 
 1309         kn->kn_data = ttnread(tp);
 1310         if (ISSET(tp->t_state, TS_ZOMBIE)) {
 1311                 kn->kn_flags |= EV_EOF;
 1312                 return (1);
 1313         }
 1314         return (kn->kn_data > 0);
 1315 }
 1316 
 1317 static void
 1318 filt_ttywdetach(struct knote *kn)
 1319 {
 1320         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1321         int s = spltty();
 1322 
 1323         knlist_remove(&tp->t_wsel.si_note, kn, 0);
 1324         splx(s);
 1325 }
 1326 
 1327 static int
 1328 filt_ttywrite(struct knote *kn, long hint)
 1329 {
 1330         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1331 
 1332         kn->kn_data = tp->t_outq.c_cc;
 1333         if (ISSET(tp->t_state, TS_ZOMBIE))
 1334                 return (1);
 1335         return (kn->kn_data <= tp->t_olowat &&
 1336             ISSET(tp->t_state, TS_CONNECTED));
 1337 }
 1338 
 1339 /*
 1340  * Must be called at spltty().
 1341  */
 1342 static int
 1343 ttnread(struct tty *tp)
 1344 {
 1345         int nread;
 1346 
 1347         if (ISSET(tp->t_lflag, PENDIN))
 1348                 ttypend(tp);
 1349         nread = tp->t_canq.c_cc;
 1350         if (!ISSET(tp->t_lflag, ICANON)) {
 1351                 nread += tp->t_rawq.c_cc;
 1352                 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
 1353                         nread = 0;
 1354         }
 1355         return (nread);
 1356 }
 1357 
 1358 /*
 1359  * Wait for output to drain.
 1360  */
 1361 int
 1362 ttywait(struct tty *tp)
 1363 {
 1364         int error, s;
 1365 
 1366         error = 0;
 1367         s = spltty();
 1368         while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
 1369                ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
 1370                 (*tp->t_oproc)(tp);
 1371                 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
 1372                     ISSET(tp->t_state, TS_CONNECTED)) {
 1373                         SET(tp->t_state, TS_SO_OCOMPLETE);
 1374                         error = ttysleep(tp, TSA_OCOMPLETE(tp),
 1375                                          TTOPRI | PCATCH, "ttywai",
 1376                                          tp->t_timeout);
 1377                         if (error) {
 1378                                 if (error == EWOULDBLOCK)
 1379                                         error = EIO;
 1380                                 break;
 1381                         }
 1382                 } else
 1383                         break;
 1384         }
 1385         if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
 1386                 error = EIO;
 1387         splx(s);
 1388         return (error);
 1389 }
 1390 
 1391 /*
 1392  * Flush if successfully wait.
 1393  */
 1394 static int
 1395 ttywflush(struct tty *tp)
 1396 {
 1397         int error;
 1398 
 1399         if ((error = ttywait(tp)) == 0)
 1400                 ttyflush(tp, FREAD);
 1401         return (error);
 1402 }
 1403 
 1404 /*
 1405  * Flush tty read and/or write queues, notifying anyone waiting.
 1406  */
 1407 void
 1408 ttyflush(struct tty *tp, int rw)
 1409 {
 1410         int s;
 1411 
 1412         s = spltty();
 1413 #if 0
 1414 again:
 1415 #endif
 1416         if (rw & FWRITE) {
 1417                 FLUSHQ(&tp->t_outq);
 1418                 CLR(tp->t_state, TS_TTSTOP);
 1419         }
 1420         (*tp->t_stop)(tp, rw);
 1421         if (rw & FREAD) {
 1422                 FLUSHQ(&tp->t_canq);
 1423                 FLUSHQ(&tp->t_rawq);
 1424                 CLR(tp->t_lflag, PENDIN);
 1425                 tp->t_rocount = 0;
 1426                 tp->t_rocol = 0;
 1427                 CLR(tp->t_state, TS_LOCAL);
 1428                 ttwakeup(tp);
 1429                 if (ISSET(tp->t_state, TS_TBLOCK)) {
 1430                         if (rw & FWRITE)
 1431                                 FLUSHQ(&tp->t_outq);
 1432                         ttyunblock(tp);
 1433 
 1434                         /*
 1435                          * Don't let leave any state that might clobber the
 1436                          * next line discipline (although we should do more
 1437                          * to send the START char).  Not clearing the state
 1438                          * may have caused the "putc to a clist with no
 1439                          * reserved cblocks" panic/printf.
 1440                          */
 1441                         CLR(tp->t_state, TS_TBLOCK);
 1442 
 1443 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
 1444                         if (ISSET(tp->t_iflag, IXOFF)) {
 1445                                 /*
 1446                                  * XXX wait a bit in the hope that the stop
 1447                                  * character (if any) will go out.  Waiting
 1448                                  * isn't good since it allows races.  This
 1449                                  * will be fixed when the stop character is
 1450                                  * put in a special queue.  Don't bother with
 1451                                  * the checks in ttywait() since the timeout
 1452                                  * will save us.
 1453                                  */
 1454                                 SET(tp->t_state, TS_SO_OCOMPLETE);
 1455                                 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
 1456                                          "ttyfls", hz / 10);
 1457                                 /*
 1458                                  * Don't try sending the stop character again.
 1459                                  */
 1460                                 CLR(tp->t_state, TS_TBLOCK);
 1461                                 goto again;
 1462                         }
 1463 #endif
 1464                 }
 1465         }
 1466         if (rw & FWRITE) {
 1467                 FLUSHQ(&tp->t_outq);
 1468                 ttwwakeup(tp);
 1469         }
 1470         splx(s);
 1471 }
 1472 
 1473 /*
 1474  * Copy in the default termios characters.
 1475  */
 1476 void
 1477 termioschars(struct termios *t)
 1478 {
 1479 
 1480         bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
 1481 }
 1482 
 1483 /*
 1484  * Old interface.
 1485  */
 1486 void
 1487 ttychars(struct tty *tp)
 1488 {
 1489 
 1490         termioschars(&tp->t_termios);
 1491 }
 1492 
 1493 /*
 1494  * Handle input high water.  Send stop character for the IXOFF case.  Turn
 1495  * on our input flow control bit and propagate the changes to the driver.
 1496  * XXX the stop character should be put in a special high priority queue.
 1497  */
 1498 void
 1499 ttyblock(struct tty *tp)
 1500 {
 1501 
 1502         SET(tp->t_state, TS_TBLOCK);
 1503         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
 1504             putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
 1505                 CLR(tp->t_state, TS_TBLOCK);    /* try again later */
 1506         ttstart(tp);
 1507 }
 1508 
 1509 /*
 1510  * Handle input low water.  Send start character for the IXOFF case.  Turn
 1511  * off our input flow control bit and propagate the changes to the driver.
 1512  * XXX the start character should be put in a special high priority queue.
 1513  */
 1514 static void
 1515 ttyunblock(struct tty *tp)
 1516 {
 1517 
 1518         CLR(tp->t_state, TS_TBLOCK);
 1519         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
 1520             putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
 1521                 SET(tp->t_state, TS_TBLOCK);    /* try again later */
 1522         ttstart(tp);
 1523 }
 1524 
 1525 #ifdef notyet
 1526 /* Not used by any current (i386) drivers. */
 1527 /*
 1528  * Restart after an inter-char delay.
 1529  */
 1530 void
 1531 ttrstrt(void *tp_arg)
 1532 {
 1533         struct tty *tp;
 1534         int s;
 1535 
 1536         KASSERT(tp_arg != NULL, ("ttrstrt"));
 1537 
 1538         tp = tp_arg;
 1539         s = spltty();
 1540 
 1541         CLR(tp->t_state, TS_TIMEOUT);
 1542         ttstart(tp);
 1543 
 1544         splx(s);
 1545 }
 1546 #endif
 1547 
 1548 int
 1549 ttstart(struct tty *tp)
 1550 {
 1551 
 1552         if (tp->t_oproc != NULL)        /* XXX: Kludge for pty. */
 1553                 (*tp->t_oproc)(tp);
 1554         return (0);
 1555 }
 1556 
 1557 /*
 1558  * "close" a line discipline
 1559  */
 1560 int
 1561 ttylclose(struct tty *tp, int flag)
 1562 {
 1563 
 1564         if (flag & FNONBLOCK || ttywflush(tp))
 1565                 ttyflush(tp, FREAD | FWRITE);
 1566         return (0);
 1567 }
 1568 
 1569 /*
 1570  * Handle modem control transition on a tty.
 1571  * Flag indicates new state of carrier.
 1572  * Returns 0 if the line should be turned off, otherwise 1.
 1573  */
 1574 int
 1575 ttymodem(struct tty *tp, int flag)
 1576 {
 1577 
 1578         if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
 1579                 /*
 1580                  * MDMBUF: do flow control according to carrier flag
 1581                  * XXX TS_CAR_OFLOW doesn't do anything yet.  TS_TTSTOP
 1582                  * works if IXON and IXANY are clear.
 1583                  */
 1584                 if (flag) {
 1585                         CLR(tp->t_state, TS_CAR_OFLOW);
 1586                         CLR(tp->t_state, TS_TTSTOP);
 1587                         ttstart(tp);
 1588                 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
 1589                         SET(tp->t_state, TS_CAR_OFLOW);
 1590                         SET(tp->t_state, TS_TTSTOP);
 1591                         (*tp->t_stop)(tp, 0);
 1592                 }
 1593         } else if (flag == 0) {
 1594                 /*
 1595                  * Lost carrier.
 1596                  */
 1597                 CLR(tp->t_state, TS_CARR_ON);
 1598                 if (ISSET(tp->t_state, TS_ISOPEN) &&
 1599                     !ISSET(tp->t_cflag, CLOCAL)) {
 1600                         SET(tp->t_state, TS_ZOMBIE);
 1601                         CLR(tp->t_state, TS_CONNECTED);
 1602                         if (tp->t_session) {
 1603                                 sx_slock(&proctree_lock);
 1604                                 if (tp->t_session->s_leader) {
 1605                                         struct proc *p;
 1606 
 1607                                         p = tp->t_session->s_leader;
 1608                                         PROC_LOCK(p);
 1609                                         psignal(p, SIGHUP);
 1610                                         PROC_UNLOCK(p);
 1611                                 }
 1612                                 sx_sunlock(&proctree_lock);
 1613                         }
 1614                         ttyflush(tp, FREAD | FWRITE);
 1615                         return (0);
 1616                 }
 1617         } else {
 1618                 /*
 1619                  * Carrier now on.
 1620                  */
 1621                 SET(tp->t_state, TS_CARR_ON);
 1622                 if (!ISSET(tp->t_state, TS_ZOMBIE))
 1623                         SET(tp->t_state, TS_CONNECTED);
 1624                 wakeup(TSA_CARR_ON(tp));
 1625                 ttwakeup(tp);
 1626                 ttwwakeup(tp);
 1627         }
 1628         return (1);
 1629 }
 1630 
 1631 /*
 1632  * Reinput pending characters after state switch
 1633  * call at spltty().
 1634  */
 1635 static void
 1636 ttypend(struct tty *tp)
 1637 {
 1638         struct clist tq;
 1639         int c;
 1640 
 1641         CLR(tp->t_lflag, PENDIN);
 1642         SET(tp->t_state, TS_TYPEN);
 1643         /*
 1644          * XXX this assumes too much about clist internals.  It may even
 1645          * fail if the cblock slush pool is empty.  We can't allocate more
 1646          * cblocks here because we are called from an interrupt handler
 1647          * and clist_alloc_cblocks() can wait.
 1648          */
 1649         tq = tp->t_rawq;
 1650         bzero(&tp->t_rawq, sizeof tp->t_rawq);
 1651         tp->t_rawq.c_cbmax = tq.c_cbmax;
 1652         tp->t_rawq.c_cbreserved = tq.c_cbreserved;
 1653         while ((c = getc(&tq)) >= 0)
 1654                 ttyinput(c, tp);
 1655         CLR(tp->t_state, TS_TYPEN);
 1656 }
 1657 
 1658 /*
 1659  * Process a read call on a tty device.
 1660  */
 1661 int
 1662 ttread(struct tty *tp, struct uio *uio, int flag)
 1663 {
 1664         struct clist *qp;
 1665         int c;
 1666         tcflag_t lflag;
 1667         cc_t *cc = tp->t_cc;
 1668         struct thread *td;
 1669         struct proc *p;
 1670         int s, first, error = 0;
 1671         int has_stime = 0, last_cc = 0;
 1672         long slp = 0;           /* XXX this should be renamed `timo'. */
 1673         struct timeval stime;
 1674         struct pgrp *pg;
 1675 
 1676         td = curthread;
 1677         p = td->td_proc;
 1678 loop:
 1679         s = spltty();
 1680         lflag = tp->t_lflag;
 1681         /*
 1682          * take pending input first
 1683          */
 1684         if (ISSET(lflag, PENDIN)) {
 1685                 ttypend(tp);
 1686                 splx(s);        /* reduce latency */
 1687                 s = spltty();
 1688                 lflag = tp->t_lflag;    /* XXX ttypend() clobbers it */
 1689         }
 1690 
 1691         /*
 1692          * Hang process if it's in the background.
 1693          */
 1694         if (isbackground(p, tp)) {
 1695                 splx(s);
 1696                 sx_slock(&proctree_lock);
 1697                 PROC_LOCK(p);
 1698                 if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) ||
 1699                     SIGISMEMBER(td->td_sigmask, SIGTTIN) ||
 1700                     (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) {
 1701                         PROC_UNLOCK(p);
 1702                         sx_sunlock(&proctree_lock);
 1703                         return (EIO);
 1704                 }
 1705                 pg = p->p_pgrp;
 1706                 PROC_UNLOCK(p);
 1707                 PGRP_LOCK(pg);
 1708                 sx_sunlock(&proctree_lock);
 1709                 pgsignal(pg, SIGTTIN, 1);
 1710                 PGRP_UNLOCK(pg);
 1711                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
 1712                 if (error)
 1713                         return (error);
 1714                 goto loop;
 1715         }
 1716 
 1717         if (ISSET(tp->t_state, TS_ZOMBIE)) {
 1718                 splx(s);
 1719                 return (0);     /* EOF */
 1720         }
 1721 
 1722         /*
 1723          * If canonical, use the canonical queue,
 1724          * else use the raw queue.
 1725          *
 1726          * (should get rid of clists...)
 1727          */
 1728         qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
 1729 
 1730         if (flag & IO_NDELAY) {
 1731                 if (qp->c_cc > 0)
 1732                         goto read;
 1733                 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
 1734                         splx(s);
 1735                         return (0);
 1736                 }
 1737                 splx(s);
 1738                 return (EWOULDBLOCK);
 1739         }
 1740         if (!ISSET(lflag, ICANON)) {
 1741                 int m = cc[VMIN];
 1742                 long t = cc[VTIME];
 1743                 struct timeval timecopy;
 1744 
 1745                 /*
 1746                  * Check each of the four combinations.
 1747                  * (m > 0 && t == 0) is the normal read case.
 1748                  * It should be fairly efficient, so we check that and its
 1749                  * companion case (m == 0 && t == 0) first.
 1750                  * For the other two cases, we compute the target sleep time
 1751                  * into slp.
 1752                  */
 1753                 if (t == 0) {
 1754                         if (qp->c_cc < m)
 1755                                 goto sleep;
 1756                         if (qp->c_cc > 0)
 1757                                 goto read;
 1758 
 1759                         /* m, t and qp->c_cc are all 0.  0 is enough input. */
 1760                         splx(s);
 1761                         return (0);
 1762                 }
 1763                 t *= 100000;            /* time in us */
 1764 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
 1765                          ((t1).tv_usec - (t2).tv_usec))
 1766                 if (m > 0) {
 1767                         if (qp->c_cc <= 0)
 1768                                 goto sleep;
 1769                         if (qp->c_cc >= m)
 1770                                 goto read;
 1771                         getmicrotime(&timecopy);
 1772                         if (!has_stime) {
 1773                                 /* first character, start timer */
 1774                                 has_stime = 1;
 1775                                 stime = timecopy;
 1776                                 slp = t;
 1777                         } else if (qp->c_cc > last_cc) {
 1778                                 /* got a character, restart timer */
 1779                                 stime = timecopy;
 1780                                 slp = t;
 1781                         } else {
 1782                                 /* nothing, check expiration */
 1783                                 slp = t - diff(timecopy, stime);
 1784                                 if (slp <= 0)
 1785                                         goto read;
 1786                         }
 1787                         last_cc = qp->c_cc;
 1788                 } else {        /* m == 0 */
 1789                         if (qp->c_cc > 0)
 1790                                 goto read;
 1791                         getmicrotime(&timecopy);
 1792                         if (!has_stime) {
 1793                                 has_stime = 1;
 1794                                 stime = timecopy;
 1795                                 slp = t;
 1796                         } else {
 1797                                 slp = t - diff(timecopy, stime);
 1798                                 if (slp <= 0) {
 1799                                         /* Timed out, but 0 is enough input. */
 1800                                         splx(s);
 1801                                         return (0);
 1802                                 }
 1803                         }
 1804                 }
 1805 #undef diff
 1806                 /*
 1807                  * Rounding down may make us wake up just short
 1808                  * of the target, so we round up.
 1809                  * The formula is ceiling(slp * hz/1000000).
 1810                  * 32-bit arithmetic is enough for hz < 169.
 1811                  * XXX see tvtohz() for how to avoid overflow if hz
 1812                  * is large (divide by `tick' and/or arrange to
 1813                  * use tvtohz() if hz is large).
 1814                  */
 1815                 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
 1816                 goto sleep;
 1817         }
 1818         if (qp->c_cc <= 0) {
 1819 sleep:
 1820                 /*
 1821                  * There is no input, or not enough input and we can block.
 1822                  */
 1823                 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
 1824                                  ISSET(tp->t_state, TS_CONNECTED) ?
 1825                                  "ttyin" : "ttyhup", (int)slp);
 1826                 splx(s);
 1827                 if (error == EWOULDBLOCK)
 1828                         error = 0;
 1829                 else if (error)
 1830                         return (error);
 1831                 /*
 1832                  * XXX what happens if another process eats some input
 1833                  * while we are asleep (not just here)?  It would be
 1834                  * safest to detect changes and reset our state variables
 1835                  * (has_stime and last_cc).
 1836                  */
 1837                 slp = 0;
 1838                 goto loop;
 1839         }
 1840 read:
 1841         splx(s);
 1842         /*
 1843          * Input present, check for input mapping and processing.
 1844          */
 1845         first = 1;
 1846         if (ISSET(lflag, ICANON | ISIG))
 1847                 goto slowcase;
 1848         for (;;) {
 1849                 char ibuf[IBUFSIZ];
 1850                 int icc;
 1851 
 1852                 icc = imin(uio->uio_resid, IBUFSIZ);
 1853                 icc = q_to_b(qp, ibuf, icc);
 1854                 if (icc <= 0) {
 1855                         if (first)
 1856                                 goto loop;
 1857                         break;
 1858                 }
 1859                 error = uiomove(ibuf, icc, uio);
 1860                 /*
 1861                  * XXX if there was an error then we should ungetc() the
 1862                  * unmoved chars and reduce icc here.
 1863                  */
 1864                 if (error)
 1865                         break;
 1866                 if (uio->uio_resid == 0)
 1867                         break;
 1868                 first = 0;
 1869         }
 1870         goto out;
 1871 slowcase:
 1872         for (;;) {
 1873                 c = getc(qp);
 1874                 if (c < 0) {
 1875                         if (first)
 1876                                 goto loop;
 1877                         break;
 1878                 }
 1879                 /*
 1880                  * delayed suspend (^Y)
 1881                  */
 1882                 if (CCEQ(cc[VDSUSP], c) &&
 1883                     ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
 1884                         if (tp->t_pgrp != NULL) {
 1885                                 PGRP_LOCK(tp->t_pgrp);
 1886                                 pgsignal(tp->t_pgrp, SIGTSTP, 1);
 1887                                 PGRP_UNLOCK(tp->t_pgrp);
 1888                         }
 1889                         if (first) {
 1890                                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
 1891                                                  "ttybg3", 0);
 1892                                 if (error)
 1893                                         break;
 1894                                 goto loop;
 1895                         }
 1896                         break;
 1897                 }
 1898                 /*
 1899                  * Interpret EOF only in canonical mode.
 1900                  */
 1901                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
 1902                         break;
 1903                 /*
 1904                  * Give user character.
 1905                  */
 1906                 error = ureadc(c, uio);
 1907                 if (error)
 1908                         /* XXX should ungetc(c, qp). */
 1909                         break;
 1910                 if (uio->uio_resid == 0)
 1911                         break;
 1912                 /*
 1913                  * In canonical mode check for a "break character"
 1914                  * marking the end of a "line of input".
 1915                  */
 1916                 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
 1917                         break;
 1918                 first = 0;
 1919         }
 1920 
 1921 out:
 1922         /*
 1923          * Look to unblock input now that (presumably)
 1924          * the input queue has gone down.
 1925          */
 1926         s = spltty();
 1927         if (ISSET(tp->t_state, TS_TBLOCK) &&
 1928             tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
 1929                 ttyunblock(tp);
 1930         splx(s);
 1931 
 1932         return (error);
 1933 }
 1934 
 1935 /*
 1936  * Check the output queue on tp for space for a kernel message (from uprintf
 1937  * or tprintf).  Allow some space over the normal hiwater mark so we don't
 1938  * lose messages due to normal flow control, but don't let the tty run amok.
 1939  * Sleeps here are not interruptible, but we return prematurely if new signals
 1940  * arrive.
 1941  */
 1942 int
 1943 ttycheckoutq(struct tty *tp, int wait)
 1944 {
 1945         int hiwat, s;
 1946         sigset_t oldmask;
 1947         struct thread *td;
 1948         struct proc *p;
 1949 
 1950         td = curthread;
 1951         p = td->td_proc;
 1952         hiwat = tp->t_ohiwat;
 1953         SIGEMPTYSET(oldmask);
 1954         s = spltty();
 1955         if (wait) {
 1956                 PROC_LOCK(p);
 1957                 oldmask = td->td_siglist;
 1958                 PROC_UNLOCK(p);
 1959         }
 1960         if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
 1961                 while (tp->t_outq.c_cc > hiwat) {
 1962                         ttstart(tp);
 1963                         if (tp->t_outq.c_cc <= hiwat)
 1964                                 break;
 1965                         if (!wait) {
 1966                                 splx(s);
 1967                                 return (0);
 1968                         }
 1969                         PROC_LOCK(p);
 1970                         if (!SIGSETEQ(td->td_siglist, oldmask)) {
 1971                                 PROC_UNLOCK(p);
 1972                                 splx(s);
 1973                                 return (0);
 1974                         }
 1975                         PROC_UNLOCK(p);
 1976                         SET(tp->t_state, TS_SO_OLOWAT);
 1977                         tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
 1978                 }
 1979         splx(s);
 1980         return (1);
 1981 }
 1982 
 1983 /*
 1984  * Process a write call on a tty device.
 1985  */
 1986 int
 1987 ttwrite(struct tty *tp, struct uio *uio, int flag)
 1988 {
 1989         char *cp = NULL;
 1990         int cc, ce;
 1991         struct thread *td;
 1992         struct proc *p;
 1993         int i, hiwat, cnt, error, s;
 1994         char obuf[OBUFSIZ];
 1995 
 1996         hiwat = tp->t_ohiwat;
 1997         cnt = uio->uio_resid;
 1998         error = 0;
 1999         cc = 0;
 2000         td = curthread;
 2001         p = td->td_proc;
 2002 loop:
 2003         s = spltty();
 2004         if (ISSET(tp->t_state, TS_ZOMBIE)) {
 2005                 splx(s);
 2006                 if (uio->uio_resid == cnt)
 2007                         error = EIO;
 2008                 goto out;
 2009         }
 2010         if (!ISSET(tp->t_state, TS_CONNECTED)) {
 2011                 if (flag & IO_NDELAY) {
 2012                         splx(s);
 2013                         error = EWOULDBLOCK;
 2014                         goto out;
 2015                 }
 2016                 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
 2017                                  "ttydcd", 0);
 2018                 splx(s);
 2019                 if (error)
 2020                         goto out;
 2021                 goto loop;
 2022         }
 2023         splx(s);
 2024         /*
 2025          * Hang the process if it's in the background.
 2026          */
 2027         sx_slock(&proctree_lock);
 2028         PROC_LOCK(p);
 2029         if (isbackground(p, tp) &&
 2030             ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
 2031             !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) &&
 2032             !SIGISMEMBER(td->td_sigmask, SIGTTOU)) {
 2033                 if (p->p_pgrp->pg_jobc == 0) {
 2034                         PROC_UNLOCK(p);
 2035                         sx_sunlock(&proctree_lock);
 2036                         error = EIO;
 2037                         goto out;
 2038                 }
 2039                 PROC_UNLOCK(p);
 2040                 PGRP_LOCK(p->p_pgrp);
 2041                 sx_sunlock(&proctree_lock);
 2042                 pgsignal(p->p_pgrp, SIGTTOU, 1);
 2043                 PGRP_UNLOCK(p->p_pgrp);
 2044                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
 2045                 if (error)
 2046                         goto out;
 2047                 goto loop;
 2048         } else {
 2049                 PROC_UNLOCK(p);
 2050                 sx_sunlock(&proctree_lock);
 2051         }
 2052         /*
 2053          * Process the user's data in at most OBUFSIZ chunks.  Perform any
 2054          * output translation.  Keep track of high water mark, sleep on
 2055          * overflow awaiting device aid in acquiring new space.
 2056          */
 2057         while (uio->uio_resid > 0 || cc > 0) {
 2058                 if (ISSET(tp->t_lflag, FLUSHO)) {
 2059                         uio->uio_resid = 0;
 2060                         return (0);
 2061                 }
 2062                 if (tp->t_outq.c_cc > hiwat)
 2063                         goto ovhiwat;
 2064                 /*
 2065                  * Grab a hunk of data from the user, unless we have some
 2066                  * leftover from last time.
 2067                  */
 2068                 if (cc == 0) {
 2069                         cc = imin(uio->uio_resid, OBUFSIZ);
 2070                         cp = obuf;
 2071                         error = uiomove(cp, cc, uio);
 2072                         if (error) {
 2073                                 cc = 0;
 2074                                 break;
 2075                         }
 2076                 }
 2077                 /*
 2078                  * If nothing fancy need be done, grab those characters we
 2079                  * can handle without any of ttyoutput's processing and
 2080                  * just transfer them to the output q.  For those chars
 2081                  * which require special processing (as indicated by the
 2082                  * bits in char_type), call ttyoutput.  After processing
 2083                  * a hunk of data, look for FLUSHO so ^O's will take effect
 2084                  * immediately.
 2085                  */
 2086                 while (cc > 0) {
 2087                         if (!ISSET(tp->t_oflag, OPOST))
 2088                                 ce = cc;
 2089                         else {
 2090                                 ce = cc - scanc((u_int)cc, (u_char *)cp,
 2091                                                 char_type, CCLASSMASK);
 2092                                 /*
 2093                                  * If ce is zero, then we're processing
 2094                                  * a special character through ttyoutput.
 2095                                  */
 2096                                 if (ce == 0) {
 2097                                         tp->t_rocount = 0;
 2098                                         if (ttyoutput(*cp, tp) >= 0) {
 2099                                                 /* No Clists, wait a bit. */
 2100                                                 ttstart(tp);
 2101                                                 if (flag & IO_NDELAY) {
 2102                                                         error = EWOULDBLOCK;
 2103                                                         goto out;
 2104                                                 }
 2105                                                 error = ttysleep(tp, &lbolt,
 2106                                                                  TTOPRI|PCATCH,
 2107                                                                  "ttybf1", 0);
 2108                                                 if (error)
 2109                                                         goto out;
 2110                                                 goto loop;
 2111                                         }
 2112                                         cp++;
 2113                                         cc--;
 2114                                         if (ISSET(tp->t_lflag, FLUSHO) ||
 2115                                             tp->t_outq.c_cc > hiwat)
 2116                                                 goto ovhiwat;
 2117                                         continue;
 2118                                 }
 2119                         }
 2120                         /*
 2121                          * A bunch of normal characters have been found.
 2122                          * Transfer them en masse to the output queue and
 2123                          * continue processing at the top of the loop.
 2124                          * If there are any further characters in this
 2125                          * <= OBUFSIZ chunk, the first should be a character
 2126                          * requiring special handling by ttyoutput.
 2127                          */
 2128                         tp->t_rocount = 0;
 2129                         i = b_to_q(cp, ce, &tp->t_outq);
 2130                         ce -= i;
 2131                         tp->t_column += ce;
 2132                         cp += ce, cc -= ce, tk_nout += ce;
 2133                         tp->t_outcc += ce;
 2134                         if (i > 0) {
 2135                                 /* No Clists, wait a bit. */
 2136                                 ttstart(tp);
 2137                                 if (flag & IO_NDELAY) {
 2138                                         error = EWOULDBLOCK;
 2139                                         goto out;
 2140                                 }
 2141                                 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
 2142                                                  "ttybf2", 0);
 2143                                 if (error)
 2144                                         goto out;
 2145                                 goto loop;
 2146                         }
 2147                         if (ISSET(tp->t_lflag, FLUSHO) ||
 2148                             tp->t_outq.c_cc > hiwat)
 2149                                 break;
 2150                 }
 2151                 ttstart(tp);
 2152         }
 2153 out:
 2154         /*
 2155          * If cc is nonzero, we leave the uio structure inconsistent, as the
 2156          * offset and iov pointers have moved forward, but it doesn't matter
 2157          * (the call will either return short or restart with a new uio).
 2158          */
 2159         uio->uio_resid += cc;
 2160         return (error);
 2161 
 2162 ovhiwat:
 2163         ttstart(tp);
 2164         s = spltty();
 2165         /*
 2166          * This can only occur if FLUSHO is set in t_lflag,
 2167          * or if ttstart/oproc is synchronous (or very fast).
 2168          */
 2169         if (tp->t_outq.c_cc <= hiwat) {
 2170                 splx(s);
 2171                 goto loop;
 2172         }
 2173         if (flag & IO_NDELAY) {
 2174                 splx(s);
 2175                 uio->uio_resid += cc;
 2176                 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
 2177         }
 2178         SET(tp->t_state, TS_SO_OLOWAT);
 2179         error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
 2180                          tp->t_timeout);
 2181         splx(s);
 2182         if (error == EWOULDBLOCK)
 2183                 error = EIO;
 2184         if (error)
 2185                 goto out;
 2186         goto loop;
 2187 }
 2188 
 2189 /*
 2190  * Rubout one character from the rawq of tp
 2191  * as cleanly as possible.
 2192  */
 2193 static void
 2194 ttyrub(int c, struct tty *tp)
 2195 {
 2196         char *cp;
 2197         int savecol;
 2198         int tabc, s;
 2199 
 2200         if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
 2201                 return;
 2202         CLR(tp->t_lflag, FLUSHO);
 2203         if (ISSET(tp->t_lflag, ECHOE)) {
 2204                 if (tp->t_rocount == 0) {
 2205                         /*
 2206                          * Screwed by ttwrite; retype
 2207                          */
 2208                         ttyretype(tp);
 2209                         return;
 2210                 }
 2211                 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
 2212                         ttyrubo(tp, 2);
 2213                 else {
 2214                         CLR(c, ~TTY_CHARMASK);
 2215                         switch (CCLASS(c)) {
 2216                         case ORDINARY:
 2217                                 ttyrubo(tp, 1);
 2218                                 break;
 2219                         case BACKSPACE:
 2220                         case CONTROL:
 2221                         case NEWLINE:
 2222                         case RETURN:
 2223                         case VTAB:
 2224                                 if (ISSET(tp->t_lflag, ECHOCTL))
 2225                                         ttyrubo(tp, 2);
 2226                                 break;
 2227                         case TAB:
 2228                                 if (tp->t_rocount < tp->t_rawq.c_cc) {
 2229                                         ttyretype(tp);
 2230                                         return;
 2231                                 }
 2232                                 s = spltty();
 2233                                 savecol = tp->t_column;
 2234                                 SET(tp->t_state, TS_CNTTB);
 2235                                 SET(tp->t_lflag, FLUSHO);
 2236                                 tp->t_column = tp->t_rocol;
 2237                                 cp = tp->t_rawq.c_cf;
 2238                                 if (cp)
 2239                                         tabc = *cp;     /* XXX FIX NEXTC */
 2240                                 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
 2241                                         ttyecho(tabc, tp);
 2242                                 CLR(tp->t_lflag, FLUSHO);
 2243                                 CLR(tp->t_state, TS_CNTTB);
 2244                                 splx(s);
 2245 
 2246                                 /* savecol will now be length of the tab. */
 2247                                 savecol -= tp->t_column;
 2248                                 tp->t_column += savecol;
 2249                                 if (savecol > 8)
 2250                                         savecol = 8;    /* overflow screw */
 2251                                 while (--savecol >= 0)
 2252                                         (void)ttyoutput('\b', tp);
 2253                                 break;
 2254                         default:                        /* XXX */
 2255 #define PANICSTR        "ttyrub: would panic c = %d, val = %d\n"
 2256                                 (void)printf(PANICSTR, c, CCLASS(c));
 2257 #ifdef notdef
 2258                                 panic(PANICSTR, c, CCLASS(c));
 2259 #endif
 2260                         }
 2261                 }
 2262         } else if (ISSET(tp->t_lflag, ECHOPRT)) {
 2263                 if (!ISSET(tp->t_state, TS_ERASE)) {
 2264                         SET(tp->t_state, TS_ERASE);
 2265                         (void)ttyoutput('\\', tp);
 2266                 }
 2267                 ttyecho(c, tp);
 2268         } else {
 2269                 ttyecho(tp->t_cc[VERASE], tp);
 2270                 /*
 2271                  * This code may be executed not only when an ERASE key
 2272                  * is pressed, but also when ^U (KILL) or ^W (WERASE) are.
 2273                  * So, I didn't think it was worthwhile to pass the extra
 2274                  * information (which would need an extra parameter,
 2275                  * changing every call) needed to distinguish the ERASE2
 2276                  * case from the ERASE.
 2277                  */
 2278         }
 2279         --tp->t_rocount;
 2280 }
 2281 
 2282 /*
 2283  * Back over cnt characters, erasing them.
 2284  */
 2285 static void
 2286 ttyrubo(struct tty *tp, int cnt)
 2287 {
 2288 
 2289         while (cnt-- > 0) {
 2290                 (void)ttyoutput('\b', tp);
 2291                 (void)ttyoutput(' ', tp);
 2292                 (void)ttyoutput('\b', tp);
 2293         }
 2294 }
 2295 
 2296 /*
 2297  * ttyretype --
 2298  *      Reprint the rawq line.  Note, it is assumed that c_cc has already
 2299  *      been checked.
 2300  */
 2301 static void
 2302 ttyretype(struct tty *tp)
 2303 {
 2304         char *cp;
 2305         int s, c;
 2306 
 2307         /* Echo the reprint character. */
 2308         if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
 2309                 ttyecho(tp->t_cc[VREPRINT], tp);
 2310 
 2311         (void)ttyoutput('\n', tp);
 2312 
 2313         /*
 2314          * XXX
 2315          * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
 2316          * BIT OF FIRST CHAR.
 2317          */
 2318         s = spltty();
 2319         for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
 2320             cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
 2321                 ttyecho(c, tp);
 2322         for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
 2323             cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
 2324                 ttyecho(c, tp);
 2325         CLR(tp->t_state, TS_ERASE);
 2326         splx(s);
 2327 
 2328         tp->t_rocount = tp->t_rawq.c_cc;
 2329         tp->t_rocol = 0;
 2330 }
 2331 
 2332 /*
 2333  * Echo a typed character to the terminal.
 2334  */
 2335 static void
 2336 ttyecho(int c, struct tty *tp)
 2337 {
 2338 
 2339         if (!ISSET(tp->t_state, TS_CNTTB))
 2340                 CLR(tp->t_lflag, FLUSHO);
 2341         if ((!ISSET(tp->t_lflag, ECHO) &&
 2342              (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
 2343             ISSET(tp->t_lflag, EXTPROC))
 2344                 return;
 2345         if (ISSET(tp->t_lflag, ECHOCTL) &&
 2346             ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
 2347             ISSET(c, TTY_CHARMASK) == 0177)) {
 2348                 (void)ttyoutput('^', tp);
 2349                 CLR(c, ~TTY_CHARMASK);
 2350                 if (c == 0177)
 2351                         c = '?';
 2352                 else
 2353                         c += 'A' - 1;
 2354         }
 2355         (void)ttyoutput(c, tp);
 2356 }
 2357 
 2358 /*
 2359  * Wake up any readers on a tty.
 2360  */
 2361 void
 2362 ttwakeup(struct tty *tp)
 2363 {
 2364 
 2365         if (SEL_WAITING(&tp->t_rsel))
 2366                 selwakeuppri(&tp->t_rsel, TTIPRI);
 2367         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
 2368                 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
 2369         wakeup(TSA_HUP_OR_INPUT(tp));
 2370         KNOTE_UNLOCKED(&tp->t_rsel.si_note, 0);
 2371 }
 2372 
 2373 /*
 2374  * Wake up any writers on a tty.
 2375  */
 2376 void
 2377 ttwwakeup(struct tty *tp)
 2378 {
 2379 
 2380         if (SEL_WAITING(&tp->t_wsel) && tp->t_outq.c_cc <= tp->t_olowat)
 2381                 selwakeuppri(&tp->t_wsel, TTOPRI);
 2382         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
 2383                 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
 2384         if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
 2385             TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
 2386                 CLR(tp->t_state, TS_SO_OCOMPLETE);
 2387                 wakeup(TSA_OCOMPLETE(tp));
 2388         }
 2389         if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
 2390             tp->t_outq.c_cc <= tp->t_olowat) {
 2391                 CLR(tp->t_state, TS_SO_OLOWAT);
 2392                 wakeup(TSA_OLOWAT(tp));
 2393         }
 2394         KNOTE_UNLOCKED(&tp->t_wsel.si_note, 0);
 2395 }
 2396 
 2397 /*
 2398  * Look up a code for a specified speed in a conversion table;
 2399  * used by drivers to map software speed values to hardware parameters.
 2400  */
 2401 int
 2402 ttspeedtab(int speed, struct speedtab *table)
 2403 {
 2404 
 2405         for ( ; table->sp_speed != -1; table++)
 2406                 if (table->sp_speed == speed)
 2407                         return (table->sp_code);
 2408         return (-1);
 2409 }
 2410 
 2411 /*
 2412  * Set input and output watermarks and buffer sizes.  For input, the
 2413  * high watermark is about one second's worth of input above empty, the
 2414  * low watermark is slightly below high water, and the buffer size is a
 2415  * driver-dependent amount above high water.  For output, the watermarks
 2416  * are near the ends of the buffer, with about 1 second's worth of input
 2417  * between them.  All this only applies to the standard line discipline.
 2418  */
 2419 void
 2420 ttsetwater(struct tty *tp)
 2421 {
 2422         int cps, ttmaxhiwat, x;
 2423 
 2424         /* Input. */
 2425         clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
 2426         switch (tp->t_ispeedwat) {
 2427         case (speed_t)-1:
 2428                 cps = tp->t_ispeed / 10;
 2429                 break;
 2430         case 0:
 2431                 /*
 2432                  * This case is for old drivers that don't know about
 2433                  * t_ispeedwat.  Arrange for them to get the old buffer
 2434                  * sizes and watermarks.
 2435                  */
 2436                 cps = TTYHOG - 2 * 256;
 2437                 tp->t_ififosize = 2 * 256;
 2438                 break;
 2439         default:
 2440                 cps = tp->t_ispeedwat / 10;
 2441                 break;
 2442         }
 2443         tp->t_ihiwat = cps;
 2444         tp->t_ilowat = 7 * cps / 8;
 2445         x = cps + tp->t_ififosize;
 2446         clist_alloc_cblocks(&tp->t_rawq, x, x);
 2447 
 2448         /* Output. */
 2449         switch (tp->t_ospeedwat) {
 2450         case (speed_t)-1:
 2451                 cps = tp->t_ospeed / 10;
 2452                 ttmaxhiwat = 2 * TTMAXHIWAT;
 2453                 break;
 2454         case 0:
 2455                 cps = tp->t_ospeed / 10;
 2456                 ttmaxhiwat = TTMAXHIWAT;
 2457                 break;
 2458         default:
 2459                 cps = tp->t_ospeedwat / 10;
 2460                 ttmaxhiwat = 8 * TTMAXHIWAT;
 2461                 break;
 2462         }
 2463 #define CLAMP(x, h, l)  ((x) > h ? h : ((x) < l) ? l : (x))
 2464         tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
 2465         x += cps;
 2466         x = CLAMP(x, ttmaxhiwat, TTMINHIWAT);   /* XXX clamps are too magic */
 2467         tp->t_ohiwat = roundup(x, CBSIZE);      /* XXX for compat */
 2468         x = imax(tp->t_ohiwat, TTMAXHIWAT);     /* XXX for compat/safety */
 2469         x += OBUFSIZ + 100;
 2470         clist_alloc_cblocks(&tp->t_outq, x, x);
 2471 #undef  CLAMP
 2472 }
 2473 
 2474 /*
 2475  * Report on state of foreground process group.
 2476  */
 2477 void
 2478 ttyinfo(struct tty *tp)
 2479 {
 2480         struct timeval utime, stime;
 2481         struct proc *p, *pick;
 2482         struct thread *td;
 2483         const char *stateprefix, *state;
 2484         long rss;
 2485         int load, pctcpu;
 2486 
 2487         if (ttycheckoutq(tp,0) == 0)
 2488                 return;
 2489 
 2490         /* Print load average. */
 2491         load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
 2492         ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
 2493 
 2494         /*
 2495          * On return following a ttyprintf(), we set tp->t_rocount to 0 so
 2496          * that pending input will be retyped on BS.
 2497          */
 2498         if (tp->t_session == NULL) {
 2499                 ttyprintf(tp, "not a controlling terminal\n");
 2500                 tp->t_rocount = 0;
 2501                 return;
 2502         }
 2503         if (tp->t_pgrp == NULL) {
 2504                 ttyprintf(tp, "no foreground process group\n");
 2505                 tp->t_rocount = 0;
 2506                 return;
 2507         }
 2508         PGRP_LOCK(tp->t_pgrp);
 2509         if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) {
 2510                 PGRP_UNLOCK(tp->t_pgrp);
 2511                 ttyprintf(tp, "empty foreground process group\n");
 2512                 tp->t_rocount = 0;
 2513                 return;
 2514         }
 2515 
 2516         /*
 2517          * Pick the most interesting process and copy some of its
 2518          * state for printing later.  sched_lock must be held for
 2519          * most parts of this.  Holding it throughout is simplest
 2520          * and prevents even unimportant inconsistencies in the
 2521          * copy of the state, but may increase interrupt latency
 2522          * too much.
 2523          */
 2524         mtx_lock_spin(&sched_lock);
 2525         for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
 2526                 if (proc_compare(pick, p))
 2527                         pick = p;
 2528         PGRP_UNLOCK(tp->t_pgrp);
 2529 
 2530         td = FIRST_THREAD_IN_PROC(pick);        /* XXXKSE */
 2531 #if 0
 2532         KASSERT(td != NULL, ("ttyinfo: no thread"));
 2533 #else
 2534         if (td == NULL) {
 2535                 mtx_unlock_spin(&sched_lock);
 2536                 ttyprintf(tp, "foreground process without thread\n");
 2537                 tp->t_rocount = 0;
 2538                 return;
 2539         }
 2540 #endif
 2541         stateprefix = "";
 2542         if (TD_IS_RUNNING(td))
 2543                 state = "running";
 2544         else if (TD_ON_RUNQ(td) || TD_CAN_RUN(td))
 2545                 state = "runnable";
 2546         else if (TD_IS_SLEEPING(td)) {
 2547                 /* XXX: If we're sleeping, are we ever not in a queue? */
 2548                 if (TD_ON_SLEEPQ(td))
 2549                         state = td->td_wmesg;
 2550                 else
 2551                         state = "sleeping without queue";
 2552         } else if (TD_ON_LOCK(td)) {
 2553                 state = td->td_lockname;
 2554                 stateprefix = "*";
 2555         } else if (TD_IS_SUSPENDED(td))
 2556                 state = "suspended";
 2557         else if (TD_AWAITING_INTR(td))
 2558                 state = "intrwait";
 2559         else
 2560                 state = "unknown";
 2561         calcru(pick, &utime, &stime, NULL);
 2562         pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT;
 2563         if (pick->p_state == PRS_NEW || pick->p_state == PRS_ZOMBIE)
 2564                 rss = 0;
 2565         else
 2566                 rss = pgtok(vmspace_resident_count(pick->p_vmspace));
 2567         mtx_unlock_spin(&sched_lock);
 2568 
 2569         /* Print command, pid, state, utime, stime, %cpu, and rss. */
 2570         ttyprintf(tp,
 2571             " cmd: %s %d [%s%s] %ld.%02ldu %ld.%02lds %d%% %ldk\n",
 2572             pick->p_comm, pick->p_pid, stateprefix, state,
 2573             (long)utime.tv_sec, utime.tv_usec / 10000,
 2574             (long)stime.tv_sec, stime.tv_usec / 10000,
 2575             pctcpu / 100, rss);
 2576         tp->t_rocount = 0;
 2577 }
 2578 
 2579 /*
 2580  * Returns 1 if p2 is "better" than p1
 2581  *
 2582  * The algorithm for picking the "interesting" process is thus:
 2583  *
 2584  *      1) Only foreground processes are eligible - implied.
 2585  *      2) Runnable processes are favored over anything else.  The runner
 2586  *         with the highest cpu utilization is picked (p_estcpu).  Ties are
 2587  *         broken by picking the highest pid.
 2588  *      3) The sleeper with the shortest sleep time is next.  With ties,
 2589  *         we pick out just "short-term" sleepers (P_SINTR == 0).
 2590  *      4) Further ties are broken by picking the highest pid.
 2591  */
 2592 #define ISRUN(p, val)                                           \
 2593 do {                                                            \
 2594         struct thread *td;                                      \
 2595         val = 0;                                                \
 2596         FOREACH_THREAD_IN_PROC(p, td) {                         \
 2597                 if (TD_ON_RUNQ(td) ||                           \
 2598                     TD_IS_RUNNING(td)) {                        \
 2599                         val = 1;                                \
 2600                         break;                                  \
 2601                 }                                               \
 2602         }                                                       \
 2603 } while (0)
 2604 
 2605 #define TESTAB(a, b)    ((a)<<1 | (b))
 2606 #define ONLYA   2
 2607 #define ONLYB   1
 2608 #define BOTH    3
 2609 
 2610 static int
 2611 proc_compare(struct proc *p1, struct proc *p2)
 2612 {
 2613 
 2614         int esta, estb;
 2615         struct ksegrp *kg;
 2616         mtx_assert(&sched_lock, MA_OWNED);
 2617         if (p1 == NULL)
 2618                 return (1);
 2619 
 2620         ISRUN(p1, esta);
 2621         ISRUN(p2, estb);
 2622         
 2623         /*
 2624          * see if at least one of them is runnable
 2625          */
 2626         switch (TESTAB(esta, estb)) {
 2627         case ONLYA:
 2628                 return (0);
 2629         case ONLYB:
 2630                 return (1);
 2631         case BOTH:
 2632                 /*
 2633                  * tie - favor one with highest recent cpu utilization
 2634                  */
 2635                 esta = estb = 0;
 2636                 FOREACH_KSEGRP_IN_PROC(p1,kg) {
 2637                         esta += kg->kg_estcpu;
 2638                 }
 2639                 FOREACH_KSEGRP_IN_PROC(p2,kg) {
 2640                         estb += kg->kg_estcpu;
 2641                 }
 2642                 if (estb > esta)
 2643                         return (1);
 2644                 if (esta > estb)
 2645                         return (0);
 2646                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2647         }
 2648         /*
 2649          * weed out zombies
 2650          */
 2651         switch (TESTAB(p1->p_state == PRS_ZOMBIE, p2->p_state == PRS_ZOMBIE)) {
 2652         case ONLYA:
 2653                 return (1);
 2654         case ONLYB:
 2655                 return (0);
 2656         case BOTH:
 2657                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2658         }
 2659 
 2660 #if 0 /* XXXKSE */
 2661         /*
 2662          * pick the one with the smallest sleep time
 2663          */
 2664         if (p2->p_slptime > p1->p_slptime)
 2665                 return (0);
 2666         if (p1->p_slptime > p2->p_slptime)
 2667                 return (1);
 2668         /*
 2669          * favor one sleeping in a non-interruptible sleep
 2670          */
 2671         if (p1->p_sflag & PS_SINTR && (p2->p_sflag & PS_SINTR) == 0)
 2672                 return (1);
 2673         if (p2->p_sflag & PS_SINTR && (p1->p_sflag & PS_SINTR) == 0)
 2674                 return (0);
 2675 #endif
 2676         return (p2->p_pid > p1->p_pid);         /* tie - return highest pid */
 2677 }
 2678 
 2679 /*
 2680  * Output char to tty; console putchar style.
 2681  */
 2682 int
 2683 tputchar(int c, struct tty *tp)
 2684 {
 2685         int s;
 2686 
 2687         s = spltty();
 2688         if (!ISSET(tp->t_state, TS_CONNECTED)) {
 2689                 splx(s);
 2690                 return (-1);
 2691         }
 2692         if (c == '\n')
 2693                 (void)ttyoutput('\r', tp);
 2694         (void)ttyoutput(c, tp);
 2695         ttstart(tp);
 2696         splx(s);
 2697         return (0);
 2698 }
 2699 
 2700 /*
 2701  * Sleep on chan, returning ERESTART if tty changed while we napped and
 2702  * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep.  If
 2703  * the tty is revoked, restarting a pending call will redo validation done
 2704  * at the start of the call.
 2705  */
 2706 int
 2707 ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo)
 2708 {
 2709         int error;
 2710         int gen;
 2711 
 2712         gen = tp->t_gen;
 2713         error = tsleep(chan, pri, wmesg, timo);
 2714         if (error)
 2715                 return (error);
 2716         return (tp->t_gen == gen ? 0 : ERESTART);
 2717 }
 2718 
 2719 /*
 2720  * Gain a reference to a TTY
 2721  */
 2722 int
 2723 ttyref(struct tty *tp)
 2724 {
 2725         int i;
 2726         
 2727         mtx_lock(&tp->t_mtx);
 2728         KASSERT(tp->t_refcnt > 0,
 2729             ("ttyref(): tty refcnt is %d (%s)",
 2730             tp->t_refcnt, tp->t_dev != NULL ? devtoname(tp->t_dev) : "??"));
 2731         i = ++tp->t_refcnt;
 2732         mtx_unlock(&tp->t_mtx);
 2733         return (i);
 2734 }
 2735 
 2736 /*
 2737  * Drop a reference to a TTY.
 2738  * When reference count drops to zero, we free it.
 2739  */
 2740 int
 2741 ttyrel(struct tty *tp)
 2742 {
 2743         int i;
 2744         
 2745         mtx_lock(&tty_list_mutex);
 2746         mtx_lock(&tp->t_mtx);
 2747         KASSERT(tp->t_refcnt > 0,
 2748             ("ttyrel(): tty refcnt is %d (%s)",
 2749             tp->t_refcnt, tp->t_dev != NULL ? devtoname(tp->t_dev) : "??"));
 2750         i = --tp->t_refcnt;
 2751         if (i != 0) {
 2752                 mtx_unlock(&tp->t_mtx);
 2753                 mtx_unlock(&tty_list_mutex);
 2754                 return (i);
 2755         }
 2756         TAILQ_REMOVE(&tty_list, tp, t_list);
 2757         mtx_unlock(&tp->t_mtx);
 2758         mtx_unlock(&tty_list_mutex);
 2759         knlist_destroy(&tp->t_rsel.si_note);
 2760         knlist_destroy(&tp->t_wsel.si_note);
 2761         mtx_destroy(&tp->t_mtx);
 2762         free(tp, M_TTYS);
 2763         return (i);
 2764 }
 2765 
 2766 /*
 2767  * Allocate a tty struct.  Clists in the struct will be allocated by
 2768  * tty_open().
 2769  */
 2770 struct tty *
 2771 ttymalloc(struct tty *tp)
 2772 {
 2773         static int once;
 2774 
 2775         if (!once) {
 2776                 mtx_init(&tty_list_mutex, "ttylist", NULL, MTX_DEF);
 2777                 once++;
 2778         }
 2779 
 2780         if (tp) {
 2781                 /*
 2782                  * XXX: Either this argument should go away, or we should
 2783                  * XXX: require it and do a ttyrel(tp) here and allocate
 2784                  * XXX: a new tty.  For now do nothing.
 2785                  */
 2786                 return(tp);
 2787         }
 2788         tp = malloc(sizeof *tp, M_TTYS, M_WAITOK | M_ZERO);
 2789         tp->t_timeout = -1;
 2790         tp->t_dtr_wait = 3 * hz;
 2791         mtx_init(&tp->t_mtx, "tty", NULL, MTX_DEF);
 2792         tp->t_refcnt = 1;
 2793         mtx_lock(&tty_list_mutex);
 2794         TAILQ_INSERT_TAIL(&tty_list, tp, t_list);
 2795         mtx_unlock(&tty_list_mutex);
 2796         knlist_init(&tp->t_rsel.si_note, &tp->t_mtx);
 2797         knlist_init(&tp->t_wsel.si_note, &tp->t_mtx);
 2798         return (tp);
 2799 }
 2800 
 2801 static int
 2802 sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
 2803 {
 2804         struct tty *tp, *tp2;
 2805         struct xtty xt;
 2806         int error;
 2807 
 2808         error = 0;
 2809         mtx_lock(&tty_list_mutex);
 2810         tp = TAILQ_FIRST(&tty_list);
 2811         if (tp != NULL)
 2812                 ttyref(tp);
 2813         mtx_unlock(&tty_list_mutex);
 2814         while (tp != NULL) {
 2815                 bzero(&xt, sizeof xt);
 2816                 xt.xt_size = sizeof xt;
 2817 #define XT_COPY(field) xt.xt_##field = tp->t_##field
 2818                 xt.xt_rawcc = tp->t_rawq.c_cc;
 2819                 xt.xt_cancc = tp->t_canq.c_cc;
 2820                 xt.xt_outcc = tp->t_outq.c_cc;
 2821                 XT_COPY(line);
 2822                 if (tp->t_dev != NULL)
 2823                         xt.xt_dev = dev2udev(tp->t_dev);
 2824                 XT_COPY(state);
 2825                 XT_COPY(flags);
 2826                 XT_COPY(timeout);
 2827                 if (tp->t_pgrp != NULL)
 2828                         xt.xt_pgid = tp->t_pgrp->pg_id;
 2829                 if (tp->t_session != NULL)
 2830                         xt.xt_sid = tp->t_session->s_sid;
 2831                 XT_COPY(termios);
 2832                 XT_COPY(winsize);
 2833                 XT_COPY(column);
 2834                 XT_COPY(rocount);
 2835                 XT_COPY(rocol);
 2836                 XT_COPY(ififosize);
 2837                 XT_COPY(ihiwat);
 2838                 XT_COPY(ilowat);
 2839                 XT_COPY(ispeedwat);
 2840                 XT_COPY(ohiwat);
 2841                 XT_COPY(olowat);
 2842                 XT_COPY(ospeedwat);
 2843 #undef XT_COPY
 2844                 error = SYSCTL_OUT(req, &xt, sizeof xt);
 2845                 if (error != 0) {
 2846                         ttyrel(tp);
 2847                         return (error);
 2848                 }
 2849                 mtx_lock(&tty_list_mutex);
 2850                 tp2 = TAILQ_NEXT(tp, t_list);
 2851                 if (tp2 != NULL)
 2852                         ttyref(tp2);
 2853                 mtx_unlock(&tty_list_mutex);
 2854                 ttyrel(tp);
 2855                 tp = tp2;
 2856         }
 2857         return (0);
 2858 }
 2859 
 2860 SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
 2861         0, 0, sysctl_kern_ttys, "S,xtty", "All ttys");
 2862 SYSCTL_LONG(_kern, OID_AUTO, tty_nin, CTLFLAG_RD,
 2863         &tk_nin, 0, "Total TTY in characters");
 2864 SYSCTL_LONG(_kern, OID_AUTO, tty_nout, CTLFLAG_RD,
 2865         &tk_nout, 0, "Total TTY out characters");
 2866 
 2867 void
 2868 nottystop(struct tty *tp, int rw)
 2869 {
 2870 
 2871         return;
 2872 }
 2873 
 2874 int
 2875 ttyread(struct cdev *dev, struct uio *uio, int flag)
 2876 {
 2877         struct tty *tp;
 2878 
 2879         KASSERT(devsw(dev)->d_flags & D_TTY,
 2880             ("ttyread() called on non D_TTY device (%s)", devtoname(dev)));
 2881         tp = dev->si_tty;
 2882         KASSERT(tp != NULL,
 2883             ("ttyread(): no tty pointer on device (%s)", devtoname(dev)));
 2884         if (tp == NULL)
 2885                 return (ENODEV);
 2886         return (ttyld_read(tp, uio, flag));
 2887 }
 2888 
 2889 int
 2890 ttywrite(struct cdev *dev, struct uio *uio, int flag)
 2891 {
 2892         struct tty *tp;
 2893 
 2894         KASSERT(devsw(dev)->d_flags & D_TTY,
 2895             ("ttywrite() called on non D_TTY device (%s)", devtoname(dev)));
 2896         tp = dev->si_tty;
 2897         KASSERT(tp != NULL,
 2898             ("ttywrite(): no tty pointer on device (%s)", devtoname(dev)));
 2899         if (tp == NULL)
 2900                 return (ENODEV);
 2901         return (ttyld_write(tp, uio, flag));
 2902 }
 2903 
 2904 int
 2905 ttyioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
 2906 {
 2907         struct  tty *tp;
 2908         int     error;
 2909 
 2910         tp = dev->si_tty;
 2911         error = ttyld_ioctl(tp, cmd, data, flag, td);
 2912         if (error == ENOIOCTL)
 2913                 error = ttioctl(tp, cmd, data, flag);
 2914         ttyldoptim(tp);
 2915         if (error != ENOIOCTL)
 2916                 return (error);
 2917         return (ENOTTY);
 2918 }
 2919 
 2920 void
 2921 ttyldoptim(struct tty *tp)
 2922 {
 2923         struct termios  *t;
 2924 
 2925         t = &tp->t_termios;
 2926         if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
 2927             && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
 2928             && (!(t->c_iflag & PARMRK)
 2929                 || (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
 2930             && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN))
 2931             && linesw[tp->t_line]->l_rint == ttyinput)
 2932                 tp->t_state |= TS_CAN_BYPASS_L_RINT;
 2933         else
 2934                 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
 2935 }
 2936 
 2937 static void
 2938 ttydtrwaitwakeup(void *arg)
 2939 {
 2940         struct tty *tp;
 2941 
 2942         tp = arg;
 2943         tp->t_state &= ~TS_DTR_WAIT;
 2944         wakeup(&tp->t_dtr_wait);
 2945 }
 2946 
 2947 
 2948 void    
 2949 ttydtrwaitstart(struct tty *tp)
 2950 {
 2951 
 2952         if (tp->t_dtr_wait == 0)
 2953                 return;
 2954         if (tp->t_state & TS_DTR_WAIT)
 2955                 return;
 2956         timeout(ttydtrwaitwakeup, tp, tp->t_dtr_wait);
 2957         tp->t_state |= TS_DTR_WAIT;
 2958 }
 2959 
 2960 int
 2961 ttydtrwaitsleep(struct tty *tp)
 2962 {
 2963         int error;
 2964 
 2965         error = 0;
 2966         while (error == 0) {
 2967                 if (tp->t_state & TS_GONE)
 2968                         error = ENXIO;
 2969                 else if (!(tp->t_state & TS_DTR_WAIT))
 2970                         break;
 2971                 else
 2972                         error = tsleep(&tp->t_dtr_wait, TTIPRI | PCATCH,
 2973                             "dtrwait", 0);
 2974         }
 2975         return (error);
 2976 }
 2977 
 2978 /*
 2979  * This function is called when the hardware disappears.  We set a flag
 2980  * and wake up stuff so all sleeping threads will notice.
 2981  */
 2982 void    
 2983 ttygone(struct tty *tp)
 2984 {
 2985 
 2986         tp->t_state |= TS_GONE;
 2987         wakeup(&tp->t_dtr_wait);
 2988 }
 2989 
 2990 /*
 2991  * Record the relationship between the serial ports notion of modem control
 2992  * signals and the one used in certain ioctls in a way the compiler can enforce
 2993  * XXX: We should define TIOCM_* in terms of SER_ if we can limit the
 2994  * XXX: consequences of the #include work that would take.
 2995  */
 2996 CTASSERT(SER_DTR == TIOCM_DTR / 2);
 2997 CTASSERT(SER_RTS == TIOCM_RTS / 2);
 2998 CTASSERT(SER_STX == TIOCM_ST / 2);
 2999 CTASSERT(SER_SRX == TIOCM_SR / 2);
 3000 CTASSERT(SER_CTS == TIOCM_CTS / 2);
 3001 CTASSERT(SER_DCD == TIOCM_DCD / 2);
 3002 CTASSERT(SER_RI == TIOCM_RI / 2);
 3003 CTASSERT(SER_DSR == TIOCM_DSR / 2);
 3004 

Cache object: e06ca4a9e4fea6c91980728ff8c7eb4a


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