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