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