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