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