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