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