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