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