xref: /csrg-svn/sys/kern/tty.c (revision 24392)
1 /*
2  * Copyright (c) 1982 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	6.21 (Berkeley) 08/22/85
7  */
8 
9 #include "../machine/reg.h"
10 
11 #include "param.h"
12 #include "systm.h"
13 #include "dir.h"
14 #include "user.h"
15 #include "ioctl.h"
16 #include "tty.h"
17 #include "proc.h"
18 #include "inode.h"
19 #include "file.h"
20 #include "conf.h"
21 #include "buf.h"
22 #include "dk.h"
23 #include "uio.h"
24 #include "kernel.h"
25 
26 /*
27  * Table giving parity for characters and indicating
28  * character classes to tty driver.  In particular,
29  * if the low 6 bits are 0, then the character needs
30  * no special processing on output.
31  */
32 
33 char partab[] = {
34 	0001,0201,0201,0001,0201,0001,0001,0201,
35 	0202,0004,0003,0201,0005,0206,0201,0001,
36 	0201,0001,0001,0201,0001,0201,0201,0001,
37 	0001,0201,0201,0001,0201,0001,0001,0201,
38 	0200,0000,0000,0200,0000,0200,0200,0000,
39 	0000,0200,0200,0000,0200,0000,0000,0200,
40 	0000,0200,0200,0000,0200,0000,0000,0200,
41 	0200,0000,0000,0200,0000,0200,0200,0000,
42 	0200,0000,0000,0200,0000,0200,0200,0000,
43 	0000,0200,0200,0000,0200,0000,0000,0200,
44 	0000,0200,0200,0000,0200,0000,0000,0200,
45 	0200,0000,0000,0200,0000,0200,0200,0000,
46 	0000,0200,0200,0000,0200,0000,0000,0200,
47 	0200,0000,0000,0200,0000,0200,0200,0000,
48 	0200,0000,0000,0200,0000,0200,0200,0000,
49 	0000,0200,0200,0000,0200,0000,0000,0201,
50 
51 	/*
52 	 * 7 bit ascii ends with the last character above,
53 	 * but we contine through all 256 codes for the sake
54 	 * of the tty output routines which use special vax
55 	 * instructions which need a 256 character trt table.
56 	 */
57 
58 	0007,0007,0007,0007,0007,0007,0007,0007,
59 	0007,0007,0007,0007,0007,0007,0007,0007,
60 	0007,0007,0007,0007,0007,0007,0007,0007,
61 	0007,0007,0007,0007,0007,0007,0007,0007,
62 	0007,0007,0007,0007,0007,0007,0007,0007,
63 	0007,0007,0007,0007,0007,0007,0007,0007,
64 	0007,0007,0007,0007,0007,0007,0007,0007,
65 	0007,0007,0007,0007,0007,0007,0007,0007,
66 	0007,0007,0007,0007,0007,0007,0007,0007,
67 	0007,0007,0007,0007,0007,0007,0007,0007,
68 	0007,0007,0007,0007,0007,0007,0007,0007,
69 	0007,0007,0007,0007,0007,0007,0007,0007,
70 	0007,0007,0007,0007,0007,0007,0007,0007,
71 	0007,0007,0007,0007,0007,0007,0007,0007,
72 	0007,0007,0007,0007,0007,0007,0007,0007,
73 	0007,0007,0007,0007,0007,0007,0007,0007
74 };
75 
76 /*
77  * Input mapping table-- if an entry is non-zero, when the
78  * corresponding character is typed preceded by "\" the escape
79  * sequence is replaced by the table value.  Mostly used for
80  * upper-case only terminals.
81  */
82 char	maptab[] ={
83 	000,000,000,000,000,000,000,000,
84 	000,000,000,000,000,000,000,000,
85 	000,000,000,000,000,000,000,000,
86 	000,000,000,000,000,000,000,000,
87 	000,'|',000,000,000,000,000,'`',
88 	'{','}',000,000,000,000,000,000,
89 	000,000,000,000,000,000,000,000,
90 	000,000,000,000,000,000,000,000,
91 	000,000,000,000,000,000,000,000,
92 	000,000,000,000,000,000,000,000,
93 	000,000,000,000,000,000,000,000,
94 	000,000,000,000,000,000,'~',000,
95 	000,'A','B','C','D','E','F','G',
96 	'H','I','J','K','L','M','N','O',
97 	'P','Q','R','S','T','U','V','W',
98 	'X','Y','Z',000,000,000,000,000,
99 };
100 
101 short	tthiwat[16] =
102    { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 };
103 short	ttlowat[16] =
104    {  30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
105 
106 struct	ttychars ttydefaults = {
107 	CERASE,	CKILL,	CINTR,	CQUIT,	CSTART,	CSTOP,	CEOF,
108 	CBRK,	CSUSP,	CDSUSP, CRPRNT, CFLUSH, CWERASE,CLNEXT
109 };
110 
111 ttychars(tp)
112 	struct tty *tp;
113 {
114 
115 	tp->t_chars = ttydefaults;
116 }
117 
118 /*
119  * Wait for output to drain, then flush input waiting.
120  */
121 ttywflush(tp)
122 	register struct tty *tp;
123 {
124 
125 	ttywait(tp);
126 	ttyflush(tp, FREAD);
127 }
128 
129 ttywait(tp)
130 	register struct tty *tp;
131 {
132 	register int s = spltty();
133 
134 	while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) &&
135 	    tp->t_state&TS_CARR_ON && tp->t_oproc) {	/* kludge for pty */
136 		(*tp->t_oproc)(tp);
137 		tp->t_state |= TS_ASLEEP;
138 		sleep((caddr_t)&tp->t_outq, TTOPRI);
139 	}
140 	splx(s);
141 }
142 
143 /*
144  * Flush all TTY queues
145  */
146 ttyflush(tp, rw)
147 	register struct tty *tp;
148 {
149 	register s;
150 
151 	s = spltty();
152 	if (rw & FREAD) {
153 		while (getc(&tp->t_canq) >= 0)
154 			;
155 		wakeup((caddr_t)&tp->t_rawq);
156 	}
157 	if (rw & FWRITE) {
158 		wakeup((caddr_t)&tp->t_outq);
159 		tp->t_state &= ~TS_TTSTOP;
160 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
161 		while (getc(&tp->t_outq) >= 0)
162 			;
163 	}
164 	if (rw & FREAD) {
165 		while (getc(&tp->t_rawq) >= 0)
166 			;
167 		tp->t_rocount = 0;
168 		tp->t_rocol = 0;
169 		tp->t_state &= ~TS_LOCAL;
170 	}
171 	splx(s);
172 }
173 
174 /*
175  * Send stop character on input overflow.
176  */
177 ttyblock(tp)
178 	register struct tty *tp;
179 {
180 	register x;
181 
182 	x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
183 	if (tp->t_rawq.c_cc > TTYHOG) {
184 		ttyflush(tp, FREAD|FWRITE);
185 		tp->t_state &= ~TS_TBLOCK;
186 	}
187 	/*
188 	 * Block further input iff:
189 	 * Current input > threshold AND input is available to user program
190 	 */
191 	if (x >= TTYHOG/2 &&
192 	    ((tp->t_flags & (RAW|CBREAK)) || (tp->t_canq.c_cc > 0))) {
193 		if (putc(tp->t_stopc, &tp->t_outq)==0) {
194 			tp->t_state |= TS_TBLOCK;
195 			ttstart(tp);
196 		}
197 	}
198 }
199 
200 /*
201  * Restart typewriter output following a delay
202  * timeout.
203  * The name of the routine is passed to the timeout
204  * subroutine and it is called during a clock interrupt.
205  */
206 ttrstrt(tp)
207 	register struct tty *tp;
208 {
209 
210 	if (tp == 0)
211 		panic("ttrstrt");
212 	tp->t_state &= ~TS_TIMEOUT;
213 	ttstart(tp);
214 }
215 
216 /*
217  * Start output on the typewriter. It is used from the top half
218  * after some characters have been put on the output queue,
219  * from the interrupt routine to transmit the next
220  * character, and after a timeout has finished.
221  */
222 ttstart(tp)
223 	register struct tty *tp;
224 {
225 	register s;
226 
227 	s = spltty();
228 	if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 &&
229 	    tp->t_oproc)		/* kludge for pty */
230 		(*tp->t_oproc)(tp);
231 	splx(s);
232 }
233 
234 /*
235  * Common code for tty ioctls.
236  */
237 /*ARGSUSED*/
238 ttioctl(tp, com, data, flag)
239 	register struct tty *tp;
240 	caddr_t data;
241 {
242 	int dev = tp->t_dev;
243 	extern int nldisp;
244 	int s;
245 	register int newflags;
246 
247 	/*
248 	 * If the ioctl involves modification,
249 	 * hang if in the background.
250 	 */
251 	switch (com) {
252 
253 	case TIOCSETD:
254 	case TIOCSETP:
255 	case TIOCSETN:
256 	case TIOCFLUSH:
257 	case TIOCSETC:
258 	case TIOCSLTC:
259 	case TIOCSPGRP:
260 	case TIOCLBIS:
261 	case TIOCLBIC:
262 	case TIOCLSET:
263 	case TIOCSTI:
264 	case TIOCSWINSZ:
265 		while (tp->t_line == NTTYDISC &&
266 		   u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
267 		   (u.u_procp->p_flag&SVFORK) == 0 &&
268 		   !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) &&
269 		   !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) {
270 			gsignal(u.u_procp->p_pgrp, SIGTTOU);
271 			sleep((caddr_t)&lbolt, TTOPRI);
272 		}
273 		break;
274 	}
275 
276 	/*
277 	 * Process the ioctl.
278 	 */
279 	switch (com) {
280 
281 	/* get discipline number */
282 	case TIOCGETD:
283 		*(int *)data = tp->t_line;
284 		break;
285 
286 	/* set line discipline */
287 	case TIOCSETD: {
288 		register int t = *(int *)data;
289 		int error = 0;
290 
291 		if ((unsigned) t >= nldisp)
292 			return (ENXIO);
293 		s = spltty();
294 		if (tp->t_line)
295 			(*linesw[tp->t_line].l_close)(tp);
296 		if (t)
297 			error = (*linesw[t].l_open)(dev, tp);
298 		if (error) {
299 			if (tp->t_line)
300 				(void) (*linesw[tp->t_line].l_open)(dev, tp);
301 			splx(s);
302 			return (error);
303 		}
304 		tp->t_line = t;
305 		splx(s);
306 		break;
307 	}
308 
309 	/* prevent more opens on channel */
310 	case TIOCEXCL:
311 		tp->t_state |= TS_XCLUDE;
312 		break;
313 
314 	case TIOCNXCL:
315 		tp->t_state &= ~TS_XCLUDE;
316 		break;
317 
318 	/* hang up line on last close */
319 	case TIOCHPCL:
320 		tp->t_state |= TS_HUPCLS;
321 		break;
322 
323 	case TIOCFLUSH: {
324 		register int flags = *(int *)data;
325 
326 		if (flags == 0)
327 			flags = FREAD|FWRITE;
328 		else
329 			flags &= FREAD|FWRITE;
330 		ttyflush(tp, flags);
331 		break;
332 	}
333 
334 	/* return number of characters immediately available */
335 	case FIONREAD:
336 		*(off_t *)data = ttnread(tp);
337 		break;
338 
339 	case TIOCOUTQ:
340 		*(int *)data = tp->t_outq.c_cc;
341 		break;
342 
343 	case TIOCSTOP:
344 		s = spltty();
345 		if ((tp->t_state&TS_TTSTOP) == 0) {
346 			tp->t_state |= TS_TTSTOP;
347 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
348 		}
349 		splx(s);
350 		break;
351 
352 	case TIOCSTART:
353 		s = spltty();
354 		if ((tp->t_state&TS_TTSTOP) || (tp->t_flags&FLUSHO)) {
355 			tp->t_state &= ~TS_TTSTOP;
356 			tp->t_flags &= ~FLUSHO;
357 			ttstart(tp);
358 		}
359 		splx(s);
360 		break;
361 
362 	/*
363 	 * Simulate typing of a character at the terminal.
364 	 */
365 	case TIOCSTI:
366 		if (u.u_uid && (flag & FREAD) == 0)
367 			return (EPERM);
368 		if (u.u_uid && u.u_ttyp != tp)
369 			return (EACCES);
370 		(*linesw[tp->t_line].l_rint)(*(char *)data, tp);
371 		break;
372 
373 	case TIOCSETP:
374 	case TIOCSETN: {
375 		register struct sgttyb *sg = (struct sgttyb *)data;
376 
377 		tp->t_erase = sg->sg_erase;
378 		tp->t_kill = sg->sg_kill;
379 		tp->t_ispeed = sg->sg_ispeed;
380 		tp->t_ospeed = sg->sg_ospeed;
381 		newflags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff);
382 		s = spltty();
383 		if (tp->t_flags&RAW || newflags&RAW || com == TIOCSETP) {
384 			ttywait(tp);
385 			ttyflush(tp, FREAD);
386 		} else if ((tp->t_flags&CBREAK) != (newflags&CBREAK)) {
387 			if (newflags&CBREAK) {
388 				struct clist tq;
389 
390 				catq(&tp->t_rawq, &tp->t_canq);
391 				tq = tp->t_rawq;
392 				tp->t_rawq = tp->t_canq;
393 				tp->t_canq = tq;
394 			} else {
395 				tp->t_flags |= PENDIN;
396 				newflags |= PENDIN;
397 				ttwakeup(tp);
398 			}
399 		}
400 		tp->t_flags = newflags;
401 		if (tp->t_flags&RAW) {
402 			tp->t_state &= ~TS_TTSTOP;
403 			ttstart(tp);
404 		}
405 		splx(s);
406 		break;
407 	}
408 
409 	/* send current parameters to user */
410 	case TIOCGETP: {
411 		register struct sgttyb *sg = (struct sgttyb *)data;
412 
413 		sg->sg_ispeed = tp->t_ispeed;
414 		sg->sg_ospeed = tp->t_ospeed;
415 		sg->sg_erase = tp->t_erase;
416 		sg->sg_kill = tp->t_kill;
417 		sg->sg_flags = tp->t_flags;
418 		break;
419 	}
420 
421 	case FIONBIO:
422 		if (*(int *)data)
423 			tp->t_state |= TS_NBIO;
424 		else
425 			tp->t_state &= ~TS_NBIO;
426 		break;
427 
428 	case FIOASYNC:
429 		if (*(int *)data)
430 			tp->t_state |= TS_ASYNC;
431 		else
432 			tp->t_state &= ~TS_ASYNC;
433 		break;
434 
435 	case TIOCGETC:
436 		bcopy((caddr_t)&tp->t_intrc, data, sizeof (struct tchars));
437 		break;
438 
439 	case TIOCSETC:
440 		bcopy(data, (caddr_t)&tp->t_intrc, sizeof (struct tchars));
441 		break;
442 
443 	/* set/get local special characters */
444 	case TIOCSLTC:
445 		bcopy(data, (caddr_t)&tp->t_suspc, sizeof (struct ltchars));
446 		break;
447 
448 	case TIOCGLTC:
449 		bcopy((caddr_t)&tp->t_suspc, data, sizeof (struct ltchars));
450 		break;
451 
452 	/*
453 	 * Modify local mode word.
454 	 */
455 	case TIOCLBIS:
456 		tp->t_flags |= *(int *)data << 16;
457 		break;
458 
459 	case TIOCLBIC:
460 		tp->t_flags &= ~(*(int *)data << 16);
461 		break;
462 
463 	case TIOCLSET:
464 		tp->t_flags &= 0xffff;
465 		tp->t_flags |= *(int *)data << 16;
466 		break;
467 
468 	case TIOCLGET:
469 		*(int *)data = ((unsigned) tp->t_flags) >> 16;
470 		break;
471 
472 	/*
473 	 * Allow SPGRP only if tty is open for reading.
474 	 * Quick check: if we can find a process in the new pgrp,
475 	 * this user must own that process.
476 	 * SHOULD VERIFY THAT PGRP IS IN USE AND IS THIS USER'S.
477 	 */
478 	case TIOCSPGRP: {
479 		struct proc *p;
480 		int pgrp = *(int *)data;
481 
482 		if (u.u_uid && (flag & FREAD) == 0)
483 			return (EPERM);
484 		p = pfind(pgrp);
485 		if (p && p->p_pgrp == pgrp &&
486 		    p->p_uid != u.u_uid && u.u_uid && !inferior(p))
487 			return (EPERM);
488 		tp->t_pgrp = pgrp;
489 		break;
490 	}
491 
492 	case TIOCGPGRP:
493 		*(int *)data = tp->t_pgrp;
494 		break;
495 
496 	case TIOCSWINSZ:
497 		if (bcmp((caddr_t)&tp->t_winsize, data,
498 		    sizeof (struct winsize))) {
499 			tp->t_winsize = *(struct winsize *)data;
500 			gsignal(tp->t_pgrp, SIGWINCH);
501 		}
502 		break;
503 
504 	case TIOCGWINSZ:
505 		*(struct winsize *)data = tp->t_winsize;
506 		break;
507 
508 	default:
509 		return (-1);
510 	}
511 	return (0);
512 }
513 
514 ttnread(tp)
515 	struct tty *tp;
516 {
517 	int nread = 0;
518 
519 	if (tp->t_flags & PENDIN)
520 		ttypend(tp);
521 	nread = tp->t_canq.c_cc;
522 	if (tp->t_flags & (RAW|CBREAK))
523 		nread += tp->t_rawq.c_cc;
524 	return (nread);
525 }
526 
527 ttselect(dev, rw)
528 	dev_t dev;
529 	int rw;
530 {
531 	register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
532 	int nread;
533 	int s = spltty();
534 
535 	switch (rw) {
536 
537 	case FREAD:
538 		nread = ttnread(tp);
539 		if ((nread > 0) || ((tp->t_state & TS_CARR_ON) == 0))
540 			goto win;
541 		if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
542 			tp->t_state |= TS_RCOLL;
543 		else
544 			tp->t_rsel = u.u_procp;
545 		break;
546 
547 	case FWRITE:
548 		if (tp->t_outq.c_cc <= TTLOWAT(tp))
549 			goto win;
550 		if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
551 			tp->t_state |= TS_WCOLL;
552 		else
553 			tp->t_wsel = u.u_procp;
554 		break;
555 	}
556 	splx(s);
557 	return (0);
558 win:
559 	splx(s);
560 	return (1);
561 }
562 
563 /*
564  * Establish a process group for distribution of
565  * quits and interrupts from the tty.
566  */
567 ttyopen(dev, tp)
568 	dev_t dev;
569 	register struct tty *tp;
570 {
571 	register struct proc *pp;
572 
573 	pp = u.u_procp;
574 	tp->t_dev = dev;
575 	if (pp->p_pgrp == 0) {
576 		u.u_ttyp = tp;
577 		u.u_ttyd = dev;
578 		if (tp->t_pgrp == 0)
579 			tp->t_pgrp = pp->p_pid;
580 		pp->p_pgrp = tp->t_pgrp;
581 	}
582 	tp->t_state &= ~TS_WOPEN;
583 	if ((tp->t_state & TS_ISOPEN) == 0) {
584 		tp->t_state |= TS_ISOPEN;
585 		bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize));
586 		if (tp->t_line != NTTYDISC)
587 			ttywflush(tp);
588 	}
589 	return (0);
590 }
591 
592 /*
593  * clean tp on last close
594  */
595 ttyclose(tp)
596 	register struct tty *tp;
597 {
598 
599 	if (tp->t_line) {
600 		ttywflush(tp);
601 		tp->t_line = 0;
602 		return;
603 	}
604 	tp->t_pgrp = 0;
605 	ttywflush(tp);
606 	tp->t_state = 0;
607 }
608 
609 /*
610  * reinput pending characters after state switch
611  * call at spltty().
612  */
613 ttypend(tp)
614 	register struct tty *tp;
615 {
616 	struct clist tq;
617 	register c;
618 
619 	tp->t_flags &= ~PENDIN;
620 	tp->t_state |= TS_TYPEN;
621 	tq = tp->t_rawq;
622 	tp->t_rawq.c_cc = 0;
623 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
624 	while ((c = getc(&tq)) >= 0)
625 		ttyinput(c, tp);
626 	tp->t_state &= ~TS_TYPEN;
627 }
628 
629 /*
630  * Place a character on raw TTY input queue,
631  * putting in delimiters and waking up top
632  * half as needed.  Also echo if required.
633  * The arguments are the character and the
634  * appropriate tty structure.
635  */
636 ttyinput(c, tp)
637 	register c;
638 	register struct tty *tp;
639 {
640 	register int t_flags = tp->t_flags;
641 	int i;
642 
643 	/*
644 	 * If input is pending take it first.
645 	 */
646 	if (t_flags&PENDIN)
647 		ttypend(tp);
648 	tk_nin++;
649 	c &= 0377;
650 
651 	/*
652 	 * In tandem mode, check high water mark.
653 	 */
654 	if (t_flags&TANDEM)
655 		ttyblock(tp);
656 
657 	if (t_flags&RAW) {
658 		/*
659 		 * Raw mode, just put character
660 		 * in input q w/o interpretation.
661 		 */
662 		if (tp->t_rawq.c_cc > TTYHOG)
663 			ttyflush(tp, FREAD|FWRITE);
664 		else {
665 			if (putc(c, &tp->t_rawq) >= 0)
666 				ttwakeup(tp);
667 			ttyecho(c, tp);
668 		}
669 		goto endcase;
670 	}
671 
672 	/*
673 	 * Ignore any high bit added during
674 	 * previous ttyinput processing.
675 	 */
676 	if ((tp->t_state&TS_TYPEN) == 0 && (t_flags&PASS8) == 0)
677 		c &= 0177;
678 	/*
679 	 * Check for literal nexting very first
680 	 */
681 	if (tp->t_state&TS_LNCH) {
682 		c |= 0200;
683 		tp->t_state &= ~TS_LNCH;
684 	}
685 
686 	/*
687 	 * Scan for special characters.  This code
688 	 * is really just a big case statement with
689 	 * non-constant cases.  The bottom of the
690 	 * case statement is labeled ``endcase'', so goto
691 	 * it after a case match, or similar.
692 	 */
693 	if (tp->t_line == NTTYDISC) {
694 		if (c == tp->t_lnextc) {
695 			if (t_flags&ECHO)
696 				ttyout("^\b", tp);
697 			tp->t_state |= TS_LNCH;
698 			goto endcase;
699 		}
700 		if (c == tp->t_flushc) {
701 			if (t_flags&FLUSHO)
702 				tp->t_flags &= ~FLUSHO;
703 			else {
704 				ttyflush(tp, FWRITE);
705 				ttyecho(c, tp);
706 				if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
707 					ttyretype(tp);
708 				tp->t_flags |= FLUSHO;
709 			}
710 			goto startoutput;
711 		}
712 		if (c == tp->t_suspc) {
713 			if ((t_flags&NOFLSH) == 0)
714 				ttyflush(tp, FREAD);
715 			ttyecho(c, tp);
716 			gsignal(tp->t_pgrp, SIGTSTP);
717 			goto endcase;
718 		}
719 	}
720 
721 	/*
722 	 * Handle start/stop characters.
723 	 */
724 	if (c == tp->t_stopc) {
725 		if ((tp->t_state&TS_TTSTOP) == 0) {
726 			tp->t_state |= TS_TTSTOP;
727 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
728 			return;
729 		}
730 		if (c != tp->t_startc)
731 			return;
732 		goto endcase;
733 	}
734 	if (c == tp->t_startc)
735 		goto restartoutput;
736 
737 	/*
738 	 * Look for interrupt/quit chars.
739 	 */
740 	if (c == tp->t_intrc || c == tp->t_quitc) {
741 		if ((t_flags&NOFLSH) == 0)
742 			ttyflush(tp, FREAD|FWRITE);
743 		ttyecho(c, tp);
744 		gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT);
745 		goto endcase;
746 	}
747 
748 	if (tp->t_flags & LCASE && c <= 0177) {
749 		if (tp->t_state&TS_BKSL) {
750 			ttyrub(unputc(&tp->t_rawq), tp);
751 			if (maptab[c])
752 				c = maptab[c];
753 			c |= 0200;
754 			tp->t_state &= ~(TS_BKSL|TS_QUOT);
755 		} else if (c >= 'A' && c <= 'Z')
756 			c += 'a' - 'A';
757 		else if (c == '\\')
758 			tp->t_state |= TS_BKSL;
759 	}
760 
761 	/*
762 	 * Cbreak mode, don't process line editing
763 	 * characters; check high water mark for wakeup.
764 	 */
765 	if (t_flags&CBREAK) {
766 		if (tp->t_rawq.c_cc > TTYHOG) {
767 			if (tp->t_outq.c_cc < TTHIWAT(tp) &&
768 			    tp->t_line == NTTYDISC)
769 				(void) ttyoutput(CTRL(g), tp);
770 		} else if (putc(c, &tp->t_rawq) >= 0) {
771 			ttwakeup(tp);
772 			ttyecho(c, tp);
773 		}
774 		goto endcase;
775 	}
776 
777 	/*
778 	 * From here on down cooked mode character
779 	 * processing takes place.
780 	 */
781 	if ((tp->t_state&TS_QUOT) &&
782 	    (c == tp->t_erase || c == tp->t_kill)) {
783 		ttyrub(unputc(&tp->t_rawq), tp);
784 		c |= 0200;
785 	}
786 	if (c == tp->t_erase) {
787 		if (tp->t_rawq.c_cc)
788 			ttyrub(unputc(&tp->t_rawq), tp);
789 		goto endcase;
790 	}
791 	if (c == tp->t_kill) {
792 		if (t_flags&CRTKIL &&
793 		    tp->t_rawq.c_cc == tp->t_rocount) {
794 			while (tp->t_rawq.c_cc)
795 				ttyrub(unputc(&tp->t_rawq), tp);
796 		} else {
797 			ttyecho(c, tp);
798 			ttyecho('\n', tp);
799 			while (getc(&tp->t_rawq) > 0)
800 				;
801 			tp->t_rocount = 0;
802 		}
803 		tp->t_state &= ~TS_LOCAL;
804 		goto endcase;
805 	}
806 
807 	/*
808 	 * New line discipline,
809 	 * check word erase/reprint line.
810 	 */
811 	if (tp->t_line == NTTYDISC) {
812 		if (c == tp->t_werasc) {
813 			if (tp->t_rawq.c_cc == 0)
814 				goto endcase;
815 			do {
816 				c = unputc(&tp->t_rawq);
817 				if (c != ' ' && c != '\t')
818 					goto erasenb;
819 				ttyrub(c, tp);
820 			} while (tp->t_rawq.c_cc);
821 			goto endcase;
822 	erasenb:
823 			do {
824 				ttyrub(c, tp);
825 				if (tp->t_rawq.c_cc == 0)
826 					goto endcase;
827 				c = unputc(&tp->t_rawq);
828 			} while (c != ' ' && c != '\t');
829 			(void) putc(c, &tp->t_rawq);
830 			goto endcase;
831 		}
832 		if (c == tp->t_rprntc) {
833 			ttyretype(tp);
834 			goto endcase;
835 		}
836 	}
837 
838 	/*
839 	 * Check for input buffer overflow
840 	 */
841 	if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
842 		if (tp->t_line == NTTYDISC)
843 			(void) ttyoutput(CTRL(g), tp);
844 		goto endcase;
845 	}
846 
847 	/*
848 	 * Put data char in q for user and
849 	 * wakeup on seeing a line delimiter.
850 	 */
851 	if (putc(c, &tp->t_rawq) >= 0) {
852 		if (ttbreakc(c, tp)) {
853 			tp->t_rocount = 0;
854 			catq(&tp->t_rawq, &tp->t_canq);
855 			ttwakeup(tp);
856 		} else if (tp->t_rocount++ == 0)
857 			tp->t_rocol = tp->t_col;
858 		tp->t_state &= ~TS_QUOT;
859 		if (c == '\\')
860 			tp->t_state |= TS_QUOT;
861 		if (tp->t_state&TS_ERASE) {
862 			tp->t_state &= ~TS_ERASE;
863 			(void) ttyoutput('/', tp);
864 		}
865 		i = tp->t_col;
866 		ttyecho(c, tp);
867 		if (c == tp->t_eofc && t_flags&ECHO) {
868 			i = MIN(2, tp->t_col - i);
869 			while (i > 0) {
870 				(void) ttyoutput('\b', tp);
871 				i--;
872 			}
873 		}
874 	}
875 endcase:
876 	/*
877 	 * If DEC-style start/stop is enabled don't restart
878 	 * output until seeing the start character.
879 	 */
880 	if (t_flags&DECCTQ && tp->t_state&TS_TTSTOP &&
881 	    tp->t_startc != tp->t_stopc)
882 		return;
883 restartoutput:
884 	tp->t_state &= ~TS_TTSTOP;
885 	tp->t_flags &= ~FLUSHO;
886 startoutput:
887 	ttstart(tp);
888 }
889 
890 /*
891  * Put character on TTY output queue, adding delays,
892  * expanding tabs, and handling the CR/NL bit.
893  * This is called both from the top half for output,
894  * and from interrupt level for echoing.
895  * The arguments are the character and the tty structure.
896  * Returns < 0 if putc succeeds, otherwise returns char to resend
897  * Must be recursive.
898  */
899 ttyoutput(c, tp)
900 	register c;
901 	register struct tty *tp;
902 {
903 	register char *colp;
904 	register ctype;
905 
906 	if (tp->t_flags & (RAW|LITOUT)) {
907 		if (tp->t_flags&FLUSHO)
908 			return (-1);
909 		if (putc(c, &tp->t_outq))
910 			return (c);
911 		tk_nout++;
912 		return (-1);
913 	}
914 
915 	/*
916 	 * Ignore EOT in normal mode to avoid
917 	 * hanging up certain terminals.
918 	 */
919 	c &= 0177;
920 	if (c == CEOT && (tp->t_flags&CBREAK) == 0)
921 		return (-1);
922 	/*
923 	 * Turn tabs to spaces as required
924 	 */
925 	if (c == '\t' && (tp->t_flags&TBDELAY) == XTABS) {
926 		register int s;
927 
928 		c = 8 - (tp->t_col&7);
929 		if ((tp->t_flags&FLUSHO) == 0) {
930 			s = spltty();		/* don't interrupt tabs */
931 			c -= b_to_q("        ", c, &tp->t_outq);
932 			tk_nout += c;
933 			splx(s);
934 		}
935 		tp->t_col += c;
936 		return (c ? -1 : '\t');
937 	}
938 	tk_nout++;
939 	/*
940 	 * for upper-case-only terminals,
941 	 * generate escapes.
942 	 */
943 	if (tp->t_flags&LCASE) {
944 		colp = "({)}!|^~'`";
945 		while (*colp++)
946 			if (c == *colp++) {
947 				if (ttyoutput('\\', tp) >= 0)
948 					return (c);
949 				c = colp[-2];
950 				break;
951 			}
952 		if ('A' <= c && c <= 'Z') {
953 			if (ttyoutput('\\', tp) >= 0)
954 				return (c);
955 		} else if ('a' <= c && c <= 'z')
956 			c += 'A' - 'a';
957 	}
958 
959 	/*
960 	 * turn <nl> to <cr><lf> if desired.
961 	 */
962 	if (c == '\n' && tp->t_flags&CRMOD)
963 		if (ttyoutput('\r', tp) >= 0)
964 			return (c);
965 	if (c == '~' && tp->t_flags&TILDE)
966 		c = '`';
967 	if ((tp->t_flags&FLUSHO) == 0 && putc(c, &tp->t_outq))
968 		return (c);
969 	/*
970 	 * Calculate delays.
971 	 * The numbers here represent clock ticks
972 	 * and are not necessarily optimal for all terminals.
973 	 * The delays are indicated by characters above 0200.
974 	 * In raw mode there are no delays and the
975 	 * transmission path is 8 bits wide.
976 	 *
977 	 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS
978 	 */
979 	colp = &tp->t_col;
980 	ctype = partab[c];
981 	c = 0;
982 	switch (ctype&077) {
983 
984 	case ORDINARY:
985 		(*colp)++;
986 
987 	case CONTROL:
988 		break;
989 
990 	case BACKSPACE:
991 		if (*colp)
992 			(*colp)--;
993 		break;
994 
995 	/*
996 	 * This macro is close enough to the correct thing;
997 	 * it should be replaced by real user settable delays
998 	 * in any event...
999 	 */
1000 #define	mstohz(ms)	(((ms) * hz) >> 10)
1001 	case NEWLINE:
1002 		ctype = (tp->t_flags >> 8) & 03;
1003 		if (ctype == 1) { /* tty 37 */
1004 			if (*colp > 0)
1005 				c = max((((unsigned)*colp) >> 4) + 3,
1006 				    (unsigned)6);
1007 		} else if (ctype == 2) /* vt05 */
1008 			c = mstohz(100);
1009 		*colp = 0;
1010 		break;
1011 
1012 	case TAB:
1013 		ctype = (tp->t_flags >> 10) & 03;
1014 		if (ctype == 1) { /* tty 37 */
1015 			c = 1 - (*colp | ~07);
1016 			if (c < 5)
1017 				c = 0;
1018 		}
1019 		*colp |= 07;
1020 		(*colp)++;
1021 		break;
1022 
1023 	case VTAB:
1024 		if (tp->t_flags&VTDELAY) /* tty 37 */
1025 			c = 0177;
1026 		break;
1027 
1028 	case RETURN:
1029 		ctype = (tp->t_flags >> 12) & 03;
1030 		if (ctype == 1) /* tn 300 */
1031 			c = mstohz(83);
1032 		else if (ctype == 2) /* ti 700 */
1033 			c = mstohz(166);
1034 		else if (ctype == 3) { /* concept 100 */
1035 			int i;
1036 
1037 			if ((i = *colp) >= 0)
1038 				for (; i < 9; i++)
1039 					(void) putc(0177, &tp->t_outq);
1040 		}
1041 		*colp = 0;
1042 	}
1043 	if (c && (tp->t_flags&FLUSHO) == 0)
1044 		(void) putc(c|0200, &tp->t_outq);
1045 	return (-1);
1046 }
1047 #undef mstohz
1048 
1049 /*
1050  * Called from device's read routine after it has
1051  * calculated the tty-structure given as argument.
1052  */
1053 ttread(tp, uio)
1054 	register struct tty *tp;
1055 	struct uio *uio;
1056 {
1057 	register struct clist *qp;
1058 	register c, t_flags;
1059 	int s, first, error = 0;
1060 
1061 loop:
1062 	/*
1063 	 * Take any pending input first.
1064 	 */
1065 	s = spltty();
1066 	if (tp->t_flags&PENDIN)
1067 		ttypend(tp);
1068 	splx(s);
1069 
1070 	if ((tp->t_state&TS_CARR_ON)==0)
1071 		return (EIO);
1072 
1073 	/*
1074 	 * Hang process if it's in the background.
1075 	 */
1076 	if (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) {
1077 		if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) ||
1078 		   (u.u_procp->p_sigmask & sigmask(SIGTTIN)) ||
1079 		    u.u_procp->p_flag&SVFORK)
1080 			return (EIO);
1081 		gsignal(u.u_procp->p_pgrp, SIGTTIN);
1082 		sleep((caddr_t)&lbolt, TTIPRI);
1083 		goto loop;
1084 	}
1085 	t_flags = tp->t_flags;
1086 
1087 	/*
1088 	 * In raw mode take characters directly from the
1089 	 * raw queue w/o processing.  Interlock against
1090 	 * device interrupts when interrogating rawq.
1091 	 */
1092 	if (t_flags&RAW) {
1093 		s = spltty();
1094 		if (tp->t_rawq.c_cc <= 0) {
1095 			if ((tp->t_state&TS_CARR_ON) == 0 ||
1096 			    (tp->t_state&TS_NBIO)) {
1097 				splx(s);
1098 				return (EWOULDBLOCK);
1099 			}
1100 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
1101 			splx(s);
1102 			goto loop;
1103 		}
1104 		splx(s);
1105  		while (!error && tp->t_rawq.c_cc && uio->uio_resid)
1106  			error = ureadc(getc(&tp->t_rawq), uio);
1107 		goto checktandem;
1108 	}
1109 
1110 	/*
1111 	 * In cbreak mode use the rawq, otherwise
1112 	 * take characters from the canonicalized q.
1113 	 */
1114 	qp = t_flags&CBREAK ? &tp->t_rawq : &tp->t_canq;
1115 
1116 	/*
1117 	 * No input, sleep on rawq awaiting hardware
1118 	 * receipt and notification.
1119 	 */
1120 	s = spltty();
1121 	if (qp->c_cc <= 0) {
1122 		if ((tp->t_state&TS_CARR_ON) == 0 ||
1123 		    (tp->t_state&TS_NBIO)) {
1124 			splx(s);
1125 			return (EWOULDBLOCK);
1126 		}
1127 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
1128 		splx(s);
1129 		goto loop;
1130 	}
1131 	splx(s);
1132 
1133 	/*
1134 	 * Input present, perform input mapping
1135 	 * and processing (we're not in raw mode).
1136 	 */
1137 	first = 1;
1138 	while ((c = getc(qp)) >= 0) {
1139 		if (t_flags&CRMOD && c == '\r')
1140 			c = '\n';
1141 		/*
1142 		 * Check for delayed suspend character.
1143 		 */
1144 		if (tp->t_line == NTTYDISC && c == tp->t_dsuspc) {
1145 			gsignal(tp->t_pgrp, SIGTSTP);
1146 			if (first) {
1147 				sleep((caddr_t)&lbolt, TTIPRI);
1148 				goto loop;
1149 			}
1150 			break;
1151 		}
1152 		/*
1153 		 * Interpret EOF only in cooked mode.
1154 		 */
1155 		if (c == tp->t_eofc && (t_flags&CBREAK) == 0)
1156 			break;
1157 		/*
1158 		 * Give user character.
1159 		 */
1160  		error = ureadc(t_flags&PASS8 ? c : c & 0177, uio);
1161 		if (error)
1162 			break;
1163  		if (uio->uio_resid == 0)
1164 			break;
1165 		/*
1166 		 * In cooked mode check for a "break character"
1167 		 * marking the end of a "line of input".
1168 		 */
1169 		if ((t_flags&CBREAK) == 0 && ttbreakc(c, tp))
1170 			break;
1171 		first = 0;
1172 	}
1173 
1174 checktandem:
1175 	/*
1176 	 * Look to unblock output now that (presumably)
1177 	 * the input queue has gone down.
1178 	 */
1179 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5)
1180 		if (putc(tp->t_startc, &tp->t_outq) == 0) {
1181 			tp->t_state &= ~TS_TBLOCK;
1182 			ttstart(tp);
1183 		}
1184 	return (error);
1185 }
1186 
1187 /*
1188  * Called from the device's write routine after it has
1189  * calculated the tty-structure given as argument.
1190  */
1191 ttwrite(tp, uio)
1192 	register struct tty *tp;
1193 	register struct uio *uio;
1194 {
1195 	register char *cp;
1196 	register int cc, ce, c;
1197 	int i, hiwat, cnt, error, s;
1198 	char obuf[OBUFSIZ];
1199 
1200 	hiwat = TTHIWAT(tp);
1201 	cnt = uio->uio_resid;
1202 	error = 0;
1203 loop:
1204 	if ((tp->t_state&TS_CARR_ON) == 0)
1205 		return (EIO);
1206 	/*
1207 	 * Hang the process if it's in the background.
1208 	 */
1209 	if (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
1210 	    (tp->t_flags&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
1211 	    !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) &&
1212 	    !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) {
1213 		gsignal(u.u_procp->p_pgrp, SIGTTOU);
1214 		sleep((caddr_t)&lbolt, TTIPRI);
1215 		goto loop;
1216 	}
1217 
1218 	/*
1219 	 * Process the user's data in at most OBUFSIZ
1220 	 * chunks.  Perform lower case simulation and
1221 	 * similar hacks.  Keep track of high water
1222 	 * mark, sleep on overflow awaiting device aid
1223 	 * in acquiring new space.
1224 	 */
1225 	while (uio->uio_resid > 0) {
1226 		/*
1227 		 * Grab a hunk of data from the user.
1228 		 */
1229 		cc = uio->uio_iov->iov_len;
1230 		if (cc == 0) {
1231 			uio->uio_iovcnt--;
1232 			uio->uio_iov++;
1233 			if (uio->uio_iovcnt <= 0)
1234 				panic("ttwrite");
1235 			continue;
1236 		}
1237 		if (cc > OBUFSIZ)
1238 			cc = OBUFSIZ;
1239 		cp = obuf;
1240 		error = uiomove(cp, cc, UIO_WRITE, uio);
1241 		if (error)
1242 			break;
1243 		if (tp->t_outq.c_cc > hiwat)
1244 			goto ovhiwat;
1245 		if (tp->t_flags&FLUSHO)
1246 			continue;
1247 		/*
1248 		 * If we're mapping lower case or kludging tildes,
1249 		 * then we've got to look at each character, so
1250 		 * just feed the stuff to ttyoutput...
1251 		 */
1252 		if (tp->t_flags & (LCASE|TILDE)) {
1253 			while (cc > 0) {
1254 				c = *cp++;
1255 				tp->t_rocount = 0;
1256 				while ((c = ttyoutput(c, tp)) >= 0) {
1257 					/* out of clists, wait a bit */
1258 					ttstart(tp);
1259 					sleep((caddr_t)&lbolt, TTOPRI);
1260 					tp->t_rocount = 0;
1261 					if (cc != 0) {
1262 						uio->uio_iov->iov_base -= cc;
1263 						uio->uio_iov->iov_len += cc;
1264 						uio->uio_resid += cc;
1265 						uio->uio_offset -= cc;
1266 					}
1267 					goto loop;
1268 				}
1269 				--cc;
1270 				if (tp->t_outq.c_cc > hiwat)
1271 					goto ovhiwat;
1272 			}
1273 			continue;
1274 		}
1275 		/*
1276 		 * If nothing fancy need be done, grab those characters we
1277 		 * can handle without any of ttyoutput's processing and
1278 		 * just transfer them to the output q.  For those chars
1279 		 * which require special processing (as indicated by the
1280 		 * bits in partab), call ttyoutput.  After processing
1281 		 * a hunk of data, look for FLUSHO so ^O's will take effect
1282 		 * immediately.
1283 		 */
1284 		while (cc > 0) {
1285 			if (tp->t_flags & (RAW|LITOUT))
1286 				ce = cc;
1287 			else {
1288 				ce = cc - scanc((unsigned)cc, (caddr_t)cp,
1289 				   (caddr_t)partab, 077);
1290 				/*
1291 				 * If ce is zero, then we're processing
1292 				 * a special character through ttyoutput.
1293 				 */
1294 				if (ce == 0) {
1295 					tp->t_rocount = 0;
1296 					if (ttyoutput(*cp, tp) >= 0) {
1297 					    /* no c-lists, wait a bit */
1298 					    ttstart(tp);
1299 					    sleep((caddr_t)&lbolt, TTOPRI);
1300 					    if (cc != 0) {
1301 					        uio->uio_iov->iov_base -= cc;
1302 					        uio->uio_iov->iov_len += cc;
1303 					        uio->uio_resid += cc;
1304 						uio->uio_offset -= cc;
1305 					    }
1306 					    goto loop;
1307 					}
1308 					cp++, cc--;
1309 					if (tp->t_flags&FLUSHO ||
1310 					    tp->t_outq.c_cc > hiwat)
1311 						goto ovhiwat;
1312 					continue;
1313 				}
1314 			}
1315 			/*
1316 			 * A bunch of normal characters have been found,
1317 			 * transfer them en masse to the output queue and
1318 			 * continue processing at the top of the loop.
1319 			 * If there are any further characters in this
1320 			 * <= OBUFSIZ chunk, the first should be a character
1321 			 * requiring special handling by ttyoutput.
1322 			 */
1323 			tp->t_rocount = 0;
1324 			i = b_to_q(cp, ce, &tp->t_outq);
1325 			ce -= i;
1326 			tp->t_col += ce;
1327 			cp += ce, cc -= ce, tk_nout += ce;
1328 			if (i > 0) {
1329 				/* out of c-lists, wait a bit */
1330 				ttstart(tp);
1331 				sleep((caddr_t)&lbolt, TTOPRI);
1332 				uio->uio_iov->iov_base -= cc;
1333 				uio->uio_iov->iov_len += cc;
1334 				uio->uio_resid += cc;
1335 				uio->uio_offset -= cc;
1336 				goto loop;
1337 			}
1338 			if (tp->t_flags&FLUSHO || tp->t_outq.c_cc > hiwat)
1339 				goto ovhiwat;
1340 		}
1341 	}
1342 	ttstart(tp);
1343 	return (error);
1344 
1345 ovhiwat:
1346 	s = spltty();
1347 	if (cc != 0) {
1348 		uio->uio_iov->iov_base -= cc;
1349 		uio->uio_iov->iov_len += cc;
1350 		uio->uio_resid += cc;
1351 		uio->uio_offset -= cc;
1352 	}
1353 	/*
1354 	 * This can only occur if FLUSHO
1355 	 * is also set in t_flags.
1356 	 */
1357 	if (tp->t_outq.c_cc <= hiwat) {
1358 		splx(s);
1359 		goto loop;
1360 	}
1361 	ttstart(tp);
1362 	if (tp->t_state&TS_NBIO) {
1363 		splx(s);
1364 		if (uio->uio_resid == cnt)
1365 			return (EWOULDBLOCK);
1366 		return (0);
1367 	}
1368 	tp->t_state |= TS_ASLEEP;
1369 	sleep((caddr_t)&tp->t_outq, TTOPRI);
1370 	splx(s);
1371 	goto loop;
1372 }
1373 
1374 /*
1375  * Rubout one character from the rawq of tp
1376  * as cleanly as possible.
1377  */
1378 ttyrub(c, tp)
1379 	register c;
1380 	register struct tty *tp;
1381 {
1382 	register char *cp;
1383 	register int savecol;
1384 	int s;
1385 	char *nextc();
1386 
1387 	if ((tp->t_flags&ECHO) == 0)
1388 		return;
1389 	tp->t_flags &= ~FLUSHO;
1390 	c &= 0377;
1391 	if (tp->t_flags&CRTBS) {
1392 		if (tp->t_rocount == 0) {
1393 			/*
1394 			 * Screwed by ttwrite; retype
1395 			 */
1396 			ttyretype(tp);
1397 			return;
1398 		}
1399 		if (c == ('\t'|0200) || c == ('\n'|0200))
1400 			ttyrubo(tp, 2);
1401 		else switch (partab[c&=0177]&0177) {
1402 
1403 		case ORDINARY:
1404 			if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z')
1405 				ttyrubo(tp, 2);
1406 			else
1407 				ttyrubo(tp, 1);
1408 			break;
1409 
1410 		case VTAB:
1411 		case BACKSPACE:
1412 		case CONTROL:
1413 		case RETURN:
1414 			if (tp->t_flags&CTLECH)
1415 				ttyrubo(tp, 2);
1416 			break;
1417 
1418 		case TAB:
1419 			if (tp->t_rocount < tp->t_rawq.c_cc) {
1420 				ttyretype(tp);
1421 				return;
1422 			}
1423 			s = spltty();
1424 			savecol = tp->t_col;
1425 			tp->t_state |= TS_CNTTB;
1426 			tp->t_flags |= FLUSHO;
1427 			tp->t_col = tp->t_rocol;
1428 			cp = tp->t_rawq.c_cf;
1429 			for (; cp; cp = nextc(&tp->t_rawq, cp))
1430 				ttyecho(*cp, tp);
1431 			tp->t_flags &= ~FLUSHO;
1432 			tp->t_state &= ~TS_CNTTB;
1433 			splx(s);
1434 			/*
1435 			 * savecol will now be length of the tab
1436 			 */
1437 			savecol -= tp->t_col;
1438 			tp->t_col += savecol;
1439 			if (savecol > 8)
1440 				savecol = 8;		/* overflow screw */
1441 			while (--savecol >= 0)
1442 				(void) ttyoutput('\b', tp);
1443 			break;
1444 
1445 		default:
1446 			panic("ttyrub");
1447 		}
1448 	} else if (tp->t_flags&PRTERA) {
1449 		if ((tp->t_state&TS_ERASE) == 0) {
1450 			(void) ttyoutput('\\', tp);
1451 			tp->t_state |= TS_ERASE;
1452 		}
1453 		ttyecho(c, tp);
1454 	} else
1455 		ttyecho(tp->t_erase, tp);
1456 	tp->t_rocount--;
1457 }
1458 
1459 /*
1460  * Crt back over cnt chars perhaps
1461  * erasing them.
1462  */
1463 ttyrubo(tp, cnt)
1464 	register struct tty *tp;
1465 	int cnt;
1466 {
1467 	register char *rubostring = tp->t_flags&CRTERA ? "\b \b" : "\b";
1468 
1469 	while (--cnt >= 0)
1470 		ttyout(rubostring, tp);
1471 }
1472 
1473 /*
1474  * Reprint the rawq line.
1475  * We assume c_cc has already been checked.
1476  */
1477 ttyretype(tp)
1478 	register struct tty *tp;
1479 {
1480 	register char *cp;
1481 	char *nextc();
1482 	int s;
1483 
1484 	if (tp->t_rprntc != 0377)
1485 		ttyecho(tp->t_rprntc, tp);
1486 	(void) ttyoutput('\n', tp);
1487 	s = spltty();
1488 	for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp))
1489 		ttyecho(*cp, tp);
1490 	for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1491 		ttyecho(*cp, tp);
1492 	tp->t_state &= ~TS_ERASE;
1493 	splx(s);
1494 	tp->t_rocount = tp->t_rawq.c_cc;
1495 	tp->t_rocol = 0;
1496 }
1497 
1498 /*
1499  * Echo a typed character to the terminal
1500  */
1501 ttyecho(c, tp)
1502 	register c;
1503 	register struct tty *tp;
1504 {
1505 
1506 	if ((tp->t_state&TS_CNTTB) == 0)
1507 		tp->t_flags &= ~FLUSHO;
1508 	if ((tp->t_flags&ECHO) == 0)
1509 		return;
1510 	c &= 0377;
1511 	if (tp->t_flags&RAW) {
1512 		(void) ttyoutput(c, tp);
1513 		return;
1514 	}
1515 	if (c == '\r' && tp->t_flags&CRMOD)
1516 		c = '\n';
1517 	if (tp->t_flags&CTLECH) {
1518 		if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) {
1519 			(void) ttyoutput('^', tp);
1520 			c &= 0177;
1521 			if (c == 0177)
1522 				c = '?';
1523 			else if (tp->t_flags&LCASE)
1524 				c += 'a' - 1;
1525 			else
1526 				c += 'A' - 1;
1527 		}
1528 	}
1529 	(void) ttyoutput(c&0177, tp);
1530 }
1531 
1532 /*
1533  * Is c a break char for tp?
1534  */
1535 ttbreakc(c, tp)
1536 	register c;
1537 	register struct tty *tp;
1538 {
1539 	return (c == '\n' || c == tp->t_eofc || c == tp->t_brkc ||
1540 		c == '\r' && (tp->t_flags&CRMOD));
1541 }
1542 
1543 /*
1544  * send string cp to tp
1545  */
1546 ttyout(cp, tp)
1547 	register char *cp;
1548 	register struct tty *tp;
1549 {
1550 	register char c;
1551 
1552 	while (c = *cp++)
1553 		(void) ttyoutput(c, tp);
1554 }
1555 
1556 ttwakeup(tp)
1557 	struct tty *tp;
1558 {
1559 
1560 	if (tp->t_rsel) {
1561 		selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1562 		tp->t_state &= ~TS_RCOLL;
1563 		tp->t_rsel = 0;
1564 	}
1565 	if (tp->t_state & TS_ASYNC)
1566 		gsignal(tp->t_pgrp, SIGIO);
1567 	wakeup((caddr_t)&tp->t_rawq);
1568 }
1569