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