xref: /original-bsd/sys/kern/tty.c (revision 333da485)
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.8 (Berkeley) 01/21/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 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 			s = spltty();		/* Don't interrupt tabs. */
532 			c -= b_to_q("        ", c, &tp->t_outq);
533 			tk_nout += c;
534 			tp->t_outcc += c;
535 			splx(s);
536 		}
537 		tp->t_column += c;
538 		return (c ? -1 : '\t');
539 	}
540 	if (c == CEOT && ISSET(oflag, ONOEOT))
541 		return (-1);
542 
543 	/*
544 	 * Newline translation: if ONLCR is set,
545 	 * translate newline into "\r\n".
546 	 */
547 	if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
548 		tk_nout++;
549 		tp->t_outcc++;
550 		if (putc('\r', &tp->t_outq))
551 			return (c);
552 	}
553 	tk_nout++;
554 	tp->t_outcc++;
555 	if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
556 		return (c);
557 
558 	col = tp->t_column;
559 	switch (CCLASS(c)) {
560 	case BACKSPACE:
561 		if (col > 0)
562 			--col;
563 		break;
564 	case CONTROL:
565 		break;
566 	case NEWLINE:
567 	case RETURN:
568 		col = 0;
569 		break;
570 	case ORDINARY:
571 		++col;
572 		break;
573 	case TAB:
574 		col = (col + 8) & ~7;
575 		break;
576 	}
577 	tp->t_column = col;
578 	return (-1);
579 }
580 
581 /*
582  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
583  * has been called to do discipline-specific functions and/or reject any
584  * of these ioctl commands.
585  */
586 /* ARGSUSED */
587 int
588 ttioctl(tp, cmd, data, flag)
589 	register struct tty *tp;
590 	int cmd, flag;
591 	void *data;
592 {
593 	extern struct tty *constty;	/* Temporary virtual console. */
594 	extern int nlinesw;
595 	register struct proc *p;
596 	int s, error;
597 
598 	p = curproc;			/* XXX */
599 
600 	/* If the ioctl involves modification, hang if in the background. */
601 	switch (cmd) {
602 	case  TIOCFLUSH:
603 	case  TIOCSETA:
604 	case  TIOCSETD:
605 	case  TIOCSETAF:
606 	case  TIOCSETAW:
607 #ifdef notdef
608 	case  TIOCSPGRP:
609 #endif
610 	case  TIOCSTI:
611 	case  TIOCSWINSZ:
612 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
613 	case  TIOCLBIC:
614 	case  TIOCLBIS:
615 	case  TIOCLSET:
616 	case  TIOCSETC:
617 	case OTIOCSETD:
618 	case  TIOCSETN:
619 	case  TIOCSETP:
620 	case  TIOCSLTC:
621 #endif
622 		while (isbackground(curproc, tp) &&
623 		    p->p_pgrp->pg_jobc && (p->p_flag & P_PPWAIT) == 0 &&
624 		    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
625 		    (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
626 			pgsignal(p->p_pgrp, SIGTTOU, 1);
627 			if (error = ttysleep(tp,
628 			    &lbolt, TTOPRI | PCATCH, ttybg, 0))
629 				return (error);
630 		}
631 		break;
632 	}
633 
634 	switch (cmd) {			/* Process the ioctl. */
635 	case FIOASYNC:			/* set/clear async i/o */
636 		s = spltty();
637 		if (*(int *)data)
638 			SET(tp->t_state, TS_ASYNC);
639 		else
640 			CLR(tp->t_state, TS_ASYNC);
641 		splx(s);
642 		break;
643 	case FIONBIO:			/* set/clear non-blocking i/o */
644 		break;			/* XXX: delete. */
645 	case FIONREAD:			/* get # bytes to read */
646 		*(int *)data = ttnread(tp);
647 		break;
648 	case TIOCEXCL:			/* set exclusive use of tty */
649 		s = spltty();
650 		SET(tp->t_state, TS_XCLUDE);
651 		splx(s);
652 		break;
653 	case TIOCFLUSH: {		/* flush buffers */
654 		register int flags = *(int *)data;
655 
656 		if (flags == 0)
657 			flags = FREAD | FWRITE;
658 		else
659 			flags &= FREAD | FWRITE;
660 		ttyflush(tp, flags);
661 		break;
662 	}
663 	case TIOCCONS:			/* become virtual console */
664 		if (*(int *)data) {
665 			if (constty && constty != tp &&
666 			    ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
667 			    (TS_CARR_ON | TS_ISOPEN))
668 				return (EBUSY);
669 #ifndef	UCONSOLE
670 			if (error = suser(p->p_ucred, &p->p_acflag))
671 				return (error);
672 #endif
673 			constty = tp;
674 		} else if (tp == constty)
675 			constty = NULL;
676 		break;
677 	case TIOCDRAIN:			/* wait till output drained */
678 		if (error = ttywait(tp))
679 			return (error);
680 		break;
681 	case TIOCGETA: {		/* get termios struct */
682 		struct termios *t = (struct termios *)data;
683 
684 		bcopy(&tp->t_termios, t, sizeof(struct termios));
685 		break;
686 	}
687 	case TIOCGETD:			/* get line discipline */
688 		*(int *)data = tp->t_line;
689 		break;
690 	case TIOCGWINSZ:		/* get window size */
691 		*(struct winsize *)data = tp->t_winsize;
692 		break;
693 	case TIOCGPGRP:			/* get pgrp of tty */
694 		if (!isctty(p, tp))
695 			return (ENOTTY);
696 		*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
697 		break;
698 #ifdef TIOCHPCL
699 	case TIOCHPCL:			/* hang up on last close */
700 		s = spltty();
701 		SET(tp->t_cflag, HUPCL);
702 		splx(s);
703 		break;
704 #endif
705 	case TIOCNXCL:			/* reset exclusive use of tty */
706 		s = spltty();
707 		CLR(tp->t_state, TS_XCLUDE);
708 		splx(s);
709 		break;
710 	case TIOCOUTQ:			/* output queue size */
711 		*(int *)data = tp->t_outq.c_cc;
712 		break;
713 	case TIOCSETA:			/* set termios struct */
714 	case TIOCSETAW:			/* drain output, set */
715 	case TIOCSETAF: {		/* drn out, fls in, set */
716 		register struct termios *t = (struct termios *)data;
717 
718 		s = spltty();
719 		if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
720 			if (error = ttywait(tp)) {
721 				splx(s);
722 				return (error);
723 			}
724 			if (cmd == TIOCSETAF)
725 				ttyflush(tp, FREAD);
726 		}
727 		if (!ISSET(t->c_cflag, CIGNORE)) {
728 			/*
729 			 * Set device hardware.
730 			 */
731 			if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
732 				splx(s);
733 				return (error);
734 			} else {
735 				if (!ISSET(tp->t_state, TS_CARR_ON) &&
736 				    ISSET(tp->t_cflag, CLOCAL) &&
737 				    !ISSET(t->c_cflag, CLOCAL)) {
738 					CLR(tp->t_state, TS_ISOPEN);
739 					SET(tp->t_state, TS_WOPEN);
740 					ttwakeup(tp);
741 				}
742 				tp->t_cflag = t->c_cflag;
743 				tp->t_ispeed = t->c_ispeed;
744 				tp->t_ospeed = t->c_ospeed;
745 			}
746 			ttsetwater(tp);
747 		}
748 		if (cmd != TIOCSETAF) {
749 			if (ISSET(t->c_lflag, ICANON) !=
750 			    ISSET(tp->t_lflag, ICANON))
751 				if (ISSET(t->c_lflag, ICANON)) {
752 					SET(tp->t_lflag, PENDIN);
753 					ttwakeup(tp);
754 				} else {
755 					struct clist tq;
756 
757 					catq(&tp->t_rawq, &tp->t_canq);
758 					tq = tp->t_rawq;
759 					tp->t_rawq = tp->t_canq;
760 					tp->t_canq = tq;
761 					CLR(tp->t_lflag, PENDIN);
762 				}
763 		}
764 		tp->t_iflag = t->c_iflag;
765 		tp->t_oflag = t->c_oflag;
766 		/*
767 		 * Make the EXTPROC bit read only.
768 		 */
769 		if (ISSET(tp->t_lflag, EXTPROC))
770 			SET(t->c_lflag, EXTPROC);
771 		else
772 			CLR(t->c_lflag, EXTPROC);
773 		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
774 		bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
775 		splx(s);
776 		break;
777 	}
778 	case TIOCSETD: {		/* set line discipline */
779 		register int t = *(int *)data;
780 		dev_t device = tp->t_dev;
781 
782 		if ((u_int)t >= nlinesw)
783 			return (ENXIO);
784 		if (t != tp->t_line) {
785 			s = spltty();
786 			(*linesw[tp->t_line].l_close)(tp, flag);
787 			error = (*linesw[t].l_open)(device, tp);
788 			if (error) {
789 				(void)(*linesw[tp->t_line].l_open)(device, tp);
790 				splx(s);
791 				return (error);
792 			}
793 			tp->t_line = t;
794 			splx(s);
795 		}
796 		break;
797 	}
798 	case TIOCSTART:			/* start output, like ^Q */
799 		s = spltty();
800 		if (ISSET(tp->t_state, TS_TTSTOP) ||
801 		    ISSET(tp->t_lflag, FLUSHO)) {
802 			CLR(tp->t_lflag, FLUSHO);
803 			CLR(tp->t_state, TS_TTSTOP);
804 			ttstart(tp);
805 		}
806 		splx(s);
807 		break;
808 	case TIOCSTI:			/* simulate terminal input */
809 		if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
810 			return (EPERM);
811 		if (p->p_ucred->cr_uid && !isctty(p, tp))
812 			return (EACCES);
813 		(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
814 		break;
815 	case TIOCSTOP:			/* stop output, like ^S */
816 		s = spltty();
817 		if (!ISSET(tp->t_state, TS_TTSTOP)) {
818 			SET(tp->t_state, TS_TTSTOP);
819 #ifdef sun4c				/* XXX */
820 			(*tp->t_stop)(tp, 0);
821 #else
822 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
823 #endif
824 		}
825 		splx(s);
826 		break;
827 	case TIOCSCTTY:			/* become controlling tty */
828 		/* Session ctty vnode pointer set in vnode layer. */
829 		if (!SESS_LEADER(p) ||
830 		    (p->p_session->s_ttyvp || tp->t_session) &&
831 		    (tp->t_session != p->p_session))
832 			return (EPERM);
833 		tp->t_session = p->p_session;
834 		tp->t_pgrp = p->p_pgrp;
835 		p->p_session->s_ttyp = tp;
836 		p->p_flag |= P_CONTROLT;
837 		break;
838 	case TIOCSPGRP: {		/* set pgrp of tty */
839 		register struct pgrp *pgrp = pgfind(*(int *)data);
840 
841 		if (!isctty(p, tp))
842 			return (ENOTTY);
843 		else if (pgrp == NULL || pgrp->pg_session != p->p_session)
844 			return (EPERM);
845 		tp->t_pgrp = pgrp;
846 		break;
847 	}
848 	case TIOCSWINSZ:		/* set window size */
849 		if (bcmp((caddr_t)&tp->t_winsize, data,
850 		    sizeof (struct winsize))) {
851 			tp->t_winsize = *(struct winsize *)data;
852 			pgsignal(tp->t_pgrp, SIGWINCH, 1);
853 		}
854 		break;
855 	default:
856 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
857 		return (ttcompat(tp, cmd, data, flag));
858 #else
859 		return (-1);
860 #endif
861 	}
862 	return (0);
863 }
864 
865 int
866 ttselect(device, rw, p)
867 	dev_t device;
868 	int rw;
869 	struct proc *p;
870 {
871 	register struct tty *tp;
872 	int nread, s;
873 
874 	tp = &cdevsw[major(device)].d_ttys[minor(device)];
875 
876 	s = spltty();
877 	switch (rw) {
878 	case FREAD:
879 		nread = ttnread(tp);
880 		if (nread > 0 || !ISSET(tp->t_cflag, CLOCAL) &&
881 		    !ISSET(tp->t_state, TS_CARR_ON))
882 			goto win;
883 		selrecord(p, &tp->t_rsel);
884 		break;
885 	case FWRITE:
886 		if (tp->t_outq.c_cc <= tp->t_lowat) {
887 win:			splx(s);
888 			return (1);
889 		}
890 		selrecord(p, &tp->t_wsel);
891 		break;
892 	}
893 	splx(s);
894 	return (0);
895 }
896 
897 static int
898 ttnread(tp)
899 	struct tty *tp;
900 {
901 	int nread;
902 
903 	if (ISSET(tp->t_lflag, PENDIN))
904 		ttypend(tp);
905 	nread = tp->t_canq.c_cc;
906 	if (!ISSET(tp->t_lflag, ICANON))
907 		nread += tp->t_rawq.c_cc;
908 	return (nread);
909 }
910 
911 /*
912  * Wait for output to drain.
913  */
914 int
915 ttywait(tp)
916 	register struct tty *tp;
917 {
918 	int error, s;
919 
920 	error = 0;
921 	s = spltty();
922 	while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
923 	    (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
924 	    && tp->t_oproc) {
925 		(*tp->t_oproc)(tp);
926 		SET(tp->t_state, TS_ASLEEP);
927 		if (error = ttysleep(tp,
928 		    &tp->t_outq, TTOPRI | PCATCH, ttyout, 0))
929 			break;
930 	}
931 	splx(s);
932 	return (error);
933 }
934 
935 /*
936  * Flush if successfully wait.
937  */
938 int
939 ttywflush(tp)
940 	struct tty *tp;
941 {
942 	int error;
943 
944 	if ((error = ttywait(tp)) == 0)
945 		ttyflush(tp, FREAD);
946 	return (error);
947 }
948 
949 /*
950  * Flush tty read and/or write queues, notifying anyone waiting.
951  */
952 void
953 ttyflush(tp, rw)
954 	register struct tty *tp;
955 	int rw;
956 {
957 	register int s;
958 
959 	s = spltty();
960 	if (rw & FREAD) {
961 		FLUSHQ(&tp->t_canq);
962 		FLUSHQ(&tp->t_rawq);
963 		tp->t_rocount = 0;
964 		tp->t_rocol = 0;
965 		CLR(tp->t_state, TS_LOCAL);
966 		ttwakeup(tp);
967 	}
968 	if (rw & FWRITE) {
969 		CLR(tp->t_state, TS_TTSTOP);
970 #ifdef sun4c						/* XXX */
971 		(*tp->t_stop)(tp, rw);
972 #else
973 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
974 #endif
975 		FLUSHQ(&tp->t_outq);
976 		wakeup((caddr_t)&tp->t_outq);
977 		selwakeup(&tp->t_wsel);
978 	}
979 	splx(s);
980 }
981 
982 /*
983  * Copy in the default termios characters.
984  */
985 void
986 ttychars(tp)
987 	struct tty *tp;
988 {
989 
990 	bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
991 }
992 
993 /*
994  * Send stop character on input overflow.
995  */
996 static void
997 ttyblock(tp)
998 	register struct tty *tp;
999 {
1000 	register int total;
1001 
1002 	total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
1003 	if (tp->t_rawq.c_cc > TTYHOG) {
1004 		ttyflush(tp, FREAD | FWRITE);
1005 		CLR(tp->t_state, TS_TBLOCK);
1006 	}
1007 	/*
1008 	 * Block further input iff: current input > threshold
1009 	 * AND input is available to user program.
1010 	 */
1011 	if (total >= TTYHOG / 2 &&
1012 	    !ISSET(tp->t_state, TS_TBLOCK) &&
1013 	    !ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0 &&
1014 	    tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
1015 		if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
1016 			SET(tp->t_state, TS_TBLOCK);
1017 			ttstart(tp);
1018 		}
1019 	}
1020 }
1021 
1022 void
1023 ttrstrt(tp_arg)
1024 	void *tp_arg;
1025 {
1026 	struct tty *tp;
1027 	int s;
1028 
1029 #ifdef DIAGNOSTIC
1030 	if (tp_arg == NULL)
1031 		panic("ttrstrt");
1032 #endif
1033 	tp = tp_arg;
1034 	s = spltty();
1035 
1036 	CLR(tp->t_state, TS_TIMEOUT);
1037 	ttstart(tp);
1038 
1039 	splx(s);
1040 }
1041 
1042 int
1043 ttstart(tp)
1044 	struct tty *tp;
1045 {
1046 
1047 	if (tp->t_oproc != NULL)	/* XXX: Kludge for pty. */
1048 		(*tp->t_oproc)(tp);
1049 	return (0);
1050 }
1051 
1052 /*
1053  * "close" a line discipline
1054  */
1055 int
1056 ttylclose(tp, flag)
1057 	struct tty *tp;
1058 	int flag;
1059 {
1060 
1061 	if (flag & IO_NDELAY)
1062 		ttyflush(tp, FREAD | FWRITE);
1063 	else
1064 		ttywflush(tp);
1065 	return (0);
1066 }
1067 
1068 /*
1069  * Handle modem control transition on a tty.
1070  * Flag indicates new state of carrier.
1071  * Returns 0 if the line should be turned off, otherwise 1.
1072  */
1073 int
1074 ttymodem(tp, flag)
1075 	register struct tty *tp;
1076 	int flag;
1077 {
1078 
1079 	if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
1080 		/*
1081 		 * MDMBUF: do flow control according to carrier flag
1082 		 */
1083 		if (flag) {
1084 			CLR(tp->t_state, TS_TTSTOP);
1085 			ttstart(tp);
1086 		} else if (!ISSET(tp->t_state, TS_TTSTOP)) {
1087 			SET(tp->t_state, TS_TTSTOP);
1088 #ifdef sun4c						/* XXX */
1089 			(*tp->t_stop)(tp, 0);
1090 #else
1091 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
1092 #endif
1093 		}
1094 	} else if (flag == 0) {
1095 		/*
1096 		 * Lost carrier.
1097 		 */
1098 		CLR(tp->t_state, TS_CARR_ON);
1099 		if (ISSET(tp->t_state, TS_ISOPEN) &&
1100 		    !ISSET(tp->t_cflag, CLOCAL)) {
1101 			if (tp->t_session && tp->t_session->s_leader)
1102 				psignal(tp->t_session->s_leader, SIGHUP);
1103 			ttyflush(tp, FREAD | FWRITE);
1104 			return (0);
1105 		}
1106 	} else {
1107 		/*
1108 		 * Carrier now on.
1109 		 */
1110 		SET(tp->t_state, TS_CARR_ON);
1111 		ttwakeup(tp);
1112 	}
1113 	return (1);
1114 }
1115 
1116 /*
1117  * Default modem control routine (for other line disciplines).
1118  * Return argument flag, to turn off device on carrier drop.
1119  */
1120 int
1121 nullmodem(tp, flag)
1122 	register struct tty *tp;
1123 	int flag;
1124 {
1125 
1126 	if (flag)
1127 		SET(tp->t_state, TS_CARR_ON);
1128 	else {
1129 		CLR(tp->t_state, TS_CARR_ON);
1130 		if (!ISSET(tp->t_cflag, CLOCAL)) {
1131 			if (tp->t_session && tp->t_session->s_leader)
1132 				psignal(tp->t_session->s_leader, SIGHUP);
1133 			return (0);
1134 		}
1135 	}
1136 	return (1);
1137 }
1138 
1139 /*
1140  * Reinput pending characters after state switch
1141  * call at spltty().
1142  */
1143 void
1144 ttypend(tp)
1145 	register struct tty *tp;
1146 {
1147 	struct clist tq;
1148 	register c;
1149 
1150 	CLR(tp->t_lflag, PENDIN);
1151 	SET(tp->t_state, TS_TYPEN);
1152 	tq = tp->t_rawq;
1153 	tp->t_rawq.c_cc = 0;
1154 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
1155 	while ((c = getc(&tq)) >= 0)
1156 		ttyinput(c, tp);
1157 	CLR(tp->t_state, TS_TYPEN);
1158 }
1159 
1160 /*
1161  * Process a read call on a tty device.
1162  */
1163 int
1164 ttread(tp, uio, flag)
1165 	register struct tty *tp;
1166 	struct uio *uio;
1167 	int flag;
1168 {
1169 	register struct clist *qp;
1170 	register int c;
1171 	register long lflag;
1172 	register u_char *cc = tp->t_cc;
1173 	register struct proc *p = curproc;
1174 	int s, first, error = 0;
1175 
1176 loop:	lflag = tp->t_lflag;
1177 	s = spltty();
1178 	/*
1179 	 * take pending input first
1180 	 */
1181 	if (ISSET(lflag, PENDIN))
1182 		ttypend(tp);
1183 	splx(s);
1184 
1185 	/*
1186 	 * Hang process if it's in the background.
1187 	 */
1188 	if (isbackground(p, tp)) {
1189 		if ((p->p_sigignore & sigmask(SIGTTIN)) ||
1190 		   (p->p_sigmask & sigmask(SIGTTIN)) ||
1191 		    p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0)
1192 			return (EIO);
1193 		pgsignal(p->p_pgrp, SIGTTIN, 1);
1194 		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
1195 			return (error);
1196 		goto loop;
1197 	}
1198 
1199 	/*
1200 	 * If canonical, use the canonical queue,
1201 	 * else use the raw queue.
1202 	 *
1203 	 * (should get rid of clists...)
1204 	 */
1205 	qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1206 
1207 	/*
1208 	 * If there is no input, sleep on rawq
1209 	 * awaiting hardware receipt and notification.
1210 	 * If we have data, we don't need to check for carrier.
1211 	 */
1212 	s = spltty();
1213 	if (qp->c_cc <= 0) {
1214 		int carrier;
1215 
1216 		carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1217 		    ISSET(tp->t_cflag, CLOCAL);
1218 		if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1219 			splx(s);
1220 			return (0);	/* EOF */
1221 		}
1222 		if (flag & IO_NDELAY) {
1223 			splx(s);
1224 			return (EWOULDBLOCK);
1225 		}
1226 		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
1227 		    carrier ? ttyin : ttopen, 0);
1228 		splx(s);
1229 		if (error)
1230 			return (error);
1231 		goto loop;
1232 	}
1233 	splx(s);
1234 
1235 	/*
1236 	 * Input present, check for input mapping and processing.
1237 	 */
1238 	first = 1;
1239 	while ((c = getc(qp)) >= 0) {
1240 		/*
1241 		 * delayed suspend (^Y)
1242 		 */
1243 		if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) {
1244 			pgsignal(tp->t_pgrp, SIGTSTP, 1);
1245 			if (first) {
1246 				if (error = ttysleep(tp,
1247 				    &lbolt, TTIPRI | PCATCH, ttybg, 0))
1248 					break;
1249 				goto loop;
1250 			}
1251 			break;
1252 		}
1253 		/*
1254 		 * Interpret EOF only in canonical mode.
1255 		 */
1256 		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1257 			break;
1258 		/*
1259 		 * Give user character.
1260 		 */
1261  		error = ureadc(c, uio);
1262 		if (error)
1263 			break;
1264  		if (uio->uio_resid == 0)
1265 			break;
1266 		/*
1267 		 * In canonical mode check for a "break character"
1268 		 * marking the end of a "line of input".
1269 		 */
1270 		if (ISSET(lflag, ICANON) && TTBREAKC(c))
1271 			break;
1272 		first = 0;
1273 	}
1274 	/*
1275 	 * Look to unblock output now that (presumably)
1276 	 * the input queue has gone down.
1277 	 */
1278 	s = spltty();
1279 	if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
1280 		if (cc[VSTART] != _POSIX_VDISABLE &&
1281 		    putc(cc[VSTART], &tp->t_outq) == 0) {
1282 			CLR(tp->t_state, TS_TBLOCK);
1283 			ttstart(tp);
1284 		}
1285 	}
1286 	splx(s);
1287 	return (error);
1288 }
1289 
1290 /*
1291  * Check the output queue on tp for space for a kernel message (from uprintf
1292  * or tprintf).  Allow some space over the normal hiwater mark so we don't
1293  * lose messages due to normal flow control, but don't let the tty run amok.
1294  * Sleeps here are not interruptible, but we return prematurely if new signals
1295  * arrive.
1296  */
1297 int
1298 ttycheckoutq(tp, wait)
1299 	register struct tty *tp;
1300 	int wait;
1301 {
1302 	int hiwat, s, oldsig;
1303 
1304 	hiwat = tp->t_hiwat;
1305 	s = spltty();
1306 	oldsig = wait ? curproc->p_siglist : 0;
1307 	if (tp->t_outq.c_cc > hiwat + 200)
1308 		while (tp->t_outq.c_cc > hiwat) {
1309 			ttstart(tp);
1310 			if (wait == 0 || curproc->p_siglist != oldsig) {
1311 				splx(s);
1312 				return (0);
1313 			}
1314 			timeout((void (*)__P((void *)))wakeup,
1315 			    (void *)&tp->t_outq, hz);
1316 			SET(tp->t_state, TS_ASLEEP);
1317 			sleep((caddr_t)&tp->t_outq, PZERO - 1);
1318 		}
1319 	splx(s);
1320 	return (1);
1321 }
1322 
1323 /*
1324  * Process a write call on a tty device.
1325  */
1326 int
1327 ttwrite(tp, uio, flag)
1328 	register struct tty *tp;
1329 	register struct uio *uio;
1330 	int flag;
1331 {
1332 	register char *cp;
1333 	register int cc, ce;
1334 	register struct proc *p;
1335 	int i, hiwat, cnt, error, s;
1336 	char obuf[OBUFSIZ];
1337 
1338 	hiwat = tp->t_hiwat;
1339 	cnt = uio->uio_resid;
1340 	error = 0;
1341 	cc = 0;
1342 loop:
1343 	s = spltty();
1344 	if (!ISSET(tp->t_state, TS_CARR_ON) &&
1345 	    !ISSET(tp->t_cflag, CLOCAL)) {
1346 		if (ISSET(tp->t_state, TS_ISOPEN)) {
1347 			splx(s);
1348 			return (EIO);
1349 		} else if (flag & IO_NDELAY) {
1350 			splx(s);
1351 			error = EWOULDBLOCK;
1352 			goto out;
1353 		} else {
1354 			/* Sleep awaiting carrier. */
1355 			error = ttysleep(tp,
1356 			    &tp->t_rawq, TTIPRI | PCATCH,ttopen, 0);
1357 			splx(s);
1358 			if (error)
1359 				goto out;
1360 			goto loop;
1361 		}
1362 	}
1363 	splx(s);
1364 	/*
1365 	 * Hang the process if it's in the background.
1366 	 */
1367 	p = curproc;
1368 	if (isbackground(p, tp) &&
1369 	    ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
1370 	    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
1371 	    (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
1372 	     p->p_pgrp->pg_jobc) {
1373 		pgsignal(p->p_pgrp, SIGTTOU, 1);
1374 		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
1375 			goto out;
1376 		goto loop;
1377 	}
1378 	/*
1379 	 * Process the user's data in at most OBUFSIZ chunks.  Perform any
1380 	 * output translation.  Keep track of high water mark, sleep on
1381 	 * overflow awaiting device aid in acquiring new space.
1382 	 */
1383 	while (uio->uio_resid > 0 || cc > 0) {
1384 		if (ISSET(tp->t_lflag, FLUSHO)) {
1385 			uio->uio_resid = 0;
1386 			return (0);
1387 		}
1388 		if (tp->t_outq.c_cc > hiwat)
1389 			goto ovhiwat;
1390 		/*
1391 		 * Grab a hunk of data from the user, unless we have some
1392 		 * leftover from last time.
1393 		 */
1394 		if (cc == 0) {
1395 			cc = min(uio->uio_resid, OBUFSIZ);
1396 			cp = obuf;
1397 			error = uiomove(cp, cc, uio);
1398 			if (error) {
1399 				cc = 0;
1400 				break;
1401 			}
1402 		}
1403 		/*
1404 		 * If nothing fancy need be done, grab those characters we
1405 		 * can handle without any of ttyoutput's processing and
1406 		 * just transfer them to the output q.  For those chars
1407 		 * which require special processing (as indicated by the
1408 		 * bits in char_type), call ttyoutput.  After processing
1409 		 * a hunk of data, look for FLUSHO so ^O's will take effect
1410 		 * immediately.
1411 		 */
1412 		while (cc > 0) {
1413 			if (!ISSET(tp->t_oflag, OPOST))
1414 				ce = cc;
1415 			else {
1416 				ce = cc - scanc((u_int)cc, (u_char *)cp,
1417 				   (u_char *)char_type, CCLASSMASK);
1418 				/*
1419 				 * If ce is zero, then we're processing
1420 				 * a special character through ttyoutput.
1421 				 */
1422 				if (ce == 0) {
1423 					tp->t_rocount = 0;
1424 					if (ttyoutput(*cp, tp) >= 0) {
1425 						/* No Clists, wait a bit. */
1426 						ttstart(tp);
1427 						if (error = ttysleep(tp, &lbolt,
1428 						    TTOPRI | PCATCH, ttybuf, 0))
1429 							break;
1430 						goto loop;
1431 					}
1432 					cp++;
1433 					cc--;
1434 					if (ISSET(tp->t_lflag, FLUSHO) ||
1435 					    tp->t_outq.c_cc > hiwat)
1436 						goto ovhiwat;
1437 					continue;
1438 				}
1439 			}
1440 			/*
1441 			 * A bunch of normal characters have been found.
1442 			 * Transfer them en masse to the output queue and
1443 			 * continue processing at the top of the loop.
1444 			 * If there are any further characters in this
1445 			 * <= OBUFSIZ chunk, the first should be a character
1446 			 * requiring special handling by ttyoutput.
1447 			 */
1448 			tp->t_rocount = 0;
1449 			i = b_to_q(cp, ce, &tp->t_outq);
1450 			ce -= i;
1451 			tp->t_column += ce;
1452 			cp += ce, cc -= ce, tk_nout += ce;
1453 			tp->t_outcc += ce;
1454 			if (i > 0) {
1455 				/* No Clists, wait a bit. */
1456 				ttstart(tp);
1457 				if (error = ttysleep(tp,
1458 				    &lbolt, TTOPRI | PCATCH, ttybuf, 0))
1459 					break;
1460 				goto loop;
1461 			}
1462 			if (ISSET(tp->t_lflag, FLUSHO) ||
1463 			    tp->t_outq.c_cc > hiwat)
1464 				break;
1465 		}
1466 		ttstart(tp);
1467 	}
1468 out:
1469 	/*
1470 	 * If cc is nonzero, we leave the uio structure inconsistent, as the
1471 	 * offset and iov pointers have moved forward, but it doesn't matter
1472 	 * (the call will either return short or restart with a new uio).
1473 	 */
1474 	uio->uio_resid += cc;
1475 	return (error);
1476 
1477 ovhiwat:
1478 	ttstart(tp);
1479 	s = spltty();
1480 	/*
1481 	 * This can only occur if FLUSHO is set in t_lflag,
1482 	 * or if ttstart/oproc is synchronous (or very fast).
1483 	 */
1484 	if (tp->t_outq.c_cc <= hiwat) {
1485 		splx(s);
1486 		goto loop;
1487 	}
1488 	if (flag & IO_NDELAY) {
1489 		splx(s);
1490 		uio->uio_resid += cc;
1491 		return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1492 	}
1493 	SET(tp->t_state, TS_ASLEEP);
1494 	error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
1495 	splx(s);
1496 	if (error)
1497 		goto out;
1498 	goto loop;
1499 }
1500 
1501 /*
1502  * Rubout one character from the rawq of tp
1503  * as cleanly as possible.
1504  */
1505 void
1506 ttyrub(c, tp)
1507 	register int c;
1508 	register struct tty *tp;
1509 {
1510 	register char *cp;
1511 	register int savecol;
1512 	int tabc, s;
1513 
1514 	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1515 		return;
1516 	CLR(tp->t_lflag, FLUSHO);
1517 	if (ISSET(tp->t_lflag, ECHOE)) {
1518 		if (tp->t_rocount == 0) {
1519 			/*
1520 			 * Screwed by ttwrite; retype
1521 			 */
1522 			ttyretype(tp);
1523 			return;
1524 		}
1525 		if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1526 			ttyrubo(tp, 2);
1527 		else {
1528 			CLR(c, ~TTY_CHARMASK);
1529 			switch (CCLASS(c)) {
1530 			case ORDINARY:
1531 				ttyrubo(tp, 1);
1532 				break;
1533 			case BACKSPACE:
1534 			case CONTROL:
1535 			case NEWLINE:
1536 			case RETURN:
1537 			case VTAB:
1538 				if (ISSET(tp->t_lflag, ECHOCTL))
1539 					ttyrubo(tp, 2);
1540 				break;
1541 			case TAB:
1542 				if (tp->t_rocount < tp->t_rawq.c_cc) {
1543 					ttyretype(tp);
1544 					return;
1545 				}
1546 				s = spltty();
1547 				savecol = tp->t_column;
1548 				SET(tp->t_state, TS_CNTTB);
1549 				SET(tp->t_lflag, FLUSHO);
1550 				tp->t_column = tp->t_rocol;
1551 				cp = tp->t_rawq.c_cf;
1552 				if (cp)
1553 					tabc = *cp;	/* XXX FIX NEXTC */
1554 				for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
1555 					ttyecho(tabc, tp);
1556 				CLR(tp->t_lflag, FLUSHO);
1557 				CLR(tp->t_state, TS_CNTTB);
1558 				splx(s);
1559 
1560 				/* savecol will now be length of the tab. */
1561 				savecol -= tp->t_column;
1562 				tp->t_column += savecol;
1563 				if (savecol > 8)
1564 					savecol = 8;	/* overflow screw */
1565 				while (--savecol >= 0)
1566 					(void)ttyoutput('\b', tp);
1567 				break;
1568 			default:			/* XXX */
1569 #define	PANICSTR	"ttyrub: would panic c = %d, val = %d\n"
1570 				(void)printf(PANICSTR, c, CCLASS(c));
1571 #ifdef notdef
1572 				panic(PANICSTR, c, CCLASS(c));
1573 #endif
1574 			}
1575 		}
1576 	} else if (ISSET(tp->t_lflag, ECHOPRT)) {
1577 		if (!ISSET(tp->t_state, TS_ERASE)) {
1578 			SET(tp->t_state, TS_ERASE);
1579 			(void)ttyoutput('\\', tp);
1580 		}
1581 		ttyecho(c, tp);
1582 	} else
1583 		ttyecho(tp->t_cc[VERASE], tp);
1584 	--tp->t_rocount;
1585 }
1586 
1587 /*
1588  * Back over cnt characters, erasing them.
1589  */
1590 static void
1591 ttyrubo(tp, cnt)
1592 	register struct tty *tp;
1593 	int cnt;
1594 {
1595 
1596 	while (cnt-- > 0) {
1597 		(void)ttyoutput('\b', tp);
1598 		(void)ttyoutput(' ', tp);
1599 		(void)ttyoutput('\b', tp);
1600 	}
1601 }
1602 
1603 /*
1604  * ttyretype --
1605  *	Reprint the rawq line.  Note, it is assumed that c_cc has already
1606  *	been checked.
1607  */
1608 void
1609 ttyretype(tp)
1610 	register struct tty *tp;
1611 {
1612 	register char *cp;
1613 	int s, c;
1614 
1615 	/* Echo the reprint character. */
1616 	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
1617 		ttyecho(tp->t_cc[VREPRINT], tp);
1618 
1619 	(void)ttyoutput('\n', tp);
1620 
1621 	/*
1622 	 * XXX
1623 	 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
1624 	 * BIT OF FIRST CHAR.
1625 	 */
1626 	s = spltty();
1627 	for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
1628 	    cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
1629 		ttyecho(c, tp);
1630 	for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
1631 	    cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
1632 		ttyecho(c, tp);
1633 	CLR(tp->t_state, TS_ERASE);
1634 	splx(s);
1635 
1636 	tp->t_rocount = tp->t_rawq.c_cc;
1637 	tp->t_rocol = 0;
1638 }
1639 
1640 /*
1641  * Echo a typed character to the terminal.
1642  */
1643 static void
1644 ttyecho(c, tp)
1645 	register int c;
1646 	register struct tty *tp;
1647 {
1648 
1649 	if (!ISSET(tp->t_state, TS_CNTTB))
1650 		CLR(tp->t_lflag, FLUSHO);
1651 	if ((!ISSET(tp->t_lflag, ECHO) &&
1652 	    (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) ||
1653 	    ISSET(tp->t_lflag, EXTPROC))
1654 		return;
1655 	if (ISSET(tp->t_lflag, ECHOCTL) &&
1656 	    (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' ||
1657 	    ISSET(c, TTY_CHARMASK) == 0177)) {
1658 		(void)ttyoutput('^', tp);
1659 		CLR(c, ~TTY_CHARMASK);
1660 		if (c == 0177)
1661 			c = '?';
1662 		else
1663 			c += 'A' - 1;
1664 	}
1665 	(void)ttyoutput(c, tp);
1666 }
1667 
1668 /*
1669  * Wake up any readers on a tty.
1670  */
1671 void
1672 ttwakeup(tp)
1673 	register struct tty *tp;
1674 {
1675 
1676 	selwakeup(&tp->t_rsel);
1677 	if (ISSET(tp->t_state, TS_ASYNC))
1678 		pgsignal(tp->t_pgrp, SIGIO, 1);
1679 	wakeup((caddr_t)&tp->t_rawq);
1680 }
1681 
1682 /*
1683  * Look up a code for a specified speed in a conversion table;
1684  * used by drivers to map software speed values to hardware parameters.
1685  */
1686 int
1687 ttspeedtab(speed, table)
1688 	int speed;
1689 	register struct speedtab *table;
1690 {
1691 
1692 	for ( ; table->sp_speed != -1; table++)
1693 		if (table->sp_speed == speed)
1694 			return (table->sp_code);
1695 	return (-1);
1696 }
1697 
1698 /*
1699  * Set tty hi and low water marks.
1700  *
1701  * Try to arrange the dynamics so there's about one second
1702  * from hi to low water.
1703  *
1704  */
1705 void
1706 ttsetwater(tp)
1707 	struct tty *tp;
1708 {
1709 	register int cps, x;
1710 
1711 #define CLAMP(x, h, l)	((x) > h ? h : ((x) < l) ? l : (x))
1712 
1713 	cps = tp->t_ospeed / 10;
1714 	tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
1715 	x += cps;
1716 	x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
1717 	tp->t_hiwat = roundup(x, CBSIZE);
1718 #undef	CLAMP
1719 }
1720 
1721 /*
1722  * Report on state of foreground process group.
1723  */
1724 void
1725 ttyinfo(tp)
1726 	register struct tty *tp;
1727 {
1728 	register struct proc *p, *pick;
1729 	struct timeval utime, stime;
1730 	int tmp;
1731 
1732 	if (ttycheckoutq(tp,0) == 0)
1733 		return;
1734 
1735 	/* Print load average. */
1736 	tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
1737 	ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
1738 
1739 	if (tp->t_session == NULL)
1740 		ttyprintf(tp, "not a controlling terminal\n");
1741 	else if (tp->t_pgrp == NULL)
1742 		ttyprintf(tp, "no foreground process group\n");
1743 	else if ((p = tp->t_pgrp->pg_mem) == NULL)
1744 		ttyprintf(tp, "empty foreground process group\n");
1745 	else {
1746 		/* Pick interesting process. */
1747 		for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
1748 			if (proc_compare(pick, p))
1749 				pick = p;
1750 
1751 		ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
1752 		    pick->p_stat == SRUN ? "running" :
1753 		    pick->p_wmesg ? pick->p_wmesg : "iowait");
1754 
1755 		calcru(pick, &utime, &stime, NULL);
1756 
1757 		/* Print user time. */
1758 		ttyprintf(tp, "%d.%02du ",
1759 		    utime.tv_sec, (utime.tv_usec + 5000) / 10000);
1760 
1761 		/* Print system time. */
1762 		ttyprintf(tp, "%d.%02ds ",
1763 		    stime.tv_sec, (stime.tv_usec + 5000) / 10000);
1764 
1765 #define	pgtok(a)	(((a) * NBPG) / 1024)
1766 		/* Print percentage cpu, resident set size. */
1767 		tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT;
1768 		ttyprintf(tp, "%d%% %dk\n",
1769 		    tmp / 100,
1770 		    pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
1771 #ifdef pmap_resident_count
1772 			pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap))
1773 #else
1774 			pgtok(pick->p_vmspace->vm_rssize)
1775 #endif
1776 			);
1777 	}
1778 	tp->t_rocount = 0;	/* so pending input will be retyped if BS */
1779 }
1780 
1781 /*
1782  * Returns 1 if p2 is "better" than p1
1783  *
1784  * The algorithm for picking the "interesting" process is thus:
1785  *
1786  *	1) Only foreground processes are eligible - implied.
1787  *	2) Runnable processes are favored over anything else.  The runner
1788  *	   with the highest cpu utilization is picked (p_estcpu).  Ties are
1789  *	   broken by picking the highest pid.
1790  *	3) The sleeper with the shortest sleep time is next.  With ties,
1791  *	   we pick out just "short-term" sleepers (P_SINTR == 0).
1792  *	4) Further ties are broken by picking the highest pid.
1793  */
1794 #define ISRUN(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
1795 #define TESTAB(a, b)    ((a)<<1 | (b))
1796 #define ONLYA   2
1797 #define ONLYB   1
1798 #define BOTH    3
1799 
1800 static int
1801 proc_compare(p1, p2)
1802 	register struct proc *p1, *p2;
1803 {
1804 
1805 	if (p1 == NULL)
1806 		return (1);
1807 	/*
1808 	 * see if at least one of them is runnable
1809 	 */
1810 	switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
1811 	case ONLYA:
1812 		return (0);
1813 	case ONLYB:
1814 		return (1);
1815 	case BOTH:
1816 		/*
1817 		 * tie - favor one with highest recent cpu utilization
1818 		 */
1819 		if (p2->p_estcpu > p1->p_estcpu)
1820 			return (1);
1821 		if (p1->p_estcpu > p2->p_estcpu)
1822 			return (0);
1823 		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
1824 	}
1825 	/*
1826  	 * weed out zombies
1827 	 */
1828 	switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
1829 	case ONLYA:
1830 		return (1);
1831 	case ONLYB:
1832 		return (0);
1833 	case BOTH:
1834 		return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1835 	}
1836 	/*
1837 	 * pick the one with the smallest sleep time
1838 	 */
1839 	if (p2->p_slptime > p1->p_slptime)
1840 		return (0);
1841 	if (p1->p_slptime > p2->p_slptime)
1842 		return (1);
1843 	/*
1844 	 * favor one sleeping in a non-interruptible sleep
1845 	 */
1846 	if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
1847 		return (1);
1848 	if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
1849 		return (0);
1850 	return (p2->p_pid > p1->p_pid);		/* tie - return highest pid */
1851 }
1852 
1853 /*
1854  * Output char to tty; console putchar style.
1855  */
1856 int
1857 tputchar(c, tp)
1858 	int c;
1859 	struct tty *tp;
1860 {
1861 	register int s;
1862 
1863 	s = spltty();
1864 	if (ISSET(tp->t_state,
1865 	    TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
1866 		splx(s);
1867 		return (-1);
1868 	}
1869 	if (c == '\n')
1870 		(void)ttyoutput('\r', tp);
1871 	(void)ttyoutput(c, tp);
1872 	ttstart(tp);
1873 	splx(s);
1874 	return (0);
1875 }
1876 
1877 /*
1878  * Sleep on chan, returning ERESTART if tty changed while we napped and
1879  * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep.  If
1880  * the tty is revoked, restarting a pending call will redo validation done
1881  * at the start of the call.
1882  */
1883 int
1884 ttysleep(tp, chan, pri, wmesg, timo)
1885 	struct tty *tp;
1886 	void *chan;
1887 	int pri, timo;
1888 	char *wmesg;
1889 {
1890 	int error;
1891 	short gen;
1892 
1893 	gen = tp->t_gen;
1894 	if (error = tsleep(chan, pri, wmesg, timo))
1895 		return (error);
1896 	return (tp->t_gen == gen ? 0 : ERESTART);
1897 }
1898