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

Cache object: 6472c10525ed8e7307bef2cb94a2bb5e


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