xref: /csrg-svn/sys/kern/tty.c (revision 8520)
1 /*	tty.c	4.30	82/10/13	*/
2 
3 /*
4  * TTY subroutines common to more than one line discipline
5  */
6 #include "../h/param.h"
7 #include "../h/systm.h"
8 #include "../h/dir.h"
9 #include "../h/user.h"
10 #include "../h/tty.h"
11 #include "../h/proc.h"
12 #include "../h/inode.h"
13 #include "../h/file.h"
14 #include "../h/reg.h"
15 #include "../h/conf.h"
16 #include "../h/buf.h"
17 #include "../h/dk.h"
18 #include "../h/uio.h"
19 #include "../h/kernel.h"
20 
21 /*
22  * Table giving parity for characters and indicating
23  * character classes to tty driver.  In particular,
24  * if the low 6 bits are 0, then the character needs
25  * no special processing on output.
26  */
27 
28 char partab[] = {
29 	0001,0201,0201,0001,0201,0001,0001,0201,
30 	0202,0004,0003,0201,0005,0206,0201,0001,
31 	0201,0001,0001,0201,0001,0201,0201,0001,
32 	0001,0201,0201,0001,0201,0001,0001,0201,
33 	0200,0000,0000,0200,0000,0200,0200,0000,
34 	0000,0200,0200,0000,0200,0000,0000,0200,
35 	0000,0200,0200,0000,0200,0000,0000,0200,
36 	0200,0000,0000,0200,0000,0200,0200,0000,
37 	0200,0000,0000,0200,0000,0200,0200,0000,
38 	0000,0200,0200,0000,0200,0000,0000,0200,
39 	0000,0200,0200,0000,0200,0000,0000,0200,
40 	0200,0000,0000,0200,0000,0200,0200,0000,
41 	0000,0200,0200,0000,0200,0000,0000,0200,
42 	0200,0000,0000,0200,0000,0200,0200,0000,
43 	0200,0000,0000,0200,0000,0200,0200,0000,
44 	0000,0200,0200,0000,0200,0000,0000,0201,
45 
46 	/*
47 	 * 7 bit ascii ends with the last character above,
48 	 * but we contine through all 256 codes for the sake
49 	 * of the tty output routines which use special vax
50 	 * instructions which need a 256 character trt table.
51 	 */
52 
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 	0007,0007,0007,0007,0007,0007,0007,0007
69 };
70 
71 /*
72  * Input mapping table-- if an entry is non-zero, when the
73  * corresponding character is typed preceded by "\" the escape
74  * sequence is replaced by the table value.  Mostly used for
75  * upper-case only terminals.
76  */
77 
78 char	maptab[] ={
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,000,000,
82 	000,000,000,000,000,000,000,000,
83 	000,'|',000,000,000,000,000,'`',
84 	'{','}',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,000,
89 	000,000,000,000,000,000,000,000,
90 	000,000,000,000,000,000,'~',000,
91 	000,'A','B','C','D','E','F','G',
92 	'H','I','J','K','L','M','N','O',
93 	'P','Q','R','S','T','U','V','W',
94 	'X','Y','Z',000,000,000,000,000,
95 };
96 
97 short	tthiwat[16] =
98    { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,650,650 };
99 short	ttlowat[16] =
100    {  30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
101 
102 #define	OBUFSIZ	100
103 
104 /*
105  * set default control characters.
106  */
107 ttychars(tp)
108 	register struct tty *tp;
109 {
110 
111 	tun.t_intrc = CINTR;
112 	tun.t_quitc = CQUIT;
113 	tun.t_startc = CSTART;
114 	tun.t_stopc = CSTOP;
115 	tun.t_eofc = CEOT;
116 	tun.t_brkc = CBRK;
117 	tp->t_erase = CERASE;
118 	tp->t_kill = CKILL;
119 /* begin local */
120 	tlun.t_suspc = CTRL(z);
121 	tlun.t_dsuspc = CTRL(y);
122 	tlun.t_rprntc = CTRL(r);
123 	tlun.t_flushc = CTRL(o);
124 	tlun.t_werasc = CTRL(w);
125 	tlun.t_lnextc = CTRL(v);
126 	tp->t_local = 0;
127 	tp->t_lstate = 0;
128 /* end local */
129 }
130 
131 /*
132  * Wait for output to drain, then flush input waiting.
133  */
134 wflushtty(tp)
135 	register struct tty *tp;
136 {
137 
138 	(void) spl5();
139 	while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON
140 	    && tp->t_oproc) {		/* kludge for pty */
141 		(*tp->t_oproc)(tp);
142 		tp->t_state |= TS_ASLEEP;
143 		sleep((caddr_t)&tp->t_outq, TTOPRI);
144 	}
145 	flushtty(tp, FREAD);
146 	(void) spl0();
147 }
148 
149 /*
150  * flush all TTY queues
151  */
152 flushtty(tp, rw)
153 	register struct tty *tp;
154 {
155 	register s;
156 
157 	s = spl6();
158 	if (rw & FREAD) {
159 		while (getc(&tp->t_canq) >= 0)
160 			;
161 		wakeup((caddr_t)&tp->t_rawq);
162 	}
163 	if (rw & FWRITE) {
164 		wakeup((caddr_t)&tp->t_outq);
165 		tp->t_state &= ~TS_TTSTOP;
166 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
167 		while (getc(&tp->t_outq) >= 0)
168 			;
169 	}
170 	if (rw & FREAD) {
171 		while (getc(&tp->t_rawq) >= 0)
172 			;
173 		tp->t_delct = 0;
174 		tp->t_rocount = 0;		/* local */
175 		tp->t_rocol = 0;
176 		tp->t_lstate = 0;
177 	}
178 	splx(s);
179 }
180 
181 /*
182  * Send stop character on input overflow.
183  */
184 ttyblock(tp)
185 	register struct tty *tp;
186 {
187 	register x;
188 	x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
189 	if (tp->t_rawq.c_cc > TTYHOG) {
190 		flushtty(tp, FREAD|FWRITE);
191 		tp->t_state &= ~TS_TBLOCK;
192 	}
193 	if (x >= TTYHOG/2) {
194 		if (putc(tun.t_stopc, &tp->t_outq)==0) {
195 			tp->t_state |= TS_TBLOCK;
196 			tp->t_char++;
197 			ttstart(tp);
198 		}
199 	}
200 }
201 
202 /*
203  * Restart typewriter output following a delay
204  * timeout.
205  * The name of the routine is passed to the timeout
206  * subroutine and it is called during a clock interrupt.
207  */
208 ttrstrt(tp)
209 	register struct tty *tp;
210 {
211 
212 	if (tp == 0) {
213 		printf("ttrstrt: arg was 0!\n");
214 		return;
215 	}
216 	tp->t_state &= ~TS_TIMEOUT;
217 	ttstart(tp);
218 }
219 
220 /*
221  * Start output on the typewriter. It is used from the top half
222  * after some characters have been put on the output queue,
223  * from the interrupt routine to transmit the next
224  * character, and after a timeout has finished.
225  */
226 ttstart(tp)
227 	register struct tty *tp;
228 {
229 	register s;
230 
231 	s = spl5();
232 	if ((tp->t_state&(TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 &&
233 	    tp->t_oproc)		/* kludge for pty */
234 		(*tp->t_oproc)(tp);
235 	splx(s);
236 }
237 
238 /*
239  * Common code for tty ioctls.
240  */
241 /*ARGSUSED*/
242 ttioctl(tp, com, data, flag)
243 	register struct tty *tp;
244 	caddr_t data;
245 {
246 	int dev = tp->t_dev;
247 	extern int nldisp;
248 
249 	/*
250 	 * If the ioctl involves modification,
251 	 * insist on being able to write the device,
252 	 * and hang if in the background.
253 	 */
254 	switch (com) {
255 
256 	case TIOCSETD:
257 	case TIOCSETP:
258 	case TIOCSETN:
259 	case TIOCFLUSH:
260 	case TIOCSETC:
261 	case TIOCSLTC:
262 	case TIOCSPGRP:
263 	case TIOCLBIS:
264 	case TIOCLBIC:
265 	case TIOCLSET:
266 /* this is reasonable, but impractical...
267 		if ((flag & FWRITE) == 0) {
268 			u.u_error = EBADF;
269 			return (1);
270 		}
271  */
272 		while (tp->t_line == NTTYDISC &&
273 		   u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
274 		   (u.u_procp->p_flag&SVFORK) == 0 &&
275 		   u.u_signal[SIGTTOU] != SIG_IGN &&
276 		   u.u_signal[SIGTTOU] != SIG_HOLD
277 /*
278 						   &&
279 		   (u.u_procp->p_flag&SDETACH)==0) {
280 */
281 		   ) {
282 			gsignal(u.u_procp->p_pgrp, SIGTTOU);
283 			sleep((caddr_t)&lbolt, TTOPRI);
284 		}
285 		break;
286 	}
287 
288 	/*
289 	 * Process the ioctl.
290 	 */
291 	switch (com) {
292 
293 	/*
294 	 * Get discipline number
295 	 */
296 	case TIOCGETD:
297 		*(int *)data = tp->t_line;
298 		break;
299 
300 	/*
301 	 * Set line discipline
302 	 */
303 	case TIOCSETD: {
304 		register int t = *(int *)data;
305 
306 		if (t >= nldisp) {
307 			u.u_error = ENXIO;
308 			break;
309 		}
310 		(void) spl5();
311 		if (tp->t_line)
312 			(*linesw[tp->t_line].l_close)(tp);
313 		if (t)
314 			(*linesw[t].l_open)(dev, tp);
315 		if (u.u_error==0)
316 			tp->t_line = t;
317 		(void) spl0();
318 		break;
319 	}
320 
321 	/*
322 	 * Prevent more opens on channel
323 	 */
324 	case TIOCEXCL:
325 		tp->t_state |= TS_XCLUDE;
326 		break;
327 
328 	case TIOCNXCL:
329 		tp->t_state &= ~TS_XCLUDE;
330 		break;
331 
332 	/*
333 	 * Set new parameters
334 	 */
335 	case TIOCSETP:
336 	case TIOCSETN: {
337 		register struct sgttyb *sg = (struct sgttyb *)data;
338 		struct clist tq;
339 
340 		(void) spl5();
341 		if (tp->t_flags&RAW || sg->sg_flags&RAW || com == TIOCSETP)
342 			wflushtty(tp);
343 		else if ((tp->t_flags&CBREAK) != (sg->sg_flags&CBREAK)) {
344 			if (sg->sg_flags & CBREAK) {
345 				catq(&tp->t_rawq, &tp->t_canq);
346 				tq = tp->t_rawq;
347 				tp->t_rawq = tp->t_canq;
348 				tp->t_canq = tq;
349 			} else {
350 				tp->t_local |= LPENDIN;
351 				ttwakeup(tp);
352 			}
353 		}
354 		tp->t_ispeed = sg->sg_ispeed;
355 		tp->t_ospeed = sg->sg_ospeed;
356 		tp->t_erase = sg->sg_erase;
357 		tp->t_kill = sg->sg_kill;
358 		tp->t_flags = sg->sg_flags;
359 		if (tp->t_flags & RAW) {
360 			tp->t_state &= ~TS_TTSTOP;
361 			ttstart(tp);
362 		}
363 		(void) spl0();
364 		break;
365 	}
366 
367 	/*
368 	 * Send current parameters to user
369 	 */
370 	case TIOCGETP: {
371 		register struct sgttyb *sg = (struct sgttyb *)data;
372 
373 		sg->sg_ispeed = tp->t_ispeed;
374 		sg->sg_ospeed = tp->t_ospeed;
375 		sg->sg_erase = tp->t_erase;
376 		sg->sg_kill = tp->t_kill;
377 		sg->sg_flags = tp->t_flags;
378 		break;
379 	}
380 
381 	/*
382 	 * Hang up line on last close
383 	 */
384 	case TIOCHPCL:
385 		tp->t_state |= TS_HUPCLS;
386 		break;
387 
388 	case TIOCFLUSH: {
389 		register int flags = *(int *)data;
390 
391 		if (flags == 0)
392 			flags = FREAD|FWRITE;
393 		else
394 			flags &= FREAD|FWRITE;
395 		flushtty(tp, flags);
396 		break;
397 	}
398 
399 	case FIONBIO:
400 		if (*(int *)data)
401 			tp->t_state |= TS_NBIO;
402 		else
403 			tp->t_state &= ~TS_NBIO;
404 		break;
405 
406 	case FIOASYNC:
407 		if (*(int *)data)
408 			tp->t_state |= TS_ASYNC;
409 		else
410 			tp->t_state &= ~TS_ASYNC;
411 		break;
412 
413 	/*
414 	 * Set and fetch special characters
415 	 */
416 	case TIOCSETC:
417 		bcopy(data, (caddr_t)&tun, sizeof (struct tchars));
418 		break;
419 
420 	case TIOCGETC:
421 		bcopy((caddr_t)&tun, data, sizeof (struct tchars));
422 		break;
423 
424 /* local ioctls */
425 	/*
426 	 * Set/get local special characters.
427 	 */
428 	case TIOCSLTC:
429 		bcopy(data, (caddr_t)&tlun, sizeof (struct ltchars));
430 		break;
431 
432 	case TIOCGLTC:
433 		bcopy((caddr_t)&tlun, data, sizeof (struct ltchars));
434 		break;
435 
436 	/*
437 	 * Return number of characters immediately available.
438 	 */
439 	case FIONREAD:
440 		*(off_t *)data = ttnread(tp);
441 		break;
442 
443 	/*
444 	 * Should allow SPGRP and GPGRP only if tty open for reading.
445 	 */
446 	case TIOCSPGRP:
447 		tp->t_pgrp = *(int *)data;
448 		break;
449 
450 	case TIOCGPGRP:
451 		*(int *)data = tp->t_pgrp;
452 		break;
453 
454 	/*
455 	 * Modify local mode word.
456 	 */
457 	case TIOCLBIS:
458 		tp->t_local |= *(int *)data;
459 		break;
460 
461 	case TIOCLBIC:
462 		tp->t_local &= ~(*(int *)data);
463 		break;
464 
465 	case TIOCLSET:
466 		tp->t_local = *(int *)data;
467 		break;
468 
469 	case TIOCLGET:
470 		*(int *)data = tp->t_local;
471 		break;
472 
473 	case TIOCSTOP: {
474 		int s = spl5();
475 
476 		if ((tp->t_state & TS_TTSTOP) == 0) {
477 			tp->t_state |= TS_TTSTOP;
478 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
479 		}
480 		splx(s);
481 		break;
482 	}
483 
484 	case TIOCSTART: {
485 		int s = spl5();
486 
487 		if ((tp->t_state & TS_TTSTOP) || (tp->t_local & LFLUSHO)) {
488 			tp->t_state &= ~TS_TTSTOP;
489 			tp->t_local &= ~LFLUSHO;
490 			ttstart(tp);
491 		}
492 		splx(s);
493 		break;
494 	}
495 
496 /* end of locals */
497 
498 	default:
499 		return (0);
500 	}
501 	return (1);
502 }
503 
504 ttnread(tp)
505 	struct tty *tp;
506 {
507 	int nread = 0;
508 
509 	if (tp->t_local & LPENDIN)
510 		ttypend(tp);
511 	nread = tp->t_canq.c_cc;
512 	if (tp->t_flags & (RAW|CBREAK))
513 		nread += tp->t_rawq.c_cc;
514 	return (nread);
515 }
516 
517 ttselect(dev, rw)
518 	dev_t dev;
519 	int rw;
520 {
521 	register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
522 	int nread;
523 	int s = spl5();
524 
525 	switch (rw) {
526 
527 	case FREAD:
528 		nread = ttnread(tp);
529 		if (nread > 0)
530 			goto win;
531 		if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
532 			tp->t_state |= TS_RCOLL;
533 		else
534 			tp->t_rsel = u.u_procp;
535 		break;
536 
537 	case FWRITE:
538 		if (tp->t_outq.c_cc <= TTLOWAT(tp))
539 			goto win;
540 		if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
541 			tp->t_state |= TS_WCOLL;
542 		else
543 			tp->t_wsel = u.u_procp;
544 		break;
545 	}
546 	splx(s);
547 	return (0);
548 win:
549 	splx(s);
550 	return (1);
551 }
552 
553 #define	OBUFSIZ	100
554 
555 /*
556  * routine called on opens while tp->t_line == NTTYDISC
557  * establishes a process group for distribution of
558  * quits and interrupts from the tty.
559  * (actually, pp->p_pgrp can't be 0 when this routine
560  * is called since NTTYDISC is not the default discipline)
561  */
562 ttyopen(dev, tp)
563 	dev_t dev;
564 	register struct tty *tp;
565 {
566 	register struct proc *pp;
567 
568 	pp = u.u_procp;
569 	tp->t_dev = dev;
570 	if (pp->p_pgrp == 0) {
571 		u.u_ttyp = tp;
572 		u.u_ttyd = dev;
573 		if (tp->t_pgrp == 0)
574 			tp->t_pgrp = pp->p_pid;
575 		pp->p_pgrp = tp->t_pgrp;
576 	}
577 	tp->t_state &= ~TS_WOPEN;
578 	tp->t_state |= TS_ISOPEN;
579 	if (tp->t_line != NTTYDISC)
580 		wflushtty(tp);
581 }
582 
583 /*
584  * clean tp on last close
585  */
586 ttyclose(tp)
587 	register struct tty *tp;
588 {
589 
590 	if (tp->t_line) {
591 		wflushtty(tp);
592 		tp->t_line = 0;
593 		return;
594 	}
595 	tp->t_pgrp = 0;
596 	wflushtty(tp);
597 	tp->t_state = 0;
598 }
599 
600 /*
601  * reinput pending characters after state switch
602  * call at spl5().
603  */
604 ttypend(tp)
605 	register struct tty *tp;
606 {
607 	struct clist tq;
608 	register c;
609 
610 	tp->t_local &= ~LPENDIN;
611 	tp->t_lstate |= LSTYPEN;
612 	tq = tp->t_rawq;
613 	tp->t_rawq.c_cc = 0;
614 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
615 	while ((c = getc(&tq)) >= 0)
616 		ttyinput(c, tp);
617 	tp->t_lstate &= ~LSTYPEN;
618 }
619 
620 /*
621  * Place a character on raw TTY input queue, putting in delimiters
622  * and waking up top half as needed.
623  * Also echo if required.
624  * The arguments are the character and the appropriate
625  * tty structure.
626  */
627 ttyinput(c, tp)
628 	register c;
629 	register struct tty *tp;
630 {
631 	register int t_flags;
632 	int i;
633 
634 	if (tp->t_local&LPENDIN)
635 		ttypend(tp);
636 	tk_nin++;
637 	c &= 0377;
638 	t_flags = tp->t_flags;
639 	if (t_flags&TANDEM)
640 		ttyblock(tp);
641 	if ((t_flags&RAW)==0) {
642 		if ((tp->t_lstate&LSTYPEN) == 0)
643 			c &= 0177;
644 	/* check for literal nexting very first */
645 		if (tp->t_lstate&LSLNCH) {
646 			c |= 0200;
647 			tp->t_lstate &= ~LSLNCH;
648 		}
649 		if (tp->t_line == NTTYDISC && c==tlun.t_lnextc) {
650 			if (tp->t_flags&ECHO)
651 				ttyout("^\b", tp);
652 			tp->t_lstate |= LSLNCH;
653 	/* check for output control functions */
654 		} else if (c==tun.t_stopc) {
655 			if ((tp->t_state&TS_TTSTOP)==0) {
656 				tp->t_state |= TS_TTSTOP;
657 				(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
658 				return;
659 			}
660 			if (c!=tun.t_startc)
661 				return;
662 		} else if (c==tun.t_startc) {
663 			tp->t_state &= ~TS_TTSTOP;
664 			tp->t_local &= ~LFLUSHO;
665 			ttstart(tp);
666 			return;
667 		} else if (tp->t_line == NTTYDISC && c==tlun.t_flushc) {
668 			if (tp->t_local & LFLUSHO)
669 				tp->t_local &= ~LFLUSHO;
670 			else {
671 				flushtty(tp, FWRITE);
672 				ttyecho(c, tp);
673 				if (tp->t_rawq.c_cc+tp->t_canq.c_cc)
674 					ttyretype(tp);
675 				tp->t_local |= LFLUSHO;
676 			}
677 			ttstart(tp);
678 			return;
679 		} else if (c==tun.t_intrc || c==tun.t_quitc ||
680 		    (tp->t_line == NTTYDISC && c==tlun.t_suspc)) {
681 			if ((tp->t_local & LNOFLSH) == 0)
682 				flushtty(tp,
683 				    c==tlun.t_suspc ? FREAD : FREAD|FWRITE);
684 			ttyecho(c, tp);
685 			c = c==tun.t_intrc ? SIGINT :
686 				((c==tun.t_quitc) ? SIGQUIT : SIGTSTP);
687 			ttsignal(tp, c);
688 	/* check for buffer editing functions - cooked mode */
689 		} else if ((t_flags&CBREAK) == 0) {
690 			if ((tp->t_lstate&LSQUOT) &&
691 			    (c==tp->t_erase||c==tp->t_kill)) {
692 				ttyrub(unputc(&tp->t_rawq), tp);
693 				c |= 0200;
694 			}
695 			if (c==tp->t_erase) {
696 				if (tp->t_rawq.c_cc)
697 					ttyrub(unputc(&tp->t_rawq), tp);
698 			} else if (c==tp->t_kill) {
699 				if (tp->t_local&LCRTKIL &&
700 				    tp->t_rawq.c_cc == tp->t_rocount) {
701 					while (tp->t_rawq.c_cc)
702 						ttyrub(unputc(&tp->t_rawq), tp);
703 				} else {
704 					ttyecho(c, tp);
705 					ttyecho('\n', tp);
706 					while (getc(&tp->t_rawq) > 0)
707 						;
708 					tp->t_rocount = 0;
709 				}
710 				tp->t_lstate = 0;
711 			} else if (tp->t_line == NTTYDISC && c==tlun.t_werasc) {
712 				if (tp->t_rawq.c_cc == 0)
713 					goto out;
714 				do {
715 					c = unputc(&tp->t_rawq);
716 					if (c != ' ' && c != '\t')
717 						goto erasenb;
718 					ttyrub(c, tp);
719 				} while (tp->t_rawq.c_cc);
720 				goto out;
721 			    erasenb:
722 				do {
723 					ttyrub(c, tp);
724 					if (tp->t_rawq.c_cc == 0)
725 						goto out;
726 					c = unputc(&tp->t_rawq);
727 				} while (c != ' ' && c != '\t');
728 				(void) putc(c, &tp->t_rawq);
729 			} else if (tp->t_line == NTTYDISC && c==tlun.t_rprntc) {
730 				ttyretype(tp);
731 	/* check for cooked mode input buffer overflow */
732 			} else if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
733 				;
734 	/* put data char in q for user and wakeup if a break char */
735 			} else if (putc(c, &tp->t_rawq) >= 0) {
736 				if (tp->t_rawq.c_cc+tp->t_canq.c_cc==TTYHOG
737 				    && tp->t_line == NTTYDISC)
738 					(void) ttyoutput(CTRL(g), tp);
739 				if (!ttbreakc(c, tp)) {
740 					if (tp->t_rocount++ == 0)
741 						tp->t_rocol = tp->t_col;
742 				} else {
743 					tp->t_rocount = 0;
744 					catq(&tp->t_rawq, &tp->t_canq);
745 					/* IF (TP->T_CHAN) (VOID) SDATA(TP->T_CHAN); */
746 					ttwakeup(tp);
747 				}
748 				tp->t_lstate &= ~LSQUOT;
749 				if (c == '\\')
750 					tp->t_lstate |= LSQUOT;
751 				if (tp->t_lstate&LSERASE) {
752 					tp->t_lstate &= ~LSERASE;
753 					(void) ttyoutput('/', tp);
754 				}
755 				i = tp->t_col;
756 				ttyecho(c, tp);
757 				if (c==tun.t_eofc && tp->t_flags&ECHO) {
758 					i = MIN(2, tp->t_col - i);
759 					while (i > 0) {
760 						(void) ttyoutput('\b', tp);
761 						i--;
762 					}
763 				}
764 			}
765 	/* CBREAK mode */
766 		} else if (tp->t_rawq.c_cc > TTYHOG) {
767 			if (tp->t_outq.c_cc < TTHIWAT(tp) &&
768 			    tp->t_line == NTTYDISC)
769 				(void) ttyoutput(CTRL(g), tp);
770 		} else if (putc(c, &tp->t_rawq) >= 0) {
771 			ttwakeup(tp);
772 			ttyecho(c, tp);
773 		}
774 	/* RAW mode */
775 	} else if (tp->t_rawq.c_cc > TTYHOG)
776 		flushtty(tp, FREAD|FWRITE);
777 	else {
778 		if (putc(c, &tp->t_rawq) >= 0)
779 			ttwakeup(tp);
780 		ttyecho(c, tp);
781 	}
782 out:
783 	if (tp->t_local & LDECCTQ && tp->t_state & TS_TTSTOP &&
784 	    tun.t_startc != tun.t_stopc)
785 		return;
786 	tp->t_state &= ~TS_TTSTOP;
787 	tp->t_local &= ~LFLUSHO;
788 	ttstart(tp);
789 }
790 
791 /*
792  * put character on TTY output queue, adding delays,
793  * expanding tabs, and handling the CR/NL bit.
794  * It is called both from the top half for output, and from
795  * interrupt level for echoing.
796  * The arguments are the character and the tty structure.
797  * Returns < 0 if putc succeeds, otherwise returns char to resend
798  * Must be recursive.
799  */
800 ttyoutput(c, tp)
801 	register c;
802 	register struct tty *tp;
803 {
804 	register char *colp;
805 	register ctype;
806 
807 	if (tp->t_flags&RAW || tp->t_local&LLITOUT) {
808 		if (tp->t_local&LFLUSHO)
809 			return (-1);
810 		if (putc(c, &tp->t_outq))
811 			return (c);
812 		tk_nout++;
813 		return (-1);
814 	}
815 	/*
816 	 * Ignore EOT in normal mode to avoid hanging up
817 	 * 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_local&LFLUSHO) == 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 	 * 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_local&LTILDE)
865 		c = '`';
866 	if ((tp->t_local&LFLUSHO) == 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 	colp = &tp->t_col;
877 	ctype = partab[c];
878 	c = 0;
879 	switch (ctype&077) {
880 
881 	case ORDINARY:
882 		(*colp)++;
883 
884 	case CONTROL:
885 		break;
886 
887 	case BACKSPACE:
888 		if (*colp)
889 			(*colp)--;
890 		break;
891 
892 	case NEWLINE:
893 		ctype = (tp->t_flags >> 8) & 03;
894 		if (ctype == 1) { /* tty 37 */
895 			if (*colp)
896 				c = max(((unsigned)*colp>>4) + 3, (unsigned)6);
897 		} else
898 		if (ctype == 2) { /* vt05 */
899 			c = 6;
900 		}
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 			if ((i = *colp) >= 0)
929 				for (; i<9; i++)
930 					(void) putc(0177, &tp->t_outq);
931 		}
932 		*colp = 0;
933 	}
934 	if (c && (tp->t_local&LFLUSHO) == 0)
935 		(void) putc(c|0200, &tp->t_outq);
936 	return (-1);
937 }
938 
939 /*
940  * Called from device's read routine after it has
941  * calculated the tty-structure given as argument.
942  */
943 ttread(tp, uio)
944 	register struct tty *tp;
945 	struct uio *uio;
946 {
947 	register struct clist *qp;
948 	register c, first;
949 	int error = 0;
950 
951 	if ((tp->t_state&TS_CARR_ON)==0)
952 		return (EIO);
953 loop:
954 	(void) spl5();
955 	if (tp->t_local&LPENDIN)
956 		ttypend(tp);
957 	(void) spl0();
958 	while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) {
959 		if (u.u_signal[SIGTTIN] == SIG_IGN ||
960 		    u.u_signal[SIGTTIN] == SIG_HOLD ||
961 /*
962 		    (u.u_procp->p_flag&SDETACH) ||
963 */
964 		    u.u_procp->p_flag&SVFORK)
965 			return (EIO);
966 		gsignal(u.u_procp->p_pgrp, SIGTTIN);
967 		sleep((caddr_t)&lbolt, TTIPRI);
968 	}
969 	if (tp->t_flags&RAW) {
970 		(void) spl5();
971 		if (tp->t_rawq.c_cc <= 0) {
972 			if ((tp->t_state&TS_CARR_ON)==0 ||
973 			    (tp->t_state&TS_NBIO)) {
974 				(void) spl0();
975 				return (EWOULDBLOCK);
976 			}
977 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
978 			(void) spl0();
979 			goto loop;
980 		}
981 		(void) spl0();
982 		while (tp->t_rawq.c_cc && uio->uio_iovcnt) {
983 			error = passuc(getc(&tp->t_rawq), uio);
984 			if (error)
985 				break;
986 		}
987 		return (error);
988 	} else {
989 		qp = tp->t_flags & CBREAK ? &tp->t_rawq : &tp->t_canq;
990 		(void) spl5();
991 		if (qp->c_cc <= 0) {
992 			if ((tp->t_state&TS_CARR_ON)==0 ||
993 			    (tp->t_state&TS_NBIO)) {
994 				(void) spl0();
995 				return (EWOULDBLOCK);
996 			}
997 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
998 			(void) spl0();
999 			goto loop;
1000 		}
1001 		(void) spl0();
1002 		first = 1;
1003 		while ((c = getc(qp)) >= 0) {
1004 			if (tp->t_flags&CRMOD && c == '\r')
1005 				c = '\n';
1006 			if (tp->t_flags&LCASE && c <= 0177)
1007 				if (tp->t_lstate&LSBKSL) {
1008 					if (maptab[c])
1009 						c = maptab[c];
1010 					tp->t_lstate &= ~LSBKSL;
1011 				} else if (c >= 'A' && c <= 'Z')
1012 					c += 'a' - 'A';
1013 				else if (c == '\\') {
1014 					tp->t_lstate |= LSBKSL;
1015 					continue;
1016 				}
1017 			if (tp->t_line == NTTYDISC && c == tlun.t_dsuspc) {
1018 				ttsignal(tp, SIGTSTP);
1019 				if (first) {
1020 					sleep((caddr_t)&lbolt, TTIPRI);
1021 					goto loop;
1022 				}
1023 				break;
1024 			}
1025 			if (c == tun.t_eofc && (tp->t_flags&CBREAK)==0)
1026 				break;
1027 			error = passuc(c & 0177, uio);
1028 			if (error)
1029 				break;
1030 			if (uio->uio_iovcnt == 0)
1031 				break;
1032 			if ((tp->t_flags&CBREAK)==0 && ttbreakc(c, tp))
1033 				break;
1034 			first = 0;
1035 		}
1036 		tp->t_lstate &= ~LSBKSL;
1037 	}
1038 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
1039 		if (putc(tun.t_startc, &tp->t_outq)==0) {
1040 			tp->t_state &= ~TS_TBLOCK;
1041 			ttstart(tp);
1042 		}
1043 		tp->t_char = 0;
1044 	}
1045 	return (error);
1046 }
1047 
1048 /*
1049  * Called from the device's write routine after it has
1050  * calculated the tty-structure given as argument.
1051  */
1052 ttwrite(tp, uio)
1053 	register struct tty *tp;
1054 	struct uio *uio;
1055 {
1056 #ifdef vax
1057 	/*
1058 	 * THE POSITIONING OF CP, CC, AND CE ARE CRITICAL
1059 	 * AND MUST NOT BE CHANGED WITHOUT PATCHING
1060 	 * THE 'ASM' INLINES BELOW.  WATCH OUT.
1061 	 */
1062 #endif
1063 	register char *cp;
1064 	register int cc, ce;
1065 	register i;
1066 	char obuf[OBUFSIZ];
1067 	register c;
1068 	int hiwat = TTHIWAT(tp);
1069 	int cnt = uio->uio_resid;
1070 	int error = 0;
1071 
1072 	if ((tp->t_state&TS_CARR_ON)==0)
1073 		return (EIO);
1074 loop:
1075 	while (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
1076 	    (tp->t_local&LTOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
1077 	    u.u_signal[SIGTTOU] != SIG_IGN &&
1078 	    u.u_signal[SIGTTOU] != SIG_HOLD
1079 /*
1080 					     &&
1081 	    (u.u_procp->p_flag&SDETACH)==0) {
1082 */
1083 	    ) {
1084 		gsignal(u.u_procp->p_pgrp, SIGTTOU);
1085 		sleep((caddr_t)&lbolt, TTIPRI);
1086 	}
1087 	while (uio->uio_resid > 0) {
1088 		cc = uio->uio_iov->iov_len;
1089 		if (cc == 0) {
1090 			uio->uio_iovcnt--;
1091 			uio->uio_iov++;
1092 			if (uio->uio_iovcnt < 0)
1093 				panic("ttwrite");
1094 			continue;
1095 		}
1096 		if (cc > OBUFSIZ)
1097 			cc = OBUFSIZ;
1098 		cp = obuf;
1099 		error = uiomove(cp, cc, UIO_WRITE, uio);
1100 		if (error)
1101 			break;
1102 		if (tp->t_outq.c_cc > hiwat)
1103 			goto ovhiwat;
1104 		if (tp->t_local&LFLUSHO)
1105 			continue;
1106 		if (tp->t_flags&LCASE || tp->t_local&LTILDE) {
1107 			while (cc) {
1108 				c = *cp++;
1109 				tp->t_rocount = 0;
1110 				while ((c = ttyoutput(c, tp)) >= 0) {
1111 					/* out of clists, wait a bit */
1112 					ttstart(tp);
1113 					sleep((caddr_t)&lbolt, TTOPRI);
1114 					tp->t_rocount = 0;
1115 				}
1116 				--cc;
1117 				if (tp->t_outq.c_cc > hiwat)
1118 					goto ovhiwat;
1119 			}
1120 			continue;
1121 		}
1122 		while (cc) {
1123 			if (tp->t_flags&RAW || tp->t_local&LLITOUT)
1124 				ce = cc;
1125 			else {
1126 #ifdef vax
1127 				asm("	scanc	r9,(r10),_partab,$077");
1128 				asm("	subl3	r0,r9,r8");
1129 #else
1130 				ce=0;
1131 				while (((partab[*(unsigned char *)(cp+ce)]&077)==0)&&(ce<cc))
1132 					ce++;
1133 #endif
1134 				if (ce==0) {
1135 					tp->t_rocount = 0;
1136 					if (ttyoutput(*cp, tp) >= 0) {
1137 						ttstart(tp);
1138 						sleep((caddr_t)&lbolt, TTOPRI);
1139 						continue;
1140 					}
1141 					cp++;
1142 					cc--;
1143 					if (tp->t_outq.c_cc > hiwat)
1144 						goto ovhiwat;
1145 				}
1146 			}
1147 			tp->t_rocount = 0;
1148 			i=b_to_q(cp,ce,&tp->t_outq);
1149 			ce-=i;
1150 			tk_nout+=ce;
1151 			tp->t_col+=ce;
1152 			cp+=ce;
1153 			cc-=ce;
1154 			if (i) {
1155 				ttstart(tp);
1156 				sleep((caddr_t)&lbolt, TTOPRI);
1157 			}
1158 			if (ce || tp->t_outq.c_cc > hiwat)
1159 				goto ovhiwat;
1160 		}
1161 	}
1162 	ttstart(tp);
1163 	return (error);
1164 
1165 ovhiwat:
1166 	(void) spl5();
1167 	uio->uio_iov->iov_base -= cc;
1168 	uio->uio_iov->iov_len += cc;
1169 	uio->uio_resid += cc;
1170 	uio->uio_offset -= cc;
1171 	if (tp->t_outq.c_cc <= hiwat) {
1172 		(void) spl0();
1173 		goto loop;
1174 	}
1175 	ttstart(tp);
1176 	if (tp->t_state & TS_NBIO) {
1177 		if (uio->uio_resid == cnt)
1178 			return (EWOULDBLOCK);
1179 		return (0);
1180 	}
1181 	tp->t_state |= TS_ASLEEP;
1182 	sleep((caddr_t)&tp->t_outq, TTOPRI);
1183 	(void) spl0();
1184 	goto loop;
1185 }
1186 
1187 /*
1188  * Rubout one character from the rawq of tp
1189  * as cleanly as possible.
1190  */
1191 ttyrub(c, tp)
1192 	register c;
1193 	register struct tty *tp;
1194 {
1195 	register char *cp;
1196 	register int savecol;
1197 	int s;
1198 	char *nextc();
1199 
1200 	if ((tp->t_flags&ECHO)==0)
1201 		return;
1202 	tp->t_local &= ~LFLUSHO;
1203 	c &= 0377;
1204 	if (tp->t_local&LCRTBS) {
1205 		if (tp->t_rocount == 0) {
1206 			/*
1207 			 * Screwed by ttwrite; retype
1208 			 */
1209 			ttyretype(tp);
1210 			return;
1211 		}
1212 		if (c==('\t'|0200) || c==('\n'|0200))
1213 			ttyrubo(tp, 2);
1214 		else switch (partab[c&=0177] & 0177) {
1215 
1216 		case ORDINARY:
1217 			if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z')
1218 				ttyrubo(tp, 2);
1219 			else
1220 				ttyrubo(tp, 1);
1221 			break;
1222 
1223 		case VTAB:
1224 		case BACKSPACE:
1225 		case CONTROL:
1226 		case RETURN:
1227 			if (tp->t_local & LCTLECH)
1228 				ttyrubo(tp, 2);
1229 			break;
1230 
1231 		case TAB:
1232 			if (tp->t_rocount < tp->t_rawq.c_cc) {
1233 				ttyretype(tp);
1234 				return;
1235 			}
1236 			s = spl5();
1237 			savecol = tp->t_col;
1238 			tp->t_lstate |= LSCNTTB;
1239 			tp->t_local |= LFLUSHO;
1240 			tp->t_col = tp->t_rocol;
1241 			for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1242 				ttyecho(*cp, tp);
1243 			tp->t_local &= ~LFLUSHO;
1244 			tp->t_lstate &= ~LSCNTTB;
1245 			splx(s);
1246 			/*
1247 			 * savecol will now be length of the tab
1248 			 */
1249 			savecol -= tp->t_col;
1250 			tp->t_col += savecol;
1251 			if (savecol > 8)
1252 				savecol = 8;		/* overflow screw */
1253 			while (--savecol >= 0)
1254 				(void) ttyoutput('\b', tp);
1255 			break;
1256 
1257 		default:
1258 			panic("ttyrub");
1259 		}
1260 	} else if (tp->t_local&LPRTERA) {
1261 		if ((tp->t_lstate&LSERASE) == 0) {
1262 			(void) ttyoutput('\\', tp);
1263 			tp->t_lstate |= LSERASE;
1264 		}
1265 		ttyecho(c, tp);
1266 	} else
1267 		ttyecho(tp->t_erase, tp);
1268 	tp->t_rocount--;
1269 }
1270 
1271 /*
1272  * Crt back over cnt chars perhaps
1273  * erasing them.
1274  */
1275 ttyrubo(tp, cnt)
1276 	register struct tty *tp;
1277 	int cnt;
1278 {
1279 
1280 	while (--cnt >= 0)
1281 		ttyout(tp->t_local&LCRTERA ? "\b \b" : "\b", tp);
1282 }
1283 
1284 /*
1285  * Reprint the rawq line.
1286  * We assume c_cc has already been checked.
1287  */
1288 ttyretype(tp)
1289 	register struct tty *tp;
1290 {
1291 	register char *cp;
1292 	char *nextc();
1293 	int s;
1294 
1295 	if (tlun.t_rprntc != 0377)
1296 		ttyecho(tlun.t_rprntc, tp);
1297 	(void) ttyoutput('\n', tp);
1298 	s = spl5();
1299 	for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp))
1300 		ttyecho(*cp, tp);
1301 	for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1302 		ttyecho(*cp, tp);
1303 	tp->t_lstate &= ~LSERASE;
1304 	splx(s);
1305 	tp->t_rocount = tp->t_rawq.c_cc;
1306 	tp->t_rocol = 0;
1307 }
1308 
1309 /*
1310  * Echo a typed character to the terminal
1311  */
1312 ttyecho(c, tp)
1313 	register c;
1314 	register struct tty *tp;
1315 {
1316 
1317 	if ((tp->t_lstate & LSCNTTB) == 0)
1318 		tp->t_local &= ~LFLUSHO;
1319 	if ((tp->t_flags&ECHO) == 0)
1320 		return;
1321 	c &= 0377;
1322 	if (tp->t_flags&RAW) {
1323 		(void) ttyoutput(c, tp);
1324 		return;
1325 	}
1326 	if (c == '\r' && tp->t_flags&CRMOD)
1327 		c = '\n';
1328 	if (tp->t_local&LCTLECH) {
1329 		if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) {
1330 			(void) ttyoutput('^', tp);
1331 			c &= 0177;
1332 			if (c == 0177)
1333 				c = '?';
1334 			else if (tp->t_flags&LCASE)
1335 				c += 'a' - 1;
1336 			else
1337 				c += 'A' - 1;
1338 		}
1339 	}
1340 	if ((tp->t_flags&LCASE) && (c >= 'A' && c <= 'Z'))
1341 		c += 'a' - 'A';
1342 	(void) ttyoutput(c & 0177, tp);
1343 }
1344 
1345 /*
1346  * Is c a break char for tp?
1347  */
1348 ttbreakc(c, tp)
1349 	register c;
1350 	register struct tty *tp;
1351 {
1352 	return (c == '\n' || c == tun.t_eofc || c == tun.t_brkc ||
1353 		c == '\r' && (tp->t_flags&CRMOD));
1354 }
1355 
1356 /*
1357  * send string cp to tp
1358  */
1359 ttyout(cp, tp)
1360 	register char *cp;
1361 	register struct tty *tp;
1362 {
1363 	register char c;
1364 
1365 	while (c = *cp++)
1366 		(void) ttyoutput(c, tp);
1367 }
1368 
1369 ttwakeup(tp)
1370 	struct tty *tp;
1371 {
1372 
1373 	if (tp->t_rsel) {
1374 		selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1375 		tp->t_state &= ~TS_RCOLL;
1376 		tp->t_rsel = 0;
1377 	}
1378 	wakeup((caddr_t)&tp->t_rawq);
1379 }
1380 
1381 ttsignal(tp, signo)
1382 	struct tty *tp;
1383 	int signo;
1384 {
1385 
1386 	gsignal(tp->t_pgrp, signo);
1387 }
1388