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