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