tty.c revision 59052
1249997Swkoszek/*-
2250015Swkoszek * Copyright (c) 1982, 1986, 1990, 1991, 1993
3249997Swkoszek *	The Regents of the University of California.  All rights reserved.
4250015Swkoszek * (c) UNIX System Laboratories, Inc.
5249997Swkoszek * All or some portions of this file are derived from material licensed
6250015Swkoszek * to the University of California by American Telephone and Telegraph
7250015Swkoszek * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8250015Swkoszek * the permission of UNIX System Laboratories, Inc.
9250015Swkoszek *
10250015Swkoszek * Redistribution and use in source and binary forms, with or without
11250015Swkoszek * modification, are permitted provided that the following conditions
12250015Swkoszek * are met:
13250015Swkoszek * 1. Redistributions of source code must retain the above copyright
14250015Swkoszek *    notice, this list of conditions and the following disclaimer.
15250015Swkoszek * 2. Redistributions in binary form must reproduce the above copyright
16249997Swkoszek *    notice, this list of conditions and the following disclaimer in the
17250015Swkoszek *    documentation and/or other materials provided with the distribution.
18250015Swkoszek * 3. All advertising materials mentioning features or use of this software
19250015Swkoszek *    must display the following acknowledgement:
20250015Swkoszek *	This product includes software developed by the University of
21250015Swkoszek *	California, Berkeley and its contributors.
22249997Swkoszek * 4. Neither the name of the University nor the names of its contributors
23250015Swkoszek *    may be used to endorse or promote products derived from this software
24250015Swkoszek *    without specific prior written permission.
25249997Swkoszek *
26250015Swkoszek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27249997Swkoszek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28249997Swkoszek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29250015Swkoszek * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30250015Swkoszek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31249997Swkoszek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32249997Swkoszek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33249997Swkoszek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34249997Swkoszek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35249997Swkoszek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36249997Swkoszek * SUCH DAMAGE.
37249997Swkoszek *
38249997Swkoszek *	@(#)tty.c	8.8 (Berkeley) 1/21/94
39249997Swkoszek * $FreeBSD: head/sys/kern/tty.c 59052 2000-04-05 18:38:21Z archie $
40249997Swkoszek */
41249997Swkoszek
42249997Swkoszek/*-
43249997Swkoszek * TODO:
44249997Swkoszek *	o Fix races for sending the start char in ttyflush().
45249997Swkoszek *	o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
46249997Swkoszek *	  With luck, there will be MIN chars before select() returns().
47249997Swkoszek *	o Handle CLOCAL consistently for ptys.  Perhaps disallow setting it.
48249997Swkoszek *	o Don't allow input in TS_ZOMBIE case.  It would be visible through
49249997Swkoszek *	  FIONREAD.
50249997Swkoszek *	o Do the new sio locking stuff here and use it to avoid special
51249997Swkoszek *	  case for EXTPROC?
52249997Swkoszek *	o Lock PENDIN too?
53249997Swkoszek *	o Move EXTPROC and/or PENDIN to t_state?
54249997Swkoszek *	o Wrap most of ttioctl in spltty/splx.
55249997Swkoszek *	o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
56249997Swkoszek *	o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
57249997Swkoszek *	o Don't allow certain termios flags to affect disciplines other
58249997Swkoszek *	  than TTYDISC.  Cancel their effects before switch disciplines
59249997Swkoszek *	  and ignore them if they are set while we are in another
60249997Swkoszek *	  discipline.
61249997Swkoszek *	o Now that historical speed conversions are handled here, don't
62249997Swkoszek *	  do them in drivers.
63249997Swkoszek *	o Check for TS_CARR_ON being set while everything is closed and not
64249997Swkoszek *	  waiting for carrier.  TS_CARR_ON isn't cleared if nothing is open,
65249997Swkoszek *	  so it would live until the next open even if carrier drops.
66249997Swkoszek *	o Restore TS_WOPEN since it is useful in pstat.  It must be cleared
67249997Swkoszek *	  only when _all_ openers leave open().
68249997Swkoszek */
69249997Swkoszek
70249997Swkoszek#include "snp.h"
71249997Swkoszek#include "opt_compat.h"
72249997Swkoszek#include "opt_uconsole.h"
73249997Swkoszek
74249997Swkoszek#include <sys/param.h>
75249997Swkoszek#include <sys/systm.h>
76249997Swkoszek#include <sys/filio.h>
77249997Swkoszek#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
78249997Swkoszek#include <sys/ioctl_compat.h>
79249997Swkoszek#endif
80249997Swkoszek#include <sys/proc.h>
81249997Swkoszek#define	TTYDEFCHARS
82249997Swkoszek#include <sys/tty.h>
83249997Swkoszek#undef	TTYDEFCHARS
84249997Swkoszek#include <sys/fcntl.h>
85249997Swkoszek#include <sys/conf.h>
86249997Swkoszek#include <sys/dkstat.h>
87249997Swkoszek#include <sys/poll.h>
88249997Swkoszek#include <sys/kernel.h>
89249997Swkoszek#include <sys/vnode.h>
90249997Swkoszek#include <sys/signalvar.h>
91249997Swkoszek#include <sys/resourcevar.h>
92249997Swkoszek#include <sys/malloc.h>
93249997Swkoszek#include <sys/filedesc.h>
94249997Swkoszek#if NSNP > 0
95249997Swkoszek#include <sys/snoop.h>
96249997Swkoszek#endif
97249997Swkoszek#include <sys/sysctl.h>
98249997Swkoszek
99249997Swkoszek#include <vm/vm.h>
100249997Swkoszek#include <sys/lock.h>
101249997Swkoszek#include <vm/pmap.h>
102249997Swkoszek#include <vm/vm_map.h>
103249997Swkoszek
104249997SwkoszekMALLOC_DEFINE(M_TTYS, "ttys", "tty data structures");
105249997Swkoszek
106249997Swkoszekstatic int	proc_compare __P((struct proc *p1, struct proc *p2));
107249997Swkoszekstatic int	ttnread __P((struct tty *tp));
108249997Swkoszekstatic void	ttyecho __P((int c, struct tty *tp));
109249997Swkoszekstatic int	ttyoutput __P((int c, register struct tty *tp));
110249997Swkoszekstatic void	ttypend __P((struct tty *tp));
111249997Swkoszekstatic void	ttyretype __P((struct tty *tp));
112249997Swkoszekstatic void	ttyrub __P((int c, struct tty *tp));
113249997Swkoszekstatic void	ttyrubo __P((struct tty *tp, int cnt));
114249997Swkoszekstatic void	ttyunblock __P((struct tty *tp));
115249997Swkoszekstatic int	ttywflush __P((struct tty *tp));
116249997Swkoszek
117249997Swkoszek/*
118249997Swkoszek * Table with character classes and parity. The 8th bit indicates parity,
119249997Swkoszek * the 7th bit indicates the character is an alphameric or underscore (for
120249997Swkoszek * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
121249997Swkoszek * are 0 then the character needs no special processing on output; classes
122249997Swkoszek * other than 0 might be translated or (not currently) require delays.
123249997Swkoszek */
124249997Swkoszek#define	E	0x00	/* Even parity. */
125249997Swkoszek#define	O	0x80	/* Odd parity. */
126249997Swkoszek#define	PARITY(c)	(char_type[c] & O)
127249997Swkoszek
128249997Swkoszek#define	ALPHA	0x40	/* Alpha or underscore. */
129249997Swkoszek#define	ISALPHA(c)	(char_type[(c) & TTY_CHARMASK] & ALPHA)
130249997Swkoszek
131249997Swkoszek#define	CCLASSMASK	0x3f
132249997Swkoszek#define	CCLASS(c)	(char_type[c] & CCLASSMASK)
133249997Swkoszek
134249997Swkoszek#define	BS	BACKSPACE
135249997Swkoszek#define	CC	CONTROL
136249997Swkoszek#define	CR	RETURN
137249997Swkoszek#define	NA	ORDINARY | ALPHA
138249997Swkoszek#define	NL	NEWLINE
139249997Swkoszek#define	NO	ORDINARY
140249997Swkoszek#define	TB	TAB
141249997Swkoszek#define	VT	VTAB
142249997Swkoszek
143249997Swkoszekstatic u_char const char_type[] = {
144249997Swkoszek	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC,	/* nul - bel */
145249997Swkoszek	O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
146249997Swkoszek	O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
147249997Swkoszek	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
148249997Swkoszek	O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
149249997Swkoszek	E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
150249997Swkoszek	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
151249997Swkoszek	O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
152249997Swkoszek	O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
153249997Swkoszek	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
154249997Swkoszek	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
155249997Swkoszek	O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
156249997Swkoszek	E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
157249997Swkoszek	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
158249997Swkoszek	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
159249997Swkoszek	E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
160249997Swkoszek	/*
161249997Swkoszek	 * Meta chars; should be settable per character set;
162249997Swkoszek	 * for now, treat them all as normal characters.
163249997Swkoszek	 */
164249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
165249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
166249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
167249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
168249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
169249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
170249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
171249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
172249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
173249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
174249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
175249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
176249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
177249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
178249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
179249997Swkoszek	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
180249997Swkoszek};
181249997Swkoszek#undef	BS
182249997Swkoszek#undef	CC
183249997Swkoszek#undef	CR
184249997Swkoszek#undef	NA
185249997Swkoszek#undef	NL
186249997Swkoszek#undef	NO
187249997Swkoszek#undef	TB
188249997Swkoszek#undef	VT
189249997Swkoszek
190249997Swkoszek/* Macros to clear/set/test flags. */
191249997Swkoszek#define	SET(t, f)	(t) |= (f)
192249997Swkoszek#define	CLR(t, f)	(t) &= ~(f)
193249997Swkoszek#define	ISSET(t, f)	((t) & (f))
194249997Swkoszek
195249997Swkoszek#undef MAX_INPUT		/* XXX wrong in <sys/syslimits.h> */
196249997Swkoszek#define	MAX_INPUT	TTYHOG	/* XXX limit is usually larger for !ICANON */
197249997Swkoszek
198249997Swkoszek/*
199249997Swkoszek * list of struct tty where pstat(8) can pick it up with sysctl
200249997Swkoszek */
201249997Swkoszekstatic SLIST_HEAD(, tty) tty_list;
202249997Swkoszek
203249997Swkoszek/*
204249997Swkoszek * Initial open of tty, or (re)entry to standard tty line discipline.
205249997Swkoszek */
206249997Swkoszekint
207249997Swkoszekttyopen(device, tp)
208249997Swkoszek	dev_t device;
209249997Swkoszek	register struct tty *tp;
210249997Swkoszek{
211249997Swkoszek	int s;
212249997Swkoszek
213249997Swkoszek	s = spltty();
214249997Swkoszek	tp->t_dev = device;
215249997Swkoszek	if (!ISSET(tp->t_state, TS_ISOPEN)) {
216249997Swkoszek		SET(tp->t_state, TS_ISOPEN);
217249997Swkoszek		if (ISSET(tp->t_cflag, CLOCAL))
218249997Swkoszek			SET(tp->t_state, TS_CONNECTED);
219249997Swkoszek		bzero(&tp->t_winsize, sizeof(tp->t_winsize));
220249997Swkoszek	}
221249997Swkoszek	ttsetwater(tp);
222249997Swkoszek	splx(s);
223249997Swkoszek	return (0);
224249997Swkoszek}
225249997Swkoszek
226249997Swkoszek/*
227249997Swkoszek * Handle close() on a tty line: flush and set to initial state,
228249997Swkoszek * bumping generation number so that pending read/write calls
229249997Swkoszek * can detect recycling of the tty.
230249997Swkoszek * XXX our caller should have done `spltty(); l_close(); ttyclose();'
231249997Swkoszek * and l_close() should have flushed, but we repeat the spltty() and
232249997Swkoszek * the flush in case there are buggy callers.
233249997Swkoszek */
234249997Swkoszekint
235249997Swkoszekttyclose(tp)
236249997Swkoszek	register struct tty *tp;
237249997Swkoszek{
238249997Swkoszek	int s;
239249997Swkoszek
240249997Swkoszek	funsetown(tp->t_sigio);
241249997Swkoszek	s = spltty();
242249997Swkoszek	if (constty == tp)
243249997Swkoszek		constty = NULL;
244249997Swkoszek
245249997Swkoszek	ttyflush(tp, FREAD | FWRITE);
246249997Swkoszek	clist_free_cblocks(&tp->t_canq);
247249997Swkoszek	clist_free_cblocks(&tp->t_outq);
248249997Swkoszek	clist_free_cblocks(&tp->t_rawq);
249249997Swkoszek
250249997Swkoszek#if NSNP > 0
251249997Swkoszek	if (ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
252249997Swkoszek		snpdown((struct snoop *)tp->t_sc);
253249997Swkoszek#endif
254249997Swkoszek
255249997Swkoszek	tp->t_gen++;
256249997Swkoszek	tp->t_line = TTYDISC;
257249997Swkoszek	tp->t_pgrp = NULL;
258249997Swkoszek	tp->t_session = NULL;
259249997Swkoszek	tp->t_state = 0;
260249997Swkoszek	splx(s);
261249997Swkoszek	return (0);
262249997Swkoszek}
263249997Swkoszek
264249997Swkoszek#define	FLUSHQ(q) {							\
265249997Swkoszek	if ((q)->c_cc)							\
266249997Swkoszek		ndflush(q, (q)->c_cc);					\
267249997Swkoszek}
268249997Swkoszek
269249997Swkoszek/* Is 'c' a line delimiter ("break" character)? */
270265690Sian#define	TTBREAKC(c, lflag)							\
271265690Sian	((c) == '\n' || (((c) == cc[VEOF] ||				\
272265690Sian	  (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) &&	\
273265690Sian	 (c) != _POSIX_VDISABLE))
274249997Swkoszek
275249997Swkoszek/*
276249997Swkoszek * Process input of a single character received on a tty.
277249997Swkoszek */
278265690Sianint
279265690Sianttyinput(c, tp)
280265690Sian	register int c;
281265690Sian	register struct tty *tp;
282265690Sian{
283265690Sian	register tcflag_t iflag, lflag;
284265690Sian	register cc_t *cc;
285265690Sian	int i, err;
286249997Swkoszek
287265690Sian	/*
288265690Sian	 * If input is pending take it first.
289265690Sian	 */
290265690Sian	lflag = tp->t_lflag;
291265690Sian	if (ISSET(lflag, PENDIN))
292265690Sian		ttypend(tp);
293265690Sian	/*
294265690Sian	 * Gather stats.
295249997Swkoszek	 */
296249997Swkoszek	if (ISSET(lflag, ICANON)) {
297249997Swkoszek		++tk_cancc;
298265690Sian		++tp->t_cancc;
299249997Swkoszek	} else {
300249997Swkoszek		++tk_rawcc;
301249997Swkoszek		++tp->t_rawcc;
302249997Swkoszek	}
303249997Swkoszek	++tk_nin;
304249997Swkoszek
305249997Swkoszek	/*
306249997Swkoszek	 * Block further input iff:
307265690Sian	 * current input > threshold AND input is available to user program
308249997Swkoszek	 * AND input flow control is enabled and not yet invoked.
309249997Swkoszek	 * The 3 is slop for PARMRK.
310249997Swkoszek	 */
311249997Swkoszek	iflag = tp->t_iflag;
312249997Swkoszek	if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 &&
313249997Swkoszek	    (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
314249997Swkoszek	    (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
315265690Sian	    !ISSET(tp->t_state, TS_TBLOCK))
316265690Sian		ttyblock(tp);
317265690Sian
318249997Swkoszek	/* Handle exceptional conditions (break, parity, framing). */
319265690Sian	cc = tp->t_cc;
320249997Swkoszek	err = (ISSET(c, TTY_ERRORMASK));
321249997Swkoszek	if (err) {
322249997Swkoszek		CLR(c, TTY_ERRORMASK);
323249997Swkoszek		if (ISSET(err, TTY_BI)) {
324249997Swkoszek			if (ISSET(iflag, IGNBRK))
325249997Swkoszek				return (0);
326249997Swkoszek			if (ISSET(iflag, BRKINT)) {
327249997Swkoszek				ttyflush(tp, FREAD | FWRITE);
328249997Swkoszek				pgsignal(tp->t_pgrp, SIGINT, 1);
329249997Swkoszek				goto endcase;
330249997Swkoszek			}
331249997Swkoszek			if (ISSET(iflag, PARMRK))
332249997Swkoszek				goto parmrk;
333249997Swkoszek		} else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
334249997Swkoszek			|| ISSET(err, TTY_FE)) {
335249997Swkoszek			if (ISSET(iflag, IGNPAR))
336249997Swkoszek				return (0);
337249997Swkoszek			else if (ISSET(iflag, PARMRK)) {
338249997Swkoszekparmrk:
339249997Swkoszek				if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
340249997Swkoszek				    MAX_INPUT - 3)
341249997Swkoszek					goto input_overflow;
342249997Swkoszek				(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
343249997Swkoszek				(void)putc(0 | TTY_QUOTE, &tp->t_rawq);
344249997Swkoszek				(void)putc(c | TTY_QUOTE, &tp->t_rawq);
345249997Swkoszek				goto endcase;
346249997Swkoszek			} else
347249997Swkoszek				c = 0;
348249997Swkoszek		}
349249997Swkoszek	}
350249997Swkoszek
351249997Swkoszek	if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
352249997Swkoszek		CLR(c, 0x80);
353249997Swkoszek	if (!ISSET(lflag, EXTPROC)) {
354249997Swkoszek		/*
355249997Swkoszek		 * Check for literal nexting very first
356249997Swkoszek		 */
357249997Swkoszek		if (ISSET(tp->t_state, TS_LNCH)) {
358249997Swkoszek			SET(c, TTY_QUOTE);
359249997Swkoszek			CLR(tp->t_state, TS_LNCH);
360249997Swkoszek		}
361249997Swkoszek		/*
362249997Swkoszek		 * Scan for special characters.  This code
363249997Swkoszek		 * is really just a big case statement with
364249997Swkoszek		 * non-constant cases.  The bottom of the
365249997Swkoszek		 * case statement is labeled ``endcase'', so goto
366249997Swkoszek		 * it after a case match, or similar.
367249997Swkoszek		 */
368249997Swkoszek
369249997Swkoszek		/*
370249997Swkoszek		 * Control chars which aren't controlled
371249997Swkoszek		 * by ICANON, ISIG, or IXON.
372249997Swkoszek		 */
373249997Swkoszek		if (ISSET(lflag, IEXTEN)) {
374249997Swkoszek			if (CCEQ(cc[VLNEXT], c)) {
375249997Swkoszek				if (ISSET(lflag, ECHO)) {
376249997Swkoszek					if (ISSET(lflag, ECHOE)) {
377249997Swkoszek						(void)ttyoutput('^', tp);
378249997Swkoszek						(void)ttyoutput('\b', tp);
379249997Swkoszek					} else
380249997Swkoszek						ttyecho(c, tp);
381249997Swkoszek				}
382249997Swkoszek				SET(tp->t_state, TS_LNCH);
383249997Swkoszek				goto endcase;
384249997Swkoszek			}
385249997Swkoszek			if (CCEQ(cc[VDISCARD], c)) {
386249997Swkoszek				if (ISSET(lflag, FLUSHO))
387249997Swkoszek					CLR(tp->t_lflag, FLUSHO);
388249997Swkoszek				else {
389249997Swkoszek					ttyflush(tp, FWRITE);
390249997Swkoszek					ttyecho(c, tp);
391249997Swkoszek					if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
392249997Swkoszek						ttyretype(tp);
393249997Swkoszek					SET(tp->t_lflag, FLUSHO);
394249997Swkoszek				}
395249997Swkoszek				goto startoutput;
396249997Swkoszek			}
397249997Swkoszek		}
398249997Swkoszek		/*
399249997Swkoszek		 * Signals.
400249997Swkoszek		 */
401249997Swkoszek		if (ISSET(lflag, ISIG)) {
402249997Swkoszek			if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
403249997Swkoszek				if (!ISSET(lflag, NOFLSH))
404249997Swkoszek					ttyflush(tp, FREAD | FWRITE);
405249997Swkoszek				ttyecho(c, tp);
406249997Swkoszek				pgsignal(tp->t_pgrp,
407249997Swkoszek				    CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
408249997Swkoszek				goto endcase;
409249997Swkoszek			}
410249997Swkoszek			if (CCEQ(cc[VSUSP], c)) {
411249997Swkoszek				if (!ISSET(lflag, NOFLSH))
412249997Swkoszek					ttyflush(tp, FREAD);
413249997Swkoszek				ttyecho(c, tp);
414249997Swkoszek				pgsignal(tp->t_pgrp, SIGTSTP, 1);
415249997Swkoszek				goto endcase;
416249997Swkoszek			}
417249997Swkoszek		}
418265690Sian		/*
419249997Swkoszek		 * Handle start/stop characters.
420265690Sian		 */
421249997Swkoszek		if (ISSET(iflag, IXON)) {
422249997Swkoszek			if (CCEQ(cc[VSTOP], c)) {
423249997Swkoszek				if (!ISSET(tp->t_state, TS_TTSTOP)) {
424249997Swkoszek					SET(tp->t_state, TS_TTSTOP);
425249997Swkoszek					(*tp->t_stop)(tp, 0);
426249997Swkoszek					return (0);
427249997Swkoszek				}
428249997Swkoszek				if (!CCEQ(cc[VSTART], c))
429249997Swkoszek					return (0);
430249997Swkoszek				/*
431249997Swkoszek				 * if VSTART == VSTOP then toggle
432249997Swkoszek				 */
433249997Swkoszek				goto endcase;
434249997Swkoszek			}
435249997Swkoszek			if (CCEQ(cc[VSTART], c))
436249997Swkoszek				goto restartoutput;
437249997Swkoszek		}
438249997Swkoszek		/*
439249997Swkoszek		 * IGNCR, ICRNL, & INLCR
440249997Swkoszek		 */
441249997Swkoszek		if (c == '\r') {
442249997Swkoszek			if (ISSET(iflag, IGNCR))
443249997Swkoszek				return (0);
444249997Swkoszek			else if (ISSET(iflag, ICRNL))
445249997Swkoszek				c = '\n';
446249997Swkoszek		} else if (c == '\n' && ISSET(iflag, INLCR))
447249997Swkoszek			c = '\r';
448249997Swkoszek	}
449249997Swkoszek	if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
450249997Swkoszek		/*
451249997Swkoszek		 * From here on down canonical mode character
452249997Swkoszek		 * processing takes place.
453249997Swkoszek		 */
454249997Swkoszek		/*
455249997Swkoszek		 * erase (^H / ^?)
456249997Swkoszek		 */
457249997Swkoszek		if (CCEQ(cc[VERASE], c)) {
458249997Swkoszek			if (tp->t_rawq.c_cc)
459249997Swkoszek				ttyrub(unputc(&tp->t_rawq), tp);
460249997Swkoszek			goto endcase;
461249997Swkoszek		}
462249997Swkoszek		/*
463249997Swkoszek		 * kill (^U)
464249997Swkoszek		 */
465249997Swkoszek		if (CCEQ(cc[VKILL], c)) {
466249997Swkoszek			if (ISSET(lflag, ECHOKE) &&
467249997Swkoszek			    tp->t_rawq.c_cc == tp->t_rocount &&
468249997Swkoszek			    !ISSET(lflag, ECHOPRT))
469249997Swkoszek				while (tp->t_rawq.c_cc)
470249997Swkoszek					ttyrub(unputc(&tp->t_rawq), tp);
471249997Swkoszek			else {
472249997Swkoszek				ttyecho(c, tp);
473249997Swkoszek				if (ISSET(lflag, ECHOK) ||
474249997Swkoszek				    ISSET(lflag, ECHOKE))
475249997Swkoszek					ttyecho('\n', tp);
476249997Swkoszek				FLUSHQ(&tp->t_rawq);
477249997Swkoszek				tp->t_rocount = 0;
478249997Swkoszek			}
479249997Swkoszek			CLR(tp->t_state, TS_LOCAL);
480249997Swkoszek			goto endcase;
481249997Swkoszek		}
482249997Swkoszek		/*
483249997Swkoszek		 * word erase (^W)
484249997Swkoszek		 */
485249997Swkoszek		if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
486249997Swkoszek			int ctype;
487249997Swkoszek
488249997Swkoszek			/*
489249997Swkoszek			 * erase whitespace
490249997Swkoszek			 */
491249997Swkoszek			while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
492249997Swkoszek				ttyrub(c, tp);
493249997Swkoszek			if (c == -1)
494249997Swkoszek				goto endcase;
495249997Swkoszek			/*
496249997Swkoszek			 * erase last char of word and remember the
497249997Swkoszek			 * next chars type (for ALTWERASE)
498249997Swkoszek			 */
499249997Swkoszek			ttyrub(c, tp);
500249997Swkoszek			c = unputc(&tp->t_rawq);
501249997Swkoszek			if (c == -1)
502249997Swkoszek				goto endcase;
503249997Swkoszek			if (c == ' ' || c == '\t') {
504249997Swkoszek				(void)putc(c, &tp->t_rawq);
505249997Swkoszek				goto endcase;
506249997Swkoszek			}
507249997Swkoszek			ctype = ISALPHA(c);
508249997Swkoszek			/*
509249997Swkoszek			 * erase rest of word
510249997Swkoszek			 */
511249997Swkoszek			do {
512249997Swkoszek				ttyrub(c, tp);
513249997Swkoszek				c = unputc(&tp->t_rawq);
514249997Swkoszek				if (c == -1)
515249997Swkoszek					goto endcase;
516249997Swkoszek			} while (c != ' ' && c != '\t' &&
517249997Swkoszek			    (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
518249997Swkoszek			(void)putc(c, &tp->t_rawq);
519249997Swkoszek			goto endcase;
520249997Swkoszek		}
521249997Swkoszek		/*
522249997Swkoszek		 * reprint line (^R)
523249997Swkoszek		 */
524249997Swkoszek		if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
525249997Swkoszek			ttyretype(tp);
526249997Swkoszek			goto endcase;
527249997Swkoszek		}
528249997Swkoszek		/*
529249997Swkoszek		 * ^T - kernel info and generate SIGINFO
530249997Swkoszek		 */
531249997Swkoszek		if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
532249997Swkoszek			if (ISSET(lflag, ISIG))
533249997Swkoszek				pgsignal(tp->t_pgrp, SIGINFO, 1);
534249997Swkoszek			if (!ISSET(lflag, NOKERNINFO))
535261410Sian				ttyinfo(tp);
536261410Sian			goto endcase;
537261410Sian		}
538261410Sian	}
539249997Swkoszek	/*
540249997Swkoszek	 * Check for input buffer overflow
541249997Swkoszek	 */
542249997Swkoszek	if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
543249997Swkoszekinput_overflow:
544249997Swkoszek		if (ISSET(iflag, IMAXBEL)) {
545249997Swkoszek			if (tp->t_outq.c_cc < tp->t_ohiwat)
546249997Swkoszek				(void)ttyoutput(CTRL('g'), tp);
547249997Swkoszek		}
548249997Swkoszek		goto endcase;
549249997Swkoszek	}
550249997Swkoszek
551249997Swkoszek	if (   c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
552249997Swkoszek	     && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
553249997Swkoszek		(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
554249997Swkoszek
555249997Swkoszek	/*
556249997Swkoszek	 * Put data char in q for user and
557249997Swkoszek	 * wakeup on seeing a line delimiter.
558249997Swkoszek	 */
559249997Swkoszek	if (putc(c, &tp->t_rawq) >= 0) {
560249997Swkoszek		if (!ISSET(lflag, ICANON)) {
561249997Swkoszek			ttwakeup(tp);
562249997Swkoszek			ttyecho(c, tp);
563249997Swkoszek			goto endcase;
564249997Swkoszek		}
565249997Swkoszek		if (TTBREAKC(c, lflag)) {
566249997Swkoszek			tp->t_rocount = 0;
567249997Swkoszek			catq(&tp->t_rawq, &tp->t_canq);
568249997Swkoszek			ttwakeup(tp);
569249997Swkoszek		} else if (tp->t_rocount++ == 0)
570249997Swkoszek			tp->t_rocol = tp->t_column;
571249997Swkoszek		if (ISSET(tp->t_state, TS_ERASE)) {
572249997Swkoszek			/*
573249997Swkoszek			 * end of prterase \.../
574249997Swkoszek			 */
575249997Swkoszek			CLR(tp->t_state, TS_ERASE);
576249997Swkoszek			(void)ttyoutput('/', tp);
577249997Swkoszek		}
578249997Swkoszek		i = tp->t_column;
579249997Swkoszek		ttyecho(c, tp);
580249997Swkoszek		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
581249997Swkoszek			/*
582249997Swkoszek			 * Place the cursor over the '^' of the ^D.
583249997Swkoszek			 */
584249997Swkoszek			i = imin(2, tp->t_column - i);
585249997Swkoszek			while (i > 0) {
586249997Swkoszek				(void)ttyoutput('\b', tp);
587249997Swkoszek				i--;
588249997Swkoszek			}
589249997Swkoszek		}
590249997Swkoszek	}
591249997Swkoszekendcase:
592249997Swkoszek	/*
593249997Swkoszek	 * IXANY means allow any character to restart output.
594249997Swkoszek	 */
595249997Swkoszek	if (ISSET(tp->t_state, TS_TTSTOP) &&
596249997Swkoszek	    !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
597249997Swkoszek		return (0);
598249997Swkoszekrestartoutput:
599249997Swkoszek	CLR(tp->t_lflag, FLUSHO);
600249997Swkoszek	CLR(tp->t_state, TS_TTSTOP);
601249997Swkoszekstartoutput:
602249997Swkoszek	return (ttstart(tp));
603249997Swkoszek}
604249997Swkoszek
605249997Swkoszek/*
606249997Swkoszek * Output a single character on a tty, doing output processing
607249997Swkoszek * as needed (expanding tabs, newline processing, etc.).
608249997Swkoszek * Returns < 0 if succeeds, otherwise returns char to resend.
609249997Swkoszek * Must be recursive.
610249997Swkoszek */
611249997Swkoszekstatic int
612249997Swkoszekttyoutput(c, tp)
613249997Swkoszek	register int c;
614249997Swkoszek	register struct tty *tp;
615249997Swkoszek{
616249997Swkoszek	register tcflag_t oflag;
617249997Swkoszek	register int col, s;
618249997Swkoszek
619249997Swkoszek	oflag = tp->t_oflag;
620249997Swkoszek	if (!ISSET(oflag, OPOST)) {
621249997Swkoszek		if (ISSET(tp->t_lflag, FLUSHO))
622249997Swkoszek			return (-1);
623249997Swkoszek		if (putc(c, &tp->t_outq))
624249997Swkoszek			return (c);
625249997Swkoszek		tk_nout++;
626249997Swkoszek		tp->t_outcc++;
627249997Swkoszek		return (-1);
628249997Swkoszek	}
629249997Swkoszek	/*
630249997Swkoszek	 * Do tab expansion if OXTABS is set.  Special case if we external
631249997Swkoszek	 * processing, we don't do the tab expansion because we'll probably
632249997Swkoszek	 * get it wrong.  If tab expansion needs to be done, let it happen
633249997Swkoszek	 * externally.
634249997Swkoszek	 */
635249997Swkoszek	CLR(c, ~TTY_CHARMASK);
636249997Swkoszek	if (c == '\t' &&
637249997Swkoszek	    ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
638249997Swkoszek		c = 8 - (tp->t_column & 7);
639249997Swkoszek		if (!ISSET(tp->t_lflag, FLUSHO)) {
640249997Swkoszek			s = spltty();		/* Don't interrupt tabs. */
641249997Swkoszek			c -= b_to_q("        ", c, &tp->t_outq);
642249997Swkoszek			tk_nout += c;
643249997Swkoszek			tp->t_outcc += c;
644249997Swkoszek			splx(s);
645249997Swkoszek		}
646249997Swkoszek		tp->t_column += c;
647249997Swkoszek		return (c ? -1 : '\t');
648249997Swkoszek	}
649249997Swkoszek	if (c == CEOT && ISSET(oflag, ONOEOT))
650249997Swkoszek		return (-1);
651249997Swkoszek
652249997Swkoszek	/*
653249997Swkoszek	 * Newline translation: if ONLCR is set,
654249997Swkoszek	 * translate newline into "\r\n".
655249997Swkoszek	 */
656249997Swkoszek	if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
657249997Swkoszek		tk_nout++;
658249997Swkoszek		tp->t_outcc++;
659249997Swkoszek		if (putc('\r', &tp->t_outq))
660249997Swkoszek			return (c);
661249997Swkoszek	}
662249997Swkoszek	tk_nout++;
663249997Swkoszek	tp->t_outcc++;
664249997Swkoszek	if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
665249997Swkoszek		return (c);
666249997Swkoszek
667249997Swkoszek	col = tp->t_column;
668249997Swkoszek	switch (CCLASS(c)) {
669	case BACKSPACE:
670		if (col > 0)
671			--col;
672		break;
673	case CONTROL:
674		break;
675	case NEWLINE:
676	case RETURN:
677		col = 0;
678		break;
679	case ORDINARY:
680		++col;
681		break;
682	case TAB:
683		col = (col + 8) & ~7;
684		break;
685	}
686	tp->t_column = col;
687	return (-1);
688}
689
690/*
691 * Ioctls for all tty devices.  Called after line-discipline specific ioctl
692 * has been called to do discipline-specific functions and/or reject any
693 * of these ioctl commands.
694 */
695/* ARGSUSED */
696int
697ttioctl(tp, cmd, data, flag)
698	register struct tty *tp;
699	u_long cmd;
700	int flag;
701	void *data;
702{
703	register struct proc *p;
704	int s, error;
705
706	p = curproc;			/* XXX */
707
708	/* If the ioctl involves modification, hang if in the background. */
709	switch (cmd) {
710	case  TIOCCBRK:
711	case  TIOCCONS:
712	case  TIOCDRAIN:
713	case  TIOCEXCL:
714	case  TIOCFLUSH:
715#ifdef TIOCHPCL
716	case  TIOCHPCL:
717#endif
718	case  TIOCNXCL:
719	case  TIOCSBRK:
720	case  TIOCSCTTY:
721	case  TIOCSDRAINWAIT:
722	case  TIOCSETA:
723	case  TIOCSETAF:
724	case  TIOCSETAW:
725	case  TIOCSETD:
726	case  TIOCSPGRP:
727	case  TIOCSTART:
728	case  TIOCSTAT:
729	case  TIOCSTI:
730	case  TIOCSTOP:
731	case  TIOCSWINSZ:
732#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
733	case  TIOCLBIC:
734	case  TIOCLBIS:
735	case  TIOCLSET:
736	case  TIOCSETC:
737	case OTIOCSETD:
738	case  TIOCSETN:
739	case  TIOCSETP:
740	case  TIOCSLTC:
741#endif
742		while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
743		    !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
744		    !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
745			if (p->p_pgrp->pg_jobc == 0)
746				return (EIO);
747			pgsignal(p->p_pgrp, SIGTTOU, 1);
748			error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1",
749					 0);
750			if (error)
751				return (error);
752		}
753		break;
754	}
755
756	switch (cmd) {			/* Process the ioctl. */
757	case FIOASYNC:			/* set/clear async i/o */
758		s = spltty();
759		if (*(int *)data)
760			SET(tp->t_state, TS_ASYNC);
761		else
762			CLR(tp->t_state, TS_ASYNC);
763		splx(s);
764		break;
765	case FIONBIO:			/* set/clear non-blocking i/o */
766		break;			/* XXX: delete. */
767	case FIONREAD:			/* get # bytes to read */
768		s = spltty();
769		*(int *)data = ttnread(tp);
770		splx(s);
771		break;
772
773	case FIOSETOWN:
774		/*
775		 * Policy -- Don't allow FIOSETOWN on someone else's
776		 *           controlling tty
777		 */
778		if (tp->t_session != NULL && !isctty(p, tp))
779			return (ENOTTY);
780
781		error = fsetown(*(int *)data, &tp->t_sigio);
782		if (error)
783			return (error);
784		break;
785	case FIOGETOWN:
786		if (tp->t_session != NULL && !isctty(p, tp))
787			return (ENOTTY);
788		*(int *)data = fgetown(tp->t_sigio);
789		break;
790
791	case TIOCEXCL:			/* set exclusive use of tty */
792		s = spltty();
793		SET(tp->t_state, TS_XCLUDE);
794		splx(s);
795		break;
796	case TIOCFLUSH: {		/* flush buffers */
797		register int flags = *(int *)data;
798
799		if (flags == 0)
800			flags = FREAD | FWRITE;
801		else
802			flags &= FREAD | FWRITE;
803		ttyflush(tp, flags);
804		break;
805	}
806	case TIOCCONS:			/* become virtual console */
807		if (*(int *)data) {
808			if (constty && constty != tp &&
809			    ISSET(constty->t_state, TS_CONNECTED))
810				return (EBUSY);
811#ifndef	UCONSOLE
812			if ((error = suser(p)) != 0)
813				return (error);
814#endif
815			constty = tp;
816		} else if (tp == constty)
817			constty = NULL;
818		break;
819	case TIOCDRAIN:			/* wait till output drained */
820		error = ttywait(tp);
821		if (error)
822			return (error);
823		break;
824	case TIOCGETA: {		/* get termios struct */
825		struct termios *t = (struct termios *)data;
826
827		bcopy(&tp->t_termios, t, sizeof(struct termios));
828		break;
829	}
830	case TIOCGETD:			/* get line discipline */
831		*(int *)data = tp->t_line;
832		break;
833	case TIOCGWINSZ:		/* get window size */
834		*(struct winsize *)data = tp->t_winsize;
835		break;
836	case TIOCGPGRP:			/* get pgrp of tty */
837		if (!isctty(p, tp))
838			return (ENOTTY);
839		*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
840		break;
841#ifdef TIOCHPCL
842	case TIOCHPCL:			/* hang up on last close */
843		s = spltty();
844		SET(tp->t_cflag, HUPCL);
845		splx(s);
846		break;
847#endif
848	case TIOCNXCL:			/* reset exclusive use of tty */
849		s = spltty();
850		CLR(tp->t_state, TS_XCLUDE);
851		splx(s);
852		break;
853	case TIOCOUTQ:			/* output queue size */
854		*(int *)data = tp->t_outq.c_cc;
855		break;
856	case TIOCSETA:			/* set termios struct */
857	case TIOCSETAW:			/* drain output, set */
858	case TIOCSETAF: {		/* drn out, fls in, set */
859		register struct termios *t = (struct termios *)data;
860
861		if (t->c_ispeed == 0)
862			t->c_ispeed = t->c_ospeed;
863		if (t->c_ispeed == 0)
864			t->c_ispeed = tp->t_ospeed;
865		if (t->c_ispeed == 0)
866			return (EINVAL);
867		s = spltty();
868		if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
869			error = ttywait(tp);
870			if (error) {
871				splx(s);
872				return (error);
873			}
874			if (cmd == TIOCSETAF)
875				ttyflush(tp, FREAD);
876		}
877		if (!ISSET(t->c_cflag, CIGNORE)) {
878			/*
879			 * Set device hardware.
880			 */
881			if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
882				splx(s);
883				return (error);
884			}
885			if (ISSET(t->c_cflag, CLOCAL) &&
886			    !ISSET(tp->t_cflag, CLOCAL)) {
887				/*
888				 * XXX disconnections would be too hard to
889				 * get rid of without this kludge.  The only
890				 * way to get rid of controlling terminals
891				 * is to exit from the session leader.
892				 */
893				CLR(tp->t_state, TS_ZOMBIE);
894
895				wakeup(TSA_CARR_ON(tp));
896				ttwakeup(tp);
897				ttwwakeup(tp);
898			}
899			if ((ISSET(tp->t_state, TS_CARR_ON) ||
900			     ISSET(t->c_cflag, CLOCAL)) &&
901			    !ISSET(tp->t_state, TS_ZOMBIE))
902				SET(tp->t_state, TS_CONNECTED);
903			else
904				CLR(tp->t_state, TS_CONNECTED);
905			tp->t_cflag = t->c_cflag;
906			tp->t_ispeed = t->c_ispeed;
907			if (t->c_ospeed != 0)
908				tp->t_ospeed = t->c_ospeed;
909			ttsetwater(tp);
910		}
911		if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
912		    cmd != TIOCSETAF) {
913			if (ISSET(t->c_lflag, ICANON))
914				SET(tp->t_lflag, PENDIN);
915			else {
916				/*
917				 * XXX we really shouldn't allow toggling
918				 * ICANON while we're in a non-termios line
919				 * discipline.  Now we have to worry about
920				 * panicing for a null queue.
921				 */
922				if (tp->t_canq.c_cbreserved > 0 &&
923				    tp->t_rawq.c_cbreserved > 0) {
924					catq(&tp->t_rawq, &tp->t_canq);
925					/*
926					 * XXX the queue limits may be
927					 * different, so the old queue
928					 * swapping method no longer works.
929					 */
930					catq(&tp->t_canq, &tp->t_rawq);
931				}
932				CLR(tp->t_lflag, PENDIN);
933			}
934			ttwakeup(tp);
935		}
936		tp->t_iflag = t->c_iflag;
937		tp->t_oflag = t->c_oflag;
938		/*
939		 * Make the EXTPROC bit read only.
940		 */
941		if (ISSET(tp->t_lflag, EXTPROC))
942			SET(t->c_lflag, EXTPROC);
943		else
944			CLR(t->c_lflag, EXTPROC);
945		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
946		if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
947		    t->c_cc[VTIME] != tp->t_cc[VTIME])
948			ttwakeup(tp);
949		bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
950		splx(s);
951		break;
952	}
953	case TIOCSETD: {		/* set line discipline */
954		register int t = *(int *)data;
955		dev_t device = tp->t_dev;
956
957		if ((u_int)t >= nlinesw)
958			return (ENXIO);
959		if (t != tp->t_line) {
960			s = spltty();
961			(*linesw[tp->t_line].l_close)(tp, flag);
962			error = (*linesw[t].l_open)(device, tp);
963			if (error) {
964				(void)(*linesw[tp->t_line].l_open)(device, tp);
965				splx(s);
966				return (error);
967			}
968			tp->t_line = t;
969			splx(s);
970		}
971		break;
972	}
973	case TIOCSTART:			/* start output, like ^Q */
974		s = spltty();
975		if (ISSET(tp->t_state, TS_TTSTOP) ||
976		    ISSET(tp->t_lflag, FLUSHO)) {
977			CLR(tp->t_lflag, FLUSHO);
978			CLR(tp->t_state, TS_TTSTOP);
979			ttstart(tp);
980		}
981		splx(s);
982		break;
983	case TIOCSTI:			/* simulate terminal input */
984		if ((flag & FREAD) == 0 && suser(p))
985			return (EPERM);
986		if (!isctty(p, tp) && suser(p))
987			return (EACCES);
988		s = spltty();
989		(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
990		splx(s);
991		break;
992	case TIOCSTOP:			/* stop output, like ^S */
993		s = spltty();
994		if (!ISSET(tp->t_state, TS_TTSTOP)) {
995			SET(tp->t_state, TS_TTSTOP);
996			(*tp->t_stop)(tp, 0);
997		}
998		splx(s);
999		break;
1000	case TIOCSCTTY:			/* become controlling tty */
1001		/* Session ctty vnode pointer set in vnode layer. */
1002		if (!SESS_LEADER(p) ||
1003		    ((p->p_session->s_ttyvp || tp->t_session) &&
1004		    (tp->t_session != p->p_session)))
1005			return (EPERM);
1006		tp->t_session = p->p_session;
1007		tp->t_pgrp = p->p_pgrp;
1008		p->p_session->s_ttyp = tp;
1009		p->p_flag |= P_CONTROLT;
1010		break;
1011	case TIOCSPGRP: {		/* set pgrp of tty */
1012		register struct pgrp *pgrp = pgfind(*(int *)data);
1013
1014		if (!isctty(p, tp))
1015			return (ENOTTY);
1016		else if (pgrp == NULL || pgrp->pg_session != p->p_session)
1017			return (EPERM);
1018		tp->t_pgrp = pgrp;
1019		break;
1020	}
1021	case TIOCSTAT:			/* simulate control-T */
1022		s = spltty();
1023		ttyinfo(tp);
1024		splx(s);
1025		break;
1026	case TIOCSWINSZ:		/* set window size */
1027		if (bcmp((caddr_t)&tp->t_winsize, data,
1028		    sizeof (struct winsize))) {
1029			tp->t_winsize = *(struct winsize *)data;
1030			pgsignal(tp->t_pgrp, SIGWINCH, 1);
1031		}
1032		break;
1033	case TIOCSDRAINWAIT:
1034		error = suser(p);
1035		if (error)
1036			return (error);
1037		tp->t_timeout = *(int *)data * hz;
1038		wakeup(TSA_OCOMPLETE(tp));
1039		wakeup(TSA_OLOWAT(tp));
1040		break;
1041	case TIOCGDRAINWAIT:
1042		*(int *)data = tp->t_timeout / hz;
1043		break;
1044	default:
1045#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1046		return (ttcompat(tp, cmd, data, flag));
1047#else
1048		return (ENOIOCTL);
1049#endif
1050	}
1051	return (0);
1052}
1053
1054int
1055ttypoll(dev, events, p)
1056	dev_t dev;
1057	int events;
1058	struct proc *p;
1059{
1060	int s;
1061	int revents = 0;
1062	struct tty *tp;
1063
1064	tp = dev->si_tty;
1065	if (tp == NULL)	/* XXX used to return ENXIO, but that means true! */
1066		return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM))
1067			| POLLHUP);
1068
1069	s = spltty();
1070	if (events & (POLLIN | POLLRDNORM)) {
1071		if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
1072			revents |= events & (POLLIN | POLLRDNORM);
1073		else
1074			selrecord(p, &tp->t_rsel);
1075	}
1076	if (events & (POLLOUT | POLLWRNORM)) {
1077		if ((tp->t_outq.c_cc <= tp->t_olowat &&
1078		     ISSET(tp->t_state, TS_CONNECTED))
1079		    || ISSET(tp->t_state, TS_ZOMBIE))
1080			revents |= events & (POLLOUT | POLLWRNORM);
1081		else
1082			selrecord(p, &tp->t_wsel);
1083	}
1084	splx(s);
1085	return (revents);
1086}
1087
1088/*
1089 * Must be called at spltty().
1090 */
1091static int
1092ttnread(tp)
1093	struct tty *tp;
1094{
1095	int nread;
1096
1097	if (ISSET(tp->t_lflag, PENDIN))
1098		ttypend(tp);
1099	nread = tp->t_canq.c_cc;
1100	if (!ISSET(tp->t_lflag, ICANON)) {
1101		nread += tp->t_rawq.c_cc;
1102		if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1103			nread = 0;
1104	}
1105	return (nread);
1106}
1107
1108/*
1109 * Wait for output to drain.
1110 */
1111int
1112ttywait(tp)
1113	register struct tty *tp;
1114{
1115	int error, s;
1116
1117	error = 0;
1118	s = spltty();
1119	while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1120	       ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1121		(*tp->t_oproc)(tp);
1122		if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1123		    ISSET(tp->t_state, TS_CONNECTED)) {
1124			SET(tp->t_state, TS_SO_OCOMPLETE);
1125			error = ttysleep(tp, TSA_OCOMPLETE(tp),
1126					 TTOPRI | PCATCH, "ttywai",
1127					 tp->t_timeout);
1128			if (error) {
1129				if (error == EWOULDBLOCK)
1130					error = EIO;
1131				break;
1132			}
1133		} else
1134			break;
1135	}
1136	if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1137		error = EIO;
1138	splx(s);
1139	return (error);
1140}
1141
1142/*
1143 * Flush if successfully wait.
1144 */
1145static int
1146ttywflush(tp)
1147	struct tty *tp;
1148{
1149	int error;
1150
1151	if ((error = ttywait(tp)) == 0)
1152		ttyflush(tp, FREAD);
1153	return (error);
1154}
1155
1156/*
1157 * Flush tty read and/or write queues, notifying anyone waiting.
1158 */
1159void
1160ttyflush(tp, rw)
1161	register struct tty *tp;
1162	int rw;
1163{
1164	register int s;
1165
1166	s = spltty();
1167#if 0
1168again:
1169#endif
1170	if (rw & FWRITE) {
1171		FLUSHQ(&tp->t_outq);
1172		CLR(tp->t_state, TS_TTSTOP);
1173	}
1174	(*tp->t_stop)(tp, rw);
1175	if (rw & FREAD) {
1176		FLUSHQ(&tp->t_canq);
1177		FLUSHQ(&tp->t_rawq);
1178		CLR(tp->t_lflag, PENDIN);
1179		tp->t_rocount = 0;
1180		tp->t_rocol = 0;
1181		CLR(tp->t_state, TS_LOCAL);
1182		ttwakeup(tp);
1183		if (ISSET(tp->t_state, TS_TBLOCK)) {
1184			if (rw & FWRITE)
1185				FLUSHQ(&tp->t_outq);
1186			ttyunblock(tp);
1187
1188			/*
1189			 * Don't let leave any state that might clobber the
1190			 * next line discipline (although we should do more
1191			 * to send the START char).  Not clearing the state
1192			 * may have caused the "putc to a clist with no
1193			 * reserved cblocks" panic/printf.
1194			 */
1195			CLR(tp->t_state, TS_TBLOCK);
1196
1197#if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1198			if (ISSET(tp->t_iflag, IXOFF)) {
1199				/*
1200				 * XXX wait a bit in the hope that the stop
1201				 * character (if any) will go out.  Waiting
1202				 * isn't good since it allows races.  This
1203				 * will be fixed when the stop character is
1204				 * put in a special queue.  Don't bother with
1205				 * the checks in ttywait() since the timeout
1206				 * will save us.
1207				 */
1208				SET(tp->t_state, TS_SO_OCOMPLETE);
1209				ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1210					 "ttyfls", hz / 10);
1211				/*
1212				 * Don't try sending the stop character again.
1213				 */
1214				CLR(tp->t_state, TS_TBLOCK);
1215				goto again;
1216			}
1217#endif
1218		}
1219	}
1220	if (rw & FWRITE) {
1221		FLUSHQ(&tp->t_outq);
1222		ttwwakeup(tp);
1223	}
1224	splx(s);
1225}
1226
1227/*
1228 * Copy in the default termios characters.
1229 */
1230void
1231termioschars(t)
1232	struct termios *t;
1233{
1234
1235	bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1236}
1237
1238/*
1239 * Old interface.
1240 */
1241void
1242ttychars(tp)
1243	struct tty *tp;
1244{
1245
1246	termioschars(&tp->t_termios);
1247}
1248
1249/*
1250 * Handle input high water.  Send stop character for the IXOFF case.  Turn
1251 * on our input flow control bit and propagate the changes to the driver.
1252 * XXX the stop character should be put in a special high priority queue.
1253 */
1254void
1255ttyblock(tp)
1256	struct tty *tp;
1257{
1258
1259	SET(tp->t_state, TS_TBLOCK);
1260	if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1261	    putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1262		CLR(tp->t_state, TS_TBLOCK);	/* try again later */
1263	ttstart(tp);
1264}
1265
1266/*
1267 * Handle input low water.  Send start character for the IXOFF case.  Turn
1268 * off our input flow control bit and propagate the changes to the driver.
1269 * XXX the start character should be put in a special high priority queue.
1270 */
1271static void
1272ttyunblock(tp)
1273	struct tty *tp;
1274{
1275
1276	CLR(tp->t_state, TS_TBLOCK);
1277	if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1278	    putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1279		SET(tp->t_state, TS_TBLOCK);	/* try again later */
1280	ttstart(tp);
1281}
1282
1283#ifdef notyet
1284/* Not used by any current (i386) drivers. */
1285/*
1286 * Restart after an inter-char delay.
1287 */
1288void
1289ttrstrt(tp_arg)
1290	void *tp_arg;
1291{
1292	struct tty *tp;
1293	int s;
1294
1295	KASSERT(tp_arg != NULL, ("ttrstrt"));
1296
1297	tp = tp_arg;
1298	s = spltty();
1299
1300	CLR(tp->t_state, TS_TIMEOUT);
1301	ttstart(tp);
1302
1303	splx(s);
1304}
1305#endif
1306
1307int
1308ttstart(tp)
1309	struct tty *tp;
1310{
1311
1312	if (tp->t_oproc != NULL)	/* XXX: Kludge for pty. */
1313		(*tp->t_oproc)(tp);
1314	return (0);
1315}
1316
1317/*
1318 * "close" a line discipline
1319 */
1320int
1321ttylclose(tp, flag)
1322	struct tty *tp;
1323	int flag;
1324{
1325
1326	if (flag & FNONBLOCK || ttywflush(tp))
1327		ttyflush(tp, FREAD | FWRITE);
1328	return (0);
1329}
1330
1331/*
1332 * Handle modem control transition on a tty.
1333 * Flag indicates new state of carrier.
1334 * Returns 0 if the line should be turned off, otherwise 1.
1335 */
1336int
1337ttymodem(tp, flag)
1338	register struct tty *tp;
1339	int flag;
1340{
1341
1342	if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1343		/*
1344		 * MDMBUF: do flow control according to carrier flag
1345		 * XXX TS_CAR_OFLOW doesn't do anything yet.  TS_TTSTOP
1346		 * works if IXON and IXANY are clear.
1347		 */
1348		if (flag) {
1349			CLR(tp->t_state, TS_CAR_OFLOW);
1350			CLR(tp->t_state, TS_TTSTOP);
1351			ttstart(tp);
1352		} else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1353			SET(tp->t_state, TS_CAR_OFLOW);
1354			SET(tp->t_state, TS_TTSTOP);
1355			(*tp->t_stop)(tp, 0);
1356		}
1357	} else if (flag == 0) {
1358		/*
1359		 * Lost carrier.
1360		 */
1361		CLR(tp->t_state, TS_CARR_ON);
1362		if (ISSET(tp->t_state, TS_ISOPEN) &&
1363		    !ISSET(tp->t_cflag, CLOCAL)) {
1364			SET(tp->t_state, TS_ZOMBIE);
1365			CLR(tp->t_state, TS_CONNECTED);
1366			if (tp->t_session && tp->t_session->s_leader)
1367				psignal(tp->t_session->s_leader, SIGHUP);
1368			ttyflush(tp, FREAD | FWRITE);
1369			return (0);
1370		}
1371	} else {
1372		/*
1373		 * Carrier now on.
1374		 */
1375		SET(tp->t_state, TS_CARR_ON);
1376		if (!ISSET(tp->t_state, TS_ZOMBIE))
1377			SET(tp->t_state, TS_CONNECTED);
1378		wakeup(TSA_CARR_ON(tp));
1379		ttwakeup(tp);
1380		ttwwakeup(tp);
1381	}
1382	return (1);
1383}
1384
1385/*
1386 * Reinput pending characters after state switch
1387 * call at spltty().
1388 */
1389static void
1390ttypend(tp)
1391	register struct tty *tp;
1392{
1393	struct clist tq;
1394	register int c;
1395
1396	CLR(tp->t_lflag, PENDIN);
1397	SET(tp->t_state, TS_TYPEN);
1398	/*
1399	 * XXX this assumes too much about clist internals.  It may even
1400	 * fail if the cblock slush pool is empty.  We can't allocate more
1401	 * cblocks here because we are called from an interrupt handler
1402	 * and clist_alloc_cblocks() can wait.
1403	 */
1404	tq = tp->t_rawq;
1405	bzero(&tp->t_rawq, sizeof tp->t_rawq);
1406	tp->t_rawq.c_cbmax = tq.c_cbmax;
1407	tp->t_rawq.c_cbreserved = tq.c_cbreserved;
1408	while ((c = getc(&tq)) >= 0)
1409		ttyinput(c, tp);
1410	CLR(tp->t_state, TS_TYPEN);
1411}
1412
1413/*
1414 * Process a read call on a tty device.
1415 */
1416int
1417ttread(tp, uio, flag)
1418	register struct tty *tp;
1419	struct uio *uio;
1420	int flag;
1421{
1422	register struct clist *qp;
1423	register int c;
1424	register tcflag_t lflag;
1425	register cc_t *cc = tp->t_cc;
1426	register struct proc *p = curproc;
1427	int s, first, error = 0;
1428	int has_stime = 0, last_cc = 0;
1429	long slp = 0;		/* XXX this should be renamed `timo'. */
1430	struct timeval stime;
1431
1432loop:
1433	s = spltty();
1434	lflag = tp->t_lflag;
1435	/*
1436	 * take pending input first
1437	 */
1438	if (ISSET(lflag, PENDIN)) {
1439		ttypend(tp);
1440		splx(s);	/* reduce latency */
1441		s = spltty();
1442		lflag = tp->t_lflag;	/* XXX ttypend() clobbers it */
1443	}
1444
1445	/*
1446	 * Hang process if it's in the background.
1447	 */
1448	if (isbackground(p, tp)) {
1449		splx(s);
1450		if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
1451		    SIGISMEMBER(p->p_sigmask, SIGTTIN) ||
1452		    (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0)
1453			return (EIO);
1454		pgsignal(p->p_pgrp, SIGTTIN, 1);
1455		error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1456		if (error)
1457			return (error);
1458		goto loop;
1459	}
1460
1461	if (ISSET(tp->t_state, TS_ZOMBIE)) {
1462		splx(s);
1463		return (0);	/* EOF */
1464	}
1465
1466	/*
1467	 * If canonical, use the canonical queue,
1468	 * else use the raw queue.
1469	 *
1470	 * (should get rid of clists...)
1471	 */
1472	qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1473
1474	if (flag & IO_NDELAY) {
1475		if (qp->c_cc > 0)
1476			goto read;
1477		if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1478			splx(s);
1479			return (0);
1480		}
1481		splx(s);
1482		return (EWOULDBLOCK);
1483	}
1484	if (!ISSET(lflag, ICANON)) {
1485		int m = cc[VMIN];
1486		long t = cc[VTIME];
1487		struct timeval timecopy;
1488
1489		/*
1490		 * Check each of the four combinations.
1491		 * (m > 0 && t == 0) is the normal read case.
1492		 * It should be fairly efficient, so we check that and its
1493		 * companion case (m == 0 && t == 0) first.
1494		 * For the other two cases, we compute the target sleep time
1495		 * into slp.
1496		 */
1497		if (t == 0) {
1498			if (qp->c_cc < m)
1499				goto sleep;
1500			if (qp->c_cc > 0)
1501				goto read;
1502
1503			/* m, t and qp->c_cc are all 0.  0 is enough input. */
1504			splx(s);
1505			return (0);
1506		}
1507		t *= 100000;		/* time in us */
1508#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1509			 ((t1).tv_usec - (t2).tv_usec))
1510		if (m > 0) {
1511			if (qp->c_cc <= 0)
1512				goto sleep;
1513			if (qp->c_cc >= m)
1514				goto read;
1515			getmicrotime(&timecopy);
1516			if (!has_stime) {
1517				/* first character, start timer */
1518				has_stime = 1;
1519				stime = timecopy;
1520				slp = t;
1521			} else if (qp->c_cc > last_cc) {
1522				/* got a character, restart timer */
1523				stime = timecopy;
1524				slp = t;
1525			} else {
1526				/* nothing, check expiration */
1527				slp = t - diff(timecopy, stime);
1528				if (slp <= 0)
1529					goto read;
1530			}
1531			last_cc = qp->c_cc;
1532		} else {	/* m == 0 */
1533			if (qp->c_cc > 0)
1534				goto read;
1535			getmicrotime(&timecopy);
1536			if (!has_stime) {
1537				has_stime = 1;
1538				stime = timecopy;
1539				slp = t;
1540			} else {
1541				slp = t - diff(timecopy, stime);
1542				if (slp <= 0) {
1543					/* Timed out, but 0 is enough input. */
1544					splx(s);
1545					return (0);
1546				}
1547			}
1548		}
1549#undef diff
1550		/*
1551		 * Rounding down may make us wake up just short
1552		 * of the target, so we round up.
1553		 * The formula is ceiling(slp * hz/1000000).
1554		 * 32-bit arithmetic is enough for hz < 169.
1555		 * XXX see tvtohz() for how to avoid overflow if hz
1556		 * is large (divide by `tick' and/or arrange to
1557		 * use tvtohz() if hz is large).
1558		 */
1559		slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1560		goto sleep;
1561	}
1562	if (qp->c_cc <= 0) {
1563sleep:
1564		/*
1565		 * There is no input, or not enough input and we can block.
1566		 */
1567		error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
1568				 ISSET(tp->t_state, TS_CONNECTED) ?
1569				 "ttyin" : "ttyhup", (int)slp);
1570		splx(s);
1571		if (error == EWOULDBLOCK)
1572			error = 0;
1573		else if (error)
1574			return (error);
1575		/*
1576		 * XXX what happens if another process eats some input
1577		 * while we are asleep (not just here)?  It would be
1578		 * safest to detect changes and reset our state variables
1579		 * (has_stime and last_cc).
1580		 */
1581		slp = 0;
1582		goto loop;
1583	}
1584read:
1585	splx(s);
1586	/*
1587	 * Input present, check for input mapping and processing.
1588	 */
1589	first = 1;
1590	if (ISSET(lflag, ICANON | ISIG))
1591		goto slowcase;
1592	for (;;) {
1593		char ibuf[IBUFSIZ];
1594		int icc;
1595
1596		icc = imin(uio->uio_resid, IBUFSIZ);
1597		icc = q_to_b(qp, ibuf, icc);
1598		if (icc <= 0) {
1599			if (first)
1600				goto loop;
1601			break;
1602		}
1603		error = uiomove(ibuf, icc, uio);
1604		/*
1605		 * XXX if there was an error then we should ungetc() the
1606		 * unmoved chars and reduce icc here.
1607		 */
1608#if NSNP > 0
1609		if (ISSET(tp->t_lflag, ECHO) &&
1610		    ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
1611			snpin((struct snoop *)tp->t_sc, ibuf, icc);
1612#endif
1613		if (error)
1614			break;
1615 		if (uio->uio_resid == 0)
1616			break;
1617		first = 0;
1618	}
1619	goto out;
1620slowcase:
1621	for (;;) {
1622		c = getc(qp);
1623		if (c < 0) {
1624			if (first)
1625				goto loop;
1626			break;
1627		}
1628		/*
1629		 * delayed suspend (^Y)
1630		 */
1631		if (CCEQ(cc[VDSUSP], c) &&
1632		    ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1633			pgsignal(tp->t_pgrp, SIGTSTP, 1);
1634			if (first) {
1635				error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1636						 "ttybg3", 0);
1637				if (error)
1638					break;
1639				goto loop;
1640			}
1641			break;
1642		}
1643		/*
1644		 * Interpret EOF only in canonical mode.
1645		 */
1646		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1647			break;
1648		/*
1649		 * Give user character.
1650		 */
1651 		error = ureadc(c, uio);
1652		if (error)
1653			/* XXX should ungetc(c, qp). */
1654			break;
1655#if NSNP > 0
1656		/*
1657		 * Only snoop directly on input in echo mode.  Non-echoed
1658		 * input will be snooped later iff the application echoes it.
1659		 */
1660		if (ISSET(tp->t_lflag, ECHO) &&
1661		    ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
1662			snpinc((struct snoop *)tp->t_sc, (char)c);
1663#endif
1664 		if (uio->uio_resid == 0)
1665			break;
1666		/*
1667		 * In canonical mode check for a "break character"
1668		 * marking the end of a "line of input".
1669		 */
1670		if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1671			break;
1672		first = 0;
1673	}
1674
1675out:
1676	/*
1677	 * Look to unblock input now that (presumably)
1678	 * the input queue has gone down.
1679	 */
1680	s = spltty();
1681	if (ISSET(tp->t_state, TS_TBLOCK) &&
1682	    tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
1683		ttyunblock(tp);
1684	splx(s);
1685
1686	return (error);
1687}
1688
1689/*
1690 * Check the output queue on tp for space for a kernel message (from uprintf
1691 * or tprintf).  Allow some space over the normal hiwater mark so we don't
1692 * lose messages due to normal flow control, but don't let the tty run amok.
1693 * Sleeps here are not interruptible, but we return prematurely if new signals
1694 * arrive.
1695 */
1696int
1697ttycheckoutq(tp, wait)
1698	register struct tty *tp;
1699	int wait;
1700{
1701	int hiwat, s;
1702	sigset_t oldmask;
1703
1704	hiwat = tp->t_ohiwat;
1705	SIGEMPTYSET(oldmask);
1706	s = spltty();
1707	if (wait)
1708		oldmask = curproc->p_siglist;
1709	if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
1710		while (tp->t_outq.c_cc > hiwat) {
1711			ttstart(tp);
1712			if (tp->t_outq.c_cc <= hiwat)
1713				break;
1714			if (!(wait && SIGSETEQ(curproc->p_siglist, oldmask))) {
1715				splx(s);
1716				return (0);
1717			}
1718			SET(tp->t_state, TS_SO_OLOWAT);
1719			tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
1720		}
1721	splx(s);
1722	return (1);
1723}
1724
1725/*
1726 * Process a write call on a tty device.
1727 */
1728int
1729ttwrite(tp, uio, flag)
1730	register struct tty *tp;
1731	register struct uio *uio;
1732	int flag;
1733{
1734	register char *cp = NULL;
1735	register int cc, ce;
1736	register struct proc *p;
1737	int i, hiwat, cnt, error, s;
1738	char obuf[OBUFSIZ];
1739
1740	hiwat = tp->t_ohiwat;
1741	cnt = uio->uio_resid;
1742	error = 0;
1743	cc = 0;
1744loop:
1745	s = spltty();
1746	if (ISSET(tp->t_state, TS_ZOMBIE)) {
1747		splx(s);
1748		if (uio->uio_resid == cnt)
1749			error = EIO;
1750		goto out;
1751	}
1752	if (!ISSET(tp->t_state, TS_CONNECTED)) {
1753		if (flag & IO_NDELAY) {
1754			splx(s);
1755			error = EWOULDBLOCK;
1756			goto out;
1757		}
1758		error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
1759				 "ttydcd", 0);
1760		splx(s);
1761		if (error)
1762			goto out;
1763		goto loop;
1764	}
1765	splx(s);
1766	/*
1767	 * Hang the process if it's in the background.
1768	 */
1769	p = curproc;
1770	if (isbackground(p, tp) &&
1771	    ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
1772	    !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
1773	    !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
1774		if (p->p_pgrp->pg_jobc == 0) {
1775			error = EIO;
1776			goto out;
1777		}
1778		pgsignal(p->p_pgrp, SIGTTOU, 1);
1779		error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
1780		if (error)
1781			goto out;
1782		goto loop;
1783	}
1784	/*
1785	 * Process the user's data in at most OBUFSIZ chunks.  Perform any
1786	 * output translation.  Keep track of high water mark, sleep on
1787	 * overflow awaiting device aid in acquiring new space.
1788	 */
1789	while (uio->uio_resid > 0 || cc > 0) {
1790		if (ISSET(tp->t_lflag, FLUSHO)) {
1791			uio->uio_resid = 0;
1792			return (0);
1793		}
1794		if (tp->t_outq.c_cc > hiwat)
1795			goto ovhiwat;
1796		/*
1797		 * Grab a hunk of data from the user, unless we have some
1798		 * leftover from last time.
1799		 */
1800		if (cc == 0) {
1801			cc = imin(uio->uio_resid, OBUFSIZ);
1802			cp = obuf;
1803			error = uiomove(cp, cc, uio);
1804			if (error) {
1805				cc = 0;
1806				break;
1807			}
1808#if NSNP > 0
1809			if (ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
1810				snpin((struct snoop *)tp->t_sc, cp, cc);
1811#endif
1812		}
1813		/*
1814		 * If nothing fancy need be done, grab those characters we
1815		 * can handle without any of ttyoutput's processing and
1816		 * just transfer them to the output q.  For those chars
1817		 * which require special processing (as indicated by the
1818		 * bits in char_type), call ttyoutput.  After processing
1819		 * a hunk of data, look for FLUSHO so ^O's will take effect
1820		 * immediately.
1821		 */
1822		while (cc > 0) {
1823			if (!ISSET(tp->t_oflag, OPOST))
1824				ce = cc;
1825			else {
1826				ce = cc - scanc((u_int)cc, (u_char *)cp,
1827						char_type, CCLASSMASK);
1828				/*
1829				 * If ce is zero, then we're processing
1830				 * a special character through ttyoutput.
1831				 */
1832				if (ce == 0) {
1833					tp->t_rocount = 0;
1834					if (ttyoutput(*cp, tp) >= 0) {
1835						/* No Clists, wait a bit. */
1836						ttstart(tp);
1837						if (flag & IO_NDELAY) {
1838							error = EWOULDBLOCK;
1839							goto out;
1840						}
1841						error = ttysleep(tp, &lbolt,
1842								 TTOPRI|PCATCH,
1843								 "ttybf1", 0);
1844						if (error)
1845							goto out;
1846						goto loop;
1847					}
1848					cp++;
1849					cc--;
1850					if (ISSET(tp->t_lflag, FLUSHO) ||
1851					    tp->t_outq.c_cc > hiwat)
1852						goto ovhiwat;
1853					continue;
1854				}
1855			}
1856			/*
1857			 * A bunch of normal characters have been found.
1858			 * Transfer them en masse to the output queue and
1859			 * continue processing at the top of the loop.
1860			 * If there are any further characters in this
1861			 * <= OBUFSIZ chunk, the first should be a character
1862			 * requiring special handling by ttyoutput.
1863			 */
1864			tp->t_rocount = 0;
1865			i = b_to_q(cp, ce, &tp->t_outq);
1866			ce -= i;
1867			tp->t_column += ce;
1868			cp += ce, cc -= ce, tk_nout += ce;
1869			tp->t_outcc += ce;
1870			if (i > 0) {
1871				/* No Clists, wait a bit. */
1872				ttstart(tp);
1873				if (flag & IO_NDELAY) {
1874					error = EWOULDBLOCK;
1875					goto out;
1876				}
1877				error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
1878						 "ttybf2", 0);
1879				if (error)
1880					goto out;
1881				goto loop;
1882			}
1883			if (ISSET(tp->t_lflag, FLUSHO) ||
1884			    tp->t_outq.c_cc > hiwat)
1885				break;
1886		}
1887		ttstart(tp);
1888	}
1889out:
1890	/*
1891	 * If cc is nonzero, we leave the uio structure inconsistent, as the
1892	 * offset and iov pointers have moved forward, but it doesn't matter
1893	 * (the call will either return short or restart with a new uio).
1894	 */
1895	uio->uio_resid += cc;
1896	return (error);
1897
1898ovhiwat:
1899	ttstart(tp);
1900	s = spltty();
1901	/*
1902	 * This can only occur if FLUSHO is set in t_lflag,
1903	 * or if ttstart/oproc is synchronous (or very fast).
1904	 */
1905	if (tp->t_outq.c_cc <= hiwat) {
1906		splx(s);
1907		goto loop;
1908	}
1909	if (flag & IO_NDELAY) {
1910		splx(s);
1911		uio->uio_resid += cc;
1912		return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1913	}
1914	SET(tp->t_state, TS_SO_OLOWAT);
1915	error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
1916			 tp->t_timeout);
1917	splx(s);
1918	if (error == EWOULDBLOCK)
1919		error = EIO;
1920	if (error)
1921		goto out;
1922	goto loop;
1923}
1924
1925/*
1926 * Rubout one character from the rawq of tp
1927 * as cleanly as possible.
1928 */
1929static void
1930ttyrub(c, tp)
1931	register int c;
1932	register struct tty *tp;
1933{
1934	register char *cp;
1935	register int savecol;
1936	int tabc, s;
1937
1938	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1939		return;
1940	CLR(tp->t_lflag, FLUSHO);
1941	if (ISSET(tp->t_lflag, ECHOE)) {
1942		if (tp->t_rocount == 0) {
1943			/*
1944			 * Screwed by ttwrite; retype
1945			 */
1946			ttyretype(tp);
1947			return;
1948		}
1949		if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1950			ttyrubo(tp, 2);
1951		else {
1952			CLR(c, ~TTY_CHARMASK);
1953			switch (CCLASS(c)) {
1954			case ORDINARY:
1955				ttyrubo(tp, 1);
1956				break;
1957			case BACKSPACE:
1958			case CONTROL:
1959			case NEWLINE:
1960			case RETURN:
1961			case VTAB:
1962				if (ISSET(tp->t_lflag, ECHOCTL))
1963					ttyrubo(tp, 2);
1964				break;
1965			case TAB:
1966				if (tp->t_rocount < tp->t_rawq.c_cc) {
1967					ttyretype(tp);
1968					return;
1969				}
1970				s = spltty();
1971				savecol = tp->t_column;
1972				SET(tp->t_state, TS_CNTTB);
1973				SET(tp->t_lflag, FLUSHO);
1974				tp->t_column = tp->t_rocol;
1975				cp = tp->t_rawq.c_cf;
1976				if (cp)
1977					tabc = *cp;	/* XXX FIX NEXTC */
1978				for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
1979					ttyecho(tabc, tp);
1980				CLR(tp->t_lflag, FLUSHO);
1981				CLR(tp->t_state, TS_CNTTB);
1982				splx(s);
1983
1984				/* savecol will now be length of the tab. */
1985				savecol -= tp->t_column;
1986				tp->t_column += savecol;
1987				if (savecol > 8)
1988					savecol = 8;	/* overflow screw */
1989				while (--savecol >= 0)
1990					(void)ttyoutput('\b', tp);
1991				break;
1992			default:			/* XXX */
1993#define	PANICSTR	"ttyrub: would panic c = %d, val = %d\n"
1994				(void)printf(PANICSTR, c, CCLASS(c));
1995#ifdef notdef
1996				panic(PANICSTR, c, CCLASS(c));
1997#endif
1998			}
1999		}
2000	} else if (ISSET(tp->t_lflag, ECHOPRT)) {
2001		if (!ISSET(tp->t_state, TS_ERASE)) {
2002			SET(tp->t_state, TS_ERASE);
2003			(void)ttyoutput('\\', tp);
2004		}
2005		ttyecho(c, tp);
2006	} else
2007		ttyecho(tp->t_cc[VERASE], tp);
2008	--tp->t_rocount;
2009}
2010
2011/*
2012 * Back over cnt characters, erasing them.
2013 */
2014static void
2015ttyrubo(tp, cnt)
2016	register struct tty *tp;
2017	int cnt;
2018{
2019
2020	while (cnt-- > 0) {
2021		(void)ttyoutput('\b', tp);
2022		(void)ttyoutput(' ', tp);
2023		(void)ttyoutput('\b', tp);
2024	}
2025}
2026
2027/*
2028 * ttyretype --
2029 *	Reprint the rawq line.  Note, it is assumed that c_cc has already
2030 *	been checked.
2031 */
2032static void
2033ttyretype(tp)
2034	register struct tty *tp;
2035{
2036	register char *cp;
2037	int s, c;
2038
2039	/* Echo the reprint character. */
2040	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2041		ttyecho(tp->t_cc[VREPRINT], tp);
2042
2043	(void)ttyoutput('\n', tp);
2044
2045	/*
2046	 * XXX
2047	 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2048	 * BIT OF FIRST CHAR.
2049	 */
2050	s = spltty();
2051	for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
2052	    cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
2053		ttyecho(c, tp);
2054	for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
2055	    cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
2056		ttyecho(c, tp);
2057	CLR(tp->t_state, TS_ERASE);
2058	splx(s);
2059
2060	tp->t_rocount = tp->t_rawq.c_cc;
2061	tp->t_rocol = 0;
2062}
2063
2064/*
2065 * Echo a typed character to the terminal.
2066 */
2067static void
2068ttyecho(c, tp)
2069	register int c;
2070	register struct tty *tp;
2071{
2072
2073	if (!ISSET(tp->t_state, TS_CNTTB))
2074		CLR(tp->t_lflag, FLUSHO);
2075	if ((!ISSET(tp->t_lflag, ECHO) &&
2076	     (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2077	    ISSET(tp->t_lflag, EXTPROC))
2078		return;
2079	if (ISSET(tp->t_lflag, ECHOCTL) &&
2080	    ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2081	    ISSET(c, TTY_CHARMASK) == 0177)) {
2082		(void)ttyoutput('^', tp);
2083		CLR(c, ~TTY_CHARMASK);
2084		if (c == 0177)
2085			c = '?';
2086		else
2087			c += 'A' - 1;
2088	}
2089	(void)ttyoutput(c, tp);
2090}
2091
2092/*
2093 * Wake up any readers on a tty.
2094 */
2095void
2096ttwakeup(tp)
2097	register struct tty *tp;
2098{
2099
2100	if (tp->t_rsel.si_pid != 0)
2101		selwakeup(&tp->t_rsel);
2102	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2103		pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
2104	wakeup(TSA_HUP_OR_INPUT(tp));
2105}
2106
2107/*
2108 * Wake up any writers on a tty.
2109 */
2110void
2111ttwwakeup(tp)
2112	register struct tty *tp;
2113{
2114
2115	if (tp->t_wsel.si_pid != 0 && tp->t_outq.c_cc <= tp->t_olowat)
2116		selwakeup(&tp->t_wsel);
2117	if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2118		pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
2119	if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2120	    TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2121		CLR(tp->t_state, TS_SO_OCOMPLETE);
2122		wakeup(TSA_OCOMPLETE(tp));
2123	}
2124	if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2125	    tp->t_outq.c_cc <= tp->t_olowat) {
2126		CLR(tp->t_state, TS_SO_OLOWAT);
2127		wakeup(TSA_OLOWAT(tp));
2128	}
2129}
2130
2131/*
2132 * Look up a code for a specified speed in a conversion table;
2133 * used by drivers to map software speed values to hardware parameters.
2134 */
2135int
2136ttspeedtab(speed, table)
2137	int speed;
2138	register struct speedtab *table;
2139{
2140
2141	for ( ; table->sp_speed != -1; table++)
2142		if (table->sp_speed == speed)
2143			return (table->sp_code);
2144	return (-1);
2145}
2146
2147/*
2148 * Set input and output watermarks and buffer sizes.  For input, the
2149 * high watermark is about one second's worth of input above empty, the
2150 * low watermark is slightly below high water, and the buffer size is a
2151 * driver-dependent amount above high water.  For output, the watermarks
2152 * are near the ends of the buffer, with about 1 second's worth of input
2153 * between them.  All this only applies to the standard line discipline.
2154 */
2155void
2156ttsetwater(tp)
2157	struct tty *tp;
2158{
2159	register int cps, ttmaxhiwat, x;
2160
2161	/* Input. */
2162	clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
2163	switch (tp->t_ispeedwat) {
2164	case (speed_t)-1:
2165		cps = tp->t_ispeed / 10;
2166		break;
2167	case 0:
2168		/*
2169		 * This case is for old drivers that don't know about
2170		 * t_ispeedwat.  Arrange for them to get the old buffer
2171		 * sizes and watermarks.
2172		 */
2173		cps = TTYHOG - 2 * 256;
2174		tp->t_ififosize = 2 * 256;
2175		break;
2176	default:
2177		cps = tp->t_ispeedwat / 10;
2178		break;
2179	}
2180	tp->t_ihiwat = cps;
2181	tp->t_ilowat = 7 * cps / 8;
2182	x = cps + tp->t_ififosize;
2183	clist_alloc_cblocks(&tp->t_rawq, x, x);
2184
2185	/* Output. */
2186	switch (tp->t_ospeedwat) {
2187	case (speed_t)-1:
2188		cps = tp->t_ospeed / 10;
2189		ttmaxhiwat = 2 * TTMAXHIWAT;
2190		break;
2191	case 0:
2192		cps = tp->t_ospeed / 10;
2193		ttmaxhiwat = TTMAXHIWAT;
2194		break;
2195	default:
2196		cps = tp->t_ospeedwat / 10;
2197		ttmaxhiwat = 8 * TTMAXHIWAT;
2198		break;
2199	}
2200#define CLAMP(x, h, l)	((x) > h ? h : ((x) < l) ? l : (x))
2201	tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2202	x += cps;
2203	x = CLAMP(x, ttmaxhiwat, TTMINHIWAT);	/* XXX clamps are too magic */
2204	tp->t_ohiwat = roundup(x, CBSIZE);	/* XXX for compat */
2205	x = imax(tp->t_ohiwat, TTMAXHIWAT);	/* XXX for compat/safety */
2206	x += OBUFSIZ + 100;
2207	clist_alloc_cblocks(&tp->t_outq, x, x);
2208#undef	CLAMP
2209}
2210
2211/*
2212 * Report on state of foreground process group.
2213 */
2214void
2215ttyinfo(tp)
2216	register struct tty *tp;
2217{
2218	register struct proc *p, *pick;
2219	struct timeval utime, stime;
2220	int tmp;
2221
2222	if (ttycheckoutq(tp,0) == 0)
2223		return;
2224
2225	/* Print load average. */
2226	tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2227	ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2228
2229	if (tp->t_session == NULL)
2230		ttyprintf(tp, "not a controlling terminal\n");
2231	else if (tp->t_pgrp == NULL)
2232		ttyprintf(tp, "no foreground process group\n");
2233	else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0)
2234		ttyprintf(tp, "empty foreground process group\n");
2235	else {
2236		/* Pick interesting process. */
2237		for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
2238			if (proc_compare(pick, p))
2239				pick = p;
2240
2241		ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
2242		    pick->p_stat == SRUN ? "running" :
2243		    pick->p_wmesg ? pick->p_wmesg : "iowait");
2244
2245		if (pick->p_flag & P_INMEM) {
2246			calcru(pick, &utime, &stime, NULL);
2247
2248			/* Print user time. */
2249			ttyprintf(tp, "%ld.%02ldu ",
2250			    utime.tv_sec, utime.tv_usec / 10000);
2251
2252			/* Print system time. */
2253			ttyprintf(tp, "%ld.%02lds ",
2254			    stime.tv_sec, stime.tv_usec / 10000);
2255		} else
2256			ttyprintf(tp, "?.??u ?.??s ");
2257
2258		/* Print percentage cpu, resident set size. */
2259		tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
2260		ttyprintf(tp, "%d%% %ldk\n",
2261		    tmp / 100,
2262		    pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
2263		    (long)pgtok(vmspace_resident_count(pick->p_vmspace)));
2264	}
2265	tp->t_rocount = 0;	/* so pending input will be retyped if BS */
2266}
2267
2268/*
2269 * Returns 1 if p2 is "better" than p1
2270 *
2271 * The algorithm for picking the "interesting" process is thus:
2272 *
2273 *	1) Only foreground processes are eligible - implied.
2274 *	2) Runnable processes are favored over anything else.  The runner
2275 *	   with the highest cpu utilization is picked (p_estcpu).  Ties are
2276 *	   broken by picking the highest pid.
2277 *	3) The sleeper with the shortest sleep time is next.  With ties,
2278 *	   we pick out just "short-term" sleepers (P_SINTR == 0).
2279 *	4) Further ties are broken by picking the highest pid.
2280 */
2281#define ISRUN(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
2282#define TESTAB(a, b)    ((a)<<1 | (b))
2283#define ONLYA   2
2284#define ONLYB   1
2285#define BOTH    3
2286
2287static int
2288proc_compare(p1, p2)
2289	register struct proc *p1, *p2;
2290{
2291
2292	if (p1 == NULL)
2293		return (1);
2294	/*
2295	 * see if at least one of them is runnable
2296	 */
2297	switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
2298	case ONLYA:
2299		return (0);
2300	case ONLYB:
2301		return (1);
2302	case BOTH:
2303		/*
2304		 * tie - favor one with highest recent cpu utilization
2305		 */
2306		if (p2->p_estcpu > p1->p_estcpu)
2307			return (1);
2308		if (p1->p_estcpu > p2->p_estcpu)
2309			return (0);
2310		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
2311	}
2312	/*
2313 	 * weed out zombies
2314	 */
2315	switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
2316	case ONLYA:
2317		return (1);
2318	case ONLYB:
2319		return (0);
2320	case BOTH:
2321		return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2322	}
2323	/*
2324	 * pick the one with the smallest sleep time
2325	 */
2326	if (p2->p_slptime > p1->p_slptime)
2327		return (0);
2328	if (p1->p_slptime > p2->p_slptime)
2329		return (1);
2330	/*
2331	 * favor one sleeping in a non-interruptible sleep
2332	 */
2333	if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
2334		return (1);
2335	if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
2336		return (0);
2337	return (p2->p_pid > p1->p_pid);		/* tie - return highest pid */
2338}
2339
2340/*
2341 * Output char to tty; console putchar style.
2342 */
2343int
2344tputchar(c, tp)
2345	int c;
2346	struct tty *tp;
2347{
2348	register int s;
2349
2350	s = spltty();
2351	if (!ISSET(tp->t_state, TS_CONNECTED)) {
2352		splx(s);
2353		return (-1);
2354	}
2355	if (c == '\n')
2356		(void)ttyoutput('\r', tp);
2357	(void)ttyoutput(c, tp);
2358	ttstart(tp);
2359	splx(s);
2360	return (0);
2361}
2362
2363/*
2364 * Sleep on chan, returning ERESTART if tty changed while we napped and
2365 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep.  If
2366 * the tty is revoked, restarting a pending call will redo validation done
2367 * at the start of the call.
2368 */
2369int
2370ttysleep(tp, chan, pri, wmesg, timo)
2371	struct tty *tp;
2372	void *chan;
2373	int pri, timo;
2374	char *wmesg;
2375{
2376	int error;
2377	int gen;
2378
2379	gen = tp->t_gen;
2380	error = tsleep(chan, pri, wmesg, timo);
2381	if (error)
2382		return (error);
2383	return (tp->t_gen == gen ? 0 : ERESTART);
2384}
2385
2386/*
2387 * Allocate a tty struct.  Clists in the struct will be allocated by
2388 * ttyopen().
2389 */
2390struct tty *
2391ttymalloc(tp)
2392	struct tty *tp;
2393{
2394
2395	if (tp)
2396		return(tp);
2397        tp = malloc(sizeof *tp, M_TTYS, M_WAITOK);
2398        bzero(tp, sizeof *tp);
2399	ttyregister(tp);
2400        return (tp);
2401}
2402
2403#if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */
2404/*
2405 * Free a tty struct.  Clists in the struct should have been freed by
2406 * ttyclose().
2407 */
2408void
2409ttyfree(tp)
2410	struct tty *tp;
2411{
2412        free(tp, M_TTYS);
2413}
2414#endif /* 0 */
2415
2416void
2417ttyregister(tp)
2418	struct tty *tp;
2419{
2420	SLIST_INSERT_HEAD(&tty_list, tp, t_list);
2421}
2422
2423static int
2424sysctl_kern_ttys SYSCTL_HANDLER_ARGS
2425{
2426	int error;
2427	struct tty *tp, t;
2428	SLIST_FOREACH(tp, &tty_list, t_list) {
2429		t = *tp;
2430		if (t.t_dev)
2431			t.t_dev = (dev_t)dev2udev(t.t_dev);
2432		error = SYSCTL_OUT(req, (caddr_t)&t, sizeof(t));
2433		if (error)
2434			return (error);
2435	}
2436	return (0);
2437}
2438
2439SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
2440	0, 0, sysctl_kern_ttys, "S,tty", "All struct ttys");
2441
2442void
2443nottystop(tp, rw)
2444	struct tty *tp;
2445	int rw;
2446{
2447
2448	return;
2449}
2450
2451int
2452ttyread(dev, uio, flag)
2453	dev_t dev;
2454	struct uio *uio;
2455	int flag;
2456{
2457	struct tty *tp;
2458
2459	tp = dev->si_tty;
2460	if (tp == NULL)
2461		return (ENODEV);
2462	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
2463}
2464
2465int
2466ttywrite(dev, uio, flag)
2467	dev_t dev;
2468	struct uio *uio;
2469	int flag;
2470{
2471	struct tty *tp;
2472
2473	tp = dev->si_tty;
2474	if (tp == NULL)
2475		return (ENODEV);
2476	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
2477}
2478