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: src/sys/kern/tty.c,v 1.228.2.5 2005/05/07 17:47:39 scottl Exp $");
   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 (ISSET(tp->t_state, TS_ZOMBIE))
 1239                         revents |= (events & (POLLIN | POLLRDNORM)) |
 1240                             POLLHUP;
 1241                 else if (ttnread(tp) > 0)
 1242                         revents |= events & (POLLIN | POLLRDNORM);
 1243                 else
 1244                         selrecord(td, &tp->t_rsel);
 1245         }
 1246         if (events & POLLOUT) {
 1247                 if (ISSET(tp->t_state, TS_ZOMBIE))
 1248                         revents |= POLLHUP;
 1249                 else if (tp->t_outq.c_cc <= tp->t_olowat &&
 1250                     ISSET(tp->t_state, TS_CONNECTED))
 1251                         revents |= events & POLLOUT;
 1252                 else
 1253                         selrecord(td, &tp->t_wsel);
 1254         }
 1255         splx(s);
 1256         return (revents);
 1257 }
 1258 
 1259 static struct filterops ttyread_filtops =
 1260         { 1, NULL, filt_ttyrdetach, filt_ttyread };
 1261 static struct filterops ttywrite_filtops =
 1262         { 1, NULL, filt_ttywdetach, filt_ttywrite };
 1263 
 1264 int
 1265 ttykqfilter(struct cdev *dev, struct knote *kn)
 1266 {
 1267         struct tty *tp;
 1268         struct knlist *klist;
 1269         int s;
 1270 
 1271         KASSERT(devsw(dev)->d_flags & D_TTY,
 1272             ("ttykqfilter() called on non D_TTY device (%s)", devtoname(dev)));
 1273         tp = dev->si_tty;
 1274         KASSERT(tp != NULL,
 1275             ("ttykqfilter(): no tty pointer on device (%s)", devtoname(dev)));
 1276         switch (kn->kn_filter) {
 1277         case EVFILT_READ:
 1278                 klist = &tp->t_rsel.si_note;
 1279                 kn->kn_fop = &ttyread_filtops;
 1280                 break;
 1281         case EVFILT_WRITE:
 1282                 klist = &tp->t_wsel.si_note;
 1283                 kn->kn_fop = &ttywrite_filtops;
 1284                 break;
 1285         default:
 1286                 return (EINVAL);
 1287         }
 1288 
 1289         kn->kn_hook = (caddr_t)dev;
 1290 
 1291         s = spltty();
 1292         knlist_add(klist, kn, 0);
 1293         splx(s);
 1294 
 1295         return (0);
 1296 }
 1297 
 1298 static void
 1299 filt_ttyrdetach(struct knote *kn)
 1300 {
 1301         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1302         int s = spltty();
 1303 
 1304         knlist_remove(&tp->t_rsel.si_note, kn, 0);
 1305         splx(s);
 1306 }
 1307 
 1308 static int
 1309 filt_ttyread(struct knote *kn, long hint)
 1310 {
 1311         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1312 
 1313         kn->kn_data = ttnread(tp);
 1314         if (ISSET(tp->t_state, TS_ZOMBIE)) {
 1315                 kn->kn_flags |= EV_EOF;
 1316                 return (1);
 1317         }
 1318         return (kn->kn_data > 0);
 1319 }
 1320 
 1321 static void
 1322 filt_ttywdetach(struct knote *kn)
 1323 {
 1324         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1325         int s = spltty();
 1326 
 1327         knlist_remove(&tp->t_wsel.si_note, kn, 0);
 1328         splx(s);
 1329 }
 1330 
 1331 static int
 1332 filt_ttywrite(struct knote *kn, long hint)
 1333 {
 1334         struct tty *tp = ((struct cdev *)kn->kn_hook)->si_tty;
 1335 
 1336         kn->kn_data = tp->t_outq.c_cc;
 1337         if (ISSET(tp->t_state, TS_ZOMBIE))
 1338                 return (1);
 1339         return (kn->kn_data <= tp->t_olowat &&
 1340             ISSET(tp->t_state, TS_CONNECTED));
 1341 }
 1342 
 1343 /*
 1344  * Must be called at spltty().
 1345  */
 1346 static int
 1347 ttnread(struct tty *tp)
 1348 {
 1349         int nread;
 1350 
 1351         if (ISSET(tp->t_lflag, PENDIN))
 1352                 ttypend(tp);
 1353         nread = tp->t_canq.c_cc;
 1354         if (!ISSET(tp->t_lflag, ICANON)) {
 1355                 nread += tp->t_rawq.c_cc;
 1356                 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
 1357                         nread = 0;
 1358         }
 1359         return (nread);
 1360 }
 1361 
 1362 /*
 1363  * Wait for output to drain.
 1364  */
 1365 int
 1366 ttywait(struct tty *tp)
 1367 {
 1368         int error, s;
 1369 
 1370         error = 0;
 1371         s = spltty();
 1372         while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
 1373                ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
 1374                 (*tp->t_oproc)(tp);
 1375                 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
 1376                     ISSET(tp->t_state, TS_CONNECTED)) {
 1377                         SET(tp->t_state, TS_SO_OCOMPLETE);
 1378                         error = ttysleep(tp, TSA_OCOMPLETE(tp),
 1379                                          TTOPRI | PCATCH, "ttywai",
 1380                                          tp->t_timeout);
 1381                         if (error) {
 1382                                 if (error == EWOULDBLOCK)
 1383                                         error = EIO;
 1384                                 break;
 1385                         }
 1386                 } else
 1387                         break;
 1388         }
 1389         if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
 1390                 error = EIO;
 1391         splx(s);
 1392         return (error);
 1393 }
 1394 
 1395 /*
 1396  * Flush if successfully wait.
 1397  */
 1398 static int
 1399 ttywflush(struct tty *tp)
 1400 {
 1401         int error;
 1402 
 1403         if ((error = ttywait(tp)) == 0)
 1404                 ttyflush(tp, FREAD);
 1405         return (error);
 1406 }
 1407 
 1408 /*
 1409  * Flush tty read and/or write queues, notifying anyone waiting.
 1410  */
 1411 void
 1412 ttyflush(struct tty *tp, int rw)
 1413 {
 1414         int s;
 1415 
 1416         s = spltty();
 1417 #if 0
 1418 again:
 1419 #endif
 1420         if (rw & FWRITE) {
 1421                 FLUSHQ(&tp->t_outq);
 1422                 CLR(tp->t_state, TS_TTSTOP);
 1423         }
 1424         (*tp->t_stop)(tp, rw);
 1425         if (rw & FREAD) {
 1426                 FLUSHQ(&tp->t_canq);
 1427                 FLUSHQ(&tp->t_rawq);
 1428                 CLR(tp->t_lflag, PENDIN);
 1429                 tp->t_rocount = 0;
 1430                 tp->t_rocol = 0;
 1431                 CLR(tp->t_state, TS_LOCAL);
 1432                 ttwakeup(tp);
 1433                 if (ISSET(tp->t_state, TS_TBLOCK)) {
 1434                         if (rw & FWRITE)
 1435                                 FLUSHQ(&tp->t_outq);
 1436                         ttyunblock(tp);
 1437 
 1438                         /*
 1439                          * Don't let leave any state that might clobber the
 1440                          * next line discipline (although we should do more
 1441                          * to send the START char).  Not clearing the state
 1442                          * may have caused the "putc to a clist with no
 1443                          * reserved cblocks" panic/printf.
 1444                          */
 1445                         CLR(tp->t_state, TS_TBLOCK);
 1446 
 1447 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
 1448                         if (ISSET(tp->t_iflag, IXOFF)) {
 1449                                 /*
 1450                                  * XXX wait a bit in the hope that the stop
 1451                                  * character (if any) will go out.  Waiting
 1452                                  * isn't good since it allows races.  This
 1453                                  * will be fixed when the stop character is
 1454                                  * put in a special queue.  Don't bother with
 1455                                  * the checks in ttywait() since the timeout
 1456                                  * will save us.
 1457                                  */
 1458                                 SET(tp->t_state, TS_SO_OCOMPLETE);
 1459                                 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
 1460                                          "ttyfls", hz / 10);
 1461                                 /*
 1462                                  * Don't try sending the stop character again.
 1463                                  */
 1464                                 CLR(tp->t_state, TS_TBLOCK);
 1465                                 goto again;
 1466                         }
 1467 #endif
 1468                 }
 1469         }
 1470         if (rw & FWRITE) {
 1471                 FLUSHQ(&tp->t_outq);
 1472                 ttwwakeup(tp);
 1473         }
 1474         splx(s);
 1475 }
 1476 
 1477 /*
 1478  * Copy in the default termios characters.
 1479  */
 1480 void
 1481 termioschars(struct termios *t)
 1482 {
 1483 
 1484         bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
 1485 }
 1486 
 1487 /*
 1488  * Old interface.
 1489  */
 1490 void
 1491 ttychars(struct tty *tp)
 1492 {
 1493 
 1494         termioschars(&tp->t_termios);
 1495 }
 1496 
 1497 /*
 1498  * Handle input high water.  Send stop character for the IXOFF case.  Turn
 1499  * on our input flow control bit and propagate the changes to the driver.
 1500  * XXX the stop character should be put in a special high priority queue.
 1501  */
 1502 void
 1503 ttyblock(struct tty *tp)
 1504 {
 1505 
 1506         SET(tp->t_state, TS_TBLOCK);
 1507         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
 1508             putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
 1509                 CLR(tp->t_state, TS_TBLOCK);    /* try again later */
 1510         ttstart(tp);
 1511 }
 1512 
 1513 /*
 1514  * Handle input low water.  Send start character for the IXOFF case.  Turn
 1515  * off our input flow control bit and propagate the changes to the driver.
 1516  * XXX the start character should be put in a special high priority queue.
 1517  */
 1518 static void
 1519 ttyunblock(struct tty *tp)
 1520 {
 1521 
 1522         CLR(tp->t_state, TS_TBLOCK);
 1523         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
 1524             putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
 1525                 SET(tp->t_state, TS_TBLOCK);    /* try again later */
 1526         ttstart(tp);
 1527 }
 1528 
 1529 #ifdef notyet
 1530 /* Not used by any current (i386) drivers. */
 1531 /*
 1532  * Restart after an inter-char delay.
 1533  */
 1534 void
 1535 ttrstrt(void *tp_arg)
 1536 {
 1537         struct tty *tp;
 1538         int s;
 1539 
 1540         KASSERT(tp_arg != NULL, ("ttrstrt"));
 1541 
 1542         tp = tp_arg;
 1543         s = spltty();
 1544 
 1545         CLR(tp->t_state, TS_TIMEOUT);
 1546         ttstart(tp);
 1547 
 1548         splx(s);
 1549 }
 1550 #endif
 1551 
 1552 int
 1553 ttstart(struct tty *tp)
 1554 {
 1555 
 1556         if (tp->t_oproc != NULL)        /* XXX: Kludge for pty. */
 1557                 (*tp->t_oproc)(tp);
 1558         return (0);
 1559 }
 1560 
 1561 /*
 1562  * "close" a line discipline
 1563  */
 1564 int
 1565 ttylclose(struct tty *tp, int flag)
 1566 {
 1567 
 1568         if (flag & FNONBLOCK || ttywflush(tp))
 1569                 ttyflush(tp, FREAD | FWRITE);
 1570         return (0);
 1571 }
 1572 
 1573 /*
 1574  * Handle modem control transition on a tty.
 1575  * Flag indicates new state of carrier.
 1576  * Returns 0 if the line should be turned off, otherwise 1.
 1577  */
 1578 int
 1579 ttymodem(struct tty *tp, int flag)
 1580 {
 1581 
 1582         if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
 1583                 /*
 1584                  * MDMBUF: do flow control according to carrier flag
 1585                  * XXX TS_CAR_OFLOW doesn't do anything yet.  TS_TTSTOP
 1586                  * works if IXON and IXANY are clear.
 1587                  */
 1588                 if (flag) {
 1589                         CLR(tp->t_state, TS_CAR_OFLOW);
 1590                         CLR(tp->t_state, TS_TTSTOP);
 1591                         ttstart(tp);
 1592                 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
 1593                         SET(tp->t_state, TS_CAR_OFLOW);
 1594                         SET(tp->t_state, TS_TTSTOP);
 1595                         (*tp->t_stop)(tp, 0);
 1596                 }
 1597         } else if (flag == 0) {
 1598                 /*
 1599                  * Lost carrier.
 1600                  */
 1601                 CLR(tp->t_state, TS_CARR_ON);
 1602                 if (ISSET(tp->t_state, TS_ISOPEN) &&
 1603                     !ISSET(tp->t_cflag, CLOCAL)) {
 1604                         SET(tp->t_state, TS_ZOMBIE);
 1605                         CLR(tp->t_state, TS_CONNECTED);
 1606                         if (tp->t_session) {
 1607                                 sx_slock(&proctree_lock);
 1608                                 if (tp->t_session->s_leader) {
 1609                                         struct proc *p;
 1610 
 1611                                         p = tp->t_session->s_leader;
 1612                                         PROC_LOCK(p);
 1613                                         psignal(p, SIGHUP);
 1614                                         PROC_UNLOCK(p);
 1615                                 }
 1616                                 sx_sunlock(&proctree_lock);
 1617                         }
 1618                         ttyflush(tp, FREAD | FWRITE);
 1619                         return (0);
 1620                 }
 1621         } else {
 1622                 /*
 1623                  * Carrier now on.
 1624                  */
 1625                 SET(tp->t_state, TS_CARR_ON);
 1626                 if (!ISSET(tp->t_state, TS_ZOMBIE))
 1627                         SET(tp->t_state, TS_CONNECTED);
 1628                 wakeup(TSA_CARR_ON(tp));
 1629                 ttwakeup(tp);
 1630                 ttwwakeup(tp);
 1631         }
 1632         return (1);
 1633 }
 1634 
 1635 /*
 1636  * Reinput pending characters after state switch
 1637  * call at spltty().
 1638  */
 1639 static void
 1640 ttypend(struct tty *tp)
 1641 {
 1642         struct clist tq;
 1643         int c;
 1644 
 1645         CLR(tp->t_lflag, PENDIN);
 1646         SET(tp->t_state, TS_TYPEN);
 1647         /*
 1648          * XXX this assumes too much about clist internals.  It may even
 1649          * fail if the cblock slush pool is empty.  We can't allocate more
 1650          * cblocks here because we are called from an interrupt handler
 1651          * and clist_alloc_cblocks() can wait.
 1652          */
 1653         tq = tp->t_rawq;
 1654         bzero(&tp->t_rawq, sizeof tp->t_rawq);
 1655         tp->t_rawq.c_cbmax = tq.c_cbmax;
 1656         tp->t_rawq.c_cbreserved = tq.c_cbreserved;
 1657         while ((c = getc(&tq)) >= 0)
 1658                 ttyinput(c, tp);
 1659         CLR(tp->t_state, TS_TYPEN);
 1660 }
 1661 
 1662 /*
 1663  * Process a read call on a tty device.
 1664  */
 1665 int
 1666 ttread(struct tty *tp, struct uio *uio, int flag)
 1667 {
 1668         struct clist *qp;
 1669         int c;
 1670         tcflag_t lflag;
 1671         cc_t *cc = tp->t_cc;
 1672         struct thread *td;
 1673         struct proc *p;
 1674         int s, first, error = 0;
 1675         int has_stime = 0, last_cc = 0;
 1676         long slp = 0;           /* XXX this should be renamed `timo'. */
 1677         struct timeval stime;
 1678         struct pgrp *pg;
 1679 
 1680         td = curthread;
 1681         p = td->td_proc;
 1682 loop:
 1683         s = spltty();
 1684         lflag = tp->t_lflag;
 1685         /*
 1686          * take pending input first
 1687          */
 1688         if (ISSET(lflag, PENDIN)) {
 1689                 ttypend(tp);
 1690                 splx(s);        /* reduce latency */
 1691                 s = spltty();
 1692                 lflag = tp->t_lflag;    /* XXX ttypend() clobbers it */
 1693         }
 1694 
 1695         /*
 1696          * Hang process if it's in the background.
 1697          */
 1698         if (isbackground(p, tp)) {
 1699                 splx(s);
 1700                 sx_slock(&proctree_lock);
 1701                 PROC_LOCK(p);
 1702                 if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) ||
 1703                     SIGISMEMBER(td->td_sigmask, SIGTTIN) ||
 1704                     (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) {
 1705                         PROC_UNLOCK(p);
 1706                         sx_sunlock(&proctree_lock);
 1707                         return (EIO);
 1708                 }
 1709                 pg = p->p_pgrp;
 1710                 PROC_UNLOCK(p);
 1711                 PGRP_LOCK(pg);
 1712                 sx_sunlock(&proctree_lock);
 1713                 pgsignal(pg, SIGTTIN, 1);
 1714                 PGRP_UNLOCK(pg);
 1715                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
 1716                 if (error)
 1717                         return (error);
 1718                 goto loop;
 1719         }
 1720 
 1721         if (ISSET(tp->t_state, TS_ZOMBIE)) {
 1722                 splx(s);
 1723                 return (0);     /* EOF */
 1724         }
 1725 
 1726         /*
 1727          * If canonical, use the canonical queue,
 1728          * else use the raw queue.
 1729          *
 1730          * (should get rid of clists...)
 1731          */
 1732         qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
 1733 
 1734         if (flag & IO_NDELAY) {
 1735                 if (qp->c_cc > 0)
 1736                         goto read;
 1737                 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
 1738                         splx(s);
 1739                         return (0);
 1740                 }
 1741                 splx(s);
 1742                 return (EWOULDBLOCK);
 1743         }
 1744         if (!ISSET(lflag, ICANON)) {
 1745                 int m = cc[VMIN];
 1746                 long t = cc[VTIME];
 1747                 struct timeval timecopy;
 1748 
 1749                 /*
 1750                  * Check each of the four combinations.
 1751                  * (m > 0 && t == 0) is the normal read case.
 1752                  * It should be fairly efficient, so we check that and its
 1753                  * companion case (m == 0 && t == 0) first.
 1754                  * For the other two cases, we compute the target sleep time
 1755                  * into slp.
 1756                  */
 1757                 if (t == 0) {
 1758                         if (qp->c_cc < m)
 1759                                 goto sleep;
 1760                         if (qp->c_cc > 0)
 1761                                 goto read;
 1762 
 1763                         /* m, t and qp->c_cc are all 0.  0 is enough input. */
 1764                         splx(s);
 1765                         return (0);
 1766                 }
 1767                 t *= 100000;            /* time in us */
 1768 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
 1769                          ((t1).tv_usec - (t2).tv_usec))
 1770                 if (m > 0) {
 1771                         if (qp->c_cc <= 0)
 1772                                 goto sleep;
 1773                         if (qp->c_cc >= m)
 1774                                 goto read;
 1775                         getmicrotime(&timecopy);
 1776                         if (!has_stime) {
 1777                                 /* first character, start timer */
 1778                                 has_stime = 1;
 1779                                 stime = timecopy;
 1780                                 slp = t;
 1781                         } else if (qp->c_cc > last_cc) {
 1782                                 /* got a character, restart timer */
 1783                                 stime = timecopy;
 1784                                 slp = t;
 1785                         } else {
 1786                                 /* nothing, check expiration */
 1787                                 slp = t - diff(timecopy, stime);
 1788                                 if (slp <= 0)
 1789                                         goto read;
 1790                         }
 1791                         last_cc = qp->c_cc;
 1792                 } else {        /* m == 0 */
 1793                         if (qp->c_cc > 0)
 1794                                 goto read;
 1795                         getmicrotime(&timecopy);
 1796                         if (!has_stime) {
 1797                                 has_stime = 1;
 1798                                 stime = timecopy;
 1799                                 slp = t;
 1800                         } else {
 1801                                 slp = t - diff(timecopy, stime);
 1802                                 if (slp <= 0) {
 1803                                         /* Timed out, but 0 is enough input. */
 1804                                         splx(s);
 1805                                         return (0);
 1806                                 }
 1807                         }
 1808                 }
 1809 #undef diff
 1810                 /*
 1811                  * Rounding down may make us wake up just short
 1812                  * of the target, so we round up.
 1813                  * The formula is ceiling(slp * hz/1000000).
 1814                  * 32-bit arithmetic is enough for hz < 169.
 1815                  * XXX see tvtohz() for how to avoid overflow if hz
 1816                  * is large (divide by `tick' and/or arrange to
 1817                  * use tvtohz() if hz is large).
 1818                  */
 1819                 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
 1820                 goto sleep;
 1821         }
 1822         if (qp->c_cc <= 0) {
 1823 sleep:
 1824                 /*
 1825                  * There is no input, or not enough input and we can block.
 1826                  */
 1827                 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
 1828                                  ISSET(tp->t_state, TS_CONNECTED) ?
 1829                                  "ttyin" : "ttyhup", (int)slp);
 1830                 splx(s);
 1831                 if (error == EWOULDBLOCK)
 1832                         error = 0;
 1833                 else if (error)
 1834                         return (error);
 1835                 /*
 1836                  * XXX what happens if another process eats some input
 1837                  * while we are asleep (not just here)?  It would be
 1838                  * safest to detect changes and reset our state variables
 1839                  * (has_stime and last_cc).
 1840                  */
 1841                 slp = 0;
 1842                 goto loop;
 1843         }
 1844 read:
 1845         splx(s);
 1846         /*
 1847          * Input present, check for input mapping and processing.
 1848          */
 1849         first = 1;
 1850         if (ISSET(lflag, ICANON | ISIG))
 1851                 goto slowcase;
 1852         for (;;) {
 1853                 char ibuf[IBUFSIZ];
 1854                 int icc;
 1855 
 1856                 icc = imin(uio->uio_resid, IBUFSIZ);
 1857                 icc = q_to_b(qp, ibuf, icc);
 1858                 if (icc <= 0) {
 1859                         if (first)
 1860                                 goto loop;
 1861                         break;
 1862                 }
 1863                 error = uiomove(ibuf, icc, uio);
 1864                 /*
 1865                  * XXX if there was an error then we should ungetc() the
 1866                  * unmoved chars and reduce icc here.
 1867                  */
 1868                 if (error)
 1869                         break;
 1870                 if (uio->uio_resid == 0)
 1871                         break;
 1872                 first = 0;
 1873         }
 1874         goto out;
 1875 slowcase:
 1876         for (;;) {
 1877                 c = getc(qp);
 1878                 if (c < 0) {
 1879                         if (first)
 1880                                 goto loop;
 1881                         break;
 1882                 }
 1883                 /*
 1884                  * delayed suspend (^Y)
 1885                  */
 1886                 if (CCEQ(cc[VDSUSP], c) &&
 1887                     ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
 1888                         if (tp->t_pgrp != NULL) {
 1889                                 PGRP_LOCK(tp->t_pgrp);
 1890                                 pgsignal(tp->t_pgrp, SIGTSTP, 1);
 1891                                 PGRP_UNLOCK(tp->t_pgrp);
 1892                         }
 1893                         if (first) {
 1894                                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
 1895                                                  "ttybg3", 0);
 1896                                 if (error)
 1897                                         break;
 1898                                 goto loop;
 1899                         }
 1900                         break;
 1901                 }
 1902                 /*
 1903                  * Interpret EOF only in canonical mode.
 1904                  */
 1905                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
 1906                         break;
 1907                 /*
 1908                  * Give user character.
 1909                  */
 1910                 error = ureadc(c, uio);
 1911                 if (error)
 1912                         /* XXX should ungetc(c, qp). */
 1913                         break;
 1914                 if (uio->uio_resid == 0)
 1915                         break;
 1916                 /*
 1917                  * In canonical mode check for a "break character"
 1918                  * marking the end of a "line of input".
 1919                  */
 1920                 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
 1921                         break;
 1922                 first = 0;
 1923         }
 1924 
 1925 out:
 1926         /*
 1927          * Look to unblock input now that (presumably)
 1928          * the input queue has gone down.
 1929          */
 1930         s = spltty();
 1931         if (ISSET(tp->t_state, TS_TBLOCK) &&
 1932             tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
 1933                 ttyunblock(tp);
 1934         splx(s);
 1935 
 1936         return (error);
 1937 }
 1938 
 1939 /*
 1940  * Check the output queue on tp for space for a kernel message (from uprintf
 1941  * or tprintf).  Allow some space over the normal hiwater mark so we don't
 1942  * lose messages due to normal flow control, but don't let the tty run amok.
 1943  * Sleeps here are not interruptible, but we return prematurely if new signals
 1944  * arrive.
 1945  */
 1946 int
 1947 ttycheckoutq(struct tty *tp, int wait)
 1948 {
 1949         int hiwat, s;
 1950         sigset_t oldmask;
 1951         struct thread *td;
 1952         struct proc *p;
 1953 
 1954         td = curthread;
 1955         p = td->td_proc;
 1956         hiwat = tp->t_ohiwat;
 1957         SIGEMPTYSET(oldmask);
 1958         s = spltty();
 1959         if (wait) {
 1960                 PROC_LOCK(p);
 1961                 oldmask = td->td_siglist;
 1962                 PROC_UNLOCK(p);
 1963         }
 1964         if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
 1965                 while (tp->t_outq.c_cc > hiwat) {
 1966                         ttstart(tp);
 1967                         if (tp->t_outq.c_cc <= hiwat)
 1968                                 break;
 1969                         if (!wait) {
 1970                                 splx(s);
 1971                                 return (0);
 1972                         }
 1973                         PROC_LOCK(p);
 1974                         if (!SIGSETEQ(td->td_siglist, oldmask)) {
 1975                                 PROC_UNLOCK(p);
 1976                                 splx(s);
 1977                                 return (0);
 1978                         }
 1979                         PROC_UNLOCK(p);
 1980                         SET(tp->t_state, TS_SO_OLOWAT);
 1981                         tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
 1982                 }
 1983         splx(s);
 1984         return (1);
 1985 }
 1986 
 1987 /*
 1988  * Process a write call on a tty device.
 1989  */
 1990 int
 1991 ttwrite(struct tty *tp, struct uio *uio, int flag)
 1992 {
 1993         char *cp = NULL;
 1994         int cc, ce;
 1995         struct thread *td;
 1996         struct proc *p;
 1997         int i, hiwat, cnt, error, s;
 1998         char obuf[OBUFSIZ];
 1999 
 2000         hiwat = tp->t_ohiwat;
 2001         cnt = uio->uio_resid;
 2002         error = 0;
 2003         cc = 0;
 2004         td = curthread;
 2005         p = td->td_proc;
 2006 loop:
 2007         s = spltty();
 2008         if (ISSET(tp->t_state, TS_ZOMBIE)) {
 2009                 splx(s);
 2010                 if (uio->uio_resid == cnt)
 2011                         error = EIO;
 2012                 goto out;
 2013         }
 2014         if (!ISSET(tp->t_state, TS_CONNECTED)) {
 2015                 if (flag & IO_NDELAY) {
 2016                         splx(s);
 2017                         error = EWOULDBLOCK;
 2018                         goto out;
 2019                 }
 2020                 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
 2021                                  "ttydcd", 0);
 2022                 splx(s);
 2023                 if (error)
 2024                         goto out;
 2025                 goto loop;
 2026         }
 2027         splx(s);
 2028         /*
 2029          * Hang the process if it's in the background.
 2030          */
 2031         sx_slock(&proctree_lock);
 2032         PROC_LOCK(p);
 2033         if (isbackground(p, tp) &&
 2034             ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
 2035             !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) &&
 2036             !SIGISMEMBER(td->td_sigmask, SIGTTOU)) {
 2037                 if (p->p_pgrp->pg_jobc == 0) {
 2038                         PROC_UNLOCK(p);
 2039                         sx_sunlock(&proctree_lock);
 2040                         error = EIO;
 2041                         goto out;
 2042                 }
 2043                 PROC_UNLOCK(p);
 2044                 PGRP_LOCK(p->p_pgrp);
 2045                 sx_sunlock(&proctree_lock);
 2046                 pgsignal(p->p_pgrp, SIGTTOU, 1);
 2047                 PGRP_UNLOCK(p->p_pgrp);
 2048                 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
 2049                 if (error)
 2050                         goto out;
 2051                 goto loop;
 2052         } else {
 2053                 PROC_UNLOCK(p);
 2054                 sx_sunlock(&proctree_lock);
 2055         }
 2056         /*
 2057          * Process the user's data in at most OBUFSIZ chunks.  Perform any
 2058          * output translation.  Keep track of high water mark, sleep on
 2059          * overflow awaiting device aid in acquiring new space.
 2060          */
 2061         while (uio->uio_resid > 0 || cc > 0) {
 2062                 if (ISSET(tp->t_lflag, FLUSHO)) {
 2063                         uio->uio_resid = 0;
 2064                         return (0);
 2065                 }
 2066                 if (tp->t_outq.c_cc > hiwat)
 2067                         goto ovhiwat;
 2068                 /*
 2069                  * Grab a hunk of data from the user, unless we have some
 2070                  * leftover from last time.
 2071                  */
 2072                 if (cc == 0) {
 2073                         cc = imin(uio->uio_resid, OBUFSIZ);
 2074                         cp = obuf;
 2075                         error = uiomove(cp, cc, uio);
 2076                         if (error) {
 2077                                 cc = 0;
 2078                                 break;
 2079                         }
 2080                 }
 2081                 /*
 2082                  * If nothing fancy need be done, grab those characters we
 2083                  * can handle without any of ttyoutput's processing and
 2084                  * just transfer them to the output q.  For those chars
 2085                  * which require special processing (as indicated by the
 2086                  * bits in char_type), call ttyoutput.  After processing
 2087                  * a hunk of data, look for FLUSHO so ^O's will take effect
 2088                  * immediately.
 2089                  */
 2090                 while (cc > 0) {
 2091                         if (!ISSET(tp->t_oflag, OPOST))
 2092                                 ce = cc;
 2093                         else {
 2094                                 ce = cc - scanc((u_int)cc, (u_char *)cp,
 2095                                                 char_type, CCLASSMASK);
 2096                                 /*
 2097                                  * If ce is zero, then we're processing
 2098                                  * a special character through ttyoutput.
 2099                                  */
 2100                                 if (ce == 0) {
 2101                                         tp->t_rocount = 0;
 2102                                         if (ttyoutput(*cp, tp) >= 0) {
 2103                                                 /* No Clists, wait a bit. */
 2104                                                 ttstart(tp);
 2105                                                 if (flag & IO_NDELAY) {
 2106                                                         error = EWOULDBLOCK;
 2107                                                         goto out;
 2108                                                 }
 2109                                                 error = ttysleep(tp, &lbolt,
 2110                                                                  TTOPRI|PCATCH,
 2111                                                                  "ttybf1", 0);
 2112                                                 if (error)
 2113                                                         goto out;
 2114                                                 goto loop;
 2115                                         }
 2116                                         cp++;
 2117                                         cc--;
 2118                                         if (ISSET(tp->t_lflag, FLUSHO) ||
 2119                                             tp->t_outq.c_cc > hiwat)
 2120                                                 goto ovhiwat;
 2121                                         continue;
 2122                                 }
 2123                         }
 2124                         /*
 2125                          * A bunch of normal characters have been found.
 2126                          * Transfer them en masse to the output queue and
 2127                          * continue processing at the top of the loop.
 2128                          * If there are any further characters in this
 2129                          * <= OBUFSIZ chunk, the first should be a character
 2130                          * requiring special handling by ttyoutput.
 2131                          */
 2132                         tp->t_rocount = 0;
 2133                         i = b_to_q(cp, ce, &tp->t_outq);
 2134                         ce -= i;
 2135                         tp->t_column += ce;
 2136                         cp += ce, cc -= ce, tk_nout += ce;
 2137                         tp->t_outcc += ce;
 2138                         if (i > 0) {
 2139                                 /* No Clists, wait a bit. */
 2140                                 ttstart(tp);
 2141                                 if (flag & IO_NDELAY) {
 2142                                         error = EWOULDBLOCK;
 2143                                         goto out;
 2144                                 }
 2145                                 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
 2146                                                  "ttybf2", 0);
 2147                                 if (error)
 2148                                         goto out;
 2149                                 goto loop;
 2150                         }
 2151                         if (ISSET(tp->t_lflag, FLUSHO) ||
 2152                             tp->t_outq.c_cc > hiwat)
 2153                                 break;
 2154                 }
 2155                 ttstart(tp);
 2156         }
 2157 out:
 2158         /*
 2159          * If cc is nonzero, we leave the uio structure inconsistent, as the
 2160          * offset and iov pointers have moved forward, but it doesn't matter
 2161          * (the call will either return short or restart with a new uio).
 2162          */
 2163         uio->uio_resid += cc;
 2164         return (error);
 2165 
 2166 ovhiwat:
 2167         ttstart(tp);
 2168         s = spltty();
 2169         /*
 2170          * This can only occur if FLUSHO is set in t_lflag,
 2171          * or if ttstart/oproc is synchronous (or very fast).
 2172          */
 2173         if (tp->t_outq.c_cc <= hiwat) {
 2174                 splx(s);
 2175                 goto loop;
 2176         }
 2177         if (flag & IO_NDELAY) {
 2178                 splx(s);
 2179                 uio->uio_resid += cc;
 2180                 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
 2181         }
 2182         SET(tp->t_state, TS_SO_OLOWAT);
 2183         error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
 2184                          tp->t_timeout);
 2185         splx(s);
 2186         if (error == EWOULDBLOCK)
 2187                 error = EIO;
 2188         if (error)
 2189                 goto out;
 2190         goto loop;
 2191 }
 2192 
 2193 /*
 2194  * Rubout one character from the rawq of tp
 2195  * as cleanly as possible.
 2196  */
 2197 static void
 2198 ttyrub(int c, struct tty *tp)
 2199 {
 2200         char *cp;
 2201         int savecol;
 2202         int tabc, s;
 2203 
 2204         if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
 2205                 return;
 2206         CLR(tp->t_lflag, FLUSHO);
 2207         if (ISSET(tp->t_lflag, ECHOE)) {
 2208                 if (tp->t_rocount == 0) {
 2209                         /*
 2210                          * Screwed by ttwrite; retype
 2211                          */
 2212                         ttyretype(tp);
 2213                         return;
 2214                 }
 2215                 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
 2216                         ttyrubo(tp, 2);
 2217                 else {
 2218                         CLR(c, ~TTY_CHARMASK);
 2219                         switch (CCLASS(c)) {
 2220                         case ORDINARY:
 2221                                 ttyrubo(tp, 1);
 2222                                 break;
 2223                         case BACKSPACE:
 2224                         case CONTROL:
 2225                         case NEWLINE:
 2226                         case RETURN:
 2227                         case VTAB:
 2228                                 if (ISSET(tp->t_lflag, ECHOCTL))
 2229                                         ttyrubo(tp, 2);
 2230                                 break;
 2231                         case TAB:
 2232                                 if (tp->t_rocount < tp->t_rawq.c_cc) {
 2233                                         ttyretype(tp);
 2234                                         return;
 2235                                 }
 2236                                 s = spltty();
 2237                                 savecol = tp->t_column;
 2238                                 SET(tp->t_state, TS_CNTTB);
 2239                                 SET(tp->t_lflag, FLUSHO);
 2240                                 tp->t_column = tp->t_rocol;
 2241                                 cp = tp->t_rawq.c_cf;
 2242                                 if (cp)
 2243                                         tabc = *cp;     /* XXX FIX NEXTC */
 2244                                 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
 2245                                         ttyecho(tabc, tp);
 2246                                 CLR(tp->t_lflag, FLUSHO);
 2247                                 CLR(tp->t_state, TS_CNTTB);
 2248                                 splx(s);
 2249 
 2250                                 /* savecol will now be length of the tab. */
 2251                                 savecol -= tp->t_column;
 2252                                 tp->t_column += savecol;
 2253                                 if (savecol > 8)
 2254                                         savecol = 8;    /* overflow screw */
 2255                                 while (--savecol >= 0)
 2256                                         (void)ttyoutput('\b', tp);
 2257                                 break;
 2258                         default:                        /* XXX */
 2259 #define PANICSTR        "ttyrub: would panic c = %d, val = %d\n"
 2260                                 (void)printf(PANICSTR, c, CCLASS(c));
 2261 #ifdef notdef
 2262                                 panic(PANICSTR, c, CCLASS(c));
 2263 #endif
 2264                         }
 2265                 }
 2266         } else if (ISSET(tp->t_lflag, ECHOPRT)) {
 2267                 if (!ISSET(tp->t_state, TS_ERASE)) {
 2268                         SET(tp->t_state, TS_ERASE);
 2269                         (void)ttyoutput('\\', tp);
 2270                 }
 2271                 ttyecho(c, tp);
 2272         } else {
 2273                 ttyecho(tp->t_cc[VERASE], tp);
 2274                 /*
 2275                  * This code may be executed not only when an ERASE key
 2276                  * is pressed, but also when ^U (KILL) or ^W (WERASE) are.
 2277                  * So, I didn't think it was worthwhile to pass the extra
 2278                  * information (which would need an extra parameter,
 2279                  * changing every call) needed to distinguish the ERASE2
 2280                  * case from the ERASE.
 2281                  */
 2282         }
 2283         --tp->t_rocount;
 2284 }
 2285 
 2286 /*
 2287  * Back over cnt characters, erasing them.
 2288  */
 2289 static void
 2290 ttyrubo(struct tty *tp, int cnt)
 2291 {
 2292 
 2293         while (cnt-- > 0) {
 2294                 (void)ttyoutput('\b', tp);
 2295                 (void)ttyoutput(' ', tp);
 2296                 (void)ttyoutput('\b', tp);
 2297         }
 2298 }
 2299 
 2300 /*
 2301  * ttyretype --
 2302  *      Reprint the rawq line.  Note, it is assumed that c_cc has already
 2303  *      been checked.
 2304  */
 2305 static void
 2306 ttyretype(struct tty *tp)
 2307 {
 2308         char *cp;
 2309         int s, c;
 2310 
 2311         /* Echo the reprint character. */
 2312         if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
 2313                 ttyecho(tp->t_cc[VREPRINT], tp);
 2314 
 2315         (void)ttyoutput('\n', tp);
 2316 
 2317         /*
 2318          * XXX
 2319          * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
 2320          * BIT OF FIRST CHAR.
 2321          */
 2322         s = spltty();
 2323         for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
 2324             cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
 2325                 ttyecho(c, tp);
 2326         for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
 2327             cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
 2328                 ttyecho(c, tp);
 2329         CLR(tp->t_state, TS_ERASE);
 2330         splx(s);
 2331 
 2332         tp->t_rocount = tp->t_rawq.c_cc;
 2333         tp->t_rocol = 0;
 2334 }
 2335 
 2336 /*
 2337  * Echo a typed character to the terminal.
 2338  */
 2339 static void
 2340 ttyecho(int c, struct tty *tp)
 2341 {
 2342 
 2343         if (!ISSET(tp->t_state, TS_CNTTB))
 2344                 CLR(tp->t_lflag, FLUSHO);
 2345         if ((!ISSET(tp->t_lflag, ECHO) &&
 2346              (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
 2347             ISSET(tp->t_lflag, EXTPROC))
 2348                 return;
 2349         if (ISSET(tp->t_lflag, ECHOCTL) &&
 2350             ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
 2351             ISSET(c, TTY_CHARMASK) == 0177)) {
 2352                 (void)ttyoutput('^', tp);
 2353                 CLR(c, ~TTY_CHARMASK);
 2354                 if (c == 0177)
 2355                         c = '?';
 2356                 else
 2357                         c += 'A' - 1;
 2358         }
 2359         (void)ttyoutput(c, tp);
 2360 }
 2361 
 2362 /*
 2363  * Wake up any readers on a tty.
 2364  */
 2365 void
 2366 ttwakeup(struct tty *tp)
 2367 {
 2368 
 2369         if (SEL_WAITING(&tp->t_rsel))
 2370                 selwakeuppri(&tp->t_rsel, TTIPRI);
 2371         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
 2372                 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
 2373         wakeup(TSA_HUP_OR_INPUT(tp));
 2374         KNOTE_UNLOCKED(&tp->t_rsel.si_note, 0);
 2375 }
 2376 
 2377 /*
 2378  * Wake up any writers on a tty.
 2379  */
 2380 void
 2381 ttwwakeup(struct tty *tp)
 2382 {
 2383 
 2384         if (SEL_WAITING(&tp->t_wsel) && tp->t_outq.c_cc <= tp->t_olowat)
 2385                 selwakeuppri(&tp->t_wsel, TTOPRI);
 2386         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
 2387                 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
 2388         if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
 2389             TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
 2390                 CLR(tp->t_state, TS_SO_OCOMPLETE);
 2391                 wakeup(TSA_OCOMPLETE(tp));
 2392         }
 2393         if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
 2394             tp->t_outq.c_cc <= tp->t_olowat) {
 2395                 CLR(tp->t_state, TS_SO_OLOWAT);
 2396                 wakeup(TSA_OLOWAT(tp));
 2397         }
 2398         KNOTE_UNLOCKED(&tp->t_wsel.si_note, 0);
 2399 }
 2400 
 2401 /*
 2402  * Look up a code for a specified speed in a conversion table;
 2403  * used by drivers to map software speed values to hardware parameters.
 2404  */
 2405 int
 2406 ttspeedtab(int speed, struct speedtab *table)
 2407 {
 2408 
 2409         for ( ; table->sp_speed != -1; table++)
 2410                 if (table->sp_speed == speed)
 2411                         return (table->sp_code);
 2412         return (-1);
 2413 }
 2414 
 2415 /*
 2416  * Set input and output watermarks and buffer sizes.  For input, the
 2417  * high watermark is about one second's worth of input above empty, the
 2418  * low watermark is slightly below high water, and the buffer size is a
 2419  * driver-dependent amount above high water.  For output, the watermarks
 2420  * are near the ends of the buffer, with about 1 second's worth of input
 2421  * between them.  All this only applies to the standard line discipline.
 2422  */
 2423 void
 2424 ttsetwater(struct tty *tp)
 2425 {
 2426         int cps, ttmaxhiwat, x;
 2427 
 2428         /* Input. */
 2429         clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
 2430         switch (tp->t_ispeedwat) {
 2431         case (speed_t)-1:
 2432                 cps = tp->t_ispeed / 10;
 2433                 break;
 2434         case 0:
 2435                 /*
 2436                  * This case is for old drivers that don't know about
 2437                  * t_ispeedwat.  Arrange for them to get the old buffer
 2438                  * sizes and watermarks.
 2439                  */
 2440                 cps = TTYHOG - 2 * 256;
 2441                 tp->t_ififosize = 2 * 256;
 2442                 break;
 2443         default:
 2444                 cps = tp->t_ispeedwat / 10;
 2445                 break;
 2446         }
 2447         tp->t_ihiwat = cps;
 2448         tp->t_ilowat = 7 * cps / 8;
 2449         x = cps + tp->t_ififosize;
 2450         clist_alloc_cblocks(&tp->t_rawq, x, x);
 2451 
 2452         /* Output. */
 2453         switch (tp->t_ospeedwat) {
 2454         case (speed_t)-1:
 2455                 cps = tp->t_ospeed / 10;
 2456                 ttmaxhiwat = 2 * TTMAXHIWAT;
 2457                 break;
 2458         case 0:
 2459                 cps = tp->t_ospeed / 10;
 2460                 ttmaxhiwat = TTMAXHIWAT;
 2461                 break;
 2462         default:
 2463                 cps = tp->t_ospeedwat / 10;
 2464                 ttmaxhiwat = 8 * TTMAXHIWAT;
 2465                 break;
 2466         }
 2467 #define CLAMP(x, h, l)  ((x) > h ? h : ((x) < l) ? l : (x))
 2468         tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
 2469         x += cps;
 2470         x = CLAMP(x, ttmaxhiwat, TTMINHIWAT);   /* XXX clamps are too magic */
 2471         tp->t_ohiwat = roundup(x, CBSIZE);      /* XXX for compat */
 2472         x = imax(tp->t_ohiwat, TTMAXHIWAT);     /* XXX for compat/safety */
 2473         x += OBUFSIZ + 100;
 2474         clist_alloc_cblocks(&tp->t_outq, x, x);
 2475 #undef  CLAMP
 2476 }
 2477 
 2478 /*
 2479  * Report on state of foreground process group.
 2480  */
 2481 void
 2482 ttyinfo(struct tty *tp)
 2483 {
 2484         struct timeval utime, stime;
 2485         struct proc *p, *pick;
 2486         struct thread *td;
 2487         const char *stateprefix, *state;
 2488         long rss;
 2489         int load, pctcpu;
 2490 
 2491         if (ttycheckoutq(tp,0) == 0)
 2492                 return;
 2493 
 2494         /* Print load average. */
 2495         load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
 2496         ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
 2497 
 2498         /*
 2499          * On return following a ttyprintf(), we set tp->t_rocount to 0 so
 2500          * that pending input will be retyped on BS.
 2501          */
 2502         if (tp->t_session == NULL) {
 2503                 ttyprintf(tp, "not a controlling terminal\n");
 2504                 tp->t_rocount = 0;
 2505                 return;
 2506         }
 2507         if (tp->t_pgrp == NULL) {
 2508                 ttyprintf(tp, "no foreground process group\n");
 2509                 tp->t_rocount = 0;
 2510                 return;
 2511         }
 2512         PGRP_LOCK(tp->t_pgrp);
 2513         if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) {
 2514                 PGRP_UNLOCK(tp->t_pgrp);
 2515                 ttyprintf(tp, "empty foreground process group\n");
 2516                 tp->t_rocount = 0;
 2517                 return;
 2518         }
 2519 
 2520         /*
 2521          * Pick the most interesting process and copy some of its
 2522          * state for printing later.  sched_lock must be held for
 2523          * most parts of this.  Holding it throughout is simplest
 2524          * and prevents even unimportant inconsistencies in the
 2525          * copy of the state, but may increase interrupt latency
 2526          * too much.
 2527          */
 2528         mtx_lock_spin(&sched_lock);
 2529         for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
 2530                 if (proc_compare(pick, p))
 2531                         pick = p;
 2532         PGRP_UNLOCK(tp->t_pgrp);
 2533 
 2534         td = FIRST_THREAD_IN_PROC(pick);        /* XXXKSE */
 2535 #if 0
 2536         KASSERT(td != NULL, ("ttyinfo: no thread"));
 2537 #else
 2538         if (td == NULL) {
 2539                 mtx_unlock_spin(&sched_lock);
 2540                 ttyprintf(tp, "foreground process without thread\n");
 2541                 tp->t_rocount = 0;
 2542                 return;
 2543         }
 2544 #endif
 2545         stateprefix = "";
 2546         if (TD_IS_RUNNING(td))
 2547                 state = "running";
 2548         else if (TD_ON_RUNQ(td) || TD_CAN_RUN(td))
 2549                 state = "runnable";
 2550         else if (TD_IS_SLEEPING(td)) {
 2551                 /* XXX: If we're sleeping, are we ever not in a queue? */
 2552                 if (TD_ON_SLEEPQ(td))
 2553                         state = td->td_wmesg;
 2554                 else
 2555                         state = "sleeping without queue";
 2556         } else if (TD_ON_LOCK(td)) {
 2557                 state = td->td_lockname;
 2558                 stateprefix = "*";
 2559         } else if (TD_IS_SUSPENDED(td))
 2560                 state = "suspended";
 2561         else if (TD_AWAITING_INTR(td))
 2562                 state = "intrwait";
 2563         else
 2564                 state = "unknown";
 2565         calcru(pick, &utime, &stime, NULL);
 2566         pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT;
 2567         if (pick->p_state == PRS_NEW || pick->p_state == PRS_ZOMBIE)
 2568                 rss = 0;
 2569         else
 2570                 rss = pgtok(vmspace_resident_count(pick->p_vmspace));
 2571         mtx_unlock_spin(&sched_lock);
 2572 
 2573         /* Print command, pid, state, utime, stime, %cpu, and rss. */
 2574         ttyprintf(tp,
 2575             " cmd: %s %d [%s%s] %ld.%02ldu %ld.%02lds %d%% %ldk\n",
 2576             pick->p_comm, pick->p_pid, stateprefix, state,
 2577             (long)utime.tv_sec, utime.tv_usec / 10000,
 2578             (long)stime.tv_sec, stime.tv_usec / 10000,
 2579             pctcpu / 100, rss);
 2580         tp->t_rocount = 0;
 2581 }
 2582 
 2583 /*
 2584  * Returns 1 if p2 is "better" than p1
 2585  *
 2586  * The algorithm for picking the "interesting" process is thus:
 2587  *
 2588  *      1) Only foreground processes are eligible - implied.
 2589  *      2) Runnable processes are favored over anything else.  The runner
 2590  *         with the highest cpu utilization is picked (p_estcpu).  Ties are
 2591  *         broken by picking the highest pid.
 2592  *      3) The sleeper with the shortest sleep time is next.  With ties,
 2593  *         we pick out just "short-term" sleepers (P_SINTR == 0).
 2594  *      4) Further ties are broken by picking the highest pid.
 2595  */
 2596 #define ISRUN(p, val)                                           \
 2597 do {                                                            \
 2598         struct thread *td;                                      \
 2599         val = 0;                                                \
 2600         FOREACH_THREAD_IN_PROC(p, td) {                         \
 2601                 if (TD_ON_RUNQ(td) ||                           \
 2602                     TD_IS_RUNNING(td)) {                        \
 2603                         val = 1;                                \
 2604                         break;                                  \
 2605                 }                                               \
 2606         }                                                       \
 2607 } while (0)
 2608 
 2609 #define TESTAB(a, b)    ((a)<<1 | (b))
 2610 #define ONLYA   2
 2611 #define ONLYB   1
 2612 #define BOTH    3
 2613 
 2614 static int
 2615 proc_compare(struct proc *p1, struct proc *p2)
 2616 {
 2617 
 2618         int esta, estb;
 2619         struct ksegrp *kg;
 2620         mtx_assert(&sched_lock, MA_OWNED);
 2621         if (p1 == NULL)
 2622                 return (1);
 2623 
 2624         ISRUN(p1, esta);
 2625         ISRUN(p2, estb);
 2626         
 2627         /*
 2628          * see if at least one of them is runnable
 2629          */
 2630         switch (TESTAB(esta, estb)) {
 2631         case ONLYA:
 2632                 return (0);
 2633         case ONLYB:
 2634                 return (1);
 2635         case BOTH:
 2636                 /*
 2637                  * tie - favor one with highest recent cpu utilization
 2638                  */
 2639                 esta = estb = 0;
 2640                 FOREACH_KSEGRP_IN_PROC(p1,kg) {
 2641                         esta += kg->kg_estcpu;
 2642                 }
 2643                 FOREACH_KSEGRP_IN_PROC(p2,kg) {
 2644                         estb += kg->kg_estcpu;
 2645                 }
 2646                 if (estb > esta)
 2647                         return (1);
 2648                 if (esta > estb)
 2649                         return (0);
 2650                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2651         }
 2652         /*
 2653          * weed out zombies
 2654          */
 2655         switch (TESTAB(p1->p_state == PRS_ZOMBIE, p2->p_state == PRS_ZOMBIE)) {
 2656         case ONLYA:
 2657                 return (1);
 2658         case ONLYB:
 2659                 return (0);
 2660         case BOTH:
 2661                 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
 2662         }
 2663 
 2664 #if 0 /* XXXKSE */
 2665         /*
 2666          * pick the one with the smallest sleep time
 2667          */
 2668         if (p2->p_slptime > p1->p_slptime)
 2669                 return (0);
 2670         if (p1->p_slptime > p2->p_slptime)
 2671                 return (1);
 2672         /*
 2673          * favor one sleeping in a non-interruptible sleep
 2674          */
 2675         if (p1->p_sflag & PS_SINTR && (p2->p_sflag & PS_SINTR) == 0)
 2676                 return (1);
 2677         if (p2->p_sflag & PS_SINTR && (p1->p_sflag & PS_SINTR) == 0)
 2678                 return (0);
 2679 #endif
 2680         return (p2->p_pid > p1->p_pid);         /* tie - return highest pid */
 2681 }
 2682 
 2683 /*
 2684  * Output char to tty; console putchar style.
 2685  */
 2686 int
 2687 tputchar(int c, struct tty *tp)
 2688 {
 2689         int s;
 2690 
 2691         s = spltty();
 2692         if (!ISSET(tp->t_state, TS_CONNECTED)) {
 2693                 splx(s);
 2694                 return (-1);
 2695         }
 2696         if (c == '\n')
 2697                 (void)ttyoutput('\r', tp);
 2698         (void)ttyoutput(c, tp);
 2699         ttstart(tp);
 2700         splx(s);
 2701         return (0);
 2702 }
 2703 
 2704 /*
 2705  * Sleep on chan, returning ERESTART if tty changed while we napped and
 2706  * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep.  If
 2707  * the tty is revoked, restarting a pending call will redo validation done
 2708  * at the start of the call.
 2709  */
 2710 int
 2711 ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo)
 2712 {
 2713         int error;
 2714         int gen;
 2715 
 2716         gen = tp->t_gen;
 2717         error = tsleep(chan, pri, wmesg, timo);
 2718         if (error)
 2719                 return (error);
 2720         return (tp->t_gen == gen ? 0 : ERESTART);
 2721 }
 2722 
 2723 /*
 2724  * Gain a reference to a TTY
 2725  */
 2726 int
 2727 ttyref(struct tty *tp)
 2728 {
 2729         int i;
 2730         
 2731         mtx_lock(&tp->t_mtx);
 2732         KASSERT(tp->t_refcnt > 0,
 2733             ("ttyref(): tty refcnt is %d (%s)",
 2734             tp->t_refcnt, tp->t_dev != NULL ? devtoname(tp->t_dev) : "??"));
 2735         i = ++tp->t_refcnt;
 2736         mtx_unlock(&tp->t_mtx);
 2737         return (i);
 2738 }
 2739 
 2740 /*
 2741  * Drop a reference to a TTY.
 2742  * When reference count drops to zero, we free it.
 2743  */
 2744 int
 2745 ttyrel(struct tty *tp)
 2746 {
 2747         int i;
 2748         
 2749         mtx_lock(&tty_list_mutex);
 2750         mtx_lock(&tp->t_mtx);
 2751         KASSERT(tp->t_refcnt > 0,
 2752             ("ttyrel(): tty refcnt is %d (%s)",
 2753             tp->t_refcnt, tp->t_dev != NULL ? devtoname(tp->t_dev) : "??"));
 2754         i = --tp->t_refcnt;
 2755         if (i != 0) {
 2756                 mtx_unlock(&tp->t_mtx);
 2757                 mtx_unlock(&tty_list_mutex);
 2758                 return (i);
 2759         }
 2760         TAILQ_REMOVE(&tty_list, tp, t_list);
 2761         mtx_unlock(&tp->t_mtx);
 2762         mtx_unlock(&tty_list_mutex);
 2763         knlist_destroy(&tp->t_rsel.si_note);
 2764         knlist_destroy(&tp->t_wsel.si_note);
 2765         mtx_destroy(&tp->t_mtx);
 2766         free(tp, M_TTYS);
 2767         return (i);
 2768 }
 2769 
 2770 /*
 2771  * Allocate a tty struct.  Clists in the struct will be allocated by
 2772  * tty_open().
 2773  */
 2774 struct tty *
 2775 ttymalloc(struct tty *tp)
 2776 {
 2777         static int once;
 2778 
 2779         if (!once) {
 2780                 mtx_init(&tty_list_mutex, "ttylist", NULL, MTX_DEF);
 2781                 once++;
 2782         }
 2783 
 2784         if (tp) {
 2785                 /*
 2786                  * XXX: Either this argument should go away, or we should
 2787                  * XXX: require it and do a ttyrel(tp) here and allocate
 2788                  * XXX: a new tty.  For now do nothing.
 2789                  */
 2790                 return(tp);
 2791         }
 2792         tp = malloc(sizeof *tp, M_TTYS, M_WAITOK | M_ZERO);
 2793         tp->t_timeout = -1;
 2794         tp->t_dtr_wait = 3 * hz;
 2795         mtx_init(&tp->t_mtx, "tty", NULL, MTX_DEF);
 2796         tp->t_refcnt = 1;
 2797         mtx_lock(&tty_list_mutex);
 2798         TAILQ_INSERT_TAIL(&tty_list, tp, t_list);
 2799         mtx_unlock(&tty_list_mutex);
 2800         knlist_init(&tp->t_rsel.si_note, &tp->t_mtx);
 2801         knlist_init(&tp->t_wsel.si_note, &tp->t_mtx);
 2802         return (tp);
 2803 }
 2804 
 2805 static int
 2806 sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
 2807 {
 2808         struct tty *tp, *tp2;
 2809         struct xtty xt;
 2810         int error;
 2811 
 2812         error = 0;
 2813         mtx_lock(&tty_list_mutex);
 2814         tp = TAILQ_FIRST(&tty_list);
 2815         if (tp != NULL)
 2816                 ttyref(tp);
 2817         mtx_unlock(&tty_list_mutex);
 2818         while (tp != NULL) {
 2819                 bzero(&xt, sizeof xt);
 2820                 xt.xt_size = sizeof xt;
 2821 #define XT_COPY(field) xt.xt_##field = tp->t_##field
 2822                 xt.xt_rawcc = tp->t_rawq.c_cc;
 2823                 xt.xt_cancc = tp->t_canq.c_cc;
 2824                 xt.xt_outcc = tp->t_outq.c_cc;
 2825                 XT_COPY(line);
 2826                 if (tp->t_dev != NULL)
 2827                         xt.xt_dev = dev2udev(tp->t_dev);
 2828                 XT_COPY(state);
 2829                 XT_COPY(flags);
 2830                 XT_COPY(timeout);
 2831                 if (tp->t_pgrp != NULL)
 2832                         xt.xt_pgid = tp->t_pgrp->pg_id;
 2833                 if (tp->t_session != NULL)
 2834                         xt.xt_sid = tp->t_session->s_sid;
 2835                 XT_COPY(termios);
 2836                 XT_COPY(winsize);
 2837                 XT_COPY(column);
 2838                 XT_COPY(rocount);
 2839                 XT_COPY(rocol);
 2840                 XT_COPY(ififosize);
 2841                 XT_COPY(ihiwat);
 2842                 XT_COPY(ilowat);
 2843                 XT_COPY(ispeedwat);
 2844                 XT_COPY(ohiwat);
 2845                 XT_COPY(olowat);
 2846                 XT_COPY(ospeedwat);
 2847 #undef XT_COPY
 2848                 error = SYSCTL_OUT(req, &xt, sizeof xt);
 2849                 if (error != 0) {
 2850                         ttyrel(tp);
 2851                         return (error);
 2852                 }
 2853                 mtx_lock(&tty_list_mutex);
 2854                 tp2 = TAILQ_NEXT(tp, t_list);
 2855                 if (tp2 != NULL)
 2856                         ttyref(tp2);
 2857                 mtx_unlock(&tty_list_mutex);
 2858                 ttyrel(tp);
 2859                 tp = tp2;
 2860         }
 2861         return (0);
 2862 }
 2863 
 2864 SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
 2865         0, 0, sysctl_kern_ttys, "S,xtty", "All ttys");
 2866 SYSCTL_LONG(_kern, OID_AUTO, tty_nin, CTLFLAG_RD,
 2867         &tk_nin, 0, "Total TTY in characters");
 2868 SYSCTL_LONG(_kern, OID_AUTO, tty_nout, CTLFLAG_RD,
 2869         &tk_nout, 0, "Total TTY out characters");
 2870 
 2871 void
 2872 nottystop(struct tty *tp, int rw)
 2873 {
 2874 
 2875         return;
 2876 }
 2877 
 2878 int
 2879 ttyread(struct cdev *dev, struct uio *uio, int flag)
 2880 {
 2881         struct tty *tp;
 2882 
 2883         KASSERT(devsw(dev)->d_flags & D_TTY,
 2884             ("ttyread() called on non D_TTY device (%s)", devtoname(dev)));
 2885         tp = dev->si_tty;
 2886         KASSERT(tp != NULL,
 2887             ("ttyread(): no tty pointer on device (%s)", devtoname(dev)));
 2888         if (tp == NULL)
 2889                 return (ENODEV);
 2890         return (ttyld_read(tp, uio, flag));
 2891 }
 2892 
 2893 int
 2894 ttywrite(struct cdev *dev, struct uio *uio, int flag)
 2895 {
 2896         struct tty *tp;
 2897 
 2898         KASSERT(devsw(dev)->d_flags & D_TTY,
 2899             ("ttywrite() called on non D_TTY device (%s)", devtoname(dev)));
 2900         tp = dev->si_tty;
 2901         KASSERT(tp != NULL,
 2902             ("ttywrite(): no tty pointer on device (%s)", devtoname(dev)));
 2903         if (tp == NULL)
 2904                 return (ENODEV);
 2905         return (ttyld_write(tp, uio, flag));
 2906 }
 2907 
 2908 int
 2909 ttyioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
 2910 {
 2911         struct  tty *tp;
 2912         int     error;
 2913 
 2914         tp = dev->si_tty;
 2915         error = ttyld_ioctl(tp, cmd, data, flag, td);
 2916         if (error == ENOIOCTL)
 2917                 error = ttioctl(tp, cmd, data, flag);
 2918         ttyldoptim(tp);
 2919         if (error != ENOIOCTL)
 2920                 return (error);
 2921         return (ENOTTY);
 2922 }
 2923 
 2924 void
 2925 ttyldoptim(struct tty *tp)
 2926 {
 2927         struct termios  *t;
 2928 
 2929         t = &tp->t_termios;
 2930         if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
 2931             && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
 2932             && (!(t->c_iflag & PARMRK)
 2933                 || (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
 2934             && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN))
 2935             && linesw[tp->t_line]->l_rint == ttyinput)
 2936                 tp->t_state |= TS_CAN_BYPASS_L_RINT;
 2937         else
 2938                 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
 2939 }
 2940 
 2941 static void
 2942 ttydtrwaitwakeup(void *arg)
 2943 {
 2944         struct tty *tp;
 2945 
 2946         tp = arg;
 2947         tp->t_state &= ~TS_DTR_WAIT;
 2948         wakeup(&tp->t_dtr_wait);
 2949 }
 2950 
 2951 
 2952 void    
 2953 ttydtrwaitstart(struct tty *tp)
 2954 {
 2955 
 2956         if (tp->t_dtr_wait == 0)
 2957                 return;
 2958         if (tp->t_state & TS_DTR_WAIT)
 2959                 return;
 2960         timeout(ttydtrwaitwakeup, tp, tp->t_dtr_wait);
 2961         tp->t_state |= TS_DTR_WAIT;
 2962 }
 2963 
 2964 int
 2965 ttydtrwaitsleep(struct tty *tp)
 2966 {
 2967         int error;
 2968 
 2969         error = 0;
 2970         while (error == 0) {
 2971                 if (tp->t_state & TS_GONE)
 2972                         error = ENXIO;
 2973                 else if (!(tp->t_state & TS_DTR_WAIT))
 2974                         break;
 2975                 else
 2976                         error = tsleep(&tp->t_dtr_wait, TTIPRI | PCATCH,
 2977                             "dtrwait", 0);
 2978         }
 2979         return (error);
 2980 }
 2981 
 2982 /*
 2983  * This function is called when the hardware disappears.  We set a flag
 2984  * and wake up stuff so all sleeping threads will notice.
 2985  */
 2986 void    
 2987 ttygone(struct tty *tp)
 2988 {
 2989 
 2990         tp->t_state |= TS_GONE;
 2991         wakeup(&tp->t_dtr_wait);
 2992 }
 2993 
 2994 /*
 2995  * Record the relationship between the serial ports notion of modem control
 2996  * signals and the one used in certain ioctls in a way the compiler can enforce
 2997  * XXX: We should define TIOCM_* in terms of SER_ if we can limit the
 2998  * XXX: consequences of the #include work that would take.
 2999  */
 3000 CTASSERT(SER_DTR == TIOCM_DTR / 2);
 3001 CTASSERT(SER_RTS == TIOCM_RTS / 2);
 3002 CTASSERT(SER_STX == TIOCM_ST / 2);
 3003 CTASSERT(SER_SRX == TIOCM_SR / 2);
 3004 CTASSERT(SER_CTS == TIOCM_CTS / 2);
 3005 CTASSERT(SER_DCD == TIOCM_DCD / 2);
 3006 CTASSERT(SER_RI == TIOCM_RI / 2);
 3007 CTASSERT(SER_DSR == TIOCM_DSR / 2);
 3008 

Cache object: 363fbfc72adb4ced1a13609caa9c1d59


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