tty.c revision 98493
11541Srgrimes/*-
21541Srgrimes * Copyright (c) 1982, 1986, 1990, 1991, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes * (c) UNIX System Laboratories, Inc.
51541Srgrimes * All or some portions of this file are derived from material licensed
61541Srgrimes * to the University of California by American Telephone and Telegraph
71541Srgrimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with
81541Srgrimes * the permission of UNIX System Laboratories, Inc.
91541Srgrimes *
101541Srgrimes * Copyright (c) 2002 Networks Associates Technologies, Inc.
111541Srgrimes * All rights reserved.
121541Srgrimes *
131541Srgrimes * Portions of this software were developed for the FreeBSD Project by
141541Srgrimes * ThinkSec AS and NAI Labs, the Security Research Division of Network
151541Srgrimes * Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
161541Srgrimes * ("CBOSS"), as part of the DARPA CHATS research program.
171541Srgrimes *
181541Srgrimes * Redistribution and use in source and binary forms, with or without
191541Srgrimes * modification, are permitted provided that the following conditions
201541Srgrimes * are met:
211541Srgrimes * 1. Redistributions of source code must retain the above copyright
221541Srgrimes *    notice, this list of conditions and the following disclaimer.
231541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
241541Srgrimes *    notice, this list of conditions and the following disclaimer in the
251541Srgrimes *    documentation and/or other materials provided with the distribution.
261541Srgrimes * 3. All advertising materials mentioning features or use of this software
271541Srgrimes *    must display the following acknowledgement:
281541Srgrimes *	This product includes software developed by the University of
291541Srgrimes *	California, Berkeley and its contributors.
301541Srgrimes * 4. Neither the name of the University nor the names of its contributors
311541Srgrimes *    may be used to endorse or promote products derived from this software
321541Srgrimes *    without specific prior written permission.
331541Srgrimes *
3450477Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
351541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
361541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
371541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
381541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
391541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
401541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
411541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
421541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4332350Seivind * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4441793Sluigi * SUCH DAMAGE.
4532350Seivind *
461541Srgrimes *	@(#)tty.c	8.8 (Berkeley) 1/21/94
4712693Sphk * $FreeBSD: head/sys/kern/tty.c 98493 2002-06-20 14:03:36Z iedowse $
4844078Sdfr */
4912693Sphk
501541Srgrimes/*-
5112693Sphk * TODO:
521541Srgrimes *	o Fix races for sending the start char in ttyflush().
5318892Sbde *	o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
541541Srgrimes *	  With luck, there will be MIN chars before select() returns().
551541Srgrimes *	o Handle CLOCAL consistently for ptys.  Perhaps disallow setting it.
561541Srgrimes *	o Don't allow input in TS_ZOMBIE case.  It would be visible through
571541Srgrimes *	  FIONREAD.
5844165Sjulian *	o Do the new sio locking stuff here and use it to avoid special
591541Srgrimes *	  case for EXTPROC?
608426Swollman *	o Lock PENDIN too?
6158313Slile *	o Move EXTPROC and/or PENDIN to t_state?
6271963Sjulian *	o Wrap most of ttioctl in spltty/splx.
6371963Sjulian *	o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
6471963Sjulian *	o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
6571963Sjulian *	o Don't allow certain termios flags to affect disciplines other
661541Srgrimes *	  than TTYDISC.  Cancel their effects before switch disciplines
671541Srgrimes *	  and ignore them if they are set while we are in another
681541Srgrimes *	  discipline.
691541Srgrimes *	o Now that historical speed conversions are handled here, don't
701541Srgrimes *	  do them in drivers.
7184931Sfjoe *	o Check for TS_CARR_ON being set while everything is closed and not
7244627Sjulian *	  waiting for carrier.  TS_CARR_ON isn't cleared if nothing is open,
7344627Sjulian *	  so it would live until the next open even if carrier drops.
741541Srgrimes *	o Restore TS_WOPEN since it is useful in pstat.  It must be cleared
751541Srgrimes *	  only when _all_ openers leave open().
761541Srgrimes */
7744078Sdfr
7812942Swollman#include "opt_compat.h"
791541Srgrimes
8012693Sphk#include <sys/param.h>
8112942Swollman#include <sys/systm.h>
8212942Swollman#include <sys/filio.h>
8312942Swollman#include <sys/lock.h>
841541Srgrimes#include <sys/mutex.h>
8512942Swollman#include <sys/namei.h>
8612942Swollman#include <sys/sx.h>
8712942Swollman#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
8812942Swollman#include <sys/ioctl_compat.h>
8912942Swollman#endif
9012942Swollman#include <sys/proc.h>
9112693Sphk#define	TTYDEFCHARS
921541Srgrimes#include <sys/tty.h>
931541Srgrimes#undef	TTYDEFCHARS
9411225Swollman#include <sys/fcntl.h>
9560938Sjake#include <sys/conf.h>
9611225Swollman#include <sys/dkstat.h>
9711225Swollman#include <sys/poll.h>
9811225Swollman#include <sys/kernel.h>
9911225Swollman#include <sys/vnode.h>
10011225Swollman#include <sys/signalvar.h>
10112693Sphk#include <sys/resourcevar.h>
10260938Sjake#include <sys/malloc.h>
10311225Swollman#include <sys/filedesc.h>
10469152Sjlemon#include <sys/sysctl.h>
10512820Sphk
1061541Srgrimes#include <vm/vm.h>
10712693Sphk#include <vm/pmap.h>
10812942Swollman#include <vm/vm_map.h>
10912942Swollman
1103282SwollmanMALLOC_DEFINE(M_TTYS, "ttys", "tty data structures");
11112942Swollman
11212942Swollmanstatic int	proc_compare(struct proc *p1, struct proc *p2);
11312942Swollmanstatic int	ttnread(struct tty *tp);
11412942Swollmanstatic void	ttyecho(int c, struct tty *tp);
11512942Swollmanstatic int	ttyoutput(int c, struct tty *tp);
11612942Swollmanstatic void	ttypend(struct tty *tp);
11712693Sphkstatic void	ttyretype(struct tty *tp);
11892723Salfredstatic void	ttyrub(int c, struct tty *tp);
11992723Salfredstatic void	ttyrubo(struct tty *tp, int cnt);
12092723Salfredstatic void	ttyunblock(struct tty *tp);
12192723Salfredstatic int	ttywflush(struct tty *tp);
12292723Salfredstatic int	filt_ttyread(struct knote *kn, long hint);
12392723Salfredstatic void	filt_ttyrdetach(struct knote *kn);
12492723Salfredstatic int	filt_ttywrite(struct knote *kn, long hint);
12512693Sphkstatic void	filt_ttywdetach(struct knote *kn);
12692723Salfred
12732350Seivind/*
12892723Salfred * Table with character classes and parity. The 8th bit indicates parity,
12932350Seivind * the 7th bit indicates the character is an alphameric or underscore (for
13012693Sphk * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
1311541Srgrimes * are 0 then the character needs no special processing on output; classes
1321541Srgrimes * other than 0 might be translated or (not currently) require delays.
1331541Srgrimes */
1341541Srgrimes#define	E	0x00	/* Even parity. */
1351541Srgrimes#define	O	0x80	/* Odd parity. */
1361541Srgrimes#define	PARITY(c)	(char_type[c] & O)
1371541Srgrimes
1381541Srgrimes#define	ALPHA	0x40	/* Alpha or underscore. */
1391541Srgrimes#define	ISALPHA(c)	(char_type[(c) & TTY_CHARMASK] & ALPHA)
14071999Sphk
14111225Swollman#define	CCLASSMASK	0x3f
1421541Srgrimes#define	CCLASS(c)	(char_type[c] & CCLASSMASK)
1431541Srgrimes
14411225Swollman#define	BS	BACKSPACE
1451541Srgrimes#define	CC	CONTROL
14671999Sphk#define	CR	RETURN
14734961Sphk#define	NA	ORDINARY | ALPHA
14811225Swollman#define	NL	NEWLINE
1491541Srgrimes#define	NO	ORDINARY
1501541Srgrimes#define	TB	TAB
1511541Srgrimes#define	VT	VTAB
1521541Srgrimes
1531541Srgrimesstatic u_char const char_type[] = {
1541541Srgrimes	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC,	/* nul - bel */
1551541Srgrimes	O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
1565196Swollman	O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
15785074Sru	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
1581541Srgrimes	O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
1591541Srgrimes	E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
16085074Sru	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
1611541Srgrimes	O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
1621541Srgrimes	O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
1631541Srgrimes	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
1641541Srgrimes	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
16512693Sphk	O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
1661541Srgrimes	E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
1671541Srgrimes	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
1681541Srgrimes	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
16911225Swollman	E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
1701541Srgrimes	/*
17157178Speter	 * Meta chars; should be settable per character set;
1721541Srgrimes	 * for now, treat them all as normal characters.
1731541Srgrimes	 */
1741541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1751541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1761541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1771541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1781541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1791541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1801541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1811541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1821541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1831541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1841541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1851541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1861541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1871541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1881541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1891541Srgrimes	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
1901541Srgrimes};
1911541Srgrimes#undef	BS
1921541Srgrimes#undef	CC
1931541Srgrimes#undef	CR
1941541Srgrimes#undef	NA
19534961Sphk#undef	NL
1961541Srgrimes#undef	NO
1971541Srgrimes#undef	TB
1981541Srgrimes#undef	VT
1991541Srgrimes
20084931Sfjoe/* Macros to clear/set/test flags. */
20136908Sjulian#define	SET(t, f)	(t) |= (f)
20236908Sjulian#define	CLR(t, f)	(t) &= ~(f)
2031541Srgrimes#define	ISSET(t, f)	((t) & (f))
2041541Srgrimes
2051541Srgrimes#undef MAX_INPUT		/* XXX wrong in <sys/syslimits.h> */
2061541Srgrimes#define	MAX_INPUT	TTYHOG	/* XXX limit is usually larger for !ICANON */
2071541Srgrimes
2086568Sdg/*
2091541Srgrimes * list of struct tty where pstat(8) can pick it up with sysctl
2101541Srgrimes */
2111541Srgrimesstatic SLIST_HEAD(, tty) tty_list;
2121541Srgrimes
2131541Srgrimesstatic int  drainwait = 5*60;
2141541SrgrimesSYSCTL_INT(_kern, OID_AUTO, drainwait, CTLFLAG_RW, &drainwait,
2151541Srgrimes	0, "Output drain timeout in seconds");
2161541Srgrimes
2171541Srgrimes/*
2181541Srgrimes * Initial open of tty, or (re)entry to standard tty line discipline.
2191541Srgrimes */
2201541Srgrimesint
2211541Srgrimesttyopen(dev_t device, struct tty *tp)
2221541Srgrimes{
2231541Srgrimes	int s;
2241541Srgrimes
2251541Srgrimes	s = spltty();
2261541Srgrimes	tp->t_dev = device;
2271541Srgrimes	if (!ISSET(tp->t_state, TS_ISOPEN)) {
2281541Srgrimes		SET(tp->t_state, TS_ISOPEN);
22911225Swollman		if (ISSET(tp->t_cflag, CLOCAL))
23013926Swollman			SET(tp->t_state, TS_CONNECTED);
23132350Seivind		bzero(&tp->t_winsize, sizeof(tp->t_winsize));
23213926Swollman	}
23313926Swollman	/* XXX don't hang forever on output */
23413926Swollman	if (tp->t_timeout < 0)
23513926Swollman		tp->t_timeout = drainwait*hz;
23613926Swollman	ttsetwater(tp);
23787776Sjlemon	splx(s);
23887776Sjlemon	return (0);
23913926Swollman}
24013926Swollman
24113926Swollman/*
24216576Speter * Handle close() on a tty line: flush and set to initial state,
24313926Swollman * bumping generation number so that pending read/write calls
24413926Swollman * can detect recycling of the tty.
24584931Sfjoe * XXX our caller should have done `spltty(); l_close(); ttyclose();'
24684931Sfjoe * and l_close() should have flushed, but we repeat the spltty() and
24784931Sfjoe * the flush in case there are buggy callers.
24816576Speter */
24913926Swollmanint
25032350Seivindttyclose(struct tty *tp)
25113926Swollman{
2521541Srgrimes	int s;
2531541Srgrimes
2541541Srgrimes	funsetown(&tp->t_sigio);
2551541Srgrimes	s = spltty();
2561541Srgrimes	if (constty == tp)
2571541Srgrimes		constty = NULL;
2581541Srgrimes
2591541Srgrimes	ttyflush(tp, FREAD | FWRITE);
2601541Srgrimes	clist_free_cblocks(&tp->t_canq);
2611541Srgrimes	clist_free_cblocks(&tp->t_outq);
2621541Srgrimes	clist_free_cblocks(&tp->t_rawq);
2631541Srgrimes
2641541Srgrimes	tp->t_gen++;
26584931Sfjoe	tp->t_line = TTYDISC;
26684931Sfjoe	tp->t_pgrp = NULL;
2671541Srgrimes	tp->t_session = NULL;
2688090Spst	tp->t_state = 0;
2691541Srgrimes	splx(s);
2701541Srgrimes	return (0);
2711541Srgrimes}
2721541Srgrimes
2731541Srgrimes#define	FLUSHQ(q) {							\
2741541Srgrimes	if ((q)->c_cc)							\
2751541Srgrimes		ndflush(q, (q)->c_cc);					\
2761541Srgrimes}
27711225Swollman
2781541Srgrimes/* Is 'c' a line delimiter ("break" character)? */
2791541Srgrimes#define	TTBREAKC(c, lflag)							\
2801541Srgrimes	((c) == '\n' || (((c) == cc[VEOF] ||				\
2811541Srgrimes	  (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) &&	\
2821541Srgrimes	 (c) != _POSIX_VDISABLE))
2831541Srgrimes
2841541Srgrimes/*
2851541Srgrimes * Process input of a single character received on a tty.
2861541Srgrimes */
2871541Srgrimesint
2881541Srgrimesttyinput(int c, struct tty *tp)
2891541Srgrimes{
2901541Srgrimes	tcflag_t iflag, lflag;
2911541Srgrimes	cc_t *cc;
2921541Srgrimes	int i, err;
29384931Sfjoe
29484931Sfjoe	/*
29536908Sjulian	 * If input is pending take it first.
2961541Srgrimes	 */
2971541Srgrimes	lflag = tp->t_lflag;
2981541Srgrimes	if (ISSET(lflag, PENDIN))
2991541Srgrimes		ttypend(tp);
30084931Sfjoe	/*
30184931Sfjoe	 * Gather stats.
3021541Srgrimes	 */
30358313Slile	if (ISSET(lflag, ICANON)) {
30458313Slile		++tk_cancc;
30584931Sfjoe		++tp->t_cancc;
3061541Srgrimes	} else {
3071541Srgrimes		++tk_rawcc;
3081541Srgrimes		++tp->t_rawcc;
30944456Swpaul	}
31084931Sfjoe	++tk_nin;
31184931Sfjoe
31284931Sfjoe	/*
31384931Sfjoe	 * Block further input iff:
31484931Sfjoe	 * current input > threshold AND input is available to user program
31584931Sfjoe	 * AND input flow control is enabled and not yet invoked.
31684931Sfjoe	 * The 3 is slop for PARMRK.
31784931Sfjoe	 */
31884931Sfjoe	iflag = tp->t_iflag;
31984931Sfjoe	if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 &&
32084931Sfjoe	    (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
32184931Sfjoe	    (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
32284931Sfjoe	    !ISSET(tp->t_state, TS_TBLOCK))
32384931Sfjoe		ttyblock(tp);
32484931Sfjoe
32544627Sjulian	/* Handle exceptional conditions (break, parity, framing). */
32684931Sfjoe	cc = tp->t_cc;
32784931Sfjoe	err = (ISSET(c, TTY_ERRORMASK));
32884931Sfjoe	if (err) {
32984931Sfjoe		CLR(c, TTY_ERRORMASK);
33084931Sfjoe		if (ISSET(err, TTY_BI)) {
33184931Sfjoe			if (ISSET(iflag, IGNBRK))
33284931Sfjoe				return (0);
33358313Slile			if (ISSET(iflag, BRKINT)) {
33484931Sfjoe				ttyflush(tp, FREAD | FWRITE);
33544627Sjulian				if (tp->t_pgrp != NULL) {
33658313Slile					PGRP_LOCK(tp->t_pgrp);
33758313Slile					pgsignal(tp->t_pgrp, SIGINT, 1);
33858313Slile					PGRP_UNLOCK(tp->t_pgrp);
33984931Sfjoe				}
34084931Sfjoe				goto endcase;
34144627Sjulian			}
34251320Slile			if (ISSET(iflag, PARMRK))
34351320Slile				goto parmrk;
34451320Slile		} else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
34551320Slile			|| ISSET(err, TTY_FE)) {
34651320Slile			if (ISSET(iflag, IGNPAR))
34751320Slile				return (0);
34844627Sjulian			else if (ISSET(iflag, PARMRK)) {
34984931Sfjoeparmrk:
35084931Sfjoe				if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
35184931Sfjoe				    MAX_INPUT - 3)
35284931Sfjoe					goto input_overflow;
35384931Sfjoe				(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
35484931Sfjoe				(void)putc(0 | TTY_QUOTE, &tp->t_rawq);
35551320Slile				(void)putc(c | TTY_QUOTE, &tp->t_rawq);
35651320Slile				goto endcase;
35751320Slile			} else
35884931Sfjoe				c = 0;
35951320Slile		}
36084931Sfjoe	}
36184931Sfjoe
36251320Slile	if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
36344627Sjulian		CLR(c, 0x80);
36484931Sfjoe	if (!ISSET(lflag, EXTPROC)) {
36584931Sfjoe		/*
36684931Sfjoe		 * Check for literal nexting very first
36784931Sfjoe		 */
36884931Sfjoe		if (ISSET(tp->t_state, TS_LNCH)) {
36984931Sfjoe			SET(c, TTY_QUOTE);
37084931Sfjoe			CLR(tp->t_state, TS_LNCH);
37184931Sfjoe		}
37284931Sfjoe		/*
37384931Sfjoe		 * Scan for special characters.  This code
3741541Srgrimes		 * is really just a big case statement with
3751541Srgrimes		 * non-constant cases.  The bottom of the
37684931Sfjoe		 * case statement is labeled ``endcase'', so goto
3771541Srgrimes		 * it after a case match, or similar.
3781541Srgrimes		 */
3791541Srgrimes
3801541Srgrimes		/*
3811541Srgrimes		 * Control chars which aren't controlled
3821541Srgrimes		 * by ICANON, ISIG, or IXON.
3831541Srgrimes		 */
3841541Srgrimes		if (ISSET(lflag, IEXTEN)) {
3851541Srgrimes			if (CCEQ(cc[VLNEXT], c)) {
3861541Srgrimes				if (ISSET(lflag, ECHO)) {
3871541Srgrimes					if (ISSET(lflag, ECHOE)) {
3881541Srgrimes						(void)ttyoutput('^', tp);
3891541Srgrimes						(void)ttyoutput('\b', tp);
39084931Sfjoe					} else
39184931Sfjoe						ttyecho(c, tp);
3921541Srgrimes				}
3931541Srgrimes				SET(tp->t_state, TS_LNCH);
3941541Srgrimes				goto endcase;
3951541Srgrimes			}
3963514Swollman			if (CCEQ(cc[VDISCARD], c)) {
3971541Srgrimes				if (ISSET(lflag, FLUSHO))
39878295Sjlemon					CLR(tp->t_lflag, FLUSHO);
3991541Srgrimes				else {
4001541Srgrimes					ttyflush(tp, FWRITE);
4011541Srgrimes					ttyecho(c, tp);
40284931Sfjoe					if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
4031541Srgrimes						ttyretype(tp);
4041541Srgrimes					SET(tp->t_lflag, FLUSHO);
40584931Sfjoe				}
4061541Srgrimes				goto startoutput;
4071541Srgrimes			}
4081541Srgrimes		}
4091541Srgrimes		/*
4101541Srgrimes		 * Signals.
41142775Sfenner		 */
4123311Sphk		if (ISSET(lflag, ISIG)) {
4133311Sphk			if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
4141541Srgrimes				if (!ISSET(lflag, NOFLSH))
4151541Srgrimes					ttyflush(tp, FREAD | FWRITE);
4161541Srgrimes				ttyecho(c, tp);
41736308Sphk				if (tp->t_pgrp != NULL) {
41836308Sphk					PGRP_LOCK(tp->t_pgrp);
41936308Sphk					pgsignal(tp->t_pgrp,
4201541Srgrimes					    CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
4211541Srgrimes					PGRP_UNLOCK(tp->t_pgrp);
4221541Srgrimes				}
4231541Srgrimes				goto endcase;
4241541Srgrimes			}
4251541Srgrimes			if (CCEQ(cc[VSUSP], c)) {
4261541Srgrimes				if (!ISSET(lflag, NOFLSH))
4271541Srgrimes					ttyflush(tp, FREAD);
42834961Sphk				ttyecho(c, tp);
4291541Srgrimes				if (tp->t_pgrp != NULL) {
43016206Sbde					PGRP_LOCK(tp->t_pgrp);
4311541Srgrimes					pgsignal(tp->t_pgrp, SIGTSTP, 1);
4321541Srgrimes					PGRP_UNLOCK(tp->t_pgrp);
4331541Srgrimes				}
43478295Sjlemon				goto endcase;
43578295Sjlemon			}
43678295Sjlemon		}
43778295Sjlemon		/*
43878295Sjlemon		 * Handle start/stop characters.
43987410Sru		 */
44087410Sru		if (ISSET(iflag, IXON)) {
44178295Sjlemon			if (CCEQ(cc[VSTOP], c)) {
44287410Sru				if (!ISSET(tp->t_state, TS_TTSTOP)) {
44378295Sjlemon					SET(tp->t_state, TS_TTSTOP);
4441541Srgrimes					(*tp->t_stop)(tp, 0);
4451541Srgrimes					return (0);
4461541Srgrimes				}
4471541Srgrimes				if (!CCEQ(cc[VSTART], c))
4481541Srgrimes					return (0);
4491541Srgrimes				/*
4501541Srgrimes				 * if VSTART == VSTOP then toggle
4511541Srgrimes				 */
4521541Srgrimes				goto endcase;
45334961Sphk			}
45434961Sphk			if (CCEQ(cc[VSTART], c))
4551541Srgrimes				goto restartoutput;
45684931Sfjoe		}
45736908Sjulian		/*
45884931Sfjoe		 * IGNCR, ICRNL, & INLCR
45984931Sfjoe		 */
4601541Srgrimes		if (c == '\r') {
4611541Srgrimes			if (ISSET(iflag, IGNCR))
4621541Srgrimes				return (0);
4631541Srgrimes			else if (ISSET(iflag, ICRNL))
4641541Srgrimes				c = '\n';
4651541Srgrimes		} else if (c == '\n' && ISSET(iflag, INLCR))
4661541Srgrimes			c = '\r';
4671541Srgrimes	}
4681541Srgrimes	if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
4691541Srgrimes		/*
4701541Srgrimes		 * From here on down canonical mode character
4711541Srgrimes		 * processing takes place.
4721541Srgrimes		 */
4731541Srgrimes		/*
4741541Srgrimes		 * erase or erase2 (^H / ^?)
47512693Sphk		 */
47631884Sbde		if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c) ) {
4771541Srgrimes			if (tp->t_rawq.c_cc)
47859143Swes				ttyrub(unputc(&tp->t_rawq), tp);
4791541Srgrimes			goto endcase;
48059143Swes		}
4811541Srgrimes		/*
4821541Srgrimes		 * kill (^U)
4831541Srgrimes		 */
4841541Srgrimes		if (CCEQ(cc[VKILL], c)) {
4851541Srgrimes			if (ISSET(lflag, ECHOKE) &&
4861541Srgrimes			    tp->t_rawq.c_cc == tp->t_rocount &&
4871541Srgrimes			    !ISSET(lflag, ECHOPRT))
48857900Srwatson				while (tp->t_rawq.c_cc)
48957900Srwatson					ttyrub(unputc(&tp->t_rawq), tp);
49058499Sdillon			else {
49158758Sjoerg				ttyecho(c, tp);
49257900Srwatson				if (ISSET(lflag, ECHOK) ||
49357900Srwatson				    ISSET(lflag, ECHOKE))
49457900Srwatson					ttyecho('\n', tp);
4951541Srgrimes				FLUSHQ(&tp->t_rawq);
49657900Srwatson				tp->t_rocount = 0;
49784931Sfjoe			}
49884931Sfjoe			CLR(tp->t_state, TS_LOCAL);
49957900Srwatson			goto endcase;
50058758Sjoerg		}
50157900Srwatson		/*
50257900Srwatson		 * word erase (^W)
50357900Srwatson		 */
50457900Srwatson		if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
5051541Srgrimes			int ctype;
50684931Sfjoe
50784931Sfjoe			/*
50858770Sjoerg			 * erase whitespace
50957900Srwatson			 */
51057900Srwatson			while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
51157900Srwatson				ttyrub(c, tp);
51257900Srwatson			if (c == -1)
51357900Srwatson				goto endcase;
51432350Seivind			/*
51557900Srwatson			 * erase last char of word and remember the
51657900Srwatson			 * next chars type (for ALTWERASE)
51757900Srwatson			 */
51832350Seivind			ttyrub(c, tp);
51957900Srwatson			c = unputc(&tp->t_rawq);
5201541Srgrimes			if (c == -1)
5211541Srgrimes				goto endcase;
5221541Srgrimes			if (c == ' ' || c == '\t') {
5231541Srgrimes				(void)putc(c, &tp->t_rawq);
52432350Seivind				goto endcase;
5251541Srgrimes			}
5261541Srgrimes			ctype = ISALPHA(c);
5271541Srgrimes			/*
5281541Srgrimes			 * erase rest of word
5291541Srgrimes			 */
5301541Srgrimes			do {
5311541Srgrimes				ttyrub(c, tp);
5321541Srgrimes				c = unputc(&tp->t_rawq);
5331541Srgrimes				if (c == -1)
5341541Srgrimes					goto endcase;
5351541Srgrimes			} while (c != ' ' && c != '\t' &&
5361541Srgrimes			    (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
5371541Srgrimes			(void)putc(c, &tp->t_rawq);
5381541Srgrimes			goto endcase;
53970699Salfred		}
54082893Salfred		/*
54170699Salfred		 * reprint line (^R)
54270699Salfred		 */
54370699Salfred		if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
54470699Salfred			ttyretype(tp);
54582893Salfred			goto endcase;
54682893Salfred		}
54782966Salfred		/*
54870699Salfred		 * ^T - kernel info and generate SIGINFO
54982893Salfred		 */
5501541Srgrimes		if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
5511541Srgrimes			if (ISSET(lflag, ISIG) && tp->t_pgrp != NULL) {
5521541Srgrimes				PGRP_LOCK(tp->t_pgrp);
5531541Srgrimes				pgsignal(tp->t_pgrp, SIGINFO, 1);
55484931Sfjoe				PGRP_UNLOCK(tp->t_pgrp);
55584931Sfjoe			}
5561541Srgrimes			if (!ISSET(lflag, NOKERNINFO))
55784931Sfjoe				ttyinfo(tp);
55844627Sjulian			goto endcase;
5591541Srgrimes		}
5601541Srgrimes	}
56184102Sjlemon	/*
56284102Sjlemon	 * Check for input buffer overflow
5631541Srgrimes	 */
5641541Srgrimes	if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
5651541Srgrimesinput_overflow:
56658313Slile		if (ISSET(iflag, IMAXBEL)) {
56784931Sfjoe			if (tp->t_outq.c_cc < tp->t_ohiwat)
5681541Srgrimes				(void)ttyoutput(CTRL('g'), tp);
56984931Sfjoe		}
57084931Sfjoe		goto endcase;
57174851Syar	}
57274851Syar
57374851Syar	if (   c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
57474851Syar	     && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
57584931Sfjoe		(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
57684931Sfjoe
57784931Sfjoe	/*
57884931Sfjoe	 * Put data char in q for user and
57972056Sjulian	 * wakeup on seeing a line delimiter.
58072056Sjulian	 */
58171963Sjulian	if (putc(c, &tp->t_rawq) >= 0) {
58272056Sjulian		if (!ISSET(lflag, ICANON)) {
58341793Sluigi			ttwakeup(tp);
58484102Sjlemon			ttyecho(c, tp);
58584102Sjlemon			goto endcase;
58684102Sjlemon		}
58784102Sjlemon		if (TTBREAKC(c, lflag)) {
58884102Sjlemon			tp->t_rocount = 0;
58984102Sjlemon			catq(&tp->t_rawq, &tp->t_canq);
59084931Sfjoe			ttwakeup(tp);
59184102Sjlemon		} else if (tp->t_rocount++ == 0)
59284102Sjlemon			tp->t_rocol = tp->t_column;
59384102Sjlemon		if (ISSET(tp->t_state, TS_ERASE)) {
59484931Sfjoe			/*
59584102Sjlemon			 * end of prterase \.../
59684102Sjlemon			 */
59784102Sjlemon			CLR(tp->t_state, TS_ERASE);
59885223Sjlemon			(void)ttyoutput('/', tp);
59984102Sjlemon		}
60084102Sjlemon		i = tp->t_column;
60185223Sjlemon		ttyecho(c, tp);
60285466Sjlemon		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
60385466Sjlemon			/*
60485466Sjlemon			 * Place the cursor over the '^' of the ^D.
60585466Sjlemon			 */
60685466Sjlemon			i = imin(2, tp->t_column - i);
60785466Sjlemon			while (i > 0) {
60885466Sjlemon				(void)ttyoutput('\b', tp);
60985466Sjlemon				i--;
61085466Sjlemon			}
61112693Sphk		}
61212693Sphk	}
61312693Sphkendcase:
61484102Sjlemon	/*
61584102Sjlemon	 * IXANY means allow any character to restart output.
61684931Sfjoe	 */
61712693Sphk	if (ISSET(tp->t_state, TS_TTSTOP) &&
61812693Sphk	    !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
61912693Sphk		return (0);
62084931Sfjoerestartoutput:
6211541Srgrimes	CLR(tp->t_lflag, FLUSHO);
62284931Sfjoe	CLR(tp->t_state, TS_TTSTOP);
6237088Swollmanstartoutput:
62412693Sphk	return (ttstart(tp));
62512693Sphk}
6261541Srgrimes
6271541Srgrimes/*
6281541Srgrimes * Output a single character on a tty, doing output processing
62984931Sfjoe * as needed (expanding tabs, newline processing, etc.).
63084931Sfjoe * Returns < 0 if succeeds, otherwise returns char to resend.
63184931Sfjoe * Must be recursive.
6321541Srgrimes */
6331541Srgrimesstatic int
6341541Srgrimesttyoutput(int c, struct tty *tp)
6351541Srgrimes{
6361541Srgrimes	tcflag_t oflag;
63772270Sluigi	int col, s;
63884931Sfjoe
63972270Sluigi	oflag = tp->t_oflag;
64084931Sfjoe	if (!ISSET(oflag, OPOST)) {
64171963Sjulian		if (ISSET(tp->t_lflag, FLUSHO))
64271963Sjulian			return (-1);
64384931Sfjoe		if (putc(c, &tp->t_outq))
64484931Sfjoe			return (c);
64572270Sluigi		tk_nout++;
64639389Sfenner		tp->t_outcc++;
6471541Srgrimes		return (-1);
64884931Sfjoe	}
64982893Salfred	/*
65082893Salfred	 * Do tab expansion if OXTABS is set.  Special case if we external
65184931Sfjoe	 * processing, we don't do the tab expansion because we'll probably
65284931Sfjoe	 * get it wrong.  If tab expansion needs to be done, let it happen
65384931Sfjoe	 * externally.
65484931Sfjoe	 */
65584931Sfjoe	CLR(c, ~TTY_CHARMASK);
65682893Salfred	if (c == '\t' &&
65739389Sfenner	    ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
65884931Sfjoe		c = 8 - (tp->t_column & 7);
65984931Sfjoe		if (!ISSET(tp->t_lflag, FLUSHO)) {
66084931Sfjoe			s = spltty();		/* Don't interrupt tabs. */
66139389Sfenner			c -= b_to_q("        ", c, &tp->t_outq);
66239389Sfenner			tk_nout += c;
66346568Speter			tp->t_outcc += c;
66484931Sfjoe			splx(s);
66584931Sfjoe		}
66684931Sfjoe		tp->t_column += c;
66784931Sfjoe		return (c ? -1 : '\t');
66884931Sfjoe	}
66984931Sfjoe	if (c == CEOT && ISSET(oflag, ONOEOT))
67084931Sfjoe		return (-1);
67184931Sfjoe
67284931Sfjoe	/*
67384931Sfjoe	 * Newline translation: if ONLCR is set,
67484931Sfjoe	 * translate newline into "\r\n".
67584931Sfjoe	 */
67684931Sfjoe	if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
67784931Sfjoe		tk_nout++;
67884931Sfjoe		tp->t_outcc++;
67984931Sfjoe		if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
68084931Sfjoe			return (c);
68184931Sfjoe	}
68284931Sfjoe	/* If OCRNL is set, translate "\r" into "\n". */
68384931Sfjoe	else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
68484931Sfjoe		c = '\n';
68558313Slile	/* If ONOCR is set, don't transmit CRs when on column 0. */
68645705Seivind	else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0)
68745705Seivind		return (-1);
68845705Seivind
68945705Seivind	tk_nout++;
69045705Seivind	tp->t_outcc++;
69184931Sfjoe	if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
69244627Sjulian		return (c);
69358313Slile
69458313Slile	col = tp->t_column;
69558313Slile	switch (CCLASS(c)) {
69658313Slile	case BACKSPACE:
69758313Slile		if (col > 0)
69858313Slile			--col;
69958313Slile		break;
70051320Slile	case CONTROL:
70151320Slile		break;
70251320Slile	case NEWLINE:
70351320Slile		if (ISSET(tp->t_oflag, ONLCR | ONLRET))
70458313Slile			col = 0;
70558313Slile		break;
70658313Slile	case RETURN:
70744627Sjulian		col = 0;
70858313Slile		break;
70944627Sjulian	case ORDINARY:
71050512Slile		++col;
71150512Slile		break;
71250512Slile	case TAB:
71344627Sjulian		col = (col + 8) & ~7;
71445705Seivind		break;
71558313Slile	}
71644627Sjulian	tp->t_column = col;
7171541Srgrimes	return (-1);
71834961Sphk}
7191541Srgrimes
7201541Srgrimes/*
7211541Srgrimes * Ioctls for all tty devices.  Called after line-discipline specific ioctl
72284931Sfjoe * has been called to do discipline-specific functions and/or reject any
7231541Srgrimes * of these ioctl commands.
7241541Srgrimes */
7251541Srgrimes/* ARGSUSED */
7261541Srgrimesint
7271541Srgrimesttioctl(struct tty *tp, u_long cmd, void *data, int flag)
7281541Srgrimes{
7291541Srgrimes	struct proc *p;
7301541Srgrimes	struct thread *td;
7311541Srgrimes	struct pgrp *pgrp;
7321541Srgrimes	int s, error;
7331541Srgrimes
73484931Sfjoe	td = curthread;			/* XXX */
73584931Sfjoe	p = td->td_proc;
7361541Srgrimes
7371541Srgrimes	/* If the ioctl involves modification, hang if in the background. */
7383282Swollman	switch (cmd) {
7393282Swollman	case  TIOCCBRK:
7403282Swollman	case  TIOCCONS:
74112693Sphk	case  TIOCDRAIN:
74212693Sphk	case  TIOCEXCL:
74312693Sphk	case  TIOCFLUSH:
74412693Sphk#ifdef TIOCHPCL
7453282Swollman	case  TIOCHPCL:
7463282Swollman#endif
7473282Swollman	case  TIOCNXCL:
7483282Swollman	case  TIOCSBRK:
7493282Swollman	case  TIOCSCTTY:
7503282Swollman	case  TIOCSDRAINWAIT:
7515101Swollman	case  TIOCSETA:
75212693Sphk	case  TIOCSETAF:
75312693Sphk	case  TIOCSETAW:
75412693Sphk	case  TIOCSETD:
75512693Sphk	case  TIOCSPGRP:
7563282Swollman	case  TIOCSTART:
7573282Swollman	case  TIOCSTAT:
7583282Swollman	case  TIOCSTI:
7593282Swollman	case  TIOCSTOP:
7603282Swollman	case  TIOCSWINSZ:
76184931Sfjoe#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
7623282Swollman	case  TIOCLBIC:
76312693Sphk	case  TIOCLBIS:
76412693Sphk	case  TIOCLSET:
7653282Swollman	case  TIOCSETC:
76684931Sfjoe	case OTIOCSETD:
76784931Sfjoe	case  TIOCSETN:
7683282Swollman	case  TIOCSETP:
76963080Sdwmalone	case  TIOCSLTC:
77063080Sdwmalone#endif
77163080Sdwmalone		sx_slock(&proctree_lock);
77263080Sdwmalone		PROC_LOCK(p);
77363080Sdwmalone		while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
77463080Sdwmalone		    !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
77563080Sdwmalone		    !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
77663080Sdwmalone			pgrp = p->p_pgrp;
77763080Sdwmalone			PROC_UNLOCK(p);
77863080Sdwmalone			if (pgrp->pg_jobc == 0) {
77963080Sdwmalone				sx_sunlock(&proctree_lock);
78063080Sdwmalone				return (EIO);
78163080Sdwmalone			}
78263080Sdwmalone			PGRP_LOCK(pgrp);
78384931Sfjoe			sx_sunlock(&proctree_lock);
78463080Sdwmalone			pgsignal(pgrp, SIGTTOU, 1);
78563080Sdwmalone			PGRP_UNLOCK(pgrp);
78684931Sfjoe			error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1",
78784931Sfjoe					 0);
78863080Sdwmalone			if (error)
78963080Sdwmalone				return (error);
79063080Sdwmalone			sx_slock(&proctree_lock);
79163080Sdwmalone			PROC_LOCK(p);
79263080Sdwmalone		}
79363080Sdwmalone		PROC_UNLOCK(p);
79463080Sdwmalone		sx_sunlock(&proctree_lock);
7954069Swollman		break;
7968876Srgrimes	}
7977088Swollman
7984069Swollman	switch (cmd) {			/* Process the ioctl. */
7993282Swollman	case FIOASYNC:			/* set/clear async i/o */
8003282Swollman		s = spltty();
80184931Sfjoe		if (*(int *)data)
8023282Swollman			SET(tp->t_state, TS_ASYNC);
80384931Sfjoe		else
8043282Swollman			CLR(tp->t_state, TS_ASYNC);
8051541Srgrimes		splx(s);
8061541Srgrimes		break;
80784931Sfjoe	case FIONBIO:			/* set/clear non-blocking i/o */
80884931Sfjoe		break;			/* XXX: delete. */
80984931Sfjoe	case FIONREAD:			/* get # bytes to read */
81084931Sfjoe		s = spltty();
81184931Sfjoe		*(int *)data = ttnread(tp);
81284931Sfjoe		splx(s);
81384931Sfjoe		break;
81484931Sfjoe
81584931Sfjoe	case FIOSETOWN:
81684931Sfjoe		/*
81784931Sfjoe		 * Policy -- Don't allow FIOSETOWN on someone else's
81845705Seivind		 *           controlling tty
81944627Sjulian		 */
82051320Slile		if (tp->t_session != NULL && !isctty(p, tp))
82151320Slile			return (ENOTTY);
82284931Sfjoe
82351320Slile		error = fsetown(*(int *)data, &tp->t_sigio);
82444627Sjulian		if (error)
82558313Slile			return (error);
82658313Slile		break;
82758313Slile	case FIOGETOWN:
82858313Slile		if (tp->t_session != NULL && !isctty(p, tp))
82944627Sjulian			return (ENOTTY);
83044627Sjulian		*(int *)data = fgetown(tp->t_sigio);
83151320Slile		break;
83251320Slile
83358313Slile	case TIOCEXCL:			/* set exclusive use of tty */
83458313Slile		s = spltty();
83544627Sjulian		SET(tp->t_state, TS_XCLUDE);
83645705Seivind		splx(s);
83751320Slile		break;
83851320Slile	case TIOCFLUSH: {		/* flush buffers */
83951320Slile		int flags = *(int *)data;
84051320Slile
84151320Slile		if (flags == 0)
84251320Slile			flags = FREAD | FWRITE;
84344627Sjulian		else
84484931Sfjoe			flags &= FREAD | FWRITE;
84551320Slile		ttyflush(tp, flags);
84644627Sjulian		break;
84744627Sjulian	}
84844627Sjulian	case TIOCCONS:			/* become virtual console */
8491541Srgrimes		if (*(int *)data) {
8501541Srgrimes			struct nameidata nid;
85184931Sfjoe
8521541Srgrimes			if (constty && constty != tp &&
8531541Srgrimes			    ISSET(constty->t_state, TS_CONNECTED))
85432350Seivind				return (EBUSY);
8551541Srgrimes
8561541Srgrimes			/* Ensure user can open the real console. */
8571541Srgrimes			NDINIT(&nid, LOOKUP, LOCKLEAF | FOLLOW, UIO_SYSSPACE,
8581541Srgrimes			    "/dev/console", td);
8591541Srgrimes			if ((error = namei(&nid)) != 0)
8601541Srgrimes				return (error);
8611541Srgrimes			NDFREE(&nid, NDF_ONLY_PNBUF);
8621541Srgrimes			error = VOP_ACCESS(nid.ni_vp, VREAD, td->td_ucred, td);
8631541Srgrimes			vput(nid.ni_vp);
8641541Srgrimes			if (error)
8651541Srgrimes				return (error);
8661541Srgrimes
8671541Srgrimes			constty = tp;
8681541Srgrimes		} else if (tp == constty)
8691541Srgrimes			constty = NULL;
8701541Srgrimes		break;
8711541Srgrimes	case TIOCDRAIN:			/* wait till output drained */
8721541Srgrimes		error = ttywait(tp);
8731541Srgrimes		if (error)
8741541Srgrimes			return (error);
8751541Srgrimes		break;
8761541Srgrimes	case TIOCGETA: {		/* get termios struct */
8771541Srgrimes		struct termios *t = (struct termios *)data;
8781541Srgrimes
8791541Srgrimes		bcopy(&tp->t_termios, t, sizeof(struct termios));
8801541Srgrimes		break;
8811541Srgrimes	}
8821541Srgrimes	case TIOCGETD:			/* get line discipline */
8831541Srgrimes		*(int *)data = tp->t_line;
8841541Srgrimes		break;
8851541Srgrimes	case TIOCGWINSZ:		/* get window size */
8861541Srgrimes		*(struct winsize *)data = tp->t_winsize;
8874069Swollman		break;
8881541Srgrimes	case TIOCGPGRP:			/* get pgrp of tty */
8891541Srgrimes		if (!isctty(p, tp))
8901541Srgrimes			return (ENOTTY);
8915101Swollman		*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
8921541Srgrimes		break;
8931541Srgrimes#ifdef TIOCHPCL
8941541Srgrimes	case TIOCHPCL:			/* hang up on last close */
8954069Swollman		s = spltty();
89612693Sphk		SET(tp->t_cflag, HUPCL);
8974069Swollman		splx(s);
89812693Sphk		break;
8994069Swollman#endif
90012693Sphk	case TIOCNXCL:			/* reset exclusive use of tty */
9014069Swollman		s = spltty();
9024069Swollman		CLR(tp->t_state, TS_XCLUDE);
90312693Sphk		splx(s);
9044069Swollman		break;
9057088Swollman	case TIOCOUTQ:			/* output queue size */
9064069Swollman		*(int *)data = tp->t_outq.c_cc;
90712693Sphk		break;
9084069Swollman	case TIOCSETA:			/* set termios struct */
9091541Srgrimes	case TIOCSETAW:			/* drain output, set */
9101541Srgrimes	case TIOCSETAF: {		/* drn out, fls in, set */
9111541Srgrimes		struct termios *t = (struct termios *)data;
9121541Srgrimes
9135195Swollman		if (t->c_ispeed == 0)
91484931Sfjoe			t->c_ispeed = t->c_ospeed;
91584931Sfjoe		if (t->c_ispeed == 0)
9165195Swollman			t->c_ispeed = tp->t_ospeed;
9175195Swollman		if (t->c_ispeed == 0)
91825822Stegge			return (EINVAL);
91984931Sfjoe		s = spltty();
92084931Sfjoe		if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
9215195Swollman			error = ttywait(tp);
9225195Swollman			if (error) {
9235195Swollman				splx(s);
92469152Sjlemon				return (error);
92569152Sjlemon			}
92669152Sjlemon			if (cmd == TIOCSETAF)
92769152Sjlemon				ttyflush(tp, FREAD);
92869152Sjlemon		}
92969152Sjlemon		if (!ISSET(t->c_cflag, CIGNORE)) {
93069152Sjlemon			/*
93169152Sjlemon			 * Set device hardware.
93269152Sjlemon			 */
93369152Sjlemon			if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
934				splx(s);
935				return (error);
936			}
937			if (ISSET(t->c_cflag, CLOCAL) &&
938			    !ISSET(tp->t_cflag, CLOCAL)) {
939				/*
940				 * XXX disconnections would be too hard to
941				 * get rid of without this kludge.  The only
942				 * way to get rid of controlling terminals
943				 * is to exit from the session leader.
944				 */
945				CLR(tp->t_state, TS_ZOMBIE);
946
947				wakeup(TSA_CARR_ON(tp));
948				ttwakeup(tp);
949				ttwwakeup(tp);
950			}
951			if ((ISSET(tp->t_state, TS_CARR_ON) ||
952			     ISSET(t->c_cflag, CLOCAL)) &&
953			    !ISSET(tp->t_state, TS_ZOMBIE))
954				SET(tp->t_state, TS_CONNECTED);
955			else
956				CLR(tp->t_state, TS_CONNECTED);
957			tp->t_cflag = t->c_cflag;
958			tp->t_ispeed = t->c_ispeed;
959			if (t->c_ospeed != 0)
960				tp->t_ospeed = t->c_ospeed;
961			ttsetwater(tp);
962		}
963		if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
964		    cmd != TIOCSETAF) {
965			if (ISSET(t->c_lflag, ICANON))
966				SET(tp->t_lflag, PENDIN);
967			else {
968				/*
969				 * XXX we really shouldn't allow toggling
970				 * ICANON while we're in a non-termios line
971				 * discipline.  Now we have to worry about
972				 * panicing for a null queue.
973				 */
974				if (tp->t_canq.c_cbreserved > 0 &&
975				    tp->t_rawq.c_cbreserved > 0) {
976					catq(&tp->t_rawq, &tp->t_canq);
977					/*
978					 * XXX the queue limits may be
979					 * different, so the old queue
980					 * swapping method no longer works.
981					 */
982					catq(&tp->t_canq, &tp->t_rawq);
983				}
984				CLR(tp->t_lflag, PENDIN);
985			}
986			ttwakeup(tp);
987		}
988		tp->t_iflag = t->c_iflag;
989		tp->t_oflag = t->c_oflag;
990		/*
991		 * Make the EXTPROC bit read only.
992		 */
993		if (ISSET(tp->t_lflag, EXTPROC))
994			SET(t->c_lflag, EXTPROC);
995		else
996			CLR(t->c_lflag, EXTPROC);
997		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
998		if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
999		    t->c_cc[VTIME] != tp->t_cc[VTIME])
1000			ttwakeup(tp);
1001		bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1002		splx(s);
1003		break;
1004	}
1005	case TIOCSETD: {		/* set line discipline */
1006		int t = *(int *)data;
1007		dev_t device = tp->t_dev;
1008
1009		if ((u_int)t >= nlinesw)
1010			return (ENXIO);
1011		if (t != tp->t_line) {
1012			s = spltty();
1013			(*linesw[tp->t_line].l_close)(tp, flag);
1014			error = (*linesw[t].l_open)(device, tp);
1015			if (error) {
1016				(void)(*linesw[tp->t_line].l_open)(device, tp);
1017				splx(s);
1018				return (error);
1019			}
1020			tp->t_line = t;
1021			splx(s);
1022		}
1023		break;
1024	}
1025	case TIOCSTART:			/* start output, like ^Q */
1026		s = spltty();
1027		if (ISSET(tp->t_state, TS_TTSTOP) ||
1028		    ISSET(tp->t_lflag, FLUSHO)) {
1029			CLR(tp->t_lflag, FLUSHO);
1030			CLR(tp->t_state, TS_TTSTOP);
1031			ttstart(tp);
1032		}
1033		splx(s);
1034		break;
1035	case TIOCSTI:			/* simulate terminal input */
1036		if ((flag & FREAD) == 0 && suser(td))
1037			return (EPERM);
1038		if (!isctty(p, tp) && suser(td))
1039			return (EACCES);
1040		s = spltty();
1041		(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1042		splx(s);
1043		break;
1044	case TIOCSTOP:			/* stop output, like ^S */
1045		s = spltty();
1046		if (!ISSET(tp->t_state, TS_TTSTOP)) {
1047			SET(tp->t_state, TS_TTSTOP);
1048			(*tp->t_stop)(tp, 0);
1049		}
1050		splx(s);
1051		break;
1052	case TIOCSCTTY:			/* become controlling tty */
1053		/* Session ctty vnode pointer set in vnode layer. */
1054		sx_slock(&proctree_lock);
1055		if (!SESS_LEADER(p) ||
1056		    ((p->p_session->s_ttyvp || tp->t_session) &&
1057		     (tp->t_session != p->p_session))) {
1058			sx_sunlock(&proctree_lock);
1059			return (EPERM);
1060		}
1061		tp->t_session = p->p_session;
1062		tp->t_pgrp = p->p_pgrp;
1063		SESS_LOCK(p->p_session);
1064		p->p_session->s_ttyp = tp;
1065		SESS_UNLOCK(p->p_session);
1066		PROC_LOCK(p);
1067		p->p_flag |= P_CONTROLT;
1068		PROC_UNLOCK(p);
1069		sx_sunlock(&proctree_lock);
1070		break;
1071	case TIOCSPGRP: {		/* set pgrp of tty */
1072		sx_slock(&proctree_lock);
1073		pgrp = pgfind(*(int *)data);
1074		if (!isctty(p, tp)) {
1075			if (pgrp != NULL)
1076				PGRP_UNLOCK(pgrp);
1077			sx_sunlock(&proctree_lock);
1078			return (ENOTTY);
1079		}
1080		if (pgrp == NULL) {
1081			sx_sunlock(&proctree_lock);
1082			return (EPERM);
1083		}
1084		PGRP_UNLOCK(pgrp);
1085		if (pgrp->pg_session != p->p_session) {
1086			sx_sunlock(&proctree_lock);
1087			return (EPERM);
1088		}
1089		sx_sunlock(&proctree_lock);
1090		tp->t_pgrp = pgrp;
1091		break;
1092	}
1093	case TIOCSTAT:			/* simulate control-T */
1094		s = spltty();
1095		ttyinfo(tp);
1096		splx(s);
1097		break;
1098	case TIOCSWINSZ:		/* set window size */
1099		if (bcmp((caddr_t)&tp->t_winsize, data,
1100		    sizeof (struct winsize))) {
1101			tp->t_winsize = *(struct winsize *)data;
1102			if (tp->t_pgrp != NULL) {
1103				PGRP_LOCK(tp->t_pgrp);
1104				pgsignal(tp->t_pgrp, SIGWINCH, 1);
1105				PGRP_UNLOCK(tp->t_pgrp);
1106			}
1107		}
1108		break;
1109	case TIOCSDRAINWAIT:
1110		error = suser(td);
1111		if (error)
1112			return (error);
1113		tp->t_timeout = *(int *)data * hz;
1114		wakeup(TSA_OCOMPLETE(tp));
1115		wakeup(TSA_OLOWAT(tp));
1116		break;
1117	case TIOCGDRAINWAIT:
1118		*(int *)data = tp->t_timeout / hz;
1119		break;
1120	default:
1121#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1122		return (ttcompat(tp, cmd, data, flag));
1123#else
1124		return (ENOIOCTL);
1125#endif
1126	}
1127	return (0);
1128}
1129
1130int
1131ttypoll(dev_t dev, int events, struct thread *td)
1132{
1133	int s;
1134	int revents = 0;
1135	struct tty *tp;
1136
1137	tp = dev->si_tty;
1138	if (tp == NULL)	/* XXX used to return ENXIO, but that means true! */
1139		return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM))
1140			| POLLHUP);
1141
1142	s = spltty();
1143	if (events & (POLLIN | POLLRDNORM)) {
1144		if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
1145			revents |= events & (POLLIN | POLLRDNORM);
1146		else
1147			selrecord(td, &tp->t_rsel);
1148	}
1149	if (events & (POLLOUT | POLLWRNORM)) {
1150		if ((tp->t_outq.c_cc <= tp->t_olowat &&
1151		     ISSET(tp->t_state, TS_CONNECTED))
1152		    || ISSET(tp->t_state, TS_ZOMBIE))
1153			revents |= events & (POLLOUT | POLLWRNORM);
1154		else
1155			selrecord(td, &tp->t_wsel);
1156	}
1157	splx(s);
1158	return (revents);
1159}
1160
1161static struct filterops ttyread_filtops =
1162	{ 1, NULL, filt_ttyrdetach, filt_ttyread };
1163static struct filterops ttywrite_filtops =
1164	{ 1, NULL, filt_ttywdetach, filt_ttywrite };
1165
1166int
1167ttykqfilter(dev_t dev, struct knote *kn)
1168{
1169	struct tty *tp = dev->si_tty;
1170	struct klist *klist;
1171	int s;
1172
1173	switch (kn->kn_filter) {
1174	case EVFILT_READ:
1175		klist = &tp->t_rsel.si_note;
1176		kn->kn_fop = &ttyread_filtops;
1177		break;
1178	case EVFILT_WRITE:
1179		klist = &tp->t_wsel.si_note;
1180		kn->kn_fop = &ttywrite_filtops;
1181		break;
1182	default:
1183		return (1);
1184	}
1185
1186	kn->kn_hook = (caddr_t)dev;
1187
1188	s = spltty();
1189	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1190	splx(s);
1191
1192	return (0);
1193}
1194
1195static void
1196filt_ttyrdetach(struct knote *kn)
1197{
1198	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1199	int s = spltty();
1200
1201	SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext);
1202	splx(s);
1203}
1204
1205static int
1206filt_ttyread(struct knote *kn, long hint)
1207{
1208	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1209
1210	kn->kn_data = ttnread(tp);
1211	if (ISSET(tp->t_state, TS_ZOMBIE)) {
1212		kn->kn_flags |= EV_EOF;
1213		return (1);
1214	}
1215	return (kn->kn_data > 0);
1216}
1217
1218static void
1219filt_ttywdetach(struct knote *kn)
1220{
1221	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1222	int s = spltty();
1223
1224	SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext);
1225	splx(s);
1226}
1227
1228static int
1229filt_ttywrite(struct knote *kn, long hint)
1230{
1231	struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1232
1233	kn->kn_data = tp->t_outq.c_cc;
1234	if (ISSET(tp->t_state, TS_ZOMBIE))
1235		return (1);
1236	return (kn->kn_data <= tp->t_olowat &&
1237	    ISSET(tp->t_state, TS_CONNECTED));
1238}
1239
1240/*
1241 * Must be called at spltty().
1242 */
1243static int
1244ttnread(struct tty *tp)
1245{
1246	int nread;
1247
1248	if (ISSET(tp->t_lflag, PENDIN))
1249		ttypend(tp);
1250	nread = tp->t_canq.c_cc;
1251	if (!ISSET(tp->t_lflag, ICANON)) {
1252		nread += tp->t_rawq.c_cc;
1253		if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1254			nread = 0;
1255	}
1256	return (nread);
1257}
1258
1259/*
1260 * Wait for output to drain.
1261 */
1262int
1263ttywait(struct tty *tp)
1264{
1265	int error, s;
1266
1267	error = 0;
1268	s = spltty();
1269	while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1270	       ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1271		(*tp->t_oproc)(tp);
1272		if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1273		    ISSET(tp->t_state, TS_CONNECTED)) {
1274			SET(tp->t_state, TS_SO_OCOMPLETE);
1275			error = ttysleep(tp, TSA_OCOMPLETE(tp),
1276					 TTOPRI | PCATCH, "ttywai",
1277					 tp->t_timeout);
1278			if (error) {
1279				if (error == EWOULDBLOCK)
1280					error = EIO;
1281				break;
1282			}
1283		} else
1284			break;
1285	}
1286	if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1287		error = EIO;
1288	splx(s);
1289	return (error);
1290}
1291
1292/*
1293 * Flush if successfully wait.
1294 */
1295static int
1296ttywflush(struct tty *tp)
1297{
1298	int error;
1299
1300	if ((error = ttywait(tp)) == 0)
1301		ttyflush(tp, FREAD);
1302	return (error);
1303}
1304
1305/*
1306 * Flush tty read and/or write queues, notifying anyone waiting.
1307 */
1308void
1309ttyflush(struct tty *tp, int rw)
1310{
1311	int s;
1312
1313	s = spltty();
1314#if 0
1315again:
1316#endif
1317	if (rw & FWRITE) {
1318		FLUSHQ(&tp->t_outq);
1319		CLR(tp->t_state, TS_TTSTOP);
1320	}
1321	(*tp->t_stop)(tp, rw);
1322	if (rw & FREAD) {
1323		FLUSHQ(&tp->t_canq);
1324		FLUSHQ(&tp->t_rawq);
1325		CLR(tp->t_lflag, PENDIN);
1326		tp->t_rocount = 0;
1327		tp->t_rocol = 0;
1328		CLR(tp->t_state, TS_LOCAL);
1329		ttwakeup(tp);
1330		if (ISSET(tp->t_state, TS_TBLOCK)) {
1331			if (rw & FWRITE)
1332				FLUSHQ(&tp->t_outq);
1333			ttyunblock(tp);
1334
1335			/*
1336			 * Don't let leave any state that might clobber the
1337			 * next line discipline (although we should do more
1338			 * to send the START char).  Not clearing the state
1339			 * may have caused the "putc to a clist with no
1340			 * reserved cblocks" panic/printf.
1341			 */
1342			CLR(tp->t_state, TS_TBLOCK);
1343
1344#if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1345			if (ISSET(tp->t_iflag, IXOFF)) {
1346				/*
1347				 * XXX wait a bit in the hope that the stop
1348				 * character (if any) will go out.  Waiting
1349				 * isn't good since it allows races.  This
1350				 * will be fixed when the stop character is
1351				 * put in a special queue.  Don't bother with
1352				 * the checks in ttywait() since the timeout
1353				 * will save us.
1354				 */
1355				SET(tp->t_state, TS_SO_OCOMPLETE);
1356				ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1357					 "ttyfls", hz / 10);
1358				/*
1359				 * Don't try sending the stop character again.
1360				 */
1361				CLR(tp->t_state, TS_TBLOCK);
1362				goto again;
1363			}
1364#endif
1365		}
1366	}
1367	if (rw & FWRITE) {
1368		FLUSHQ(&tp->t_outq);
1369		ttwwakeup(tp);
1370	}
1371	splx(s);
1372}
1373
1374/*
1375 * Copy in the default termios characters.
1376 */
1377void
1378termioschars(struct termios *t)
1379{
1380
1381	bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1382}
1383
1384/*
1385 * Old interface.
1386 */
1387void
1388ttychars(struct tty *tp)
1389{
1390
1391	termioschars(&tp->t_termios);
1392}
1393
1394/*
1395 * Handle input high water.  Send stop character for the IXOFF case.  Turn
1396 * on our input flow control bit and propagate the changes to the driver.
1397 * XXX the stop character should be put in a special high priority queue.
1398 */
1399void
1400ttyblock(struct tty *tp)
1401{
1402
1403	SET(tp->t_state, TS_TBLOCK);
1404	if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1405	    putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1406		CLR(tp->t_state, TS_TBLOCK);	/* try again later */
1407	ttstart(tp);
1408}
1409
1410/*
1411 * Handle input low water.  Send start character for the IXOFF case.  Turn
1412 * off our input flow control bit and propagate the changes to the driver.
1413 * XXX the start character should be put in a special high priority queue.
1414 */
1415static void
1416ttyunblock(struct tty *tp)
1417{
1418
1419	CLR(tp->t_state, TS_TBLOCK);
1420	if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1421	    putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1422		SET(tp->t_state, TS_TBLOCK);	/* try again later */
1423	ttstart(tp);
1424}
1425
1426#ifdef notyet
1427/* Not used by any current (i386) drivers. */
1428/*
1429 * Restart after an inter-char delay.
1430 */
1431void
1432ttrstrt(void *tp_arg)
1433{
1434	struct tty *tp;
1435	int s;
1436
1437	KASSERT(tp_arg != NULL, ("ttrstrt"));
1438
1439	tp = tp_arg;
1440	s = spltty();
1441
1442	CLR(tp->t_state, TS_TIMEOUT);
1443	ttstart(tp);
1444
1445	splx(s);
1446}
1447#endif
1448
1449int
1450ttstart(struct tty *tp)
1451{
1452
1453	if (tp->t_oproc != NULL)	/* XXX: Kludge for pty. */
1454		(*tp->t_oproc)(tp);
1455	return (0);
1456}
1457
1458/*
1459 * "close" a line discipline
1460 */
1461int
1462ttylclose(struct tty *tp, int flag)
1463{
1464
1465	if (flag & FNONBLOCK || ttywflush(tp))
1466		ttyflush(tp, FREAD | FWRITE);
1467	return (0);
1468}
1469
1470/*
1471 * Handle modem control transition on a tty.
1472 * Flag indicates new state of carrier.
1473 * Returns 0 if the line should be turned off, otherwise 1.
1474 */
1475int
1476ttymodem(struct tty *tp, int flag)
1477{
1478
1479	if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1480		/*
1481		 * MDMBUF: do flow control according to carrier flag
1482		 * XXX TS_CAR_OFLOW doesn't do anything yet.  TS_TTSTOP
1483		 * works if IXON and IXANY are clear.
1484		 */
1485		if (flag) {
1486			CLR(tp->t_state, TS_CAR_OFLOW);
1487			CLR(tp->t_state, TS_TTSTOP);
1488			ttstart(tp);
1489		} else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1490			SET(tp->t_state, TS_CAR_OFLOW);
1491			SET(tp->t_state, TS_TTSTOP);
1492			(*tp->t_stop)(tp, 0);
1493		}
1494	} else if (flag == 0) {
1495		/*
1496		 * Lost carrier.
1497		 */
1498		CLR(tp->t_state, TS_CARR_ON);
1499		if (ISSET(tp->t_state, TS_ISOPEN) &&
1500		    !ISSET(tp->t_cflag, CLOCAL)) {
1501			SET(tp->t_state, TS_ZOMBIE);
1502			CLR(tp->t_state, TS_CONNECTED);
1503			if (tp->t_session) {
1504				sx_slock(&proctree_lock);
1505				if (tp->t_session->s_leader) {
1506					struct proc *p;
1507
1508					p = tp->t_session->s_leader;
1509					PROC_LOCK(p);
1510					psignal(p, SIGHUP);
1511					PROC_UNLOCK(p);
1512				}
1513				sx_sunlock(&proctree_lock);
1514			}
1515			ttyflush(tp, FREAD | FWRITE);
1516			return (0);
1517		}
1518	} else {
1519		/*
1520		 * Carrier now on.
1521		 */
1522		SET(tp->t_state, TS_CARR_ON);
1523		if (!ISSET(tp->t_state, TS_ZOMBIE))
1524			SET(tp->t_state, TS_CONNECTED);
1525		wakeup(TSA_CARR_ON(tp));
1526		ttwakeup(tp);
1527		ttwwakeup(tp);
1528	}
1529	return (1);
1530}
1531
1532/*
1533 * Reinput pending characters after state switch
1534 * call at spltty().
1535 */
1536static void
1537ttypend(struct tty *tp)
1538{
1539	struct clist tq;
1540	int c;
1541
1542	CLR(tp->t_lflag, PENDIN);
1543	SET(tp->t_state, TS_TYPEN);
1544	/*
1545	 * XXX this assumes too much about clist internals.  It may even
1546	 * fail if the cblock slush pool is empty.  We can't allocate more
1547	 * cblocks here because we are called from an interrupt handler
1548	 * and clist_alloc_cblocks() can wait.
1549	 */
1550	tq = tp->t_rawq;
1551	bzero(&tp->t_rawq, sizeof tp->t_rawq);
1552	tp->t_rawq.c_cbmax = tq.c_cbmax;
1553	tp->t_rawq.c_cbreserved = tq.c_cbreserved;
1554	while ((c = getc(&tq)) >= 0)
1555		ttyinput(c, tp);
1556	CLR(tp->t_state, TS_TYPEN);
1557}
1558
1559/*
1560 * Process a read call on a tty device.
1561 */
1562int
1563ttread(struct tty *tp, struct uio *uio, int flag)
1564{
1565	struct clist *qp;
1566	int c;
1567	tcflag_t lflag;
1568	cc_t *cc = tp->t_cc;
1569	struct proc *p = curproc;
1570	int s, first, error = 0;
1571	int has_stime = 0, last_cc = 0;
1572	long slp = 0;		/* XXX this should be renamed `timo'. */
1573	struct timeval stime;
1574	struct pgrp *pg;
1575
1576loop:
1577	s = spltty();
1578	lflag = tp->t_lflag;
1579	/*
1580	 * take pending input first
1581	 */
1582	if (ISSET(lflag, PENDIN)) {
1583		ttypend(tp);
1584		splx(s);	/* reduce latency */
1585		s = spltty();
1586		lflag = tp->t_lflag;	/* XXX ttypend() clobbers it */
1587	}
1588
1589	/*
1590	 * Hang process if it's in the background.
1591	 */
1592	if (isbackground(p, tp)) {
1593		splx(s);
1594		sx_slock(&proctree_lock);
1595		PROC_LOCK(p);
1596		if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
1597		    SIGISMEMBER(p->p_sigmask, SIGTTIN) ||
1598		    (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) {
1599			PROC_UNLOCK(p);
1600			sx_sunlock(&proctree_lock);
1601			return (EIO);
1602		}
1603		pg = p->p_pgrp;
1604		PROC_UNLOCK(p);
1605		PGRP_LOCK(pg);
1606		sx_sunlock(&proctree_lock);
1607		pgsignal(pg, SIGTTIN, 1);
1608		PGRP_UNLOCK(pg);
1609		error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1610		if (error)
1611			return (error);
1612		goto loop;
1613	}
1614
1615	if (ISSET(tp->t_state, TS_ZOMBIE)) {
1616		splx(s);
1617		return (0);	/* EOF */
1618	}
1619
1620	/*
1621	 * If canonical, use the canonical queue,
1622	 * else use the raw queue.
1623	 *
1624	 * (should get rid of clists...)
1625	 */
1626	qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1627
1628	if (flag & IO_NDELAY) {
1629		if (qp->c_cc > 0)
1630			goto read;
1631		if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1632			splx(s);
1633			return (0);
1634		}
1635		splx(s);
1636		return (EWOULDBLOCK);
1637	}
1638	if (!ISSET(lflag, ICANON)) {
1639		int m = cc[VMIN];
1640		long t = cc[VTIME];
1641		struct timeval timecopy;
1642
1643		/*
1644		 * Check each of the four combinations.
1645		 * (m > 0 && t == 0) is the normal read case.
1646		 * It should be fairly efficient, so we check that and its
1647		 * companion case (m == 0 && t == 0) first.
1648		 * For the other two cases, we compute the target sleep time
1649		 * into slp.
1650		 */
1651		if (t == 0) {
1652			if (qp->c_cc < m)
1653				goto sleep;
1654			if (qp->c_cc > 0)
1655				goto read;
1656
1657			/* m, t and qp->c_cc are all 0.  0 is enough input. */
1658			splx(s);
1659			return (0);
1660		}
1661		t *= 100000;		/* time in us */
1662#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1663			 ((t1).tv_usec - (t2).tv_usec))
1664		if (m > 0) {
1665			if (qp->c_cc <= 0)
1666				goto sleep;
1667			if (qp->c_cc >= m)
1668				goto read;
1669			getmicrotime(&timecopy);
1670			if (!has_stime) {
1671				/* first character, start timer */
1672				has_stime = 1;
1673				stime = timecopy;
1674				slp = t;
1675			} else if (qp->c_cc > last_cc) {
1676				/* got a character, restart timer */
1677				stime = timecopy;
1678				slp = t;
1679			} else {
1680				/* nothing, check expiration */
1681				slp = t - diff(timecopy, stime);
1682				if (slp <= 0)
1683					goto read;
1684			}
1685			last_cc = qp->c_cc;
1686		} else {	/* m == 0 */
1687			if (qp->c_cc > 0)
1688				goto read;
1689			getmicrotime(&timecopy);
1690			if (!has_stime) {
1691				has_stime = 1;
1692				stime = timecopy;
1693				slp = t;
1694			} else {
1695				slp = t - diff(timecopy, stime);
1696				if (slp <= 0) {
1697					/* Timed out, but 0 is enough input. */
1698					splx(s);
1699					return (0);
1700				}
1701			}
1702		}
1703#undef diff
1704		/*
1705		 * Rounding down may make us wake up just short
1706		 * of the target, so we round up.
1707		 * The formula is ceiling(slp * hz/1000000).
1708		 * 32-bit arithmetic is enough for hz < 169.
1709		 * XXX see tvtohz() for how to avoid overflow if hz
1710		 * is large (divide by `tick' and/or arrange to
1711		 * use tvtohz() if hz is large).
1712		 */
1713		slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1714		goto sleep;
1715	}
1716	if (qp->c_cc <= 0) {
1717sleep:
1718		/*
1719		 * There is no input, or not enough input and we can block.
1720		 */
1721		error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
1722				 ISSET(tp->t_state, TS_CONNECTED) ?
1723				 "ttyin" : "ttyhup", (int)slp);
1724		splx(s);
1725		if (error == EWOULDBLOCK)
1726			error = 0;
1727		else if (error)
1728			return (error);
1729		/*
1730		 * XXX what happens if another process eats some input
1731		 * while we are asleep (not just here)?  It would be
1732		 * safest to detect changes and reset our state variables
1733		 * (has_stime and last_cc).
1734		 */
1735		slp = 0;
1736		goto loop;
1737	}
1738read:
1739	splx(s);
1740	/*
1741	 * Input present, check for input mapping and processing.
1742	 */
1743	first = 1;
1744	if (ISSET(lflag, ICANON | ISIG))
1745		goto slowcase;
1746	for (;;) {
1747		char ibuf[IBUFSIZ];
1748		int icc;
1749
1750		icc = imin(uio->uio_resid, IBUFSIZ);
1751		icc = q_to_b(qp, ibuf, icc);
1752		if (icc <= 0) {
1753			if (first)
1754				goto loop;
1755			break;
1756		}
1757		error = uiomove(ibuf, icc, uio);
1758		/*
1759		 * XXX if there was an error then we should ungetc() the
1760		 * unmoved chars and reduce icc here.
1761		 */
1762		if (error)
1763			break;
1764		if (uio->uio_resid == 0)
1765			break;
1766		first = 0;
1767	}
1768	goto out;
1769slowcase:
1770	for (;;) {
1771		c = getc(qp);
1772		if (c < 0) {
1773			if (first)
1774				goto loop;
1775			break;
1776		}
1777		/*
1778		 * delayed suspend (^Y)
1779		 */
1780		if (CCEQ(cc[VDSUSP], c) &&
1781		    ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1782			if (tp->t_pgrp != NULL) {
1783				PGRP_LOCK(tp->t_pgrp);
1784				pgsignal(tp->t_pgrp, SIGTSTP, 1);
1785				PGRP_UNLOCK(tp->t_pgrp);
1786			}
1787			if (first) {
1788				error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1789						 "ttybg3", 0);
1790				if (error)
1791					break;
1792				goto loop;
1793			}
1794			break;
1795		}
1796		/*
1797		 * Interpret EOF only in canonical mode.
1798		 */
1799		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1800			break;
1801		/*
1802		 * Give user character.
1803		 */
1804		error = ureadc(c, uio);
1805		if (error)
1806			/* XXX should ungetc(c, qp). */
1807			break;
1808		if (uio->uio_resid == 0)
1809			break;
1810		/*
1811		 * In canonical mode check for a "break character"
1812		 * marking the end of a "line of input".
1813		 */
1814		if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1815			break;
1816		first = 0;
1817	}
1818
1819out:
1820	/*
1821	 * Look to unblock input now that (presumably)
1822	 * the input queue has gone down.
1823	 */
1824	s = spltty();
1825	if (ISSET(tp->t_state, TS_TBLOCK) &&
1826	    tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
1827		ttyunblock(tp);
1828	splx(s);
1829
1830	return (error);
1831}
1832
1833/*
1834 * Check the output queue on tp for space for a kernel message (from uprintf
1835 * or tprintf).  Allow some space over the normal hiwater mark so we don't
1836 * lose messages due to normal flow control, but don't let the tty run amok.
1837 * Sleeps here are not interruptible, but we return prematurely if new signals
1838 * arrive.
1839 */
1840int
1841ttycheckoutq(struct tty *tp, int wait)
1842{
1843	int hiwat, s;
1844	sigset_t oldmask;
1845
1846	hiwat = tp->t_ohiwat;
1847	SIGEMPTYSET(oldmask);
1848	s = spltty();
1849	if (wait)
1850		oldmask = curproc->p_siglist;
1851	if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
1852		while (tp->t_outq.c_cc > hiwat) {
1853			ttstart(tp);
1854			if (tp->t_outq.c_cc <= hiwat)
1855				break;
1856			if (!(wait && SIGSETEQ(curproc->p_siglist, oldmask))) {
1857				splx(s);
1858				return (0);
1859			}
1860			SET(tp->t_state, TS_SO_OLOWAT);
1861			tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
1862		}
1863	splx(s);
1864	return (1);
1865}
1866
1867/*
1868 * Process a write call on a tty device.
1869 */
1870int
1871ttwrite(struct tty *tp, struct uio *uio, int flag)
1872{
1873	char *cp = NULL;
1874	int cc, ce;
1875	struct proc *p;
1876	int i, hiwat, cnt, error, s;
1877	char obuf[OBUFSIZ];
1878
1879	hiwat = tp->t_ohiwat;
1880	cnt = uio->uio_resid;
1881	error = 0;
1882	cc = 0;
1883loop:
1884	s = spltty();
1885	if (ISSET(tp->t_state, TS_ZOMBIE)) {
1886		splx(s);
1887		if (uio->uio_resid == cnt)
1888			error = EIO;
1889		goto out;
1890	}
1891	if (!ISSET(tp->t_state, TS_CONNECTED)) {
1892		if (flag & IO_NDELAY) {
1893			splx(s);
1894			error = EWOULDBLOCK;
1895			goto out;
1896		}
1897		error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
1898				 "ttydcd", 0);
1899		splx(s);
1900		if (error)
1901			goto out;
1902		goto loop;
1903	}
1904	splx(s);
1905	/*
1906	 * Hang the process if it's in the background.
1907	 */
1908	p = curproc;
1909	sx_slock(&proctree_lock);
1910	PROC_LOCK(p);
1911	if (isbackground(p, tp) &&
1912	    ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
1913	    !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
1914	    !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
1915		if (p->p_pgrp->pg_jobc == 0) {
1916			PROC_UNLOCK(p);
1917			sx_sunlock(&proctree_lock);
1918			error = EIO;
1919			goto out;
1920		}
1921		PROC_UNLOCK(p);
1922		PGRP_LOCK(p->p_pgrp);
1923		sx_sunlock(&proctree_lock);
1924		pgsignal(p->p_pgrp, SIGTTOU, 1);
1925		PGRP_UNLOCK(p->p_pgrp);
1926		error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
1927		if (error)
1928			goto out;
1929		goto loop;
1930	} else {
1931		PROC_UNLOCK(p);
1932		sx_sunlock(&proctree_lock);
1933	}
1934	/*
1935	 * Process the user's data in at most OBUFSIZ chunks.  Perform any
1936	 * output translation.  Keep track of high water mark, sleep on
1937	 * overflow awaiting device aid in acquiring new space.
1938	 */
1939	while (uio->uio_resid > 0 || cc > 0) {
1940		if (ISSET(tp->t_lflag, FLUSHO)) {
1941			uio->uio_resid = 0;
1942			return (0);
1943		}
1944		if (tp->t_outq.c_cc > hiwat)
1945			goto ovhiwat;
1946		/*
1947		 * Grab a hunk of data from the user, unless we have some
1948		 * leftover from last time.
1949		 */
1950		if (cc == 0) {
1951			cc = imin(uio->uio_resid, OBUFSIZ);
1952			cp = obuf;
1953			error = uiomove(cp, cc, uio);
1954			if (error) {
1955				cc = 0;
1956				break;
1957			}
1958		}
1959		/*
1960		 * If nothing fancy need be done, grab those characters we
1961		 * can handle without any of ttyoutput's processing and
1962		 * just transfer them to the output q.  For those chars
1963		 * which require special processing (as indicated by the
1964		 * bits in char_type), call ttyoutput.  After processing
1965		 * a hunk of data, look for FLUSHO so ^O's will take effect
1966		 * immediately.
1967		 */
1968		while (cc > 0) {
1969			if (!ISSET(tp->t_oflag, OPOST))
1970				ce = cc;
1971			else {
1972				ce = cc - scanc((u_int)cc, (u_char *)cp,
1973						char_type, CCLASSMASK);
1974				/*
1975				 * If ce is zero, then we're processing
1976				 * a special character through ttyoutput.
1977				 */
1978				if (ce == 0) {
1979					tp->t_rocount = 0;
1980					if (ttyoutput(*cp, tp) >= 0) {
1981						/* No Clists, wait a bit. */
1982						ttstart(tp);
1983						if (flag & IO_NDELAY) {
1984							error = EWOULDBLOCK;
1985							goto out;
1986						}
1987						error = ttysleep(tp, &lbolt,
1988								 TTOPRI|PCATCH,
1989								 "ttybf1", 0);
1990						if (error)
1991							goto out;
1992						goto loop;
1993					}
1994					cp++;
1995					cc--;
1996					if (ISSET(tp->t_lflag, FLUSHO) ||
1997					    tp->t_outq.c_cc > hiwat)
1998						goto ovhiwat;
1999					continue;
2000				}
2001			}
2002			/*
2003			 * A bunch of normal characters have been found.
2004			 * Transfer them en masse to the output queue and
2005			 * continue processing at the top of the loop.
2006			 * If there are any further characters in this
2007			 * <= OBUFSIZ chunk, the first should be a character
2008			 * requiring special handling by ttyoutput.
2009			 */
2010			tp->t_rocount = 0;
2011			i = b_to_q(cp, ce, &tp->t_outq);
2012			ce -= i;
2013			tp->t_column += ce;
2014			cp += ce, cc -= ce, tk_nout += ce;
2015			tp->t_outcc += ce;
2016			if (i > 0) {
2017				/* No Clists, wait a bit. */
2018				ttstart(tp);
2019				if (flag & IO_NDELAY) {
2020					error = EWOULDBLOCK;
2021					goto out;
2022				}
2023				error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
2024						 "ttybf2", 0);
2025				if (error)
2026					goto out;
2027				goto loop;
2028			}
2029			if (ISSET(tp->t_lflag, FLUSHO) ||
2030			    tp->t_outq.c_cc > hiwat)
2031				break;
2032		}
2033		ttstart(tp);
2034	}
2035out:
2036	/*
2037	 * If cc is nonzero, we leave the uio structure inconsistent, as the
2038	 * offset and iov pointers have moved forward, but it doesn't matter
2039	 * (the call will either return short or restart with a new uio).
2040	 */
2041	uio->uio_resid += cc;
2042	return (error);
2043
2044ovhiwat:
2045	ttstart(tp);
2046	s = spltty();
2047	/*
2048	 * This can only occur if FLUSHO is set in t_lflag,
2049	 * or if ttstart/oproc is synchronous (or very fast).
2050	 */
2051	if (tp->t_outq.c_cc <= hiwat) {
2052		splx(s);
2053		goto loop;
2054	}
2055	if (flag & IO_NDELAY) {
2056		splx(s);
2057		uio->uio_resid += cc;
2058		return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
2059	}
2060	SET(tp->t_state, TS_SO_OLOWAT);
2061	error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
2062			 tp->t_timeout);
2063	splx(s);
2064	if (error == EWOULDBLOCK)
2065		error = EIO;
2066	if (error)
2067		goto out;
2068	goto loop;
2069}
2070
2071/*
2072 * Rubout one character from the rawq of tp
2073 * as cleanly as possible.
2074 */
2075static void
2076ttyrub(int c, struct tty *tp)
2077{
2078	char *cp;
2079	int savecol;
2080	int tabc, s;
2081
2082	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2083		return;
2084	CLR(tp->t_lflag, FLUSHO);
2085	if (ISSET(tp->t_lflag, ECHOE)) {
2086		if (tp->t_rocount == 0) {
2087			/*
2088			 * Screwed by ttwrite; retype
2089			 */
2090			ttyretype(tp);
2091			return;
2092		}
2093		if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
2094			ttyrubo(tp, 2);
2095		else {
2096			CLR(c, ~TTY_CHARMASK);
2097			switch (CCLASS(c)) {
2098			case ORDINARY:
2099				ttyrubo(tp, 1);
2100				break;
2101			case BACKSPACE:
2102			case CONTROL:
2103			case NEWLINE:
2104			case RETURN:
2105			case VTAB:
2106				if (ISSET(tp->t_lflag, ECHOCTL))
2107					ttyrubo(tp, 2);
2108				break;
2109			case TAB:
2110				if (tp->t_rocount < tp->t_rawq.c_cc) {
2111					ttyretype(tp);
2112					return;
2113				}
2114				s = spltty();
2115				savecol = tp->t_column;
2116				SET(tp->t_state, TS_CNTTB);
2117				SET(tp->t_lflag, FLUSHO);
2118				tp->t_column = tp->t_rocol;
2119				cp = tp->t_rawq.c_cf;
2120				if (cp)
2121					tabc = *cp;	/* XXX FIX NEXTC */
2122				for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
2123					ttyecho(tabc, tp);
2124				CLR(tp->t_lflag, FLUSHO);
2125				CLR(tp->t_state, TS_CNTTB);
2126				splx(s);
2127
2128				/* savecol will now be length of the tab. */
2129				savecol -= tp->t_column;
2130				tp->t_column += savecol;
2131				if (savecol > 8)
2132					savecol = 8;	/* overflow screw */
2133				while (--savecol >= 0)
2134					(void)ttyoutput('\b', tp);
2135				break;
2136			default:			/* XXX */
2137#define	PANICSTR	"ttyrub: would panic c = %d, val = %d\n"
2138				(void)printf(PANICSTR, c, CCLASS(c));
2139#ifdef notdef
2140				panic(PANICSTR, c, CCLASS(c));
2141#endif
2142			}
2143		}
2144	} else if (ISSET(tp->t_lflag, ECHOPRT)) {
2145		if (!ISSET(tp->t_state, TS_ERASE)) {
2146			SET(tp->t_state, TS_ERASE);
2147			(void)ttyoutput('\\', tp);
2148		}
2149		ttyecho(c, tp);
2150	} else {
2151		ttyecho(tp->t_cc[VERASE], tp);
2152		/*
2153		 * This code may be executed not only when an ERASE key
2154		 * is pressed, but also when ^U (KILL) or ^W (WERASE) are.
2155		 * So, I didn't think it was worthwhile to pass the extra
2156		 * information (which would need an extra parameter,
2157		 * changing every call) needed to distinguish the ERASE2
2158		 * case from the ERASE.
2159		 */
2160	}
2161	--tp->t_rocount;
2162}
2163
2164/*
2165 * Back over cnt characters, erasing them.
2166 */
2167static void
2168ttyrubo(struct tty *tp, int cnt)
2169{
2170
2171	while (cnt-- > 0) {
2172		(void)ttyoutput('\b', tp);
2173		(void)ttyoutput(' ', tp);
2174		(void)ttyoutput('\b', tp);
2175	}
2176}
2177
2178/*
2179 * ttyretype --
2180 *	Reprint the rawq line.  Note, it is assumed that c_cc has already
2181 *	been checked.
2182 */
2183static void
2184ttyretype(struct tty *tp)
2185{
2186	char *cp;
2187	int s, c;
2188
2189	/* Echo the reprint character. */
2190	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2191		ttyecho(tp->t_cc[VREPRINT], tp);
2192
2193	(void)ttyoutput('\n', tp);
2194
2195	/*
2196	 * XXX
2197	 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2198	 * BIT OF FIRST CHAR.
2199	 */
2200	s = spltty();
2201	for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
2202	    cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
2203		ttyecho(c, tp);
2204	for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
2205	    cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
2206		ttyecho(c, tp);
2207	CLR(tp->t_state, TS_ERASE);
2208	splx(s);
2209
2210	tp->t_rocount = tp->t_rawq.c_cc;
2211	tp->t_rocol = 0;
2212}
2213
2214/*
2215 * Echo a typed character to the terminal.
2216 */
2217static void
2218ttyecho(int c, struct tty *tp)
2219{
2220
2221	if (!ISSET(tp->t_state, TS_CNTTB))
2222		CLR(tp->t_lflag, FLUSHO);
2223	if ((!ISSET(tp->t_lflag, ECHO) &&
2224	     (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2225	    ISSET(tp->t_lflag, EXTPROC))
2226		return;
2227	if (ISSET(tp->t_lflag, ECHOCTL) &&
2228	    ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2229	    ISSET(c, TTY_CHARMASK) == 0177)) {
2230		(void)ttyoutput('^', tp);
2231		CLR(c, ~TTY_CHARMASK);
2232		if (c == 0177)
2233			c = '?';
2234		else
2235			c += 'A' - 1;
2236	}
2237	(void)ttyoutput(c, tp);
2238}
2239
2240/*
2241 * Wake up any readers on a tty.
2242 */
2243void
2244ttwakeup(struct tty *tp)
2245{
2246
2247	if (SEL_WAITING(&tp->t_rsel))
2248		selwakeup(&tp->t_rsel);
2249	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2250		pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
2251	wakeup(TSA_HUP_OR_INPUT(tp));
2252	KNOTE(&tp->t_rsel.si_note, 0);
2253}
2254
2255/*
2256 * Wake up any writers on a tty.
2257 */
2258void
2259ttwwakeup(struct tty *tp)
2260{
2261
2262	if (SEL_WAITING(&tp->t_wsel) && tp->t_outq.c_cc <= tp->t_olowat)
2263		selwakeup(&tp->t_wsel);
2264	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2265		pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
2266	if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2267	    TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2268		CLR(tp->t_state, TS_SO_OCOMPLETE);
2269		wakeup(TSA_OCOMPLETE(tp));
2270	}
2271	if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2272	    tp->t_outq.c_cc <= tp->t_olowat) {
2273		CLR(tp->t_state, TS_SO_OLOWAT);
2274		wakeup(TSA_OLOWAT(tp));
2275	}
2276	KNOTE(&tp->t_wsel.si_note, 0);
2277}
2278
2279/*
2280 * Look up a code for a specified speed in a conversion table;
2281 * used by drivers to map software speed values to hardware parameters.
2282 */
2283int
2284ttspeedtab(int speed, struct speedtab *table)
2285{
2286
2287	for ( ; table->sp_speed != -1; table++)
2288		if (table->sp_speed == speed)
2289			return (table->sp_code);
2290	return (-1);
2291}
2292
2293/*
2294 * Set input and output watermarks and buffer sizes.  For input, the
2295 * high watermark is about one second's worth of input above empty, the
2296 * low watermark is slightly below high water, and the buffer size is a
2297 * driver-dependent amount above high water.  For output, the watermarks
2298 * are near the ends of the buffer, with about 1 second's worth of input
2299 * between them.  All this only applies to the standard line discipline.
2300 */
2301void
2302ttsetwater(struct tty *tp)
2303{
2304	int cps, ttmaxhiwat, x;
2305
2306	/* Input. */
2307	clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
2308	switch (tp->t_ispeedwat) {
2309	case (speed_t)-1:
2310		cps = tp->t_ispeed / 10;
2311		break;
2312	case 0:
2313		/*
2314		 * This case is for old drivers that don't know about
2315		 * t_ispeedwat.  Arrange for them to get the old buffer
2316		 * sizes and watermarks.
2317		 */
2318		cps = TTYHOG - 2 * 256;
2319		tp->t_ififosize = 2 * 256;
2320		break;
2321	default:
2322		cps = tp->t_ispeedwat / 10;
2323		break;
2324	}
2325	tp->t_ihiwat = cps;
2326	tp->t_ilowat = 7 * cps / 8;
2327	x = cps + tp->t_ififosize;
2328	clist_alloc_cblocks(&tp->t_rawq, x, x);
2329
2330	/* Output. */
2331	switch (tp->t_ospeedwat) {
2332	case (speed_t)-1:
2333		cps = tp->t_ospeed / 10;
2334		ttmaxhiwat = 2 * TTMAXHIWAT;
2335		break;
2336	case 0:
2337		cps = tp->t_ospeed / 10;
2338		ttmaxhiwat = TTMAXHIWAT;
2339		break;
2340	default:
2341		cps = tp->t_ospeedwat / 10;
2342		ttmaxhiwat = 8 * TTMAXHIWAT;
2343		break;
2344	}
2345#define CLAMP(x, h, l)	((x) > h ? h : ((x) < l) ? l : (x))
2346	tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2347	x += cps;
2348	x = CLAMP(x, ttmaxhiwat, TTMINHIWAT);	/* XXX clamps are too magic */
2349	tp->t_ohiwat = roundup(x, CBSIZE);	/* XXX for compat */
2350	x = imax(tp->t_ohiwat, TTMAXHIWAT);	/* XXX for compat/safety */
2351	x += OBUFSIZ + 100;
2352	clist_alloc_cblocks(&tp->t_outq, x, x);
2353#undef	CLAMP
2354}
2355
2356/*
2357 * Report on state of foreground process group.
2358 */
2359void
2360ttyinfo(struct tty *tp)
2361{
2362	struct proc *p, *pick;
2363	struct timeval utime, stime;
2364	const char *stmp;
2365	long ltmp;
2366	int tmp;
2367	struct thread *td;
2368
2369	if (ttycheckoutq(tp,0) == 0)
2370		return;
2371
2372	/* Print load average. */
2373	tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2374	ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2375
2376	if (tp->t_session == NULL)
2377		ttyprintf(tp, "not a controlling terminal\n");
2378	else if (tp->t_pgrp == NULL)
2379		ttyprintf(tp, "no foreground process group\n");
2380	else {
2381		PGRP_LOCK(tp->t_pgrp);
2382		if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) {
2383			PGRP_UNLOCK(tp->t_pgrp);
2384			ttyprintf(tp, "empty foreground process group\n");
2385		} else {
2386			mtx_lock_spin(&sched_lock);
2387
2388			/* Pick interesting process. */
2389			for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
2390				if (proc_compare(pick, p))
2391					pick = p;
2392			PGRP_UNLOCK(tp->t_pgrp);
2393
2394			td = FIRST_THREAD_IN_PROC(pick);
2395			stmp = pick->p_stat == SRUN ? "running" :  /* XXXKSE */
2396			    pick->p_stat == SMTX ? td->td_mtxname :
2397			    td->td_wmesg ? td->td_wmesg : "iowait";
2398			calcru(pick, &utime, &stime, NULL);
2399			ltmp = pick->p_stat == SIDL || pick->p_stat == SWAIT ||
2400			    pick->p_stat == SZOMB ? 0 :
2401			    pgtok(vmspace_resident_count(pick->p_vmspace));
2402			mtx_unlock_spin(&sched_lock);
2403
2404			ttyprintf(tp, " cmd: %s %d [%s%s] ", pick->p_comm,
2405			    pick->p_pid, pick->p_stat == SMTX ? "*" : "", stmp);
2406
2407			/* Print user time. */
2408			ttyprintf(tp, "%ld.%02ldu ",
2409			    utime.tv_sec, utime.tv_usec / 10000);
2410
2411			/* Print system time. */
2412			ttyprintf(tp, "%ld.%02lds ",
2413			    (long)stime.tv_sec, stime.tv_usec / 10000);
2414
2415			/* Print percentage cpu, resident set size. */
2416			ttyprintf(tp, "%d%% %ldk\n", tmp / 100, ltmp);
2417
2418		}
2419	}
2420	tp->t_rocount = 0;	/* so pending input will be retyped if BS */
2421}
2422
2423/*
2424 * Returns 1 if p2 is "better" than p1
2425 *
2426 * The algorithm for picking the "interesting" process is thus:
2427 *
2428 *	1) Only foreground processes are eligible - implied.
2429 *	2) Runnable processes are favored over anything else.  The runner
2430 *	   with the highest cpu utilization is picked (p_estcpu).  Ties are
2431 *	   broken by picking the highest pid.
2432 *	3) The sleeper with the shortest sleep time is next.  With ties,
2433 *	   we pick out just "short-term" sleepers (P_SINTR == 0).
2434 *	4) Further ties are broken by picking the highest pid.
2435 */
2436#define ISRUN(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
2437#define TESTAB(a, b)    ((a)<<1 | (b))
2438#define ONLYA   2
2439#define ONLYB   1
2440#define BOTH    3
2441
2442static int
2443proc_compare(struct proc *p1, struct proc *p2)
2444{
2445
2446	int esta, estb;
2447	struct ksegrp *kg;
2448	mtx_assert(&sched_lock, MA_OWNED);
2449	if (p1 == NULL)
2450		return (1);
2451
2452	/*
2453	 * see if at least one of them is runnable
2454	 */
2455	switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
2456	case ONLYA:
2457		return (0);
2458	case ONLYB:
2459		return (1);
2460	case BOTH:
2461		/*
2462		 * tie - favor one with highest recent cpu utilization
2463		 */
2464		esta = estb = 0;
2465		FOREACH_KSEGRP_IN_PROC(p1,kg) {
2466			esta += kg->kg_estcpu;
2467		}
2468		FOREACH_KSEGRP_IN_PROC(p2,kg) {
2469			estb += kg->kg_estcpu;
2470		}
2471		if (estb > esta)
2472			return (1);
2473		if (esta > estb)
2474			return (0);
2475		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
2476	}
2477	/*
2478	 * weed out zombies
2479	 */
2480	switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
2481	case ONLYA:
2482		return (1);
2483	case ONLYB:
2484		return (0);
2485	case BOTH:
2486		return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2487	}
2488
2489#if 0 /* XXXKSE */
2490	/*
2491	 * pick the one with the smallest sleep time
2492	 */
2493	if (p2->p_slptime > p1->p_slptime)
2494		return (0);
2495	if (p1->p_slptime > p2->p_slptime)
2496		return (1);
2497	/*
2498	 * favor one sleeping in a non-interruptible sleep
2499	 */
2500	if (p1->p_sflag & PS_SINTR && (p2->p_sflag & PS_SINTR) == 0)
2501		return (1);
2502	if (p2->p_sflag & PS_SINTR && (p1->p_sflag & PS_SINTR) == 0)
2503		return (0);
2504#endif
2505	return (p2->p_pid > p1->p_pid);		/* tie - return highest pid */
2506}
2507
2508/*
2509 * Output char to tty; console putchar style.
2510 */
2511int
2512tputchar(int c, struct tty *tp)
2513{
2514	int s;
2515
2516	s = spltty();
2517	if (!ISSET(tp->t_state, TS_CONNECTED)) {
2518		splx(s);
2519		return (-1);
2520	}
2521	if (c == '\n')
2522		(void)ttyoutput('\r', tp);
2523	(void)ttyoutput(c, tp);
2524	ttstart(tp);
2525	splx(s);
2526	return (0);
2527}
2528
2529/*
2530 * Sleep on chan, returning ERESTART if tty changed while we napped and
2531 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep.  If
2532 * the tty is revoked, restarting a pending call will redo validation done
2533 * at the start of the call.
2534 */
2535int
2536ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo)
2537{
2538	int error;
2539	int gen;
2540
2541	gen = tp->t_gen;
2542	error = tsleep(chan, pri, wmesg, timo);
2543	if (error)
2544		return (error);
2545	return (tp->t_gen == gen ? 0 : ERESTART);
2546}
2547
2548/*
2549 * Allocate a tty struct.  Clists in the struct will be allocated by
2550 * ttyopen().
2551 */
2552struct tty *
2553ttymalloc(struct tty *tp)
2554{
2555
2556	if (tp)
2557		return(tp);
2558	tp = malloc(sizeof *tp, M_TTYS, M_WAITOK | M_ZERO);
2559	ttyregister(tp);
2560	return (tp);
2561}
2562
2563#if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */
2564/*
2565 * Free a tty struct.  Clists in the struct should have been freed by
2566 * ttyclose().
2567 */
2568void
2569ttyfree(struct tty *tp)
2570{
2571	free(tp, M_TTYS);
2572}
2573#endif /* 0 */
2574
2575void
2576ttyregister(struct tty *tp)
2577{
2578	tp->t_timeout = -1;
2579	SLIST_INSERT_HEAD(&tty_list, tp, t_list);
2580}
2581
2582static int
2583sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
2584{
2585	struct tty *tp;
2586	struct xtty xt;
2587	int error;
2588
2589	SLIST_FOREACH(tp, &tty_list, t_list) {
2590		bzero(&xt, sizeof xt);
2591		xt.xt_size = sizeof xt;
2592#define XT_COPY(field) xt.xt_##field = tp->t_##field
2593		xt.xt_rawcc = tp->t_rawq.c_cc;
2594		xt.xt_cancc = tp->t_canq.c_cc;
2595		xt.xt_outcc = tp->t_outq.c_cc;
2596		XT_COPY(line);
2597		if (tp->t_dev)
2598			xt.xt_dev = dev2udev(tp->t_dev);
2599		XT_COPY(state);
2600		XT_COPY(flags);
2601		XT_COPY(timeout);
2602		if (tp->t_pgrp)
2603			xt.xt_pgid = tp->t_pgrp->pg_id;
2604		if (tp->t_session)
2605			xt.xt_sid = tp->t_session->s_sid;
2606		XT_COPY(termios);
2607		XT_COPY(winsize);
2608		XT_COPY(column);
2609		XT_COPY(rocount);
2610		XT_COPY(rocol);
2611		XT_COPY(ififosize);
2612		XT_COPY(ihiwat);
2613		XT_COPY(ilowat);
2614		XT_COPY(ispeedwat);
2615		XT_COPY(ohiwat);
2616		XT_COPY(olowat);
2617		XT_COPY(ospeedwat);
2618#undef XT_COPY
2619		error = SYSCTL_OUT(req, &xt, sizeof xt);
2620		if (error)
2621			return (error);
2622	}
2623	return (0);
2624}
2625
2626SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
2627	0, 0, sysctl_kern_ttys, "S,xtty", "All ttys");
2628SYSCTL_LONG(_kern, OID_AUTO, tty_nin, CTLFLAG_RD,
2629	&tk_nin, 0, "Total TTY in characters");
2630SYSCTL_LONG(_kern, OID_AUTO, tty_nout, CTLFLAG_RD,
2631	&tk_nout, 0, "Total TTY out characters");
2632
2633void
2634nottystop(struct tty *tp, int rw)
2635{
2636
2637	return;
2638}
2639
2640int
2641ttyread(dev_t dev, struct uio *uio, int flag)
2642{
2643	struct tty *tp;
2644
2645	tp = dev->si_tty;
2646	if (tp == NULL)
2647		return (ENODEV);
2648	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
2649}
2650
2651int
2652ttywrite(dev_t dev, struct uio *uio, int flag)
2653{
2654	struct tty *tp;
2655
2656	tp = dev->si_tty;
2657	if (tp == NULL)
2658		return (ENODEV);
2659	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
2660}
2661