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