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

Cache object: 0289d65c947b08b54799a8e6a73706db


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