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


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

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

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

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

Cache object: 153df1c10e119b7d5a494a98d8310bb8


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