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 /*      $NetBSD: tty.c,v 1.307 2022/10/26 23:41:49 riastradh Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   26  * POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 /*-
   30  * Copyright (c) 1982, 1986, 1990, 1991, 1993
   31  *      The Regents of the University of California.  All rights reserved.
   32  * (c) UNIX System Laboratories, Inc.
   33  * All or some portions of this file are derived from material licensed
   34  * to the University of California by American Telephone and Telegraph
   35  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   36  * the permission of UNIX System Laboratories, Inc.
   37  *
   38  * Redistribution and use in source and binary forms, with or without
   39  * modification, are permitted provided that the following conditions
   40  * are met:
   41  * 1. Redistributions of source code must retain the above copyright
   42  *    notice, this list of conditions and the following disclaimer.
   43  * 2. Redistributions in binary form must reproduce the above copyright
   44  *    notice, this list of conditions and the following disclaimer in the
   45  *    documentation and/or other materials provided with the distribution.
   46  * 3. Neither the name of the University nor the names of its contributors
   47  *    may be used to endorse or promote products derived from this software
   48  *    without specific prior written permission.
   49  *
   50  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   51  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   52  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   53  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   54  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   57  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   58  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   59  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   60  * SUCH DAMAGE.
   61  *
   62  *      @(#)tty.c       8.13 (Berkeley) 1/9/95
   63  */
   64 
   65 #include <sys/cdefs.h>
   66 __KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.307 2022/10/26 23:41:49 riastradh Exp $");
   67 
   68 #ifdef _KERNEL_OPT
   69 #include "opt_compat_netbsd.h"
   70 #endif
   71 
   72 #define TTY_ALLOW_PRIVATE
   73 
   74 #include <sys/param.h>
   75 #include <sys/systm.h>
   76 #include <sys/ioctl.h>
   77 #include <sys/proc.h>
   78 #define TTYDEFCHARS
   79 #include <sys/tty.h>
   80 #undef  TTYDEFCHARS
   81 #include <sys/file.h>
   82 #include <sys/conf.h>
   83 #include <sys/cpu.h>
   84 #include <sys/dkstat.h>
   85 #include <sys/uio.h>
   86 #include <sys/kernel.h>
   87 #include <sys/vnode.h>
   88 #include <sys/syslog.h>
   89 #include <sys/kmem.h>
   90 #include <sys/signalvar.h>
   91 #include <sys/resourcevar.h>
   92 #include <sys/poll.h>
   93 #include <sys/kprintf.h>
   94 #include <sys/namei.h>
   95 #include <sys/sysctl.h>
   96 #include <sys/kauth.h>
   97 #include <sys/intr.h>
   98 #include <sys/ioctl_compat.h>
   99 #include <sys/module.h>
  100 #include <sys/bitops.h>
  101 #include <sys/compat_stub.h>
  102 #include <sys/atomic.h>
  103 #include <sys/condvar.h>
  104 #include <sys/pserialize.h>
  105 
  106 #ifdef COMPAT_60
  107 #include <compat/sys/ttycom.h>
  108 #endif /* COMPAT_60 */
  109 
  110 static int      ttnread(struct tty *);
  111 static void     ttyblock(struct tty *);
  112 static void     ttyecho(int, struct tty *);
  113 static void     ttyrubo(struct tty *, int);
  114 static void     ttyprintf_nolock(struct tty *, const char *fmt, ...)
  115     __printflike(2, 3);
  116 static int      proc_compare_wrapper(struct proc *, struct proc *);
  117 static void     ttysigintr(void *);
  118 
  119 /* Symbolic sleep message strings. */
  120 const char      ttclos[] = "ttycls";
  121 const char      ttopen[] = "ttyopn";
  122 const char      ttybg[] = "ttybg";
  123 const char      ttyin[] = "ttyin";
  124 const char      ttyout[] = "ttyout";
  125 
  126 /*
  127  * Used to determine whether we still have a connection.  This is true in
  128  * one of 3 cases:
  129  * 1) We have carrier.
  130  * 2) It's a locally attached terminal, and we are therefore ignoring carrier.
  131  * 3) We're using a flow control mechanism that overloads the carrier signal.
  132  */
  133 #define CONNECTED(tp)   (ISSET(tp->t_state, TS_CARR_ON) ||      \
  134                          ISSET(tp->t_cflag, CLOCAL | MDMBUF))
  135 
  136 /*
  137  * Table with character classes and parity. The 8th bit indicates parity,
  138  * the 7th bit indicates the character is an alphameric or underscore (for
  139  * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
  140  * are 0 then the character needs no special processing on output; classes
  141  * other than 0 might be translated or (not currently) require delays.
  142  */
  143 #define E       0x00    /* Even parity. */
  144 #define O       0x80    /* Odd parity. */
  145 #define PARITY(c)       (char_type[c] & O)
  146 
  147 #define ALPHA   0x40    /* Alpha or underscore. */
  148 #define ISALPHA(c)      (char_type[(c) & TTY_CHARMASK] & ALPHA)
  149 
  150 #define CCLASSMASK      0x3f
  151 #define CCLASS(c)       (char_type[c] & CCLASSMASK)
  152 
  153 #define BS      BACKSPACE
  154 #define CC      CONTROL
  155 #define CR      RETURN
  156 #define NA      ORDINARY | ALPHA
  157 #define NL      NEWLINE
  158 #define NO      ORDINARY
  159 #define TB      TAB
  160 #define VT      VTAB
  161 
  162 unsigned char const char_type[] = {
  163         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
  164         O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
  165         O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
  166         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
  167         O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
  168         E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
  169         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
  170         O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
  171         O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
  172         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
  173         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
  174         O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
  175         E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
  176         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
  177         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
  178         E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
  179         /*
  180          * Meta chars; should be settable per character set;
  181          * for now, treat them all as normal characters.
  182          */
  183         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  184         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  185         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  186         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  187         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  188         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  189         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  190         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  191         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  192         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  193         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  194         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  195         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  196         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  197         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  198         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  199 };
  200 #undef  BS
  201 #undef  CC
  202 #undef  CR
  203 #undef  NA
  204 #undef  NL
  205 #undef  NO
  206 #undef  TB
  207 #undef  VT
  208 
  209 static struct ttylist_head tty_sigqueue = TAILQ_HEAD_INITIALIZER(tty_sigqueue);
  210 static void *tty_sigsih;
  211 
  212 struct ttylist_head ttylist = TAILQ_HEAD_INITIALIZER(ttylist);
  213 int tty_count;
  214 kmutex_t tty_lock;
  215 kmutex_t constty_lock;
  216 static struct pserialize *constty_psz;
  217 static kcondvar_t ttyref_cv;
  218 
  219 struct ptm_pty *ptm = NULL;
  220 
  221 uint64_t tk_cancc;
  222 uint64_t tk_nin;
  223 uint64_t tk_nout;
  224 uint64_t tk_rawcc;
  225 
  226 static kauth_listener_t tty_listener;
  227 
  228 #define TTY_MINQSIZE    0x00400
  229 #define TTY_MAXQSIZE    0x10000
  230 int tty_qsize = TTY_MINQSIZE;
  231 
  232 static int
  233 tty_get_qsize(int *qsize, int newsize)
  234 {
  235         if (newsize <= 0)
  236                 return EINVAL;
  237 
  238         newsize = 1 << ilog2(newsize);  /* Make it a power of two */
  239 
  240         if (newsize < TTY_MINQSIZE || newsize > TTY_MAXQSIZE)
  241                 return EINVAL;
  242 
  243         *qsize = newsize;
  244         return 0;
  245 }
  246 
  247 static int
  248 tty_set_qsize(struct tty *tp, int newsize)
  249 {
  250         struct clist rawq, canq, outq;
  251         struct clist orawq, ocanq, ooutq;
  252 
  253         clalloc(&rawq, newsize, 1);
  254         clalloc(&canq, newsize, 1);
  255         clalloc(&outq, newsize, 0);
  256 
  257         mutex_spin_enter(&tty_lock);
  258 
  259         if (tp->t_outq.c_cc != 0) {
  260                 mutex_spin_exit(&tty_lock);
  261                 clfree(&rawq);
  262                 clfree(&canq);
  263                 clfree(&outq);
  264                 return EBUSY;
  265         }
  266 
  267         orawq = tp->t_rawq;
  268         ocanq = tp->t_canq;
  269         ooutq = tp->t_outq;
  270 
  271         tp->t_qsize = newsize;
  272         tp->t_rawq = rawq;
  273         tp->t_canq = canq;
  274         tp->t_outq = outq;
  275 
  276         ttsetwater(tp);
  277 
  278         mutex_spin_exit(&tty_lock);
  279 
  280         clfree(&orawq);
  281         clfree(&ocanq);
  282         clfree(&ooutq);
  283 
  284         return 0;
  285 }
  286 
  287 static int
  288 sysctl_kern_tty_qsize(SYSCTLFN_ARGS)
  289 {
  290         int newsize;
  291         int error;
  292         struct sysctlnode node;
  293         node = *rnode;
  294         node.sysctl_data = &newsize;
  295 
  296         newsize = tty_qsize;
  297         error = sysctl_lookup(SYSCTLFN_CALL(&node));
  298         if (error || newp == NULL)
  299                 return error;
  300 
  301 
  302         return tty_get_qsize(&tty_qsize, newsize);
  303 }
  304 
  305 static void
  306 sysctl_kern_tty_setup(void)
  307 {
  308         const struct sysctlnode *rnode, *cnode;
  309 
  310         sysctl_createv(NULL, 0, NULL, NULL,
  311                        CTLFLAG_PERMANENT,
  312                        CTLTYPE_NODE, "tkstat",
  313                        SYSCTL_DESCR("Number of characters sent and received "
  314                                     "on ttys"),
  315                        NULL, 0, NULL, 0,
  316                        CTL_KERN, KERN_TKSTAT, CTL_EOL);
  317 
  318         sysctl_createv(NULL, 0, NULL, NULL,
  319                        CTLFLAG_PERMANENT,
  320                        CTLTYPE_QUAD, "nin",
  321                        SYSCTL_DESCR("Total number of tty input characters"),
  322                        NULL, 0, &tk_nin, 0,
  323                        CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_NIN, CTL_EOL);
  324         sysctl_createv(NULL, 0, NULL, NULL,
  325                        CTLFLAG_PERMANENT,
  326                        CTLTYPE_QUAD, "nout",
  327                        SYSCTL_DESCR("Total number of tty output characters"),
  328                        NULL, 0, &tk_nout, 0,
  329                        CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_NOUT, CTL_EOL);
  330         sysctl_createv(NULL, 0, NULL, NULL,
  331                        CTLFLAG_PERMANENT,
  332                        CTLTYPE_QUAD, "cancc",
  333                        SYSCTL_DESCR("Number of canonical tty input characters"),
  334                        NULL, 0, &tk_cancc, 0,
  335                        CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_CANCC, CTL_EOL);
  336         sysctl_createv(NULL, 0, NULL, NULL,
  337                        CTLFLAG_PERMANENT,
  338                        CTLTYPE_QUAD, "rawcc",
  339                        SYSCTL_DESCR("Number of raw tty input characters"),
  340                        NULL, 0, &tk_rawcc, 0,
  341                        CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_RAWCC, CTL_EOL);
  342 
  343         sysctl_createv(NULL, 0, NULL, &rnode,
  344                        CTLFLAG_PERMANENT,
  345                        CTLTYPE_NODE, "tty", NULL,
  346                        NULL, 0, NULL, 0,
  347                        CTL_KERN, CTL_CREATE, CTL_EOL);
  348         sysctl_createv(NULL, 0, &rnode, &cnode,
  349                        CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
  350                        CTLTYPE_INT, "qsize",
  351                        SYSCTL_DESCR("TTY input and output queue size"),
  352                        sysctl_kern_tty_qsize, 0, &tty_qsize, 0,
  353                        CTL_CREATE, CTL_EOL);
  354 }
  355 
  356 /*
  357  * ttylock(tp), ttyunlock(tp), ttylocked(tp)
  358  *
  359  *      Exclusive lock on tty.  Currently a single global lock.
  360  *
  361  *      ttylocked is for positive DIAGNOSTIC assertions only.
  362  */
  363 void
  364 ttylock(struct tty *tp)
  365 {
  366 
  367         mutex_spin_enter(&tty_lock);
  368 }
  369 
  370 void
  371 ttyunlock(struct tty *tp)
  372 {
  373 
  374         mutex_spin_exit(&tty_lock);
  375 }
  376 
  377 bool
  378 ttylocked(struct tty *tp)
  379 {
  380 
  381         return mutex_owned(&tty_lock);
  382 }
  383 
  384 int
  385 ttyopen(struct tty *tp, int dialout, int nonblock)
  386 {
  387         int     error;
  388 
  389         error = 0;
  390 
  391         mutex_spin_enter(&tty_lock);
  392 
  393         if (dialout) {
  394                 /*
  395                  * If the device is already open for non-dialout, fail.
  396                  * Otherwise, set TS_DIALOUT to block any pending non-dialout
  397                  * opens.
  398                  */
  399                 if (ISSET(tp->t_state, TS_ISOPEN) &&
  400                     !ISSET(tp->t_state, TS_DIALOUT)) {
  401                         error = EBUSY;
  402                         goto out;
  403                 }
  404                 SET(tp->t_state, TS_DIALOUT);
  405         } else {
  406                 if (!nonblock) {
  407                         /*
  408                          * Wait for carrier.  Also wait for any dialout
  409                          * processes to close the tty first.
  410                          */
  411                         while (ISSET(tp->t_state, TS_DIALOUT) ||
  412                                !CONNECTED(tp)) {
  413                                 tp->t_wopen++;
  414                                 error = ttysleep(tp, &tp->t_rawcv, true, 0);
  415                                 tp->t_wopen--;
  416                                 if (error)
  417                                         goto out;
  418                         }
  419                 } else {
  420                         /*
  421                          * Don't allow a non-blocking non-dialout open if the
  422                          * device is already open for dialout.
  423                          */
  424                         if (ISSET(tp->t_state, TS_DIALOUT)) {
  425                                 error = EBUSY;
  426                                 goto out;
  427                         }
  428                 }
  429         }
  430 
  431 out:
  432         mutex_spin_exit(&tty_lock);
  433         return (error);
  434 }
  435 
  436 /*
  437  * Initial open of tty, or (re)entry to standard tty line discipline.
  438  */
  439 int
  440 ttylopen(dev_t device, struct tty *tp)
  441 {
  442 
  443         mutex_spin_enter(&tty_lock);
  444         tp->t_dev = device;
  445         if (!ISSET(tp->t_state, TS_ISOPEN)) {
  446                 SET(tp->t_state, TS_ISOPEN);
  447                 memset(&tp->t_winsize, 0, sizeof(tp->t_winsize));
  448                 tp->t_flags = 0;
  449         }
  450         mutex_spin_exit(&tty_lock);
  451         if (tp->t_qsize != tty_qsize)
  452                 tty_set_qsize(tp, tty_qsize);
  453         return (0);
  454 }
  455 
  456 /*
  457  * Interrupt any pending I/O and make it fail.  Used before close to
  458  * interrupt pending open/read/write/&c. and make it fail promptly.
  459  */
  460 void
  461 ttycancel(struct tty *tp)
  462 {
  463 
  464         mutex_spin_enter(&tty_lock);
  465         tp->t_state |= TS_CANCEL;
  466         cv_broadcast(&tp->t_outcv);
  467         cv_broadcast(&tp->t_rawcv);
  468         mutex_spin_exit(&tty_lock);
  469 }
  470 
  471 /*
  472  * Handle close() on a tty line: flush and set to initial state,
  473  * bumping generation number so that pending read/write calls
  474  * can detect recycling of the tty.
  475  */
  476 int
  477 ttyclose(struct tty *tp)
  478 {
  479         struct session *sess;
  480 
  481         /*
  482          * Make sure this is not the constty.  Without constty_lock it
  483          * is always allowed to transition from nonnull to null.
  484          */
  485         (void)atomic_cas_ptr(&constty, tp, NULL);
  486 
  487         /*
  488          * We don't know if this has _ever_ been the constty: another
  489          * thread may have kicked it out as constty before we started
  490          * to close.
  491          *
  492          * So we wait for all users that might be acquiring references
  493          * to finish doing so -- after that, no more references can be
  494          * made, at which point we can safely flush the tty, wait for
  495          * the existing references to drain, and finally free or reuse
  496          * the tty.
  497          */
  498         pserialize_perform(constty_psz);
  499 
  500         mutex_spin_enter(&tty_lock);
  501 
  502         ttyflush(tp, FREAD | FWRITE);
  503 
  504         tp->t_gen++;
  505         tp->t_pgrp = NULL;
  506         tp->t_state = 0;
  507         sess = tp->t_session;
  508         tp->t_session = NULL;
  509 
  510         while (tp->t_refcnt)
  511                 cv_wait(&ttyref_cv, &tty_lock);
  512 
  513         mutex_spin_exit(&tty_lock);
  514 
  515         if (sess != NULL) {
  516                 mutex_enter(&proc_lock);
  517                 /* Releases proc_lock. */
  518                 proc_sessrele(sess);
  519         }
  520         return (0);
  521 }
  522 
  523 #define FLUSHQ(q) {                                                     \
  524         if ((q)->c_cc)                                                  \
  525                 ndflush(q, (q)->c_cc);                                  \
  526 }
  527 
  528 /*
  529  * tty_acquire(tp), tty_release(tp)
  530  *
  531  *      Acquire a reference to tp that prevents it from being closed
  532  *      until released.  Caller must guarantee tp has not yet been
  533  *      closed, e.g. by obtaining tp from constty during a pserialize
  534  *      read section.  Caller must not hold tty_lock.
  535  */
  536 void
  537 tty_acquire(struct tty *tp)
  538 {
  539         unsigned refcnt __diagused;
  540 
  541         refcnt = atomic_inc_uint_nv(&tp->t_refcnt);
  542         KASSERT(refcnt < UINT_MAX);
  543 }
  544 
  545 void
  546 tty_release(struct tty *tp)
  547 {
  548         unsigned old, new;
  549 
  550         KDASSERT(mutex_ownable(&tty_lock));
  551 
  552         do {
  553                 old = atomic_load_relaxed(&tp->t_refcnt);
  554                 if (old == 1) {
  555                         mutex_spin_enter(&tty_lock);
  556                         if (atomic_dec_uint_nv(&tp->t_refcnt) == 0)
  557                                 cv_broadcast(&ttyref_cv);
  558                         mutex_spin_exit(&tty_lock);
  559                         return;
  560                 }
  561                 KASSERT(old != 0);
  562                 new = old - 1;
  563         } while (atomic_cas_uint(&tp->t_refcnt, old, new) != old);
  564 }
  565 
  566 /*
  567  * This macro is used in canonical mode input processing, where a read
  568  * request shall not return unless a 'line delimiter' ('\n') or 'break'
  569  * (EOF, EOL, EOL2) character (or a signal) has been received. As EOL2
  570  * is an extension to the POSIX.1 defined set of special characters,
  571  * recognize it only if IEXTEN is set in the set of local flags.
  572  */
  573 #define TTBREAKC(c, lflg)                                               \
  574         ((c) == '\n' || (((c) == cc[VEOF] || (c) == cc[VEOL] ||         \
  575         ((c) == cc[VEOL2] && ISSET(lflg, IEXTEN))) && (c) != _POSIX_VDISABLE))
  576 
  577 
  578 
  579 /*
  580  * ttyinput() helper.
  581  * Call with the tty lock held.
  582  */
  583 /* XXX static */ int
  584 ttyinput_wlock(int c, struct tty *tp)
  585 {
  586         int     iflag, lflag, i, error;
  587         u_char  *cc;
  588 
  589         KASSERT(mutex_owned(&tty_lock));
  590 
  591         /*
  592          * If input is pending take it first.
  593          */
  594         lflag = tp->t_lflag;
  595         if (ISSET(lflag, PENDIN))
  596                 ttypend(tp);
  597         /*
  598          * Gather stats.
  599          */
  600         if (ISSET(lflag, ICANON)) {
  601                 ++tk_cancc;
  602                 ++tp->t_cancc;
  603         } else {
  604                 ++tk_rawcc;
  605                 ++tp->t_rawcc;
  606         }
  607         ++tk_nin;
  608 
  609         cc = tp->t_cc;
  610 
  611         /*
  612          * Handle exceptional conditions (break, parity, framing).
  613          */
  614         iflag = tp->t_iflag;
  615         if ((error = (ISSET(c, TTY_ERRORMASK))) != 0) {
  616                 CLR(c, TTY_ERRORMASK);
  617                 if (ISSET(error, TTY_FE) && c == 0) {           /* Break. */
  618                         if (ISSET(iflag, IGNBRK))
  619                                 return (0);
  620                         else if (ISSET(iflag, BRKINT)) {
  621                                 ttyflush(tp, FREAD | FWRITE);
  622                                 ttysig(tp, TTYSIG_PG1, SIGINT);
  623                                 return (0);
  624                         } else if (ISSET(iflag, PARMRK))
  625                                 goto parmrk;
  626                 } else if ((ISSET(error, TTY_PE) && ISSET(iflag, INPCK)) ||
  627                     ISSET(error, TTY_FE)) {
  628                         if (ISSET(iflag, IGNPAR))
  629                                 return (0);
  630                         else if (ISSET(iflag, PARMRK)) {
  631  parmrk:                        (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
  632                                 (void)putc(0    | TTY_QUOTE, &tp->t_rawq);
  633                                 (void)putc(c    | TTY_QUOTE, &tp->t_rawq);
  634                                 return (0);
  635                         } else
  636                                 c = 0;
  637                 }
  638         } else if (c == 0377 &&
  639             ISSET(iflag, ISTRIP|IGNPAR|INPCK|PARMRK) == (INPCK|PARMRK)) {
  640                 /* "Escape" a valid character of '\377'. */
  641                 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
  642                 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
  643                 goto endcase;
  644         }
  645 
  646         /*
  647          * In tandem mode, check high water mark.
  648          */
  649         if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW))
  650                 ttyblock(tp);
  651         if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
  652                 CLR(c, 0x80);
  653         if (!ISSET(lflag, EXTPROC)) {
  654                 /*
  655                  * Check for literal nexting very first
  656                  */
  657                 if (ISSET(tp->t_state, TS_LNCH)) {
  658                         SET(c, TTY_QUOTE);
  659                         CLR(tp->t_state, TS_LNCH);
  660                 }
  661                 /*
  662                  * Scan for special characters.  This code
  663                  * is really just a big case statement with
  664                  * non-constant cases.  The bottom of the
  665                  * case statement is labeled ``endcase'', so goto
  666                  * it after a case match, or similar.
  667                  */
  668 
  669                 /*
  670                  * Control chars which aren't controlled
  671                  * by ICANON, ISIG, or IXON.
  672                  */
  673                 if (ISSET(lflag, IEXTEN)) {
  674                         if (CCEQ(cc[VLNEXT], c)) {
  675                                 if (ISSET(lflag, ECHO)) {
  676                                         if (ISSET(lflag, ECHOE)) {
  677                                                 (void)ttyoutput('^', tp);
  678                                                 (void)ttyoutput('\b', tp);
  679                                         } else
  680                                                 ttyecho(c, tp);
  681                                 }
  682                                 SET(tp->t_state, TS_LNCH);
  683                                 goto endcase;
  684                         }
  685                         if (CCEQ(cc[VDISCARD], c)) {
  686                                 if (ISSET(lflag, FLUSHO))
  687                                         CLR(tp->t_lflag, FLUSHO);
  688                                 else {
  689                                         ttyflush(tp, FWRITE);
  690                                         ttyecho(c, tp);
  691                                         if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
  692                                                 ttyretype(tp);
  693                                         SET(tp->t_lflag, FLUSHO);
  694                                 }
  695                                 goto startoutput;
  696                         }
  697                 }
  698                 /*
  699                  * Signals.
  700                  */
  701                 if (ISSET(lflag, ISIG)) {
  702                         if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
  703                                 if (!ISSET(lflag, NOFLSH))
  704                                         ttyflush(tp, FREAD | FWRITE);
  705                                 ttyecho(c, tp);
  706                                 ttysig(tp, TTYSIG_PG1, CCEQ(cc[VINTR], c) ?
  707                                     SIGINT : SIGQUIT);
  708                                 goto endcase;
  709                         }
  710                         if (CCEQ(cc[VSUSP], c)) {
  711                                 if (!ISSET(lflag, NOFLSH))
  712                                         ttyflush(tp, FREAD);
  713                                 ttyecho(c, tp);
  714                                 ttysig(tp, TTYSIG_PG1, SIGTSTP);
  715                                 goto endcase;
  716                         }
  717                 }
  718                 /*
  719                  * Handle start/stop characters.
  720                  */
  721                 if (ISSET(iflag, IXON)) {
  722                         if (CCEQ(cc[VSTOP], c)) {
  723                                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
  724                                         SET(tp->t_state, TS_TTSTOP);
  725                                         cdev_stop(tp, 0);
  726                                         return (0);
  727                                 }
  728                                 if (!CCEQ(cc[VSTART], c))
  729                                         return (0);
  730                                 /*
  731                                  * if VSTART == VSTOP then toggle
  732                                  */
  733                                 goto endcase;
  734                         }
  735                         if (CCEQ(cc[VSTART], c))
  736                                 goto restartoutput;
  737                 }
  738                 /*
  739                  * IGNCR, ICRNL, & INLCR
  740                  */
  741                 if (c == '\r') {
  742                         if (ISSET(iflag, IGNCR))
  743                                 goto endcase;
  744                         else if (ISSET(iflag, ICRNL))
  745                                 c = '\n';
  746                 } else if (c == '\n' && ISSET(iflag, INLCR))
  747                         c = '\r';
  748         }
  749         if (!ISSET(lflag, EXTPROC) && ISSET(lflag, ICANON)) {
  750                 /*
  751                  * From here on down canonical mode character
  752                  * processing takes place.
  753                  */
  754                 /*
  755                  * erase (^H / ^?)
  756                  */
  757                 if (CCEQ(cc[VERASE], c)) {
  758                         if (tp->t_rawq.c_cc)
  759                                 ttyrub(unputc(&tp->t_rawq), tp);
  760                         goto endcase;
  761                 }
  762                 /*
  763                  * kill (^U)
  764                  */
  765                 if (CCEQ(cc[VKILL], c)) {
  766                         if (ISSET(lflag, ECHOKE) &&
  767                             tp->t_rawq.c_cc == tp->t_rocount &&
  768                             !ISSET(lflag, ECHOPRT))
  769                                 while (tp->t_rawq.c_cc)
  770                                         ttyrub(unputc(&tp->t_rawq), tp);
  771                         else {
  772                                 ttyecho(c, tp);
  773                                 if (ISSET(lflag, ECHOK) ||
  774                                     ISSET(lflag, ECHOKE))
  775                                         ttyecho('\n', tp);
  776                                 FLUSHQ(&tp->t_rawq);
  777                                 tp->t_rocount = 0;
  778                         }
  779                         CLR(tp->t_state, TS_LOCAL);
  780                         goto endcase;
  781                 }
  782                 /*
  783                  * Extensions to the POSIX.1 GTI set of functions.
  784                  */
  785                 if (ISSET(lflag, IEXTEN)) {
  786                         /*
  787                          * word erase (^W)
  788                          */
  789                         if (CCEQ(cc[VWERASE], c)) {
  790                                 int alt = ISSET(lflag, ALTWERASE);
  791                                 int ctype;
  792 
  793                                 /*
  794                                  * erase whitespace
  795                                  */
  796                                 while ((c = unputc(&tp->t_rawq)) == ' ' ||
  797                                     c == '\t')
  798                                         ttyrub(c, tp);
  799                                 if (c == -1)
  800                                         goto endcase;
  801                                 /*
  802                                  * erase last char of word and remember the
  803                                  * next chars type (for ALTWERASE)
  804                                  */
  805                                 ttyrub(c, tp);
  806                                 c = unputc(&tp->t_rawq);
  807                                 if (c == -1)
  808                                         goto endcase;
  809                                 if (c == ' ' || c == '\t') {
  810                                         (void)putc(c, &tp->t_rawq);
  811                                         goto endcase;
  812                                 }
  813                                 ctype = ISALPHA(c);
  814                                 /*
  815                                  * erase rest of word
  816                                  */
  817                                 do {
  818                                         ttyrub(c, tp);
  819                                         c = unputc(&tp->t_rawq);
  820                                         if (c == -1)
  821                                                 goto endcase;
  822                                 } while (c != ' ' && c != '\t' &&
  823                                     (alt == 0 || ISALPHA(c) == ctype));
  824                                 (void)putc(c, &tp->t_rawq);
  825                                 goto endcase;
  826                         }
  827                         /*
  828                          * reprint line (^R)
  829                          */
  830                         if (CCEQ(cc[VREPRINT], c)) {
  831                                 ttyretype(tp);
  832                                 goto endcase;
  833                         }
  834                         /*
  835                          * ^T - kernel info and generate SIGINFO
  836                          */
  837                         if (CCEQ(cc[VSTATUS], c)) {
  838                                 ttysig(tp, TTYSIG_PG1, SIGINFO);
  839                                 goto endcase;
  840                         }
  841                 }
  842         }
  843         /*
  844          * Check for input buffer overflow
  845          */
  846         if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
  847                 if (ISSET(iflag, IMAXBEL)) {
  848                         if (tp->t_outq.c_cc < tp->t_hiwat)
  849                                 (void)ttyoutput(CTRL('g'), tp);
  850                 } else
  851                         ttyflush(tp, FREAD | FWRITE);
  852                 goto endcase;
  853         }
  854         /*
  855          * Put data char in q for user and
  856          * wakeup on seeing a line delimiter.
  857          */
  858         if (putc(c, &tp->t_rawq) >= 0) {
  859                 if (!ISSET(lflag, ICANON)) {
  860                         ttwakeup(tp);
  861                         ttyecho(c, tp);
  862                         goto endcase;
  863                 }
  864                 if (TTBREAKC(c, lflag)) {
  865                         tp->t_rocount = 0;
  866                         catq(&tp->t_rawq, &tp->t_canq);
  867                         ttwakeup(tp);
  868                 } else if (tp->t_rocount++ == 0)
  869                         tp->t_rocol = tp->t_column;
  870                 if (ISSET(tp->t_state, TS_ERASE)) {
  871                         /*
  872                          * end of prterase \.../
  873                          */
  874                         CLR(tp->t_state, TS_ERASE);
  875                         (void)ttyoutput('/', tp);
  876                 }
  877                 i = tp->t_column;
  878                 ttyecho(c, tp);
  879                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
  880                         /*
  881                          * Place the cursor over the '^' of the ^D.
  882                          */
  883                         i = uimin(2, tp->t_column - i);
  884                         while (i > 0) {
  885                                 (void)ttyoutput('\b', tp);
  886                                 i--;
  887                         }
  888                 }
  889         }
  890  endcase:
  891         /*
  892          * IXANY means allow any character to restart output.
  893          */
  894         if (ISSET(tp->t_state, TS_TTSTOP) &&
  895             !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) {
  896                 return (0);
  897         }
  898  restartoutput:
  899         CLR(tp->t_lflag, FLUSHO);
  900         CLR(tp->t_state, TS_TTSTOP);
  901  startoutput:
  902         return (ttstart(tp));
  903 }
  904 
  905 /*
  906  * Process input of a single character received on a tty.
  907  *
  908  * XXX - this is a hack, all drivers must changed to acquire the
  909  *       lock before calling linesw->l_rint()
  910  */
  911 int
  912 ttyinput(int c, struct tty *tp)
  913 {
  914         int error;
  915 
  916         /*
  917          * Unless the receiver is enabled, drop incoming data.
  918          */
  919         if (!ISSET(tp->t_cflag, CREAD))
  920                 return (0);
  921 
  922         mutex_spin_enter(&tty_lock);
  923         error = ttyinput_wlock(c, tp);
  924         mutex_spin_exit(&tty_lock);
  925 
  926         return (error);
  927 }
  928 
  929 /*
  930  * Output a single character on a tty, doing output processing
  931  * as needed (expanding tabs, newline processing, etc.).
  932  * Returns < 0 if succeeds, otherwise returns char to resend.
  933  * Must be recursive.
  934  *
  935  * Call with tty lock held.
  936  */
  937 int
  938 ttyoutput(int c, struct tty *tp)
  939 {
  940         long    oflag;
  941         int     col, notout;
  942 
  943         KASSERT(mutex_owned(&tty_lock));
  944 
  945         oflag = tp->t_oflag;
  946         if (!ISSET(oflag, OPOST)) {
  947                 tk_nout++;
  948                 tp->t_outcc++;
  949                 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
  950                         return (c);
  951                 return (-1);
  952         }
  953         /*
  954          * Do tab expansion if OXTABS is set.  Special case if we do external
  955          * processing, we don't do the tab expansion because we'll probably
  956          * get it wrong.  If tab expansion needs to be done, let it happen
  957          * externally.
  958          */
  959         CLR(c, ~TTY_CHARMASK);
  960         if (c == '\t' &&
  961             ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
  962                 c = 8 - (tp->t_column & 7);
  963                 if (ISSET(tp->t_lflag, FLUSHO)) {
  964                         notout = 0;
  965                 } else {
  966                         notout = b_to_q("        ", c, &tp->t_outq);
  967                         c -= notout;
  968                         tk_nout += c;
  969                         tp->t_outcc += c;
  970                 }
  971                 tp->t_column += c;
  972                 return (notout ? '\t' : -1);
  973         }
  974         if (c == CEOT && ISSET(oflag, ONOEOT))
  975                 return (-1);
  976 
  977         /*
  978          * Newline translation: if ONLCR is set,
  979          * translate newline into "\r\n".
  980          */
  981         if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
  982                 tk_nout++;
  983                 tp->t_outcc++;
  984                 if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
  985                         return (c);
  986         }
  987         /* If OCRNL is set, translate "\r" into "\n". */
  988         else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
  989                 c = '\n';
  990         /* If ONOCR is set, don't transmit CRs when on column 0. */
  991         else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0)
  992                 return (-1);
  993 
  994         tk_nout++;
  995         tp->t_outcc++;
  996         if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
  997                 return (c);
  998 
  999         col = tp->t_column;
 1000         switch (CCLASS(c)) {
 1001         case BACKSPACE:
 1002                 if (col > 0)
 1003                         --col;
 1004                 break;
 1005         case CONTROL:
 1006                 break;
 1007         case NEWLINE:
 1008                 if (ISSET(tp->t_oflag, ONLCR | ONLRET))
 1009                         col = 0;
 1010                 break;
 1011         case RETURN:
 1012                 col = 0;
 1013                 break;
 1014         case ORDINARY:
 1015                 ++col;
 1016                 break;
 1017         case TAB:
 1018                 col = (col + 8) & ~7;
 1019                 break;
 1020         }
 1021         tp->t_column = col;
 1022         return (-1);
 1023 }
 1024 
 1025 /*
 1026  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
 1027  * has been called to do discipline-specific functions and/or reject any
 1028  * of these ioctl commands.
 1029  */
 1030 /* ARGSUSED */
 1031 int
 1032 ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l)
 1033 {
 1034         struct proc *p;
 1035         struct linesw   *lp;
 1036         int             s, error;
 1037         struct pathbuf *pb;
 1038         struct nameidata nd;
 1039         char            infobuf[200];
 1040 
 1041         KASSERT(l != NULL);
 1042         p = l->l_proc;
 1043 
 1044         /* If the ioctl involves modification, hang if in the background. */
 1045         switch (cmd) {
 1046         case  TIOCFLUSH:
 1047         case  TIOCDRAIN:
 1048         case  TIOCSBRK:
 1049         case  TIOCCBRK:
 1050         case  TIOCSTART:
 1051         case  TIOCSETA:
 1052         case  TIOCSETD:
 1053         case  TIOCSLINED:
 1054         case  TIOCSETAF:
 1055         case  TIOCSETAW:
 1056 #ifdef notdef
 1057         case  TIOCSPGRP:
 1058         case  FIOSETOWN:
 1059 #endif
 1060         case  TIOCSTAT:
 1061         case  TIOCSTI:
 1062         case  TIOCSWINSZ:
 1063         case  TIOCSQSIZE:
 1064         case  TIOCLBIC:
 1065         case  TIOCLBIS:
 1066         case  TIOCLSET:
 1067         case  TIOCSETC:
 1068         case OTIOCSETD:
 1069         case  TIOCSETN:
 1070         case  TIOCSETP:
 1071         case  TIOCSLTC:
 1072                 mutex_spin_enter(&tty_lock);
 1073                 while (isbackground(curproc, tp) &&
 1074                     p->p_pgrp->pg_jobc && (p->p_lflag & PL_PPWAIT) == 0 &&
 1075                     !sigismasked(l, SIGTTOU)) {
 1076                         mutex_spin_exit(&tty_lock);
 1077 
 1078                         mutex_enter(&proc_lock);
 1079                         pgsignal(p->p_pgrp, SIGTTOU, 1);
 1080                         mutex_exit(&proc_lock);
 1081                         
 1082                         mutex_spin_enter(&tty_lock);
 1083                         error = ttypause(tp, hz);
 1084                         if (error) {
 1085                                 mutex_spin_exit(&tty_lock);
 1086                                 return (error);
 1087                         }
 1088                 }
 1089                 mutex_spin_exit(&tty_lock);
 1090                 break;
 1091         }
 1092 
 1093         switch (cmd) {                  /* Process the ioctl. */
 1094         case FIOASYNC:                  /* set/clear async i/o */
 1095                 mutex_spin_enter(&tty_lock);
 1096                 if (*(int *)data)
 1097                         SET(tp->t_state, TS_ASYNC);
 1098                 else
 1099                         CLR(tp->t_state, TS_ASYNC);
 1100                 mutex_spin_exit(&tty_lock);
 1101                 break;
 1102         case FIONBIO:                   /* set/clear non-blocking i/o */
 1103                 break;                  /* XXX: delete. */
 1104         case FIONREAD:                  /* get # bytes to read */
 1105                 mutex_spin_enter(&tty_lock);
 1106                 *(int *)data = ttnread(tp);
 1107                 mutex_spin_exit(&tty_lock);
 1108                 break;
 1109         case FIONWRITE:                 /* get # bytes to written & unsent */
 1110                 mutex_spin_enter(&tty_lock);
 1111                 *(int *)data = tp->t_outq.c_cc;
 1112                 mutex_spin_exit(&tty_lock);
 1113                 break;
 1114         case FIONSPACE:                 /* get # bytes to written & unsent */
 1115                 mutex_spin_enter(&tty_lock);
 1116                 *(int *)data = tp->t_outq.c_cn - tp->t_outq.c_cc;
 1117                 mutex_spin_exit(&tty_lock);
 1118                 break;
 1119         case TIOCEXCL:                  /* set exclusive use of tty */
 1120                 mutex_spin_enter(&tty_lock);
 1121                 SET(tp->t_state, TS_XCLUDE);
 1122                 mutex_spin_exit(&tty_lock);
 1123                 break;
 1124         case TIOCFLUSH: {               /* flush buffers */
 1125                 int flags = *(int *)data;
 1126 
 1127                 if (flags == 0)
 1128                         flags = FREAD | FWRITE;
 1129                 else
 1130                         flags &= FREAD | FWRITE;
 1131                 mutex_spin_enter(&tty_lock);
 1132                 ttyflush(tp, flags);
 1133                 mutex_spin_exit(&tty_lock);
 1134                 break;
 1135         }
 1136         case TIOCCONS: {                /* become virtual console */
 1137                 struct tty *ctp;
 1138 
 1139                 mutex_enter(&constty_lock);
 1140                 error = 0;
 1141                 ctp = atomic_load_relaxed(&constty);
 1142                 if (*(int *)data) {
 1143                         if (ctp != NULL && ctp != tp &&
 1144                             ISSET(ctp->t_state, TS_CARR_ON | TS_ISOPEN) ==
 1145                             (TS_CARR_ON | TS_ISOPEN)) {
 1146                                 error = EBUSY;
 1147                                 goto unlock_constty;
 1148                         }
 1149 
 1150                         pb = pathbuf_create("/dev/console");
 1151                         if (pb == NULL) {
 1152                                 error = ENOMEM;
 1153                                 goto unlock_constty;
 1154                         }
 1155                         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pb);
 1156                         if ((error = namei(&nd)) != 0) {
 1157                                 pathbuf_destroy(pb);
 1158                                 goto unlock_constty;
 1159                         }
 1160                         error = VOP_ACCESS(nd.ni_vp, VREAD, l->l_cred);
 1161                         vput(nd.ni_vp);
 1162                         pathbuf_destroy(pb);
 1163                         if (error)
 1164                                 goto unlock_constty;
 1165 
 1166                         KASSERT(atomic_load_relaxed(&constty) == ctp ||
 1167                             atomic_load_relaxed(&constty) == NULL);
 1168                         atomic_store_release(&constty, tp);
 1169                 } else if (tp == ctp) {
 1170                         atomic_store_relaxed(&constty, NULL);
 1171                 }
 1172 unlock_constty: mutex_exit(&constty_lock);
 1173                 if (error)
 1174                         return error;
 1175                 break;
 1176         }
 1177         case TIOCDRAIN:                 /* wait till output drained */
 1178                 if ((error = ttywait(tp)) != 0)
 1179                         return (error);
 1180                 break;
 1181         case TIOCGETA: {                /* get termios struct */
 1182                 struct termios *t = (struct termios *)data;
 1183 
 1184                 memcpy(t, &tp->t_termios, sizeof(struct termios));
 1185                 break;
 1186         }
 1187         case TIOCGETD:                  /* get line discipline (old) */
 1188                 *(int *)data = tp->t_linesw->l_no;
 1189                 break;
 1190         case TIOCGLINED:                /* get line discipline (new) */
 1191                 (void)strncpy((char *)data, tp->t_linesw->l_name,
 1192                     TTLINEDNAMELEN - 1);
 1193                 break;
 1194         case TIOCGWINSZ:                /* get window size */
 1195                 *(struct winsize *)data = tp->t_winsize;
 1196                 break;
 1197         case TIOCGQSIZE:
 1198                 *(int *)data = tp->t_qsize;
 1199                 break;
 1200         case FIOGETOWN:
 1201                 mutex_enter(&proc_lock);
 1202                 if (tp->t_session != NULL && !isctty(p, tp)) {
 1203                         mutex_exit(&proc_lock);
 1204                         return (ENOTTY);
 1205                 }
 1206                 *(int *)data = tp->t_pgrp ? -tp->t_pgrp->pg_id : 0;
 1207                 mutex_exit(&proc_lock);
 1208                 break;
 1209         case TIOCGPGRP:                 /* get pgrp of tty */
 1210                 mutex_enter(&proc_lock);
 1211                 if (!isctty(p, tp)) {
 1212                         mutex_exit(&proc_lock);
 1213                         return (ENOTTY);
 1214                 }
 1215                 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
 1216                 mutex_exit(&proc_lock);
 1217                 break;
 1218         case TIOCGSID:                  /* get sid of tty */
 1219                 mutex_enter(&proc_lock);
 1220                 if (!isctty(p, tp)) {
 1221                         mutex_exit(&proc_lock);
 1222                         return (ENOTTY);
 1223                 }
 1224                 *(int *)data = tp->t_session->s_sid;
 1225                 mutex_exit(&proc_lock);
 1226                 break;
 1227 #ifdef TIOCHPCL
 1228         case TIOCHPCL:                  /* hang up on last close */
 1229                 mutex_spin_enter(&tty_lock);
 1230                 SET(tp->t_cflag, HUPCL);
 1231                 mutex_spin_exit(&tty_lock);
 1232                 break;
 1233 #endif
 1234         case TIOCNXCL:                  /* reset exclusive use of tty */
 1235                 mutex_spin_enter(&tty_lock);
 1236                 CLR(tp->t_state, TS_XCLUDE);
 1237                 mutex_spin_exit(&tty_lock);
 1238                 break;
 1239         case TIOCOUTQ:                  /* output queue size */
 1240                 *(int *)data = tp->t_outq.c_cc;
 1241                 break;
 1242         case TIOCSETA:                  /* set termios struct */
 1243         case TIOCSETAW:                 /* drain output, set */
 1244         case TIOCSETAF: {               /* drn out, fls in, set */
 1245                 struct termios *t = (struct termios *)data;
 1246 
 1247                 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
 1248                         if ((error = ttywait(tp)) != 0)
 1249                                 return (error);
 1250 
 1251                         if (cmd == TIOCSETAF) {
 1252                                 mutex_spin_enter(&tty_lock);
 1253                                 ttyflush(tp, FREAD);
 1254                                 mutex_spin_exit(&tty_lock);
 1255                         }
 1256                 }
 1257 
 1258                 s = spltty();
 1259                 /*
 1260                  * XXXSMP - some drivers call back on us from t_param(), so
 1261                  *          don't take the tty spin lock here.
 1262                  *          require t_param() to unlock upon callback?
 1263                  */
 1264                 /* wanted here: mutex_spin_enter(&tty_lock); */
 1265                 if (!ISSET(t->c_cflag, CIGNORE)) {
 1266                         /*
 1267                          * Set device hardware.
 1268                          */
 1269                         if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
 1270                                 /* wanted here: mutex_spin_exit(&tty_lock); */
 1271                                 splx(s);
 1272                                 return (error);
 1273                         } else {
 1274                                 tp->t_cflag = t->c_cflag;
 1275                                 tp->t_ispeed = t->c_ispeed;
 1276                                 tp->t_ospeed = t->c_ospeed;
 1277                                 if (t->c_ospeed == 0)
 1278                                         ttysig(tp, TTYSIG_LEADER, SIGHUP);
 1279                         }
 1280                         ttsetwater(tp);
 1281                 }
 1282 
 1283                 /* delayed lock acquiring */
 1284                 mutex_spin_enter(&tty_lock);
 1285                 if (cmd != TIOCSETAF) {
 1286                         if (ISSET(t->c_lflag, ICANON) !=
 1287                             ISSET(tp->t_lflag, ICANON)) {
 1288                                 if (ISSET(t->c_lflag, ICANON)) {
 1289                                         SET(tp->t_lflag, PENDIN);
 1290                                         ttwakeup(tp);
 1291                                 } else {
 1292                                         struct clist tq;
 1293 
 1294                                         catq(&tp->t_rawq, &tp->t_canq);
 1295                                         tq = tp->t_rawq;
 1296                                         tp->t_rawq = tp->t_canq;
 1297                                         tp->t_canq = tq;
 1298                                         CLR(tp->t_lflag, PENDIN);
 1299                                 }
 1300                         }
 1301                 }
 1302                 tp->t_iflag = t->c_iflag;
 1303                 tp->t_oflag = t->c_oflag;
 1304                 /*
 1305                  * Make the EXTPROC bit read only.
 1306                  */
 1307                 if (ISSET(tp->t_lflag, EXTPROC))
 1308                         SET(t->c_lflag, EXTPROC);
 1309                 else
 1310                         CLR(t->c_lflag, EXTPROC);
 1311                 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
 1312                 memcpy(tp->t_cc, t->c_cc, sizeof(t->c_cc));
 1313                 mutex_spin_exit(&tty_lock);
 1314                 splx(s);
 1315                 break;
 1316         }
 1317         case TIOCSETD:                  /* set line discipline (old) */
 1318                 lp = ttyldisc_lookup_bynum(*(int *)data);
 1319                 goto setldisc;
 1320 
 1321         case TIOCSLINED: {              /* set line discipline (new) */
 1322                 char *name = (char *)data;
 1323                 dev_t device;
 1324 
 1325                 /* Null terminate to prevent buffer overflow */
 1326                 name[TTLINEDNAMELEN - 1] = '\0';
 1327                 lp = ttyldisc_lookup(name);
 1328  setldisc:
 1329                 if (lp == NULL)
 1330                         return (ENXIO);
 1331 
 1332                 if (lp != tp->t_linesw) {
 1333                         device = tp->t_dev;
 1334                         s = spltty();
 1335                         (*tp->t_linesw->l_close)(tp, flag);
 1336                         error = (*lp->l_open)(device, tp);
 1337                         if (error) {
 1338                                 (void)(*tp->t_linesw->l_open)(device, tp);
 1339                                 splx(s);
 1340                                 ttyldisc_release(lp);
 1341                                 return (error);
 1342                         }
 1343                         ttyldisc_release(tp->t_linesw);
 1344                         tp->t_linesw = lp;
 1345                         splx(s);
 1346                 } else {
 1347                         /* Drop extra reference. */
 1348                         ttyldisc_release(lp);
 1349                 }
 1350                 break;
 1351         }
 1352         case TIOCSTART:                 /* start output, like ^Q */
 1353                 mutex_spin_enter(&tty_lock);
 1354                 if (ISSET(tp->t_state, TS_TTSTOP) ||
 1355                     ISSET(tp->t_lflag, FLUSHO)) {
 1356                         CLR(tp->t_lflag, FLUSHO);
 1357                         CLR(tp->t_state, TS_TTSTOP);
 1358                         ttstart(tp);
 1359                 }
 1360                 mutex_spin_exit(&tty_lock);
 1361                 break;
 1362         case TIOCSTI:                   /* simulate terminal input */
 1363                 if ((error = kauth_authorize_device_tty(l->l_cred,
 1364                     KAUTH_DEVICE_TTY_STI, tp)) != 0) {
 1365                         if (!ISSET(flag, FREAD))
 1366                                 return EPERM;
 1367                         if (!isctty(p, tp))
 1368                                 return EACCES;
 1369                         if (tp->t_session->s_leader->p_cred != p->p_cred)
 1370                                 return error;
 1371                 }
 1372                 (*tp->t_linesw->l_rint)(*(u_char *)data, tp);
 1373                 break;
 1374         case TIOCSTOP:                  /* stop output, like ^S */
 1375         {
 1376                 mutex_spin_enter(&tty_lock);
 1377                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
 1378                         SET(tp->t_state, TS_TTSTOP);
 1379                         cdev_stop(tp, 0);
 1380                 }
 1381                 mutex_spin_exit(&tty_lock);
 1382                 break;
 1383         }
 1384         case TIOCSCTTY:                 /* become controlling tty */
 1385                 mutex_enter(&proc_lock);
 1386                 mutex_spin_enter(&tty_lock);
 1387 
 1388                 /* Session ctty vnode pointer set in vnode layer. */
 1389                 if (!SESS_LEADER(p) ||
 1390                     ((p->p_session->s_ttyvp || tp->t_session) &&
 1391                     (tp->t_session != p->p_session))) {
 1392                         mutex_spin_exit(&tty_lock);
 1393                         mutex_exit(&proc_lock);
 1394                         return (EPERM);
 1395                 }
 1396 
 1397                 /*
 1398                  * `p_session' acquires a reference.
 1399                  * But note that if `t_session' is set at this point,
 1400                  * it must equal `p_session', in which case the session
 1401                  * already has the correct reference count.
 1402                  */
 1403                 if (tp->t_session == NULL) {
 1404                         proc_sesshold(p->p_session);
 1405                 }
 1406                 tp->t_session = p->p_session;
 1407                 tp->t_pgrp = p->p_pgrp;
 1408                 p->p_session->s_ttyp = tp;
 1409                 p->p_lflag |= PL_CONTROLT;
 1410                 mutex_spin_exit(&tty_lock);
 1411                 mutex_exit(&proc_lock);
 1412                 break;
 1413         case FIOSETOWN: {               /* set pgrp of tty */
 1414                 pid_t pgid = *(pid_t *)data;
 1415                 struct pgrp *pgrp;
 1416 
 1417                 mutex_enter(&proc_lock);
 1418                 if (tp->t_session != NULL && !isctty(p, tp)) {
 1419                         mutex_exit(&proc_lock);
 1420                         return (ENOTTY);
 1421                 }
 1422 
 1423                 if (pgid < 0) {
 1424                         if (pgid == INT_MIN) {
 1425                                 mutex_exit(&proc_lock);
 1426                                 return (EINVAL);
 1427                         }
 1428                         pgrp = pgrp_find(-pgid);
 1429                         if (pgrp == NULL) {
 1430                                 mutex_exit(&proc_lock);
 1431                                 return (EINVAL);
 1432                         }
 1433                 } else {
 1434                         struct proc *p1;
 1435                         p1 = proc_find(pgid);
 1436                         if (!p1) {
 1437                                 mutex_exit(&proc_lock);
 1438                                 return (ESRCH);
 1439                         }
 1440                         pgrp = p1->p_pgrp;
 1441                 }
 1442 
 1443                 if (pgrp->pg_session != p->p_session) {
 1444                         mutex_exit(&proc_lock);
 1445                         return (EPERM);
 1446                 }
 1447                 mutex_spin_enter(&tty_lock);
 1448                 tp->t_pgrp = pgrp;
 1449                 mutex_spin_exit(&tty_lock);
 1450                 mutex_exit(&proc_lock);
 1451                 break;
 1452         }
 1453         case TIOCSPGRP: {               /* set pgrp of tty */
 1454                 struct pgrp *pgrp;
 1455                 pid_t pgid = *(pid_t *)data;
 1456 
 1457                 if (pgid == NO_PGID)
 1458                         return EINVAL;
 1459 
 1460                 mutex_enter(&proc_lock);
 1461                 if (!isctty(p, tp)) {
 1462                         mutex_exit(&proc_lock);
 1463                         return (ENOTTY);
 1464                 }
 1465                 pgrp = pgrp_find(pgid);
 1466                 if (pgrp == NULL || pgrp->pg_session != p->p_session) {
 1467                         mutex_exit(&proc_lock);
 1468                         return (EPERM);
 1469                 }
 1470                 mutex_spin_enter(&tty_lock);
 1471                 tp->t_pgrp = pgrp;
 1472                 mutex_spin_exit(&tty_lock);
 1473                 mutex_exit(&proc_lock);
 1474                 break;
 1475         }
 1476         case TIOCSTAT:                  /* get load avg stats */
 1477                 mutex_enter(&proc_lock);
 1478                 ttygetinfo(tp, 0, infobuf, sizeof(infobuf));
 1479                 mutex_exit(&proc_lock);
 1480 
 1481                 mutex_spin_enter(&tty_lock);
 1482                 ttyputinfo(tp, infobuf);
 1483                 mutex_spin_exit(&tty_lock);
 1484                 break;
 1485         case TIOCSWINSZ:                /* set window size */
 1486                 mutex_spin_enter(&tty_lock);
 1487                 if (memcmp((void *)&tp->t_winsize, data,
 1488                     sizeof(struct winsize))) {
 1489                         tp->t_winsize = *(struct winsize *)data;
 1490                         ttysig(tp, TTYSIG_PG1, SIGWINCH);
 1491                 }
 1492                 mutex_spin_exit(&tty_lock);
 1493                 break;
 1494         case TIOCSQSIZE:
 1495                 if ((error = tty_get_qsize(&s, *(int *)data)) == 0 &&
 1496                     s != tp->t_qsize)
 1497                         error = tty_set_qsize(tp, s);
 1498                 return error;
 1499 
 1500         case TIOCSBRK:
 1501         case TIOCCBRK:
 1502         case TIOCSDTR:
 1503         case TIOCCDTR:
 1504         case TIOCSFLAGS:
 1505         case TIOCGFLAGS:
 1506         case TIOCMSET:
 1507         case TIOCMGET:
 1508         case TIOCMBIS:
 1509         case TIOCMBIC:
 1510                 /* Handled by the driver layer */
 1511                 return EPASSTHROUGH;
 1512 
 1513         case TIOCEXT:
 1514         case TIOCPTSNAME:
 1515         case TIOCGRANTPT:
 1516         case TIOCPKT:
 1517         case TIOCUCNTL:
 1518         case TIOCREMOTE:
 1519         case TIOCSIG:
 1520                 /* for ptys */
 1521                 return EPASSTHROUGH;
 1522 
 1523         default:
 1524                 /* Pass through various console ioctls */
 1525                 switch (IOCGROUP(cmd)) {
 1526                 case 'c':       /* syscons console */
 1527                 case 'v':       /* usl console, video - where one letter */
 1528                 case 'K':       /* usl console, keyboard - aint enough */
 1529                 case 'V':       /* pcvt compat */
 1530                 case 'W':       /* wscons console */
 1531                         return EPASSTHROUGH;
 1532                 default:
 1533                         break;
 1534                 }
 1535 
 1536                 /* We may have to load the compat_60 module for this. */
 1537                 (void)module_autoload("compat_60", MODULE_CLASS_EXEC);
 1538                 MODULE_HOOK_CALL(tty_ttioctl_60_hook,
 1539                     (tp, cmd, data, flag, l), enosys(), error);
 1540                 if (error != EPASSTHROUGH)
 1541                         return error;
 1542 
 1543                 /* We may have to load the compat_43 module for this. */
 1544                 (void)module_autoload("compat_43", MODULE_CLASS_EXEC);
 1545                 MODULE_HOOK_CALL(tty_ttioctl_43_hook,
 1546                     (tp, cmd, data, flag, l), enosys(), error);
 1547                 return error;
 1548         }
 1549         return (0);
 1550 }
 1551 
 1552 int
 1553 ttpoll(struct tty *tp, int events, struct lwp *l)
 1554 {
 1555         int     revents;
 1556 
 1557         revents = 0;
 1558         mutex_spin_enter(&tty_lock);
 1559         if (events & (POLLIN | POLLRDNORM))
 1560                 if (ttnread(tp) > 0)
 1561                         revents |= events & (POLLIN | POLLRDNORM);
 1562 
 1563         if (events & (POLLOUT | POLLWRNORM))
 1564                 if (tp->t_outq.c_cc <= tp->t_lowat)
 1565                         revents |= events & (POLLOUT | POLLWRNORM);
 1566 
 1567         if (events & POLLHUP)
 1568                 if (!CONNECTED(tp))
 1569                         revents |= POLLHUP;
 1570 
 1571         if (revents == 0) {
 1572                 if (events & (POLLIN | POLLHUP | POLLRDNORM))
 1573                         selrecord(l, &tp->t_rsel);
 1574 
 1575                 if (events & (POLLOUT | POLLWRNORM))
 1576                         selrecord(l, &tp->t_wsel);
 1577         }
 1578 
 1579         mutex_spin_exit(&tty_lock);
 1580 
 1581         return (revents);
 1582 }
 1583 
 1584 static void
 1585 filt_ttyrdetach(struct knote *kn)
 1586 {
 1587         struct tty      *tp;
 1588 
 1589         tp = kn->kn_hook;
 1590         mutex_spin_enter(&tty_lock);
 1591         selremove_knote(&tp->t_rsel, kn);
 1592         mutex_spin_exit(&tty_lock);
 1593 }
 1594 
 1595 static int
 1596 filt_ttyread(struct knote *kn, long hint)
 1597 {
 1598         struct tty      *tp;
 1599         int rv;
 1600 
 1601         tp = kn->kn_hook;
 1602         if ((hint & NOTE_SUBMIT) == 0)
 1603                 mutex_spin_enter(&tty_lock);
 1604         kn->kn_data = ttnread(tp);
 1605         rv = kn->kn_data > 0;
 1606         if ((hint & NOTE_SUBMIT) == 0)
 1607                 mutex_spin_exit(&tty_lock);
 1608         return rv;
 1609 }
 1610 
 1611 static void
 1612 filt_ttywdetach(struct knote *kn)
 1613 {
 1614         struct tty      *tp;
 1615 
 1616         tp = kn->kn_hook;
 1617         mutex_spin_enter(&tty_lock);
 1618         selremove_knote(&tp->t_wsel, kn);
 1619         mutex_spin_exit(&tty_lock);
 1620 }
 1621 
 1622 static int
 1623 filt_ttywrite(struct knote *kn, long hint)
 1624 {
 1625         struct tty      *tp;
 1626         int             canwrite;
 1627 
 1628         tp = kn->kn_hook;
 1629         if ((hint & NOTE_SUBMIT) == 0)
 1630                 mutex_spin_enter(&tty_lock);
 1631         kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc;
 1632         canwrite = (tp->t_outq.c_cc <= tp->t_lowat) && CONNECTED(tp);
 1633         if ((hint & NOTE_SUBMIT) == 0)
 1634                 mutex_spin_exit(&tty_lock);
 1635         return (canwrite);
 1636 }
 1637 
 1638 static const struct filterops ttyread_filtops = {
 1639         .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
 1640         .f_attach = NULL,
 1641         .f_detach = filt_ttyrdetach,
 1642         .f_event = filt_ttyread,
 1643 };
 1644 
 1645 static const struct filterops ttywrite_filtops = {
 1646         .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
 1647         .f_attach = NULL,
 1648         .f_detach = filt_ttywdetach,
 1649         .f_event = filt_ttywrite,
 1650 };
 1651 
 1652 int
 1653 ttykqfilter(dev_t dev, struct knote *kn)
 1654 {
 1655         struct tty      *tp;
 1656         struct selinfo  *sip;
 1657 
 1658         if ((tp = cdev_tty(dev)) == NULL)
 1659                 return (ENXIO);
 1660 
 1661         switch (kn->kn_filter) {
 1662         case EVFILT_READ:
 1663                 sip = &tp->t_rsel;
 1664                 kn->kn_fop = &ttyread_filtops;
 1665                 break;
 1666         case EVFILT_WRITE:
 1667                 sip = &tp->t_wsel;
 1668                 kn->kn_fop = &ttywrite_filtops;
 1669                 break;
 1670         default:
 1671                 return EINVAL;
 1672         }
 1673 
 1674         kn->kn_hook = tp;
 1675 
 1676         mutex_spin_enter(&tty_lock);
 1677         selrecord_knote(sip, kn);
 1678         mutex_spin_exit(&tty_lock);
 1679 
 1680         return (0);
 1681 }
 1682 
 1683 /*
 1684  * Find the number of chars ready to be read from this tty.
 1685  * Call with the tty lock held.
 1686  */
 1687 static int
 1688 ttnread(struct tty *tp)
 1689 {
 1690         int     nread;
 1691 
 1692         KASSERT(mutex_owned(&tty_lock));
 1693 
 1694         if (ISSET(tp->t_lflag, PENDIN))
 1695                 ttypend(tp);
 1696         nread = tp->t_canq.c_cc;
 1697         if (!ISSET(tp->t_lflag, ICANON)) {
 1698                 nread += tp->t_rawq.c_cc;
 1699                 if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
 1700                         nread = 0;
 1701         }
 1702         return (nread);
 1703 }
 1704 
 1705 /*
 1706  * Wait for output to drain, or if this times out, flush it.
 1707  */
 1708 static int
 1709 ttywait_timo(struct tty *tp, int timo)
 1710 {
 1711         int     error;
 1712 
 1713         error = 0;
 1714 
 1715         mutex_spin_enter(&tty_lock);
 1716         while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
 1717             CONNECTED(tp) && tp->t_oproc) {
 1718                 (*tp->t_oproc)(tp);
 1719                 error = ttysleep(tp, &tp->t_outcv, true, timo);
 1720                 if (error == EWOULDBLOCK)
 1721                         ttyflush(tp, FWRITE);
 1722                 if (error)
 1723                         break;
 1724         }
 1725         mutex_spin_exit(&tty_lock);
 1726 
 1727         return (error);
 1728 }
 1729 
 1730 /*
 1731  * Wait for output to drain.
 1732  */
 1733 int
 1734 ttywait(struct tty *tp)
 1735 {
 1736         return ttywait_timo(tp, 0);
 1737 }
 1738 
 1739 /*
 1740  * Flush if successfully wait.
 1741  */
 1742 int
 1743 ttywflush(struct tty *tp)
 1744 {
 1745         int     error;
 1746 
 1747         error = ttywait_timo(tp, 5 * hz);
 1748         if (error == 0 || error == EWOULDBLOCK) {
 1749                 mutex_spin_enter(&tty_lock);
 1750                 ttyflush(tp, FREAD);
 1751                 mutex_spin_exit(&tty_lock);
 1752         }
 1753         return (error);
 1754 }
 1755 
 1756 /*
 1757  * Flush tty read and/or write queues, notifying anyone waiting.
 1758  * Call with the tty lock held.
 1759  */
 1760 void
 1761 ttyflush(struct tty *tp, int rw)
 1762 {
 1763 
 1764         KASSERT(mutex_owned(&tty_lock));
 1765 
 1766         if (rw & FREAD) {
 1767                 FLUSHQ(&tp->t_canq);
 1768                 FLUSHQ(&tp->t_rawq);
 1769                 tp->t_rocount = 0;
 1770                 tp->t_rocol = 0;
 1771                 CLR(tp->t_state, TS_LOCAL);
 1772                 ttwakeup(tp);
 1773         }
 1774         if (rw & FWRITE) {
 1775                 CLR(tp->t_state, TS_TTSTOP);
 1776                 cdev_stop(tp, rw);
 1777                 FLUSHQ(&tp->t_outq);
 1778                 cv_broadcast(&tp->t_outcv);
 1779                 selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
 1780         }
 1781 }
 1782 
 1783 /*
 1784  * Copy in the default termios characters.
 1785  */
 1786 void
 1787 ttychars(struct tty *tp)
 1788 {
 1789 
 1790         memcpy(tp->t_cc, ttydefchars, sizeof(ttydefchars));
 1791 }
 1792 
 1793 /*
 1794  * Send stop character on input overflow.
 1795  * Call with the tty lock held.
 1796  */
 1797 static void
 1798 ttyblock(struct tty *tp)
 1799 {
 1800         int     total;
 1801 
 1802         KASSERT(mutex_owned(&tty_lock));
 1803 
 1804         total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
 1805         if (tp->t_rawq.c_cc > TTYHOG) {
 1806                 ttyflush(tp, FREAD | FWRITE);
 1807                 CLR(tp->t_state, TS_TBLOCK);
 1808         }
 1809         /*
 1810          * Block further input iff: current input > threshold
 1811          * AND input is available to user program.
 1812          */
 1813         if (total >= TTYHOG / 2 &&
 1814             !ISSET(tp->t_state, TS_TBLOCK) &&
 1815             (!ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0)) {
 1816                 if (ISSET(tp->t_iflag, IXOFF) &&
 1817                     tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
 1818                     putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
 1819                         SET(tp->t_state, TS_TBLOCK);
 1820                         ttstart(tp);
 1821                 }
 1822                 /* Try to block remote output via hardware flow control. */
 1823                 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
 1824                     (*tp->t_hwiflow)(tp, 1) != 0)
 1825                         SET(tp->t_state, TS_TBLOCK);
 1826         }
 1827 }
 1828 
 1829 /*
 1830  * Delayed line discipline output
 1831  */
 1832 void
 1833 ttrstrt(void *tp_arg)
 1834 {
 1835         struct tty      *tp;
 1836 
 1837 #ifdef DIAGNOSTIC
 1838         if (tp_arg == NULL)
 1839                 panic("ttrstrt");
 1840 #endif
 1841         tp = tp_arg;
 1842         mutex_spin_enter(&tty_lock);
 1843 
 1844         CLR(tp->t_state, TS_TIMEOUT);
 1845         ttstart(tp); /* XXX - Shouldn't this be tp->l_start(tp)? */
 1846 
 1847         mutex_spin_exit(&tty_lock);
 1848 }
 1849 
 1850 /*
 1851  * start a line discipline
 1852  * Always call with tty lock held?
 1853  */
 1854 int
 1855 ttstart(struct tty *tp)
 1856 {
 1857 
 1858         if (tp->t_oproc != NULL)        /* XXX: Kludge for pty. */
 1859                 (*tp->t_oproc)(tp);
 1860         return (0);
 1861 }
 1862 
 1863 /*
 1864  * "close" a line discipline
 1865  */
 1866 int
 1867 ttylclose(struct tty *tp, int flag)
 1868 {
 1869 
 1870         if (flag & FNONBLOCK) {
 1871                 mutex_spin_enter(&tty_lock);
 1872                 ttyflush(tp, FREAD | FWRITE);
 1873                 mutex_spin_exit(&tty_lock);
 1874         } else
 1875                 ttywflush(tp);
 1876         return (0);
 1877 }
 1878 
 1879 /*
 1880  * Handle modem control transition on a tty.
 1881  * Flag indicates new state of carrier.
 1882  * Returns 0 if the line should be turned off, otherwise 1.
 1883  */
 1884 int
 1885 ttymodem(struct tty *tp, int flag)
 1886 {
 1887 
 1888         mutex_spin_enter(&tty_lock);
 1889         if (flag == 0) {
 1890                 if (ISSET(tp->t_state, TS_CARR_ON)) {
 1891                         /*
 1892                          * Lost carrier.
 1893                          */
 1894                         CLR(tp->t_state, TS_CARR_ON);
 1895                         if (ISSET(tp->t_state, TS_ISOPEN) && !CONNECTED(tp)) {
 1896                                 ttysig(tp, TTYSIG_LEADER, SIGHUP);
 1897                                 ttyflush(tp, FREAD | FWRITE);
 1898                                 mutex_spin_exit(&tty_lock);
 1899                                 return (0);
 1900                         }
 1901                 }
 1902         } else {
 1903                 if (!ISSET(tp->t_state, TS_CARR_ON)) {
 1904                         /*
 1905                          * Carrier now on.
 1906                          */
 1907                         SET(tp->t_state, TS_CARR_ON);
 1908                         ttwakeup(tp);
 1909                 }
 1910         }
 1911         mutex_spin_exit(&tty_lock);
 1912 
 1913         return (1);
 1914 }
 1915 
 1916 /*
 1917  * Default modem control routine (for other line disciplines).
 1918  * Return argument flag, to turn off device on carrier drop.
 1919  */
 1920 int
 1921 nullmodem(struct tty *tp, int flag)
 1922 {
 1923 
 1924         mutex_spin_enter(&tty_lock);
 1925         if (flag)
 1926                 SET(tp->t_state, TS_CARR_ON);
 1927         else {
 1928                 CLR(tp->t_state, TS_CARR_ON);
 1929                 if (!CONNECTED(tp)) {
 1930                         ttysig(tp, TTYSIG_LEADER, SIGHUP);
 1931                         mutex_spin_exit(&tty_lock);
 1932                         return (0);
 1933                 }
 1934         }
 1935         mutex_spin_exit(&tty_lock);
 1936 
 1937         return (1);
 1938 }
 1939 
 1940 /*
 1941  * Reinput pending characters after state switch.
 1942  */
 1943 void
 1944 ttypend(struct tty *tp)
 1945 {
 1946         struct clist    tq;
 1947         int             c;
 1948 
 1949         KASSERT(mutex_owned(&tty_lock));
 1950 
 1951         CLR(tp->t_lflag, PENDIN);
 1952         SET(tp->t_state, TS_TYPEN);
 1953         tq = tp->t_rawq;
 1954         tp->t_rawq.c_cc = 0;
 1955         tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
 1956         while ((c = getc(&tq)) >= 0)
 1957                 ttyinput_wlock(c, tp);
 1958         CLR(tp->t_state, TS_TYPEN);
 1959 }
 1960 
 1961 /*
 1962  * Process a read call on a tty device.
 1963  */
 1964 int
 1965 ttread(struct tty *tp, struct uio *uio, int flag)
 1966 {
 1967         struct clist    *qp;
 1968         u_char          *cc;
 1969         struct proc     *p;
 1970         int             c, first, error, has_stime, last_cc;
 1971         long            lflag, slp;
 1972         struct timeval  now, stime;
 1973 
 1974         if (uio->uio_resid == 0)
 1975                 return 0;
 1976 
 1977         stime.tv_usec = 0;      /* XXX gcc */
 1978         stime.tv_sec = 0;       /* XXX gcc */
 1979 
 1980         cc = tp->t_cc;
 1981         p = curproc;
 1982         error = 0;
 1983         has_stime = 0;
 1984         last_cc = 0;
 1985         slp = 0;
 1986 
 1987  loop:
 1988         mutex_spin_enter(&tty_lock);
 1989         lflag = tp->t_lflag;
 1990         /*
 1991          * take pending input first
 1992          */
 1993         if (ISSET(lflag, PENDIN))
 1994                 ttypend(tp);
 1995 
 1996         /*
 1997          * Hang process if it's in the background.
 1998          */
 1999         if (isbackground(p, tp)) {
 2000                 if (sigismasked(curlwp, SIGTTIN) ||
 2001                     p->p_lflag & PL_PPWAIT || p->p_pgrp->pg_jobc == 0) {
 2002                         mutex_spin_exit(&tty_lock);
 2003                         return (EIO);
 2004                 }
 2005                 mutex_spin_exit(&tty_lock);
 2006 
 2007                 mutex_enter(&proc_lock);
 2008                 pgsignal(p->p_pgrp, SIGTTIN, 1);
 2009                 mutex_exit(&proc_lock);
 2010 
 2011                 mutex_spin_enter(&tty_lock);
 2012                 error = ttypause(tp, hz);
 2013                 mutex_spin_exit(&tty_lock);
 2014                 if (error)
 2015                         return (error);
 2016                 goto loop;
 2017         }
 2018 
 2019         if (!ISSET(lflag, ICANON)) {
 2020                 int m = cc[VMIN];
 2021                 long t = cc[VTIME];
 2022 
 2023                 qp = &tp->t_rawq;
 2024                 /*
 2025                  * Check each of the four combinations.
 2026                  * (m > 0 && t == 0) is the normal read case.
 2027                  * It should be fairly efficient, so we check that and its
 2028                  * companion case (m == 0 && t == 0) first.
 2029                  * For the other two cases, we compute the target sleep time
 2030                  * into slp.
 2031                  */
 2032                 if (t == 0) {
 2033                         if (qp->c_cc < m)
 2034                                 goto sleep;
 2035                         goto read;
 2036                 }
 2037                 t *= hz;                /* time in deca-ticks */
 2038 /*
 2039  * Time difference in deca-ticks, split division to avoid numeric overflow.
 2040  * Ok for hz < ~200kHz
 2041  */
 2042 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 10 * hz + \
 2043                          ((t1).tv_usec - (t2).tv_usec) / 100 * hz / 1000)
 2044                 if (m > 0) {
 2045                         if (qp->c_cc <= 0)
 2046                                 goto sleep;
 2047                         if (qp->c_cc >= m)
 2048                                 goto read;
 2049                         if (!has_stime) {
 2050                                 /* first character, start timer */
 2051                                 has_stime = 1;
 2052                                 getmicrotime(&stime);
 2053                                 slp = t;
 2054                         } else if (qp->c_cc > last_cc) {
 2055                                 /* got a character, restart timer */
 2056                                 getmicrotime(&stime);
 2057                                 slp = t;
 2058                         } else {
 2059                                 /* nothing, check expiration */
 2060                                 getmicrotime(&now);
 2061                                 slp = t - diff(now, stime);
 2062                         }
 2063                 } else {        /* m == 0 */
 2064                         if (qp->c_cc > 0)
 2065                                 goto read;
 2066                         if (!has_stime) {
 2067                                 has_stime = 1;
 2068                                 getmicrotime(&stime);
 2069                                 slp = t;
 2070                         } else {
 2071                                 getmicrotime(&now);
 2072                                 slp = t - diff(now, stime);
 2073                         }
 2074                 }
 2075                 last_cc = qp->c_cc;
 2076 #undef diff
 2077                 if (slp > 0) {
 2078                         /*
 2079                          * Convert deca-ticks back to ticks.
 2080                          * Rounding down may make us wake up just short
 2081                          * of the target, so we round up.
 2082                          * Maybe we should do 'slp/10 + 1' because the
 2083                          * first tick maybe almost immediate.
 2084                          * However it is more useful for a program that sets
 2085                          * VTIME=10 to wakeup every second not every 1.01
 2086                          * seconds (if hz=100).
 2087                          */
 2088                         slp = (slp + 9)/ 10;
 2089                         goto sleep;
 2090                 }
 2091         } else if ((qp = &tp->t_canq)->c_cc <= 0) {
 2092                 int     carrier;
 2093 
 2094  sleep:
 2095                 /*
 2096                  * If there is no input, sleep on rawq
 2097                  * awaiting hardware receipt and notification.
 2098                  * If we have data, we don't need to check for carrier.
 2099                  */
 2100                 carrier = CONNECTED(tp);
 2101                 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
 2102                         mutex_spin_exit(&tty_lock);
 2103                         return (0);     /* EOF */
 2104                 }
 2105                 if (!has_stime || slp <= 0) {
 2106                         if (flag & IO_NDELAY) {
 2107                                 mutex_spin_exit(&tty_lock);
 2108                                 return (EWOULDBLOCK);
 2109                         }
 2110                 }
 2111                 error = ttysleep(tp, &tp->t_rawcv, true, slp);
 2112                 mutex_spin_exit(&tty_lock);
 2113                 /* VMIN == 0: any quantity read satisfies */
 2114                 if (cc[VMIN] == 0 && error == EWOULDBLOCK)
 2115                         return (0);
 2116                 if (error && error != EWOULDBLOCK)
 2117                         return (error);
 2118                 goto loop;
 2119         }
 2120  read:
 2121 
 2122         /*
 2123          * Input present, check for input mapping and processing.
 2124          */
 2125         first = 1;
 2126         while ((c = getc(qp)) >= 0) {
 2127                 /*
 2128                  * delayed suspend (^Y)
 2129                  */
 2130                 if (CCEQ(cc[VDSUSP], c) &&
 2131                     ISSET(lflag, IEXTEN|ISIG) == (IEXTEN|ISIG)) {
 2132                         ttysig(tp, TTYSIG_PG1, SIGTSTP);
 2133                         if (first) {
 2134                                 error = ttypause(tp, hz);
 2135                                 if (error)
 2136                                         break;
 2137                                 mutex_spin_exit(&tty_lock);
 2138                                 goto loop;
 2139                         }
 2140                         break;
 2141                 }
 2142                 /*
 2143                  * Interpret EOF only in canonical mode.
 2144                  */
 2145                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
 2146                         break;
 2147                 /*
 2148                  * Give user character.
 2149                  */
 2150                 mutex_spin_exit(&tty_lock);
 2151                 error = ureadc(c, uio);
 2152                 mutex_spin_enter(&tty_lock);
 2153                 if (error)
 2154                         break;
 2155                 if (uio->uio_resid == 0)
 2156                         break;
 2157                 /*
 2158                  * In canonical mode check for a "break character"
 2159                  * marking the end of a "line of input".
 2160                  */
 2161                 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
 2162                         break;
 2163                 first = 0;
 2164         }
 2165 
 2166         /*
 2167          * Look to unblock output now that (presumably)
 2168          * the input queue has gone down.
 2169          */
 2170         if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG / 5) {
 2171                 if (ISSET(tp->t_iflag, IXOFF) &&
 2172                     cc[VSTART] != _POSIX_VDISABLE &&
 2173                     putc(cc[VSTART], &tp->t_outq) == 0) {
 2174                         CLR(tp->t_state, TS_TBLOCK);
 2175                         ttstart(tp);
 2176                 }
 2177                 /* Try to unblock remote output via hardware flow control. */
 2178                 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
 2179                     (*tp->t_hwiflow)(tp, 0) != 0)
 2180                         CLR(tp->t_state, TS_TBLOCK);
 2181         }
 2182         mutex_spin_exit(&tty_lock);
 2183 
 2184         return (error);
 2185 }
 2186 
 2187 /*
 2188  * Check the output queue on tp for space for a kernel message (from uprintf
 2189  * or tprintf).  Allow some space over the normal hiwater mark so we don't
 2190  * lose messages due to normal flow control, but don't let the tty run amok.
 2191  * Sleeps here are not interruptible, but we return prematurely if new signals
 2192  * arrive.
 2193  * Call with tty lock held.
 2194  */
 2195 static int
 2196 ttycheckoutq_wlock(struct tty *tp, int wait)
 2197 {
 2198         int     hiwat, error;
 2199 
 2200         KASSERT(mutex_owned(&tty_lock));
 2201 
 2202         hiwat = tp->t_hiwat;
 2203         if (tp->t_outq.c_cc > hiwat + 200)
 2204                 while (tp->t_outq.c_cc > hiwat) {
 2205                         ttstart(tp);
 2206                         if (wait == 0)
 2207                                 return (0);
 2208                         error = ttysleep(tp, &tp->t_outcv, true, hz);
 2209                         if (error == EINTR)
 2210                                 wait = 0;
 2211                 }
 2212 
 2213         return (1);
 2214 }
 2215 
 2216 int
 2217 ttycheckoutq(struct tty *tp, int wait)
 2218 {
 2219         int     r;
 2220 
 2221         mutex_spin_enter(&tty_lock);
 2222         r = ttycheckoutq_wlock(tp, wait);
 2223         mutex_spin_exit(&tty_lock);
 2224 
 2225         return (r);
 2226 }
 2227 
 2228 /*
 2229  * Process a write call on a tty device.
 2230  */
 2231 int
 2232 ttwrite(struct tty *tp, struct uio *uio, int flag)
 2233 {
 2234         u_char          *cp;
 2235         struct proc     *p;
 2236         int             cc, ce, i, hiwat, error;
 2237         u_char          obuf[OBUFSIZ];
 2238 
 2239         cp = NULL;
 2240         hiwat = tp->t_hiwat;
 2241         error = 0;
 2242         cc = 0;
 2243  loop:
 2244         mutex_spin_enter(&tty_lock);
 2245         if (!CONNECTED(tp)) {
 2246                 if (ISSET(tp->t_state, TS_ISOPEN)) {
 2247                         mutex_spin_exit(&tty_lock);
 2248                         return (EIO);
 2249                 } else if (flag & IO_NDELAY) {
 2250                         mutex_spin_exit(&tty_lock);
 2251                         error = EWOULDBLOCK;
 2252                         goto out;
 2253                 } else {
 2254                         /* Sleep awaiting carrier. */
 2255                         error = ttysleep(tp, &tp->t_rawcv, true, 0);
 2256                         mutex_spin_exit(&tty_lock);
 2257                         if (error)
 2258                                 goto out;
 2259                         goto loop;
 2260                 }
 2261         }
 2262 
 2263         /*
 2264          * Hang the process if it's in the background.
 2265          */
 2266         p = curproc;
 2267         if (isbackground(p, tp) &&
 2268             ISSET(tp->t_lflag, TOSTOP) && (p->p_lflag & PL_PPWAIT) == 0 &&
 2269             !sigismasked(curlwp, SIGTTOU)) {
 2270                 if (p->p_pgrp->pg_jobc == 0) {
 2271                         error = EIO;
 2272                         mutex_spin_exit(&tty_lock);
 2273                         goto out;
 2274                 }
 2275                 mutex_spin_exit(&tty_lock);
 2276 
 2277                 mutex_enter(&proc_lock);
 2278                 pgsignal(p->p_pgrp, SIGTTOU, 1);
 2279                 mutex_exit(&proc_lock);
 2280 
 2281                 mutex_spin_enter(&tty_lock);
 2282                 error = ttypause(tp, hz);
 2283                 mutex_spin_exit(&tty_lock);
 2284                 if (error)
 2285                         goto out;
 2286                 goto loop;
 2287         }
 2288         mutex_spin_exit(&tty_lock);
 2289 
 2290         /*
 2291          * Process the user's data in at most OBUFSIZ chunks.  Perform any
 2292          * output translation.  Keep track of high water mark, sleep on
 2293          * overflow awaiting device aid in acquiring new space.
 2294          */
 2295         while (uio->uio_resid > 0 || cc > 0) {
 2296                 if (ISSET(tp->t_lflag, FLUSHO)) {
 2297                         uio->uio_resid = 0;
 2298                         return (0);
 2299                 }
 2300                 if (tp->t_outq.c_cc > hiwat)
 2301                         goto ovhiwat;
 2302                 /*
 2303                  * Grab a hunk of data from the user, unless we have some
 2304                  * leftover from last time.
 2305                  */
 2306                 if (cc == 0) {
 2307                         cc = uimin(uio->uio_resid, OBUFSIZ);
 2308                         cp = obuf;
 2309                         error = uiomove(cp, cc, uio);
 2310                         if (error) {
 2311                                 cc = 0;
 2312                                 goto out;
 2313                         }
 2314                 }
 2315                 /*
 2316                  * If nothing fancy need be done, grab those characters we
 2317                  * can handle without any of ttyoutput's processing and
 2318                  * just transfer them to the output q.  For those chars
 2319                  * which require special processing (as indicated by the
 2320                  * bits in char_type), call ttyoutput.  After processing
 2321                  * a hunk of data, look for FLUSHO so ^O's will take effect
 2322                  * immediately.
 2323                  */
 2324                 mutex_spin_enter(&tty_lock);
 2325                 while (cc > 0) {
 2326                         if (!ISSET(tp->t_oflag, OPOST))
 2327                                 ce = cc;
 2328                         else {
 2329                                 ce = cc - scanc((u_int)cc, cp, char_type,
 2330                                     CCLASSMASK);
 2331                                 /*
 2332                                  * If ce is zero, then we're processing
 2333                                  * a special character through ttyoutput.
 2334                                  */
 2335                                 if (ce == 0) {
 2336                                         tp->t_rocount = 0;
 2337                                         if (ttyoutput(*cp, tp) >= 0) {
 2338                                                 /* out of space */
 2339                                                 mutex_spin_exit(&tty_lock);
 2340                                                 goto overfull;
 2341                                         }
 2342                                         cp++;
 2343                                         cc--;
 2344                                         if (ISSET(tp->t_lflag, FLUSHO) ||
 2345                                             tp->t_outq.c_cc > hiwat) {
 2346                                                 mutex_spin_exit(&tty_lock);
 2347                                                 goto ovhiwat;
 2348                                         }
 2349                                         continue;
 2350                                 }
 2351                         }
 2352                         /*
 2353                          * A bunch of normal characters have been found.
 2354                          * Transfer them en masse to the output queue and
 2355                          * continue processing at the top of the loop.
 2356                          * If there are any further characters in this
 2357                          * <= OBUFSIZ chunk, the first should be a character
 2358                          * requiring special handling by ttyoutput.
 2359                          */
 2360                         tp->t_rocount = 0;
 2361                         i = b_to_q(cp, ce, &tp->t_outq);
 2362                         ce -= i;
 2363                         tp->t_column += ce;
 2364                         cp += ce, cc -= ce, tk_nout += ce;
 2365                         tp->t_outcc += ce;
 2366                         if (i > 0) {
 2367                                 /* out of space */
 2368                                 mutex_spin_exit(&tty_lock);
 2369                                 goto overfull;
 2370                         }
 2371                         if (ISSET(tp->t_lflag, FLUSHO) ||
 2372                             tp->t_outq.c_cc > hiwat)
 2373                                 break;
 2374                 }
 2375                 ttstart(tp);
 2376                 mutex_spin_exit(&tty_lock);
 2377         }
 2378 
 2379  out:
 2380         /*
 2381          * If cc is nonzero, we leave the uio structure inconsistent, as the
 2382          * offset and iov pointers have moved forward, but it doesn't matter
 2383          * (the call will either return short or restart with a new uio).
 2384          */
 2385         uio->uio_resid += cc;
 2386         return (error);
 2387 
 2388  overfull:
 2389         /*
 2390          * Since we are using ring buffers, if we can't insert any more into
 2391          * the output queue, we can assume the ring is full and that someone
 2392          * forgot to set the high water mark correctly.  We set it and then
 2393          * proceed as normal.
 2394          */
 2395         hiwat = tp->t_outq.c_cc - 1;
 2396 
 2397  ovhiwat:
 2398         mutex_spin_enter(&tty_lock);
 2399         ttstart(tp);
 2400         /*
 2401          * This can only occur if FLUSHO is set in t_lflag,
 2402          * or if ttstart/oproc is synchronous (or very fast).
 2403          */
 2404         if (tp->t_outq.c_cc <= hiwat) {
 2405                 mutex_spin_exit(&tty_lock);
 2406                 goto loop;
 2407         }
 2408         if (flag & IO_NDELAY) {
 2409                 mutex_spin_exit(&tty_lock);
 2410                 error = EWOULDBLOCK;
 2411                 goto out;
 2412         }
 2413         error = ttysleep(tp, &tp->t_outcv, true, 0);
 2414         mutex_spin_exit(&tty_lock);
 2415         if (error)
 2416                 goto out;
 2417         goto loop;
 2418 }
 2419 
 2420 /*
 2421  * Try to pull more output from the producer.  Return non-zero if
 2422  * there is output ready to be sent.
 2423  */
 2424 bool
 2425 ttypull(struct tty *tp)
 2426 {
 2427 
 2428         /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
 2429 
 2430         if (tp->t_outq.c_cc <= tp->t_lowat) {
 2431                 cv_broadcast(&tp->t_outcv);
 2432                 selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
 2433         }
 2434         return tp->t_outq.c_cc != 0;
 2435 }
 2436 
 2437 /*
 2438  * Rubout one character from the rawq of tp
 2439  * as cleanly as possible.
 2440  * Called with tty lock held.
 2441  */
 2442 void
 2443 ttyrub(int c, struct tty *tp)
 2444 {
 2445         u_char  *cp;
 2446         int     savecol, tabc;
 2447 
 2448         KASSERT(mutex_owned(&tty_lock));
 2449 
 2450         if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
 2451                 return;
 2452         CLR(tp->t_lflag, FLUSHO);
 2453         if (ISSET(tp->t_lflag, ECHOE)) {
 2454                 if (tp->t_rocount == 0) {
 2455                         /*
 2456                          * Screwed by ttwrite; retype
 2457                          */
 2458                         ttyretype(tp);
 2459                         return;
 2460                 }
 2461                 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
 2462                         ttyrubo(tp, 2);
 2463                 else {
 2464                         CLR(c, ~TTY_CHARMASK);
 2465                         switch (CCLASS(c)) {
 2466                         case ORDINARY:
 2467                                 ttyrubo(tp, 1);
 2468                                 break;
 2469                         case BACKSPACE:
 2470                         case CONTROL:
 2471                         case NEWLINE:
 2472                         case RETURN:
 2473                         case VTAB:
 2474                                 if (ISSET(tp->t_lflag, ECHOCTL))
 2475                                         ttyrubo(tp, 2);
 2476                                 break;
 2477                         case TAB:
 2478                                 if (tp->t_rocount < tp->t_rawq.c_cc) {
 2479                                         ttyretype(tp);
 2480                                         return;
 2481                                 }
 2482                                 savecol = tp->t_column;
 2483                                 SET(tp->t_state, TS_CNTTB);
 2484                                 SET(tp->t_lflag, FLUSHO);
 2485                                 tp->t_column = tp->t_rocol;
 2486                                 for (cp = firstc(&tp->t_rawq, &tabc); cp;
 2487                                     cp = nextc(&tp->t_rawq, cp, &tabc))
 2488                                         ttyecho(tabc, tp);
 2489                                 CLR(tp->t_lflag, FLUSHO);
 2490                                 CLR(tp->t_state, TS_CNTTB);
 2491 
 2492                                 /* savecol will now be length of the tab. */
 2493                                 savecol -= tp->t_column;
 2494                                 tp->t_column += savecol;
 2495                                 if (savecol > 8)
 2496                                         savecol = 8;    /* overflow screw */
 2497                                 while (--savecol >= 0)
 2498                                         (void)ttyoutput('\b', tp);
 2499                                 break;
 2500                         default:                        /* XXX */
 2501                                 (void)printf("ttyrub: would panic c = %d, "
 2502                                     "val = %d\n", c, CCLASS(c));
 2503                         }
 2504                 }
 2505         } else if (ISSET(tp->t_lflag, ECHOPRT)) {
 2506                 if (!ISSET(tp->t_state, TS_ERASE)) {
 2507                         SET(tp->t_state, TS_ERASE);
 2508                         (void)ttyoutput('\\', tp);
 2509                 }
 2510                 ttyecho(c, tp);
 2511         } else
 2512                 ttyecho(tp->t_cc[VERASE], tp);
 2513         --tp->t_rocount;
 2514 }
 2515 
 2516 /*
 2517  * Back over cnt characters, erasing them.
 2518  * Called with tty lock held.
 2519  */
 2520 static void
 2521 ttyrubo(struct tty *tp, int cnt)
 2522 {
 2523 
 2524         KASSERT(mutex_owned(&tty_lock));
 2525 
 2526         while (cnt-- > 0) {
 2527                 (void)ttyoutput('\b', tp);
 2528                 (void)ttyoutput(' ', tp);
 2529                 (void)ttyoutput('\b', tp);
 2530         }
 2531 }
 2532 
 2533 /*
 2534  * ttyretype --
 2535  *      Reprint the rawq line.  Note, it is assumed that c_cc has already
 2536  *      been checked.
 2537  *
 2538  * Called with tty lock held.
 2539  */
 2540 void
 2541 ttyretype(struct tty *tp)
 2542 {
 2543         u_char  *cp;
 2544         int     c;
 2545 
 2546         KASSERT(mutex_owned(&tty_lock));
 2547 
 2548         /* Echo the reprint character. */
 2549         if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
 2550                 ttyecho(tp->t_cc[VREPRINT], tp);
 2551 
 2552         (void)ttyoutput('\n', tp);
 2553 
 2554         for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
 2555                 ttyecho(c, tp);
 2556         for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
 2557                 ttyecho(c, tp);
 2558         CLR(tp->t_state, TS_ERASE);
 2559 
 2560         tp->t_rocount = tp->t_rawq.c_cc;
 2561         tp->t_rocol = 0;
 2562 }
 2563 
 2564 /*
 2565  * Echo a typed character to the terminal.
 2566  * Called with tty lock held.
 2567  */
 2568 static void
 2569 ttyecho(int c, struct tty *tp)
 2570 {
 2571 
 2572         KASSERT(mutex_owned(&tty_lock));
 2573 
 2574         if (!ISSET(tp->t_state, TS_CNTTB))
 2575                 CLR(tp->t_lflag, FLUSHO);
 2576         if ((!ISSET(tp->t_lflag, ECHO) &&
 2577             (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
 2578             ISSET(tp->t_lflag, EXTPROC))
 2579                 return;
 2580         if (((ISSET(tp->t_lflag, ECHOCTL) &&
 2581             (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
 2582             ISSET(c, TTY_CHARMASK) == 0177)) {
 2583                 (void)ttyoutput('^', tp);
 2584                 CLR(c, ~TTY_CHARMASK);
 2585                 if (c == 0177)
 2586                         c = '?';
 2587                 else
 2588                         c += 'A' - 1;
 2589         }
 2590         (void)ttyoutput(c, tp);
 2591 }
 2592 
 2593 /*
 2594  * Wake up any readers on a tty.
 2595  * Called with tty lock held.
 2596  */
 2597 void
 2598 ttwakeup(struct tty *tp)
 2599 {
 2600 
 2601         KASSERT(mutex_owned(&tty_lock));
 2602 
 2603         selnotify(&tp->t_rsel, 0, NOTE_SUBMIT);
 2604         if (ISSET(tp->t_state, TS_ASYNC))
 2605                 ttysig(tp, TTYSIG_PG2, SIGIO);
 2606         cv_broadcast(&tp->t_rawcv);
 2607 }
 2608 
 2609 /*
 2610  * Look up a code for a specified speed in a conversion table;
 2611  * used by drivers to map software speed values to hardware parameters.
 2612  */
 2613 int
 2614 ttspeedtab(int speed, const struct speedtab *table)
 2615 {
 2616 
 2617         for (; table->sp_speed != -1; table++)
 2618                 if (table->sp_speed == speed)
 2619                         return (table->sp_code);
 2620         return (-1);
 2621 }
 2622 
 2623 /*
 2624  * Set tty hi and low water marks.
 2625  *
 2626  * Try to arrange the dynamics so there's about one second
 2627  * from hi to low water.
 2628  */
 2629 void
 2630 ttsetwater(struct tty *tp)
 2631 {
 2632         int     cps, x;
 2633 
 2634         /* XXX not yet KASSERT(mutex_owned(&tty_lock)); */
 2635 
 2636 #define CLAMP(x, h, l)  ((x) > h ? h : ((x) < l) ? l : (x))
 2637 
 2638         cps = tp->t_ospeed / 10;
 2639         tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
 2640         x += cps;
 2641         x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
 2642         tp->t_hiwat = roundup(x, TTROUND);
 2643 #undef  CLAMP
 2644 }
 2645 
 2646 /*
 2647  * Prepare report on state of foreground process group.
 2648  * Call with &proc_lock held.
 2649  */
 2650 void
 2651 ttygetinfo(struct tty *tp, int fromsig, char *buf, size_t bufsz)
 2652 {
 2653         struct lwp      *l;
 2654         struct proc     *p, *pick = NULL;
 2655         struct timeval  utime, stime;
 2656         int             tmp;
 2657         fixpt_t         pctcpu = 0;
 2658         const char      *msg = NULL;
 2659         char            lmsg[100];
 2660         long            rss;
 2661         bool            again = false;
 2662 
 2663         KASSERT(mutex_owned(&proc_lock));
 2664 
 2665         *buf = '\0';
 2666 
 2667  retry:
 2668         if (tp->t_session == NULL)
 2669                 msg = "not a controlling terminal\n";
 2670         else if (tp->t_pgrp == NULL)
 2671                 msg = "no foreground process group\n";
 2672         else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL)
 2673                 msg = "empty foreground process group\n";
 2674         else {
 2675                 /* Pick interesting process. */
 2676                 for (; p != NULL; p = LIST_NEXT(p, p_pglist)) {
 2677                         struct proc *oldpick;
 2678 
 2679                         if (pick == NULL) {
 2680                                 pick = p;
 2681                                 continue;
 2682                         }
 2683                         if (pick->p_lock < p->p_lock) {
 2684                                 mutex_enter(pick->p_lock);
 2685                                 mutex_enter(p->p_lock);
 2686                         } else if (pick->p_lock > p->p_lock) {
 2687                                 mutex_enter(p->p_lock);
 2688                                 mutex_enter(pick->p_lock);
 2689                         } else
 2690                                 mutex_enter(p->p_lock);
 2691                         oldpick = pick;
 2692                         if (proc_compare_wrapper(pick, p))
 2693                                 pick = p;
 2694                         mutex_exit(p->p_lock);
 2695                         if (p->p_lock != oldpick->p_lock)
 2696                                 mutex_exit(oldpick->p_lock);
 2697                 }
 2698 
 2699                 if (pick != NULL) {
 2700                         mutex_enter(pick->p_lock);
 2701                         if (P_ZOMBIE(pick)) {
 2702                                 mutex_exit(pick->p_lock);
 2703                                 pick = NULL;
 2704                                 if (!again) {
 2705                                         again = true;
 2706                                         goto retry;
 2707                                 }
 2708                                 msg = "found only zombie processes\n";
 2709                         }
 2710                         if (pick && fromsig &&
 2711                             (SIGACTION_PS(pick->p_sigacts, SIGINFO).sa_flags &
 2712                             SA_NOKERNINFO)) {
 2713                                 mutex_exit(pick->p_lock);
 2714                                 return;
 2715                         }
 2716                 }
 2717         }
 2718 
 2719         /* Print load average. */
 2720         tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
 2721         snprintf(lmsg, sizeof(lmsg), "load: %d.%02d ", tmp / 100, tmp % 100);
 2722         strlcat(buf, lmsg, bufsz);
 2723 
 2724         if (pick == NULL) {
 2725                 strlcat(buf, msg, bufsz);
 2726                 return;
 2727         }
 2728 
 2729         snprintf(lmsg, sizeof(lmsg), " cmd: %s %d [", pick->p_comm,
 2730             pick->p_pid);
 2731         strlcat(buf, lmsg, bufsz);
 2732 
 2733         KASSERT(mutex_owned(pick->p_lock));
 2734         LIST_FOREACH(l, &pick->p_lwps, l_sibling) {
 2735                 const char *lp;
 2736                 lwp_lock(l);
 2737 #ifdef LWP_PC
 2738 #define FMT_RUN "%#"PRIxVADDR
 2739 #define VAL_RUNNING (vaddr_t)LWP_PC(l)
 2740 #define VAL_RUNNABLE (vaddr_t)LWP_PC(l)
 2741 #else
 2742 #define FMT_RUN "%s"
 2743 #define VAL_RUNNING "running"
 2744 #define VAL_RUNNABLE "runnable"
 2745 #endif
 2746                 switch (l->l_stat) {
 2747                 case LSONPROC:
 2748                         snprintf(lmsg, sizeof(lmsg), FMT_RUN"/%d", VAL_RUNNING,
 2749                             cpu_index(l->l_cpu));
 2750                         lp = lmsg;
 2751                         break;
 2752                 case LSRUN:
 2753                         snprintf(lmsg, sizeof(lmsg), FMT_RUN, VAL_RUNNABLE);
 2754                         lp = lmsg;
 2755                         break;
 2756                 default:
 2757                         lp = l->l_wchan ? l->l_wmesg : "iowait";
 2758                         break;
 2759                 }
 2760                 strlcat(buf, lp, bufsz);
 2761                 strlcat(buf, LIST_NEXT(l, l_sibling) != NULL ? " " : "] ",
 2762                     bufsz);
 2763                 pctcpu += l->l_pctcpu;
 2764                 lwp_unlock(l);
 2765         }
 2766         pctcpu += pick->p_pctcpu;
 2767         calcru(pick, &utime, &stime, NULL, NULL);
 2768         mutex_exit(pick->p_lock);
 2769 
 2770         /* Round up and print user+system time, %CPU and RSS. */
 2771         utime.tv_usec += 5000;
 2772         if (utime.tv_usec >= 1000000) {
 2773                 utime.tv_sec += 1;
 2774                 utime.tv_usec -= 1000000;
 2775         }
 2776         stime.tv_usec += 5000;
 2777         if (stime.tv_usec >= 1000000) {
 2778                 stime.tv_sec += 1;
 2779                 stime.tv_usec -= 1000000;
 2780         }
 2781 #define pgtok(a)        (((u_long) ((a) * PAGE_SIZE) / 1024))
 2782         tmp = (pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
 2783         if (pick->p_stat == SIDL || P_ZOMBIE(pick))
 2784                 rss = 0;
 2785         else
 2786                 rss = pgtok(vm_resident_count(pick->p_vmspace));
 2787 
 2788         snprintf(lmsg, sizeof(lmsg), "%ld.%02ldu %ld.%02lds %d%% %ldk",
 2789             (long)utime.tv_sec, (long)utime.tv_usec / 10000,
 2790             (long)stime.tv_sec, (long)stime.tv_usec / 10000,
 2791             tmp / 100, rss);
 2792         strlcat(buf, lmsg, bufsz);
 2793 }
 2794 
 2795 /*
 2796  * Print report on state of foreground process group.
 2797  * Call with tty_lock held.
 2798  */
 2799 void
 2800 ttyputinfo(struct tty *tp, char *buf)
 2801 {
 2802 
 2803         KASSERT(mutex_owned(&tty_lock));
 2804 
 2805         if (ttycheckoutq_wlock(tp, 0) == 0)
 2806                 return;
 2807         ttyprintf_nolock(tp, "%s\n", buf);
 2808         tp->t_rocount = 0;      /* so pending input will be retyped if BS */
 2809 }
 2810 
 2811 /*
 2812  * Returns 1 if p2 has a better chance being the active foreground process
 2813  * in a terminal instead of p1.
 2814  */
 2815 static int
 2816 proc_compare_wrapper(struct proc *p1, struct proc *p2)
 2817 {
 2818         lwp_t *l1, *l2;
 2819 
 2820         KASSERT(mutex_owned(p1->p_lock));
 2821         KASSERT(mutex_owned(p2->p_lock));
 2822 
 2823         l1 = LIST_FIRST(&p1->p_lwps);
 2824         l2 = LIST_FIRST(&p2->p_lwps);
 2825 
 2826         return proc_compare(p1, l1, p2, l2);
 2827 }
 2828 
 2829 /*
 2830  * Output char to tty; console putchar style.
 2831  * Can be called with tty lock held through kprintf() machinery..
 2832  */
 2833 int
 2834 tputchar(int c, int flags, struct tty *tp)
 2835 {
 2836         int r = 0;
 2837 
 2838         if ((flags & NOLOCK) == 0)
 2839                 mutex_spin_enter(&tty_lock);
 2840         if (!CONNECTED(tp)) {
 2841                 r = -1;
 2842                 goto out;
 2843         }
 2844         if (c == '\n')
 2845                 (void)ttyoutput('\r', tp);
 2846         (void)ttyoutput(c, tp);
 2847         ttstart(tp);
 2848 out:
 2849         if ((flags & NOLOCK) == 0)
 2850                 mutex_spin_exit(&tty_lock);
 2851         return (r);
 2852 }
 2853 
 2854 /*
 2855  * Sleep on chan, returning ERESTART if tty changed while we napped and
 2856  * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by
 2857  * cv_timedwait(_sig).
 2858  * If the tty is revoked, restarting a pending call will redo validation done
 2859  * at the start of the call.
 2860  *
 2861  * Must be called with the tty lock held.
 2862  */
 2863 int
 2864 ttysleep(struct tty *tp, kcondvar_t *cv, bool catch_p, int timo)
 2865 {
 2866         int     error;
 2867         short   gen;
 2868 
 2869         KASSERT(mutex_owned(&tty_lock));
 2870 
 2871         gen = tp->t_gen;
 2872         if (ISSET(tp->t_state, TS_CANCEL))
 2873                 error = ERESTART;
 2874         else if (cv == NULL)
 2875                 error = kpause("ttypause", catch_p, timo, &tty_lock);
 2876         else if (catch_p)
 2877                 error = cv_timedwait_sig(cv, &tty_lock, timo);
 2878         else
 2879                 error = cv_timedwait(cv, &tty_lock, timo);
 2880         if (error != 0)
 2881                 return (error);
 2882         return (tp->t_gen == gen ? 0 : ERESTART);
 2883 }
 2884 
 2885 int
 2886 ttypause(struct tty *tp, int timo)
 2887 {
 2888         int error;
 2889 
 2890         error = ttysleep(tp, NULL, true, timo);
 2891         if (error == EWOULDBLOCK)
 2892                 error = 0;
 2893         return error;
 2894 }
 2895 
 2896 /*
 2897  * Attach a tty to the tty list.
 2898  *
 2899  * This should be called ONLY once per real tty (including pty's).
 2900  * eg, on the sparc, the keyboard and mouse have struct tty's that are
 2901  * distinctly NOT usable as tty's, and thus should not be attached to
 2902  * the ttylist.  This is why this call is not done from tty_alloc().
 2903  *
 2904  * Device drivers should attach tty's at a similar time that they are
 2905  * allocated, or, for the case of statically allocated struct tty's
 2906  * either in the attach or (first) open routine.
 2907  */
 2908 void
 2909 tty_attach(struct tty *tp)
 2910 {
 2911 
 2912         mutex_spin_enter(&tty_lock);
 2913         TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
 2914         ++tty_count;
 2915         mutex_spin_exit(&tty_lock);
 2916 }
 2917 
 2918 /*
 2919  * Remove a tty from the tty list.
 2920  */
 2921 void
 2922 tty_detach(struct tty *tp)
 2923 {
 2924 
 2925         mutex_spin_enter(&tty_lock);
 2926         --tty_count;
 2927 #ifdef DIAGNOSTIC
 2928         if (tty_count < 0)
 2929                 panic("tty_detach: tty_count < 0");
 2930 #endif
 2931         TAILQ_REMOVE(&ttylist, tp, tty_link);
 2932         mutex_spin_exit(&tty_lock);
 2933 }
 2934 
 2935 /*
 2936  * Allocate a tty structure and its associated buffers.
 2937  */
 2938 struct tty *
 2939 tty_alloc(void)
 2940 {
 2941         struct tty *tp;
 2942         int i;
 2943 
 2944         tp = kmem_zalloc(sizeof(*tp), KM_SLEEP);
 2945         callout_init(&tp->t_rstrt_ch, 0);
 2946         callout_setfunc(&tp->t_rstrt_ch, ttrstrt, tp);
 2947         tp->t_qsize = tty_qsize;
 2948         clalloc(&tp->t_rawq, tp->t_qsize, 1);
 2949         cv_init(&tp->t_rawcv, "ttyraw");
 2950         cv_init(&tp->t_rawcvf, "ttyrawf");
 2951         clalloc(&tp->t_canq, tp->t_qsize, 1);
 2952         cv_init(&tp->t_cancv, "ttycan");
 2953         cv_init(&tp->t_cancvf, "ttycanf");
 2954         /* output queue doesn't need quoting */
 2955         clalloc(&tp->t_outq, tp->t_qsize, 0);
 2956         cv_init(&tp->t_outcv, "ttyout");
 2957         cv_init(&tp->t_outcvf, "ttyoutf");
 2958         /* Set default line discipline. */
 2959         tp->t_linesw = ttyldisc_default();
 2960         tp->t_dev = NODEV;
 2961         selinit(&tp->t_rsel);
 2962         selinit(&tp->t_wsel);
 2963         for (i = 0; i < TTYSIG_COUNT; i++)  {
 2964                 sigemptyset(&tp->t_sigs[i]);
 2965         }
 2966 
 2967         return tp;
 2968 }
 2969 
 2970 /*
 2971  * Free a tty structure and its buffers.
 2972  *
 2973  * Be sure to call tty_detach() for any tty that has been
 2974  * tty_attach()ed.
 2975  */
 2976 void
 2977 tty_free(struct tty *tp)
 2978 {
 2979         int i;
 2980 
 2981         mutex_enter(&proc_lock);
 2982         mutex_enter(&tty_lock);
 2983         for (i = 0; i < TTYSIG_COUNT; i++)
 2984                 sigemptyset(&tp->t_sigs[i]);
 2985         if (tp->t_sigcount != 0)
 2986                 TAILQ_REMOVE(&tty_sigqueue, tp, t_sigqueue);
 2987         mutex_exit(&tty_lock);
 2988         mutex_exit(&proc_lock);
 2989 
 2990         callout_halt(&tp->t_rstrt_ch, NULL);
 2991         callout_destroy(&tp->t_rstrt_ch);
 2992         ttyldisc_release(tp->t_linesw);
 2993         clfree(&tp->t_rawq);
 2994         clfree(&tp->t_canq);
 2995         clfree(&tp->t_outq);
 2996         cv_destroy(&tp->t_rawcv);
 2997         cv_destroy(&tp->t_rawcvf);
 2998         cv_destroy(&tp->t_cancv);
 2999         cv_destroy(&tp->t_cancvf);
 3000         cv_destroy(&tp->t_outcv);
 3001         cv_destroy(&tp->t_outcvf);
 3002         seldestroy(&tp->t_rsel);
 3003         seldestroy(&tp->t_wsel);
 3004         kmem_free(tp, sizeof(*tp));
 3005 }
 3006 
 3007 /*
 3008  * tty_unit: map dev_t to tty unit number, as with TTUNIT
 3009  *
 3010  * => defined as function for use with struct cdevsw::d_devtounit
 3011  * => not for drivers with different unit numbering, e.g. TTUNIT(d) >> 4
 3012  */
 3013 int
 3014 tty_unit(dev_t dev)
 3015 {
 3016         return TTUNIT(dev);
 3017 }
 3018 
 3019 /*
 3020  * ttyprintf_nolock: send a message to a specific tty, without locking.
 3021  *
 3022  * => should be used only by tty driver or anything that knows the
 3023  *    underlying tty will not be revoked(2)'d away.  [otherwise,
 3024  *    use tprintf]
 3025  */
 3026 static void
 3027 ttyprintf_nolock(struct tty *tp, const char *fmt, ...)
 3028 {
 3029         va_list ap;
 3030 
 3031         /* No mutex needed; going to process TTY. */
 3032         va_start(ap, fmt);
 3033         kprintf(fmt, TOTTY|NOLOCK, tp, NULL, ap);
 3034         va_end(ap);
 3035 }
 3036 
 3037 static int
 3038 tty_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
 3039     void *arg0, void *arg1, void *arg2, void *arg3)
 3040 {
 3041         struct tty *tty;
 3042         int result;
 3043 
 3044         result = KAUTH_RESULT_DEFER;
 3045 
 3046         if (action != KAUTH_DEVICE_TTY_OPEN)
 3047                 return result;
 3048 
 3049         tty = arg0;
 3050 
 3051         /* If it's not opened, we allow. */
 3052         if ((tty->t_state & TS_ISOPEN) == 0)
 3053                 result = KAUTH_RESULT_ALLOW;
 3054         else {
 3055                 /*
 3056                  * If it's opened, we can only allow if it's not exclusively
 3057                  * opened; otherwise, that's a privileged operation and we
 3058                  * let the secmodel handle it.
 3059                  */
 3060                 if ((tty->t_state & TS_XCLUDE) == 0)
 3061                         result = KAUTH_RESULT_ALLOW;
 3062         }
 3063 
 3064         return result;
 3065 }
 3066 
 3067 /*
 3068  * Initialize the tty subsystem.
 3069  */
 3070 void
 3071 tty_init(void)
 3072 {
 3073 
 3074         mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_VM);
 3075         mutex_init(&constty_lock, MUTEX_DEFAULT, IPL_NONE);
 3076         constty_psz = pserialize_create();
 3077         cv_init(&ttyref_cv, "ttyref");
 3078         tty_sigsih = softint_establish(SOFTINT_CLOCK, ttysigintr, NULL);
 3079         KASSERT(tty_sigsih != NULL);
 3080 
 3081         tty_listener = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
 3082             tty_listener_cb, NULL);
 3083 
 3084         sysctl_kern_tty_setup();
 3085 }
 3086 
 3087 /*
 3088  * Send a signal from a tty to its process group or session leader.
 3089  * Handoff to the target is deferred to a soft interrupt.
 3090  */
 3091 void
 3092 ttysig(struct tty *tp, enum ttysigtype st, int sig)
 3093 {
 3094         sigset_t *sp;
 3095 
 3096         /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
 3097 
 3098         sp = &tp->t_sigs[st];
 3099         if (sigismember(sp, sig))
 3100                 return;
 3101         sigaddset(sp, sig);
 3102         if (tp->t_sigcount++ == 0)
 3103                 TAILQ_INSERT_TAIL(&tty_sigqueue, tp, t_sigqueue);
 3104         softint_schedule(tty_sigsih);
 3105 }
 3106 
 3107 /*
 3108  * Deliver deferred signals from ttys.  Note that the process groups
 3109  * and sessions associated with the ttys may have changed from when
 3110  * the signal was originally sent, but in practice it should not matter.
 3111  * For signals produced as a result of a syscall, the soft interrupt
 3112  * will fire before the syscall returns to the user.
 3113  */
 3114 static void
 3115 ttysigintr(void *cookie)
 3116 {
 3117         struct tty *tp;
 3118         enum ttysigtype st;
 3119         struct pgrp *pgrp;
 3120         struct session *sess;
 3121         int sig, lflag;
 3122         char infobuf[200];
 3123 
 3124         mutex_enter(&proc_lock);
 3125         mutex_spin_enter(&tty_lock);
 3126         while ((tp = TAILQ_FIRST(&tty_sigqueue)) != NULL) {
 3127                 KASSERT(tp->t_sigcount > 0);
 3128                 for (st = TTYSIG_PG1; st < TTYSIG_COUNT; st++) {
 3129                         if ((sig = firstsig(&tp->t_sigs[st])) != 0)
 3130                                 break;
 3131                 }
 3132                 KASSERT(st < TTYSIG_COUNT);
 3133                 sigdelset(&tp->t_sigs[st], sig);
 3134                 if (--tp->t_sigcount == 0)
 3135                         TAILQ_REMOVE(&tty_sigqueue, tp, t_sigqueue);
 3136                 pgrp = tp->t_pgrp;
 3137                 sess = tp->t_session;
 3138                 lflag = tp->t_lflag;
 3139                 if (sig == SIGINFO) {
 3140                         if (ISSET(tp->t_state, TS_SIGINFO)) {
 3141                                 /* Via ioctl: ignore tty option. */
 3142                                 tp->t_state &= ~TS_SIGINFO;
 3143                                 lflag |= ISIG;
 3144                         }
 3145                         if (!ISSET(lflag, NOKERNINFO)) {
 3146                                 mutex_spin_exit(&tty_lock);
 3147                                 ttygetinfo(tp, 1, infobuf, sizeof(infobuf));
 3148                                 mutex_spin_enter(&tty_lock);
 3149                                 ttyputinfo(tp, infobuf);
 3150                         }
 3151                         if (!ISSET(lflag, ISIG))
 3152                                 continue;
 3153                 }
 3154                 mutex_spin_exit(&tty_lock);
 3155                 KASSERT(sig != 0);
 3156                 switch (st) {
 3157                 case TTYSIG_PG1:
 3158                         if (pgrp != NULL)
 3159                                 pgsignal(pgrp, sig, 1);
 3160                         break;
 3161                 case TTYSIG_PG2:
 3162                         if (pgrp != NULL)
 3163                                 pgsignal(pgrp, sig, sess != NULL);
 3164                         break;
 3165                 case TTYSIG_LEADER:
 3166                         if (sess != NULL && sess->s_leader != NULL)
 3167                                 psignal(sess->s_leader, sig);
 3168                         break;
 3169                 default:
 3170                         /* NOTREACHED */
 3171                         break;
 3172                 }
 3173                 mutex_spin_enter(&tty_lock);
 3174         }
 3175         mutex_spin_exit(&tty_lock);
 3176         mutex_exit(&proc_lock);
 3177 }
 3178 
 3179 unsigned char
 3180 tty_getctrlchar(struct tty *tp, unsigned which)
 3181 {
 3182         KASSERT(which < NCCS);
 3183         return tp->t_cc[which];
 3184 }
 3185 
 3186 void
 3187 tty_setctrlchar(struct tty *tp, unsigned which, unsigned char val)
 3188 {
 3189         KASSERT(which < NCCS);
 3190         tp->t_cc[which] = val;
 3191 }
 3192 
 3193 int
 3194 tty_try_xonxoff(struct tty *tp, unsigned char c)
 3195 {
 3196     const struct cdevsw *cdev;
 3197 
 3198     if (tp->t_iflag & IXON) {
 3199         if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
 3200             if ((tp->t_state & TS_TTSTOP) == 0) {
 3201                 tp->t_state |= TS_TTSTOP;
 3202                 cdev = cdevsw_lookup(tp->t_dev);
 3203                 if (cdev != NULL)
 3204                         (*cdev->d_stop)(tp, 0);
 3205             }
 3206             return 0;
 3207         }
 3208         if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
 3209             tp->t_state &= ~TS_TTSTOP;
 3210             if (tp->t_oproc != NULL) {
 3211                 mutex_spin_enter(&tty_lock);    /* XXX */
 3212                 (*tp->t_oproc)(tp);
 3213                 mutex_spin_exit(&tty_lock);     /* XXX */
 3214             }
 3215             return 0;
 3216         }
 3217     }
 3218     return EAGAIN;
 3219 }

Cache object: c57a65743f145c0a408ebe95914e1531


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