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


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

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

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6aa973c544646b120e905381742cc668


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