xref: /csrg-svn/sys/kern/tty.c (revision 9624)
1 /*	tty.c	4.36	82/12/13	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/dir.h"
6 #include "../h/user.h"
7 #include "../h/ioctl.h"
8 #include "../h/tty.h"
9 #include "../h/proc.h"
10 #include "../h/inode.h"
11 #include "../h/file.h"
12 #include "../h/reg.h"
13 #include "../h/conf.h"
14 #include "../h/buf.h"
15 #include "../h/dk.h"
16 #include "../h/uio.h"
17 #include "../h/kernel.h"
18 
19 /*
20  * Table giving parity for characters and indicating
21  * character classes to tty driver.  In particular,
22  * if the low 6 bits are 0, then the character needs
23  * no special processing on output.
24  */
25 
26 char partab[] = {
27 	0001,0201,0201,0001,0201,0001,0001,0201,
28 	0202,0004,0003,0201,0005,0206,0201,0001,
29 	0201,0001,0001,0201,0001,0201,0201,0001,
30 	0001,0201,0201,0001,0201,0001,0001,0201,
31 	0200,0000,0000,0200,0000,0200,0200,0000,
32 	0000,0200,0200,0000,0200,0000,0000,0200,
33 	0000,0200,0200,0000,0200,0000,0000,0200,
34 	0200,0000,0000,0200,0000,0200,0200,0000,
35 	0200,0000,0000,0200,0000,0200,0200,0000,
36 	0000,0200,0200,0000,0200,0000,0000,0200,
37 	0000,0200,0200,0000,0200,0000,0000,0200,
38 	0200,0000,0000,0200,0000,0200,0200,0000,
39 	0000,0200,0200,0000,0200,0000,0000,0200,
40 	0200,0000,0000,0200,0000,0200,0200,0000,
41 	0200,0000,0000,0200,0000,0200,0200,0000,
42 	0000,0200,0200,0000,0200,0000,0000,0201,
43 
44 	/*
45 	 * 7 bit ascii ends with the last character above,
46 	 * but we contine through all 256 codes for the sake
47 	 * of the tty output routines which use special vax
48 	 * instructions which need a 256 character trt table.
49 	 */
50 
51 	0007,0007,0007,0007,0007,0007,0007,0007,
52 	0007,0007,0007,0007,0007,0007,0007,0007,
53 	0007,0007,0007,0007,0007,0007,0007,0007,
54 	0007,0007,0007,0007,0007,0007,0007,0007,
55 	0007,0007,0007,0007,0007,0007,0007,0007,
56 	0007,0007,0007,0007,0007,0007,0007,0007,
57 	0007,0007,0007,0007,0007,0007,0007,0007,
58 	0007,0007,0007,0007,0007,0007,0007,0007,
59 	0007,0007,0007,0007,0007,0007,0007,0007,
60 	0007,0007,0007,0007,0007,0007,0007,0007,
61 	0007,0007,0007,0007,0007,0007,0007,0007,
62 	0007,0007,0007,0007,0007,0007,0007,0007,
63 	0007,0007,0007,0007,0007,0007,0007,0007,
64 	0007,0007,0007,0007,0007,0007,0007,0007,
65 	0007,0007,0007,0007,0007,0007,0007,0007,
66 	0007,0007,0007,0007,0007,0007,0007,0007
67 };
68 
69 /*
70  * Input mapping table-- if an entry is non-zero, when the
71  * corresponding character is typed preceded by "\" the escape
72  * sequence is replaced by the table value.  Mostly used for
73  * upper-case only terminals.
74  */
75 char	maptab[] ={
76 	000,000,000,000,000,000,000,000,
77 	000,000,000,000,000,000,000,000,
78 	000,000,000,000,000,000,000,000,
79 	000,000,000,000,000,000,000,000,
80 	000,'|',000,000,000,000,000,'`',
81 	'{','}',000,000,000,000,000,000,
82 	000,000,000,000,000,000,000,000,
83 	000,000,000,000,000,000,000,000,
84 	000,000,000,000,000,000,000,000,
85 	000,000,000,000,000,000,000,000,
86 	000,000,000,000,000,000,000,000,
87 	000,000,000,000,000,000,'~',000,
88 	000,'A','B','C','D','E','F','G',
89 	'H','I','J','K','L','M','N','O',
90 	'P','Q','R','S','T','U','V','W',
91 	'X','Y','Z',000,000,000,000,000,
92 };
93 
94 short	tthiwat[16] =
95    { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 };
96 short	ttlowat[16] =
97    {  30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
98 
99 struct	ttychars ttydefaults = {
100 	CERASE,	CKILL,	CINTR,	CQUIT,	CSTART,	CSTOP,	CEOF,
101 	CBRK,	CSUSP,	CDSUSP, CRPRNT, CFLUSH, CWERASE,CLNEXT
102 };
103 
104 ttychars(tp)
105 	struct tty *tp;
106 {
107 
108 	tp->t_chars = ttydefaults;
109 }
110 
111 /*
112  * Wait for output to drain, then flush input waiting.
113  */
114 wflushtty(tp)
115 	register struct tty *tp;
116 {
117 
118 	(void) spl5();
119 	while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON
120 	    && tp->t_oproc) {		/* kludge for pty */
121 		(*tp->t_oproc)(tp);
122 		tp->t_state |= TS_ASLEEP;
123 		sleep((caddr_t)&tp->t_outq, TTOPRI);
124 	}
125 	flushtty(tp, FREAD);
126 	(void) spl0();
127 }
128 
129 /*
130  * Flush all TTY queues
131  */
132 flushtty(tp, rw)
133 	register struct tty *tp;
134 {
135 	register s;
136 
137 	s = spl6();
138 	if (rw & FREAD) {
139 		while (getc(&tp->t_canq) >= 0)
140 			;
141 		wakeup((caddr_t)&tp->t_rawq);
142 	}
143 	if (rw & FWRITE) {
144 		wakeup((caddr_t)&tp->t_outq);
145 		tp->t_state &= ~TS_TTSTOP;
146 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
147 		while (getc(&tp->t_outq) >= 0)
148 			;
149 	}
150 	if (rw & FREAD) {
151 		while (getc(&tp->t_rawq) >= 0)
152 			;
153 		tp->t_delct = 0;
154 		tp->t_rocount = 0;
155 		tp->t_rocol = 0;
156 		tp->t_state &= ~TS_LOCAL;
157 	}
158 	splx(s);
159 }
160 
161 /*
162  * Send stop character on input overflow.
163  */
164 ttyblock(tp)
165 	register struct tty *tp;
166 {
167 	register x;
168 
169 	x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
170 	if (tp->t_rawq.c_cc > TTYHOG) {
171 		flushtty(tp, FREAD|FWRITE);
172 		tp->t_state &= ~TS_TBLOCK;
173 	}
174 	if (x >= TTYHOG/2 && putc(tp->t_stopc, &tp->t_outq) == 0) {
175 		tp->t_state |= TS_TBLOCK;
176 		tp->t_char++;
177 		ttstart(tp);
178 	}
179 }
180 
181 /*
182  * Restart typewriter output following a delay
183  * timeout.
184  * The name of the routine is passed to the timeout
185  * subroutine and it is called during a clock interrupt.
186  */
187 ttrstrt(tp)
188 	register struct tty *tp;
189 {
190 
191 	if (tp == 0)
192 		panic("ttrstrt");
193 	tp->t_state &= ~TS_TIMEOUT;
194 	ttstart(tp);
195 }
196 
197 /*
198  * Start output on the typewriter. It is used from the top half
199  * after some characters have been put on the output queue,
200  * from the interrupt routine to transmit the next
201  * character, and after a timeout has finished.
202  */
203 ttstart(tp)
204 	register struct tty *tp;
205 {
206 	register s;
207 
208 	s = spl5();
209 	if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 &&
210 	    tp->t_oproc)		/* kludge for pty */
211 		(*tp->t_oproc)(tp);
212 	splx(s);
213 }
214 
215 /*
216  * Common code for tty ioctls.
217  */
218 /*ARGSUSED*/
219 ttioctl(tp, com, data, flag)
220 	register struct tty *tp;
221 	caddr_t data;
222 {
223 	int dev = tp->t_dev;
224 	extern int nldisp;
225 	int s;
226 
227 	/*
228 	 * If the ioctl involves modification,
229 	 * insist on being able to write the device,
230 	 * and hang if in the background.
231 	 */
232 	switch (com) {
233 
234 	case TIOCSETD:
235 	case TIOCSETP:
236 	case TIOCSETN:
237 	case TIOCFLUSH:
238 	case TIOCSETC:
239 	case TIOCSLTC:
240 	case TIOCSPGRP:
241 	case TIOCLBIS:
242 	case TIOCLBIC:
243 	case TIOCLSET:
244 	case TIOCBIS:
245 	case TIOCBIC:
246 	case TIOCSET:
247 	case TIOCSTI:
248 		while (tp->t_line == NTTYDISC &&
249 		   u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
250 		   (u.u_procp->p_flag&SVFORK) == 0 &&
251 		   u.u_signal[SIGTTOU] != SIG_IGN &&
252 		   u.u_signal[SIGTTOU] != SIG_HOLD) {
253 			gsignal(u.u_procp->p_pgrp, SIGTTOU);
254 			sleep((caddr_t)&lbolt, TTOPRI);
255 		}
256 		break;
257 	}
258 
259 	/*
260 	 * Process the ioctl.
261 	 */
262 	switch (com) {
263 
264 	/* get discipline number */
265 	case TIOCGETD:
266 		*(int *)data = tp->t_line;
267 		break;
268 
269 	/* set line discipline */
270 	case TIOCSETD: {
271 		register int t = *(int *)data;
272 		int error = 0;
273 
274 		if (t >= nldisp) {
275 			u.u_error = ENXIO;
276 			break;
277 		}
278 		s = spl5();
279 		if (tp->t_line)
280 			(*linesw[tp->t_line].l_close)(tp);
281 		if (t)
282 			error = (*linesw[t].l_open)(dev, tp);
283 		splx(s);
284 		if (error)
285 			return (error);
286 		tp->t_line = t;
287 		break;
288 	}
289 
290 	/* prevent more opens on channel */
291 	case TIOCEXCL:
292 		tp->t_state |= TS_XCLUDE;
293 		break;
294 
295 	case TIOCNXCL:
296 		tp->t_state &= ~TS_XCLUDE;
297 		break;
298 
299 	case TIOCSET:
300 	case TIOCBIS: {
301 		u_long newflags = *(u_long *)data;
302 
303 		s = spl5();
304 		if (tp->t_flags&RAW || newflags&RAW)
305 			wflushtty(tp);
306 		else if ((tp->t_flags&CBREAK) != (newflags&CBREAK))
307 			if (newflags&CBREAK) {
308 				struct clist tq;
309 
310 				catq(&tp->t_rawq, &tp->t_canq);
311 				tq = tp->t_rawq;
312 				tp->t_rawq = tp->t_canq;
313 				tp->t_canq = tq;
314 			} else {
315 				tp->t_flags |= PENDIN;
316 				ttwakeup(tp);
317 			}
318 		if (com == TIOCSET)
319 			tp->t_flags = newflags;
320 		else
321 			tp->t_flags |= newflags;
322 		if (tp->t_flags&RAW) {
323 			tp->t_state &= ~TS_TTSTOP;
324 			ttstart(tp);
325 		}
326 		splx(s);
327 		break;
328 	}
329 
330 	case TIOCBIC: {
331 		u_long newflags = *(long *)data;
332 
333 		if (tp->t_flags&RAW)
334 			wflushtty(tp);
335 		else if ((tp->t_flags&CBREAK) != (CBREAK&~newflags))
336 			if (newflags&CBREAK) {
337 				tp->t_flags |= PENDIN;
338 				ttwakeup(tp);
339 			} else {
340 				struct clist tq;
341 
342 				catq(&tp->t_rawq, &tp->t_canq);
343 				tq = tp->t_rawq;
344 				tp->t_rawq = tp->t_canq;
345 				tp->t_canq = tq;
346 			}
347 		if (tp->t_flags&RAW) {
348 			tp->t_state &= ~TS_TTSTOP;
349 			ttstart(tp);
350 		}
351 		splx(s);
352 		break;
353 	}
354 
355 	case TIOCGET:
356 		*(long *)data = tp->t_flags;
357 		break;
358 
359 	case TIOCCGET:
360 		bcopy((caddr_t)&tp->t_chars, data, sizeof (struct ttychars));
361 		break;
362 
363 	case TIOCCSET:
364 		bcopy(data, (caddr_t)&tp->t_chars, sizeof (struct ttychars));
365 		break;
366 
367 	/* hang up line on last close */
368 	case TIOCHPCL:
369 		tp->t_state |= TS_HUPCLS;
370 		break;
371 
372 	case TIOCFLUSH: {
373 		register int flags = *(int *)data;
374 
375 		if (flags == 0)
376 			flags = FREAD|FWRITE;
377 		else
378 			flags &= FREAD|FWRITE;
379 		flushtty(tp, flags);
380 		break;
381 	}
382 
383 	/* return number of characters immediately available */
384 	case FIONREAD:
385 		*(off_t *)data = ttnread(tp);
386 		break;
387 
388 	case TIOCSTOP:
389 		s = spl5();
390 		if ((tp->t_state&TS_TTSTOP) == 0) {
391 			tp->t_state |= TS_TTSTOP;
392 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
393 		}
394 		splx(s);
395 		break;
396 
397 	case TIOCSTART:
398 		s = spl5();
399 		if ((tp->t_state&TS_TTSTOP) || (tp->t_flags&FLUSHO)) {
400 			tp->t_state &= ~TS_TTSTOP;
401 			tp->t_flags &= ~FLUSHO;
402 			ttstart(tp);
403 		}
404 		splx(s);
405 		break;
406 
407 	/*
408 	 * Simulate typing of a character at the terminal.
409 	 */
410 	case TIOCSTI:
411 		if (u.u_uid && u.u_ttyp != tp)
412 			return (EACCES);
413 		(*linesw[tp->t_line].l_rint)(*(char *)data, tp);
414 		break;
415 
416 	default:
417 #ifndef NOCOMPAT
418 		return (ottioctl(tp, com, data, flag));
419 #else
420 		return (-1);
421 #endif
422 	}
423 	return (0);
424 }
425 
426 ttnread(tp)
427 	struct tty *tp;
428 {
429 	int nread = 0;
430 
431 	if (tp->t_flags & PENDIN)
432 		ttypend(tp);
433 	nread = tp->t_canq.c_cc;
434 	if (tp->t_flags & (RAW|CBREAK))
435 		nread += tp->t_rawq.c_cc;
436 	return (nread);
437 }
438 
439 ttselect(dev, rw)
440 	dev_t dev;
441 	int rw;
442 {
443 	register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
444 	int nread;
445 	int s = spl5();
446 
447 	switch (rw) {
448 
449 	case FREAD:
450 		nread = ttnread(tp);
451 		if (nread > 0)
452 			goto win;
453 		if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
454 			tp->t_state |= TS_RCOLL;
455 		else
456 			tp->t_rsel = u.u_procp;
457 		break;
458 
459 	case FWRITE:
460 		if (tp->t_outq.c_cc <= TTLOWAT(tp))
461 			goto win;
462 		if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
463 			tp->t_state |= TS_WCOLL;
464 		else
465 			tp->t_wsel = u.u_procp;
466 		break;
467 	}
468 	splx(s);
469 	return (0);
470 win:
471 	splx(s);
472 	return (1);
473 }
474 
475 /*
476  * Establish a process group for distribution of
477  * quits and interrupts from the tty.
478  */
479 ttyopen(dev, tp)
480 	dev_t dev;
481 	register struct tty *tp;
482 {
483 	register struct proc *pp;
484 
485 	pp = u.u_procp;
486 	tp->t_dev = dev;
487 	if (pp->p_pgrp == 0) {
488 		u.u_ttyp = tp;
489 		u.u_ttyd = dev;
490 		if (tp->t_pgrp == 0)
491 			tp->t_pgrp = pp->p_pid;
492 		pp->p_pgrp = tp->t_pgrp;
493 	}
494 	tp->t_state &= ~TS_WOPEN;
495 	tp->t_state |= TS_ISOPEN;
496 	if (tp->t_line != NTTYDISC)
497 		wflushtty(tp);
498 	return (0);
499 }
500 
501 /*
502  * clean tp on last close
503  */
504 ttyclose(tp)
505 	register struct tty *tp;
506 {
507 
508 	if (tp->t_line) {
509 		wflushtty(tp);
510 		tp->t_line = 0;
511 		return;
512 	}
513 	tp->t_pgrp = 0;
514 	wflushtty(tp);
515 	tp->t_state = 0;
516 }
517 
518 /*
519  * reinput pending characters after state switch
520  * call at spl5().
521  */
522 ttypend(tp)
523 	register struct tty *tp;
524 {
525 	struct clist tq;
526 	register c;
527 
528 	tp->t_flags &= ~PENDIN;
529 	tp->t_state |= TS_TYPEN;
530 	tq = tp->t_rawq;
531 	tp->t_rawq.c_cc = 0;
532 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
533 	while ((c = getc(&tq)) >= 0)
534 		ttyinput(c, tp);
535 	tp->t_state &= ~TS_TYPEN;
536 }
537 
538 /*
539  * Place a character on raw TTY input queue,
540  * putting in delimiters and waking up top
541  * half as needed.  Also echo if required.
542  * The arguments are the character and the
543  * appropriate tty structure.
544  */
545 ttyinput(c, tp)
546 	register c;
547 	register struct tty *tp;
548 {
549 	register int t_flags = tp->t_flags;
550 	int i;
551 
552 	/*
553 	 * If input is pending take it first.
554 	 */
555 	if (t_flags&PENDIN)
556 		ttypend(tp);
557 	tk_nin++;
558 	c &= 0377;
559 
560 	/*
561 	 * In tandem mode, check high water mark.
562 	 */
563 	if (t_flags&TANDEM)
564 		ttyblock(tp);
565 
566 	if (t_flags&RAW) {
567 		/*
568 		 * Raw mode, just put character
569 		 * in input q w/o interpretation.
570 		 */
571 		if (tp->t_rawq.c_cc > TTYHOG)
572 			flushtty(tp, FREAD|FWRITE);
573 		else {
574 			if (putc(c, &tp->t_rawq) >= 0)
575 				ttwakeup(tp);
576 			ttyecho(c, tp);
577 		}
578 		goto endcase;
579 	}
580 
581 	/*
582 	 * Ignore any high bit added during
583 	 * previous ttyinput processing.
584 	 */
585 	if ((tp->t_state&TS_TYPEN) == 0)
586 		c &= 0177;
587 	/*
588 	 * Check for literal nexting very first
589 	 */
590 	if (tp->t_state&TS_LNCH) {
591 		c |= 0200;
592 		tp->t_state &= ~TS_LNCH;
593 	}
594 
595 	/*
596 	 * Scan for special characters.  This code
597 	 * is really just a big case statement with
598 	 * non-constant cases.  The bottom of the
599 	 * case statement is labeled ``endcase'', so goto
600 	 * it after a case match, or similar.
601 	 */
602 	if (tp->t_line == NTTYDISC) {
603 		if (c == tp->t_lnextc) {
604 			if (tp->t_flags&ECHO)
605 				ttyout("^\b", tp);
606 			tp->t_state |= TS_LNCH;
607 			goto endcase;
608 		}
609 		if (c == tp->t_flushc) {
610 			if (tp->t_flags&FLUSHO)
611 				tp->t_flags &= ~FLUSHO;
612 			else {
613 				flushtty(tp, FWRITE);
614 				ttyecho(c, tp);
615 				if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
616 					ttyretype(tp);
617 				tp->t_flags |= FLUSHO;
618 			}
619 			goto startoutput;
620 		}
621 		if (c == tp->t_suspc) {
622 			if ((tp->t_flags&NOFLSH) == 0)
623 				flushtty(tp, FREAD);
624 			ttyecho(c, tp);
625 			gsignal(tp->t_pgrp, SIGTSTP);
626 			goto endcase;
627 		}
628 	}
629 
630 	/*
631 	 * Handle start/stop characters.
632 	 */
633 	if (c == tp->t_stopc) {
634 		if ((tp->t_state&TS_TTSTOP) == 0) {
635 			tp->t_state |= TS_TTSTOP;
636 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
637 			return;
638 		}
639 		if (c != tp->t_startc)
640 			return;
641 		goto endcase;
642 	}
643 	if (c == tp->t_startc)
644 		goto restartoutput;
645 
646 	/*
647 	 * Look for interrupt/quit chars.
648 	 */
649 	if (c == tp->t_intrc || c == tp->t_quitc) {
650 		if ((tp->t_flags&NOFLSH) == 0)
651 			flushtty(tp, FREAD|FWRITE);
652 		ttyecho(c, tp);
653 		gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT);
654 		goto endcase;
655 	}
656 
657 	/*
658 	 * Cbreak mode, don't process line editing
659 	 * characters; check high water mark for wakeup.
660 	 */
661 	if (t_flags&CBREAK) {
662 		if (tp->t_rawq.c_cc > TTYHOG) {
663 			if (tp->t_outq.c_cc < TTHIWAT(tp) &&
664 			    tp->t_line == NTTYDISC)
665 				(void) ttyoutput(CTRL(g), tp);
666 		} else if (putc(c, &tp->t_rawq) >= 0) {
667 			ttwakeup(tp);
668 			ttyecho(c, tp);
669 		}
670 		goto endcase;
671 	}
672 
673 	/*
674 	 * From here on down cooked mode character
675 	 * processing takes place.
676 	 */
677 	if ((tp->t_state&TS_QUOT) &&
678 	    (c == tp->t_erase || c == tp->t_kill)) {
679 		ttyrub(unputc(&tp->t_rawq), tp);
680 		c |= 0200;
681 	}
682 	if (c == tp->t_erase) {
683 		if (tp->t_rawq.c_cc)
684 			ttyrub(unputc(&tp->t_rawq), tp);
685 		goto endcase;
686 	}
687 	if (c == tp->t_kill) {
688 		if (tp->t_flags&CRTKIL &&
689 		    tp->t_rawq.c_cc == tp->t_rocount) {
690 			while (tp->t_rawq.c_cc)
691 				ttyrub(unputc(&tp->t_rawq), tp);
692 		} else {
693 			ttyecho(c, tp);
694 			ttyecho('\n', tp);
695 			while (getc(&tp->t_rawq) > 0)
696 				;
697 			tp->t_rocount = 0;
698 		}
699 		tp->t_state &= ~TS_LOCAL;
700 		goto endcase;
701 	}
702 
703 	/*
704 	 * New line discipline,
705 	 * check word erase/reprint line.
706 	 */
707 	if (tp->t_line == NTTYDISC) {
708 		if (c == tp->t_werasc) {
709 			if (tp->t_rawq.c_cc == 0)
710 				goto endcase;
711 			do {
712 				c = unputc(&tp->t_rawq);
713 				if (c != ' ' && c != '\t')
714 					goto erasenb;
715 				ttyrub(c, tp);
716 			} while (tp->t_rawq.c_cc);
717 			goto endcase;
718 	erasenb:
719 			do {
720 				ttyrub(c, tp);
721 				if (tp->t_rawq.c_cc == 0)
722 					goto endcase;
723 				c = unputc(&tp->t_rawq);
724 			} while (c != ' ' && c != '\t');
725 			(void) putc(c, &tp->t_rawq);
726 			goto endcase;
727 		}
728 		if (c == tp->t_rprntc) {
729 			ttyretype(tp);
730 			goto endcase;
731 		}
732 	}
733 
734 	/*
735 	 * Check for input buffer overflow
736 	 */
737 	if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG)
738 		goto endcase;
739 
740 	/*
741 	 * Put data char in q for user and
742 	 * wakeup on seeing a line delimiter.
743 	 */
744 	if (putc(c, &tp->t_rawq) >= 0) {
745 		if (tp->t_rawq.c_cc + tp->t_canq.c_cc == TTYHOG
746 		    && tp->t_line == NTTYDISC)
747 			(void) ttyoutput(CTRL(g), tp);
748 		if (ttbreakc(c, tp)) {
749 			tp->t_rocount = 0;
750 			catq(&tp->t_rawq, &tp->t_canq);
751 			ttwakeup(tp);
752 		} else if (tp->t_rocount++ == 0)
753 			tp->t_rocol = tp->t_col;
754 		tp->t_state &= ~TS_QUOT;
755 		if (c == '\\')
756 			tp->t_state |= TS_QUOT;
757 		if (tp->t_state&TS_ERASE) {
758 			tp->t_state &= ~TS_ERASE;
759 			(void) ttyoutput('/', tp);
760 		}
761 		i = tp->t_col;
762 		ttyecho(c, tp);
763 		if (c == tp->t_eofc && tp->t_flags&ECHO) {
764 			i = MIN(2, tp->t_col - i);
765 			while (i > 0) {
766 				(void) ttyoutput('\b', tp);
767 				i--;
768 			}
769 		}
770 	}
771 
772 endcase:
773 	/*
774 	 * If DEC-style start/stop is enabled don't restart
775 	 * output until seeing the start character.
776 	 */
777 	if (tp->t_flags&DECCTQ && tp->t_state&TS_TTSTOP &&
778 	    tp->t_startc != tp->t_stopc)
779 		return;
780 
781 restartoutput:
782 	tp->t_state &= ~TS_TTSTOP;
783 	tp->t_flags &= ~FLUSHO;
784 
785 startoutput:
786 	ttstart(tp);
787 }
788 
789 /*
790  * Put character on TTY output queue, adding delays,
791  * expanding tabs, and handling the CR/NL bit.
792  * This is called both from the top half for output,
793  * and from interrupt level for echoing.
794  * The arguments are the character and the tty structure.
795  * Returns < 0 if putc succeeds, otherwise returns char to resend
796  * Must be recursive.
797  */
798 ttyoutput(c, tp)
799 	register c;
800 	register struct tty *tp;
801 {
802 	register char *colp;
803 	register ctype;
804 
805 	if (tp->t_flags & (RAW|LITOUT)) {
806 		if (tp->t_flags&FLUSHO)
807 			return (-1);
808 		if (putc(c, &tp->t_outq))
809 			return (c);
810 		tk_nout++;
811 		return (-1);
812 	}
813 
814 	/*
815 	 * Ignore EOT in normal mode to avoid
816 	 * hanging up certain terminals.
817 	 */
818 	c &= 0177;
819 	if (c == CEOT && (tp->t_flags&CBREAK) == 0)
820 		return (-1);
821 	/*
822 	 * Turn tabs to spaces as required
823 	 */
824 	if (c == '\t' && (tp->t_flags&TBDELAY) == XTABS) {
825 		register int s;
826 
827 		c = 8 - (tp->t_col&7);
828 		if ((tp->t_flags&FLUSHO) == 0) {
829 			s = spl5();		/* don't interrupt tabs */
830 			c -= b_to_q("        ", c, &tp->t_outq);
831 			tk_nout += c;
832 			splx(s);
833 		}
834 		tp->t_col += c;
835 		return (c ? -1 : '\t');
836 	}
837 	tk_nout++;
838 	/*
839 	 * for upper-case-only terminals,
840 	 * generate escapes.
841 	 */
842 	if (tp->t_flags&LCASE) {
843 		colp = "({)}!|^~'`";
844 		while (*colp++)
845 			if (c == *colp++) {
846 				if (ttyoutput('\\', tp) >= 0)
847 					return (c);
848 				c = colp[-2];
849 				break;
850 			}
851 		if ('A' <= c && c <= 'Z') {
852 			if (ttyoutput('\\', tp) >= 0)
853 				return (c);
854 		} else if ('a' <= c && c <= 'z')
855 			c += 'A' - 'a';
856 	}
857 
858 	/*
859 	 * turn <nl> to <cr><lf> if desired.
860 	 */
861 	if (c == '\n' && tp->t_flags&CRMOD)
862 		if (ttyoutput('\r', tp) >= 0)
863 			return (c);
864 	if (c == '~' && tp->t_flags&TILDE)
865 		c = '`';
866 	if ((tp->t_flags&FLUSHO) == 0 && putc(c, &tp->t_outq))
867 		return (c);
868 	/*
869 	 * Calculate delays.
870 	 * The numbers here represent clock ticks
871 	 * and are not necessarily optimal for all terminals.
872 	 * The delays are indicated by characters above 0200.
873 	 * In raw mode there are no delays and the
874 	 * transmission path is 8 bits wide.
875 	 *
876 	 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS
877 	 */
878 	colp = &tp->t_col;
879 	ctype = partab[c];
880 	c = 0;
881 	switch (ctype&077) {
882 
883 	case ORDINARY:
884 		(*colp)++;
885 
886 	case CONTROL:
887 		break;
888 
889 	case BACKSPACE:
890 		if (*colp)
891 			(*colp)--;
892 		break;
893 
894 	case NEWLINE:
895 		ctype = (tp->t_flags >> 8) & 03;
896 		if (ctype == 1) { /* tty 37 */
897 			if (*colp)
898 				c = max(((unsigned)*colp>>4) + 3, (unsigned)6);
899 		} else if (ctype == 2) /* vt05 */
900 			c = 6;
901 		*colp = 0;
902 		break;
903 
904 	case TAB:
905 		ctype = (tp->t_flags >> 10) & 03;
906 		if (ctype == 1) { /* tty 37 */
907 			c = 1 - (*colp | ~07);
908 			if (c < 5)
909 				c = 0;
910 		}
911 		*colp |= 07;
912 		(*colp)++;
913 		break;
914 
915 	case VTAB:
916 		if (tp->t_flags&VTDELAY) /* tty 37 */
917 			c = 0177;
918 		break;
919 
920 	case RETURN:
921 		ctype = (tp->t_flags >> 12) & 03;
922 		if (ctype == 1) /* tn 300 */
923 			c = 5;
924 		else if (ctype == 2) /* ti 700 */
925 			c = 10;
926 		else if (ctype == 3) { /* concept 100 */
927 			int i;
928 
929 			if ((i = *colp) >= 0)
930 				for (; i < 9; i++)
931 					(void) putc(0177, &tp->t_outq);
932 		}
933 		*colp = 0;
934 	}
935 	if (c && (tp->t_flags&FLUSHO) == 0)
936 		(void) putc(c|0200, &tp->t_outq);
937 	return (-1);
938 }
939 
940 /*
941  * Called from device's read routine after it has
942  * calculated the tty-structure given as argument.
943  */
944 ttread(tp, uio)
945 	register struct tty *tp;
946 	struct uio *uio;
947 {
948 	register struct clist *qp;
949 	register c, t_flags;
950 	int first, error = 0;
951 
952 	if ((tp->t_state&TS_CARR_ON)==0)
953 		return (EIO);
954 loop:
955 	/*
956 	 * Take any pending input first.
957 	 */
958 	(void) spl5();
959 	if (tp->t_flags&PENDIN)
960 		ttypend(tp);
961 	(void) spl0();
962 
963 	/*
964 	 * Hang process if it's in the background.
965 	 */
966 	while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) {
967 		if (u.u_signal[SIGTTIN] == SIG_IGN ||
968 		    u.u_signal[SIGTTIN] == SIG_HOLD ||
969 /*
970 		    (u.u_procp->p_flag&SDETACH) ||
971 */
972 		    u.u_procp->p_flag&SVFORK)
973 			return (EIO);
974 		gsignal(u.u_procp->p_pgrp, SIGTTIN);
975 		sleep((caddr_t)&lbolt, TTIPRI);
976 	}
977 	t_flags = tp->t_flags;
978 
979 	/*
980 	 * In raw mode take characters directly from the
981 	 * raw queue w/o processing.  Interlock against
982 	 * device interrupts when interrogating rawq.
983 	 */
984 	if (t_flags&RAW) {
985 		(void) spl5();
986 		if (tp->t_rawq.c_cc <= 0) {
987 			if ((tp->t_state&TS_CARR_ON) == 0 ||
988 			    (tp->t_state&TS_NBIO)) {
989 				(void) spl0();
990 				return (0);
991 			}
992 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
993 			(void) spl0();
994 			goto loop;
995 		}
996 		(void) spl0();
997 		while (tp->t_rawq.c_cc && uio->uio_iovcnt) {
998 			error = passuc(getc(&tp->t_rawq), uio);
999 			if (error)
1000 				break;
1001 		}
1002 		return (error);
1003 	}
1004 
1005 	/*
1006 	 * In cbreak mode use the rawq, otherwise
1007 	 * take characters from the canonicalized q.
1008 	 */
1009 	qp = t_flags&CBREAK ? &tp->t_rawq : &tp->t_canq;
1010 
1011 	/*
1012 	 * No input, sleep on rawq awaiting hardware
1013 	 * receipt and notification.
1014 	 */
1015 	(void) spl5();
1016 	if (qp->c_cc <= 0) {
1017 		if ((tp->t_state&TS_CARR_ON) == 0 ||
1018 		    (tp->t_state&TS_NBIO)) {
1019 			(void) spl0();
1020 			return (EWOULDBLOCK);
1021 		}
1022 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
1023 		(void) spl0();
1024 		goto loop;
1025 	}
1026 	(void) spl0();
1027 
1028 	/*
1029 	 * Input present, perform input mapping
1030 	 * and processing (we're not in raw mode).
1031 	 */
1032 	first = 1;
1033 	while ((c = getc(qp)) >= 0) {
1034 		if (t_flags&CRMOD && c == '\r')
1035 			c = '\n';
1036 		/*
1037 		 * Hack lower case simulation on
1038 		 * upper case only terminals.
1039 		 */
1040 		if (t_flags&LCASE && c <= 0177)
1041 			if (tp->t_state&TS_BKSL) {
1042 				if (maptab[c])
1043 					c = maptab[c];
1044 				tp->t_state &= ~TS_BKSL;
1045 			} else if (c >= 'A' && c <= 'Z')
1046 				c += 'a' - 'A';
1047 			else if (c == '\\') {
1048 				tp->t_state |= TS_BKSL;
1049 				continue;
1050 			}
1051 		/*
1052 		 * Check for delayed suspend character.
1053 		 */
1054 		if (tp->t_line == NTTYDISC && c == tp->t_dsuspc) {
1055 			gsignal(tp->t_pgrp, SIGTSTP);
1056 			if (first) {
1057 				sleep((caddr_t)&lbolt, TTIPRI);
1058 				goto loop;
1059 			}
1060 			break;
1061 		}
1062 		/*
1063 		 * Interpret EOF only in cooked mode.
1064 		 */
1065 		if (c == tp->t_eofc && (t_flags&CBREAK) == 0)
1066 			break;
1067 		/*
1068 		 * Give user character.
1069 		 */
1070 		error = passuc(c & 0177, uio);
1071 		if (error)
1072 			break;
1073 		if (uio->uio_iovcnt == 0)
1074 			break;
1075 		/*
1076 		 * In cooked mode check for a "break character"
1077 		 * marking the end of a "line of input".
1078 		 */
1079 		if ((t_flags&CBREAK) == 0 && ttbreakc(c, tp))
1080 			break;
1081 		first = 0;
1082 	}
1083 	tp->t_state &= ~TS_BKSL;
1084 
1085 	/*
1086 	 * Look to unblock output now that (presumably)
1087 	 * the input queue has gone down.
1088 	 */
1089 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
1090 		if (putc(tp->t_startc, &tp->t_outq) == 0) {
1091 			tp->t_state &= ~TS_TBLOCK;
1092 			ttstart(tp);
1093 		}
1094 		tp->t_char = 0;
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 #ifndef vax
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