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