xref: /original-bsd/sys/kern/tty.c (revision f0fd5f8a)
1 /*	tty.c	4.37	82/12/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 
119 	(void) spl5();
120 	while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON
121 	    && tp->t_oproc) {		/* kludge for pty */
122 		(*tp->t_oproc)(tp);
123 		tp->t_state |= TS_ASLEEP;
124 		sleep((caddr_t)&tp->t_outq, TTOPRI);
125 	}
126 	flushtty(tp, FREAD);
127 	(void) spl0();
128 }
129 
130 /*
131  * Flush all TTY queues
132  */
133 flushtty(tp, rw)
134 	register struct tty *tp;
135 {
136 	register s;
137 
138 	s = spl6();
139 	if (rw & FREAD) {
140 		while (getc(&tp->t_canq) >= 0)
141 			;
142 		wakeup((caddr_t)&tp->t_rawq);
143 	}
144 	if (rw & FWRITE) {
145 		wakeup((caddr_t)&tp->t_outq);
146 		tp->t_state &= ~TS_TTSTOP;
147 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
148 		while (getc(&tp->t_outq) >= 0)
149 			;
150 	}
151 	if (rw & FREAD) {
152 		while (getc(&tp->t_rawq) >= 0)
153 			;
154 		tp->t_delct = 0;
155 		tp->t_rocount = 0;
156 		tp->t_rocol = 0;
157 		tp->t_state &= ~TS_LOCAL;
158 	}
159 	splx(s);
160 }
161 
162 /*
163  * Send stop character on input overflow.
164  */
165 ttyblock(tp)
166 	register struct tty *tp;
167 {
168 	register x;
169 
170 	x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
171 	if (tp->t_rawq.c_cc > TTYHOG) {
172 		flushtty(tp, FREAD|FWRITE);
173 		tp->t_state &= ~TS_TBLOCK;
174 	}
175 	if (x >= TTYHOG/2 && putc(tp->t_stopc, &tp->t_outq) == 0) {
176 		tp->t_state |= TS_TBLOCK;
177 		tp->t_char++;
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 		goto endcase;
740 
741 	/*
742 	 * Put data char in q for user and
743 	 * wakeup on seeing a line delimiter.
744 	 */
745 	if (putc(c, &tp->t_rawq) >= 0) {
746 		if (tp->t_rawq.c_cc + tp->t_canq.c_cc == TTYHOG
747 		    && tp->t_line == NTTYDISC)
748 			(void) ttyoutput(CTRL(g), tp);
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 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 	(void) spl5();
960 	if (tp->t_flags&PENDIN)
961 		ttypend(tp);
962 	(void) spl0();
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 		(void) 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 				(void) spl0();
991 				return (0);
992 			}
993 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
994 			(void) spl0();
995 			goto loop;
996 		}
997 		(void) spl0();
998 		while (tp->t_rawq.c_cc && uio->uio_iovcnt) {
999 			error = passuc(getc(&tp->t_rawq), uio);
1000 			if (error)
1001 				break;
1002 		}
1003 		return (error);
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 	(void) spl5();
1017 	if (qp->c_cc <= 0) {
1018 		if ((tp->t_state&TS_CARR_ON) == 0 ||
1019 		    (tp->t_state&TS_NBIO)) {
1020 			(void) spl0();
1021 			return (EWOULDBLOCK);
1022 		}
1023 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
1024 		(void) spl0();
1025 		goto loop;
1026 	}
1027 	(void) spl0();
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 	/*
1087 	 * Look to unblock output now that (presumably)
1088 	 * the input queue has gone down.
1089 	 */
1090 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
1091 		if (putc(tp->t_startc, &tp->t_outq) == 0) {
1092 			tp->t_state &= ~TS_TBLOCK;
1093 			ttstart(tp);
1094 		}
1095 		tp->t_char = 0;
1096 	}
1097 	return (error);
1098 }
1099 
1100 /*
1101  * Called from the device's write routine after it has
1102  * calculated the tty-structure given as argument.
1103  */
1104 ttwrite(tp, uio)
1105 	register struct tty *tp;
1106 	register struct uio *uio;
1107 {
1108 	register char *cp;
1109 	register int cc, ce, c;
1110 	int i, hiwat, cnt, error, s;
1111 	char obuf[OBUFSIZ];
1112 
1113 	if ((tp->t_state&TS_CARR_ON) == 0)
1114 		return (EIO);
1115 	hiwat = TTHIWAT(tp);
1116 	cnt = uio->uio_resid;
1117 	error = 0;
1118 loop:
1119 	/*
1120 	 * Hang the process if it's in the background.
1121 	 */
1122 	while (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
1123 	    (tp->t_flags&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
1124 	    u.u_signal[SIGTTOU] != SIG_IGN &&
1125 	    u.u_signal[SIGTTOU] != SIG_HOLD
1126 /*
1127 					     &&
1128 	    (u.u_procp->p_flag&SDETACH)==0) {
1129 */
1130 	    ) {
1131 		gsignal(u.u_procp->p_pgrp, SIGTTOU);
1132 		sleep((caddr_t)&lbolt, TTIPRI);
1133 	}
1134 
1135 	/*
1136 	 * Process the user's data in at most OBUFSIZ
1137 	 * chunks.  Perform lower case simulation and
1138 	 * similar hacks.  Keep track of high water
1139 	 * mark, sleep on overflow awaiting device aid
1140 	 * in acquiring new space.
1141 	 */
1142 	while (uio->uio_resid > 0) {
1143 		/*
1144 		 * Grab a hunk of data from the user.
1145 		 */
1146 		cc = uio->uio_iov->iov_len;
1147 		if (cc == 0) {
1148 			uio->uio_iovcnt--;
1149 			uio->uio_iov++;
1150 			if (uio->uio_iovcnt < 0)
1151 				panic("ttwrite");
1152 			continue;
1153 		}
1154 		if (cc > OBUFSIZ)
1155 			cc = OBUFSIZ;
1156 		cp = obuf;
1157 		error = uiomove(cp, (unsigned)cc, UIO_WRITE, uio);
1158 		if (error)
1159 			break;
1160 		if (tp->t_outq.c_cc > hiwat)
1161 			goto ovhiwat;
1162 		if (tp->t_flags&FLUSHO)
1163 			continue;
1164 		/*
1165 		 * If we're mapping lower case or kludging tildes,
1166 		 * then we've got to look at each character, so
1167 		 * just feed the stuff to ttyoutput...
1168 		 */
1169 		if (tp->t_flags & (LCASE|TILDE)) {
1170 			while (cc > 0) {
1171 				c = *cp++;
1172 				tp->t_rocount = 0;
1173 				while ((c = ttyoutput(c, tp)) >= 0) {
1174 					/* out of clists, wait a bit */
1175 					ttstart(tp);
1176 					sleep((caddr_t)&lbolt, TTOPRI);
1177 					tp->t_rocount = 0;
1178 				}
1179 				--cc;
1180 				if (tp->t_outq.c_cc > hiwat)
1181 					goto ovhiwat;
1182 			}
1183 			continue;
1184 		}
1185 		/*
1186 		 * If nothing fancy need be done, grab those characters we
1187 		 * can handle without any of ttyoutput's processing and
1188 		 * just transfer them to the output q.  For those chars
1189 		 * which require special processing (as indicated by the
1190 		 * bits in partab), call ttyoutput.  After processing
1191 		 * a hunk of data, look for FLUSHO so ^O's will take effect
1192 		 * immediately.
1193 		 */
1194 		while (cc > 0) {
1195 			if (tp->t_flags & (RAW|LITOUT))
1196 				ce = cc;
1197 			else {
1198 				ce = cc - scanc(cc, cp, partab, 077);
1199 				/*
1200 				 * If ce is zero, then we're processing
1201 				 * a special character through ttyoutput.
1202 				 */
1203 				if (ce == 0) {
1204 					tp->t_rocount = 0;
1205 					if (ttyoutput(*cp, tp) >= 0) {
1206 						/* no c-lists, wait a bit */
1207 						ttstart(tp);
1208 						sleep((caddr_t)&lbolt, TTOPRI);
1209 						continue;
1210 					}
1211 					cp++, cc--;
1212 					if (tp->t_flags&FLUSHO ||
1213 					    tp->t_outq.c_cc > hiwat)
1214 						goto ovhiwat;
1215 					continue;
1216 				}
1217 			}
1218 			/*
1219 			 * A bunch of normal characters have been found,
1220 			 * transfer them en masse to the output queue and
1221 			 * continue processing at the top of the loop.
1222 			 * If there are any further characters in this
1223 			 * <= OBUFSIZ chunk, the first should be a character
1224 			 * requiring special handling by ttyoutput.
1225 			 */
1226 			tp->t_rocount = 0;
1227 			i = b_to_q(cp, ce, &tp->t_outq);
1228 			ce -= i;
1229 			tp->t_col += ce;
1230 			cp += ce, cc -= ce, tk_nout += ce;
1231 			if (i > 0) {
1232 				/* out of c-lists, wait a bit */
1233 				ttstart(tp);
1234 				sleep((caddr_t)&lbolt, TTOPRI);
1235 			}
1236 			if (tp->t_flags&FLUSHO || tp->t_outq.c_cc > hiwat)
1237 				goto ovhiwat;
1238 		}
1239 	}
1240 	ttstart(tp);
1241 	return (error);
1242 
1243 ovhiwat:
1244 	s = spl5();
1245 	if (cc != 0) {
1246 		uio->uio_iov->iov_base -= cc;
1247 		uio->uio_iov->iov_len += cc;
1248 		uio->uio_resid += cc;
1249 		uio->uio_offset -= cc;
1250 	}
1251 	/*
1252 	 * This can only occur if FLUSHO
1253 	 * is also set in t_flags.
1254 	 */
1255 	if (tp->t_outq.c_cc <= hiwat) {
1256 		splx(s);
1257 		goto loop;
1258 	}
1259 	ttstart(tp);
1260 	if (tp->t_state&TS_NBIO) {
1261 		if (uio->uio_resid == cnt)
1262 			return (EWOULDBLOCK);
1263 		return (0);
1264 	}
1265 	tp->t_state |= TS_ASLEEP;
1266 	sleep((caddr_t)&tp->t_outq, TTOPRI);
1267 	splx(s);
1268 	goto loop;
1269 }
1270 
1271 /*
1272  * Rubout one character from the rawq of tp
1273  * as cleanly as possible.
1274  */
1275 ttyrub(c, tp)
1276 	register c;
1277 	register struct tty *tp;
1278 {
1279 	register char *cp;
1280 	register int savecol;
1281 	int s;
1282 	char *nextc();
1283 
1284 	if ((tp->t_flags&ECHO) == 0)
1285 		return;
1286 	tp->t_flags &= ~FLUSHO;
1287 	c &= 0377;
1288 	if (tp->t_flags&CRTBS) {
1289 		if (tp->t_rocount == 0) {
1290 			/*
1291 			 * Screwed by ttwrite; retype
1292 			 */
1293 			ttyretype(tp);
1294 			return;
1295 		}
1296 		if (c == ('\t'|0200) || c == ('\n'|0200))
1297 			ttyrubo(tp, 2);
1298 		else switch (partab[c&=0177]&0177) {
1299 
1300 		case ORDINARY:
1301 			if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z')
1302 				ttyrubo(tp, 2);
1303 			else
1304 				ttyrubo(tp, 1);
1305 			break;
1306 
1307 		case VTAB:
1308 		case BACKSPACE:
1309 		case CONTROL:
1310 		case RETURN:
1311 			if (tp->t_flags&CTLECH)
1312 				ttyrubo(tp, 2);
1313 			break;
1314 
1315 		case TAB:
1316 			if (tp->t_rocount < tp->t_rawq.c_cc) {
1317 				ttyretype(tp);
1318 				return;
1319 			}
1320 			s = spl5();
1321 			savecol = tp->t_col;
1322 			tp->t_state |= TS_CNTTB;
1323 			tp->t_flags |= FLUSHO;
1324 			tp->t_col = tp->t_rocol;
1325 			cp = tp->t_rawq.c_cf;
1326 			for (; cp; cp = nextc(&tp->t_rawq, cp))
1327 				ttyecho(*cp, tp);
1328 			tp->t_flags &= ~FLUSHO;
1329 			tp->t_state &= ~TS_CNTTB;
1330 			splx(s);
1331 			/*
1332 			 * savecol will now be length of the tab
1333 			 */
1334 			savecol -= tp->t_col;
1335 			tp->t_col += savecol;
1336 			if (savecol > 8)
1337 				savecol = 8;		/* overflow screw */
1338 			while (--savecol >= 0)
1339 				(void) ttyoutput('\b', tp);
1340 			break;
1341 
1342 		default:
1343 			panic("ttyrub");
1344 		}
1345 	} else if (tp->t_flags&PRTERA) {
1346 		if ((tp->t_state&TS_ERASE) == 0) {
1347 			(void) ttyoutput('\\', tp);
1348 			tp->t_state |= TS_ERASE;
1349 		}
1350 		ttyecho(c, tp);
1351 	} else
1352 		ttyecho(tp->t_erase, tp);
1353 	tp->t_rocount--;
1354 }
1355 
1356 /*
1357  * Crt back over cnt chars perhaps
1358  * erasing them.
1359  */
1360 ttyrubo(tp, cnt)
1361 	register struct tty *tp;
1362 	int cnt;
1363 {
1364 	register char *rubostring = tp->t_flags&CRTERA ? "\b \b" : "\b";
1365 
1366 	while (--cnt >= 0)
1367 		ttyout(rubostring, tp);
1368 }
1369 
1370 /*
1371  * Reprint the rawq line.
1372  * We assume c_cc has already been checked.
1373  */
1374 ttyretype(tp)
1375 	register struct tty *tp;
1376 {
1377 	register char *cp;
1378 	char *nextc();
1379 	int s;
1380 
1381 	if (tp->t_rprntc != 0377)
1382 		ttyecho(tp->t_rprntc, tp);
1383 	(void) ttyoutput('\n', tp);
1384 	s = spl5();
1385 	for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp))
1386 		ttyecho(*cp, tp);
1387 	for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1388 		ttyecho(*cp, tp);
1389 	tp->t_state &= ~TS_ERASE;
1390 	splx(s);
1391 	tp->t_rocount = tp->t_rawq.c_cc;
1392 	tp->t_rocol = 0;
1393 }
1394 
1395 /*
1396  * Echo a typed character to the terminal
1397  */
1398 ttyecho(c, tp)
1399 	register c;
1400 	register struct tty *tp;
1401 {
1402 
1403 	if ((tp->t_state&TS_CNTTB) == 0)
1404 		tp->t_flags &= ~FLUSHO;
1405 	if ((tp->t_flags&ECHO) == 0)
1406 		return;
1407 	c &= 0377;
1408 	if (tp->t_flags&RAW) {
1409 		(void) ttyoutput(c, tp);
1410 		return;
1411 	}
1412 	if (c == '\r' && tp->t_flags&CRMOD)
1413 		c = '\n';
1414 	if (tp->t_flags&CTLECH) {
1415 		if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) {
1416 			(void) ttyoutput('^', tp);
1417 			c &= 0177;
1418 			if (c == 0177)
1419 				c = '?';
1420 			else if (tp->t_flags&LCASE)
1421 				c += 'a' - 1;
1422 			else
1423 				c += 'A' - 1;
1424 		}
1425 	}
1426 	if ((tp->t_flags&LCASE) && (c >= 'A' && c <= 'Z'))
1427 		c += 'a' - 'A';
1428 	(void) ttyoutput(c&0177, tp);
1429 }
1430 
1431 /*
1432  * Is c a break char for tp?
1433  */
1434 ttbreakc(c, tp)
1435 	register c;
1436 	register struct tty *tp;
1437 {
1438 	return (c == '\n' || c == tp->t_eofc || c == tp->t_brkc ||
1439 		c == '\r' && (tp->t_flags&CRMOD));
1440 }
1441 
1442 /*
1443  * send string cp to tp
1444  */
1445 ttyout(cp, tp)
1446 	register char *cp;
1447 	register struct tty *tp;
1448 {
1449 	register char c;
1450 
1451 	while (c = *cp++)
1452 		(void) ttyoutput(c, tp);
1453 }
1454 
1455 ttwakeup(tp)
1456 	struct tty *tp;
1457 {
1458 
1459 	if (tp->t_rsel) {
1460 		selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1461 		tp->t_state &= ~TS_RCOLL;
1462 		tp->t_rsel = 0;
1463 	}
1464 	wakeup((caddr_t)&tp->t_rawq);
1465 }
1466 
1467 #ifndef vax
1468 scanc(size, cp, table, mask)
1469 	register int size;
1470 	register char *cp, table[];
1471 	register int mask;
1472 {
1473 	register int i = 0;
1474 
1475 	while ((table[*(u_char *)(cp + i)]&mask) == 0 && i < size)
1476 		i++;
1477 	return (i);
1478 }
1479 #endif
1480