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