xref: /csrg-svn/sys/kern/tty.c (revision 31924)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)tty.c	7.6 (Berkeley) 07/21/87
7  */
8 
9 #include "../machine/reg.h"
10 
11 #include "param.h"
12 #include "systm.h"
13 #include "dir.h"
14 #include "user.h"
15 #include "ioctl.h"
16 #include "tty.h"
17 #include "proc.h"
18 #include "file.h"
19 #include "conf.h"
20 #include "dkstat.h"
21 #include "uio.h"
22 #include "kernel.h"
23 
24 /*
25  * Table giving parity for characters and indicating
26  * character classes to tty driver.  In particular,
27  * if the low 6 bits are 0, then the character needs
28  * no special processing on output.
29  */
30 
31 char partab[] = {
32 	0001,0201,0201,0001,0201,0001,0001,0201,
33 	0202,0004,0003,0201,0005,0206,0201,0001,
34 	0201,0001,0001,0201,0001,0201,0201,0001,
35 	0001,0201,0201,0001,0201,0001,0001,0201,
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 	0200,0000,0000,0200,0000,0200,0200,0000,
41 	0000,0200,0200,0000,0200,0000,0000,0200,
42 	0000,0200,0200,0000,0200,0000,0000,0200,
43 	0200,0000,0000,0200,0000,0200,0200,0000,
44 	0000,0200,0200,0000,0200,0000,0000,0200,
45 	0200,0000,0000,0200,0000,0200,0200,0000,
46 	0200,0000,0000,0200,0000,0200,0200,0000,
47 	0000,0200,0200,0000,0200,0000,0000,0201,
48 
49 	/*
50 	 * 7 bit ascii ends with the last character above,
51 	 * but we contine through all 256 codes for the sake
52 	 * of the tty output routines which use special vax
53 	 * instructions which need a 256 character trt table.
54 	 */
55 
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 	0007,0007,0007,0007,0007,0007,0007,0007,
70 	0007,0007,0007,0007,0007,0007,0007,0007,
71 	0007,0007,0007,0007,0007,0007,0007,0007
72 };
73 
74 /*
75  * Input mapping table-- if an entry is non-zero, when the
76  * corresponding character is typed preceded by "\" the escape
77  * sequence is replaced by the table value.  Mostly used for
78  * upper-case only terminals.
79  */
80 char	maptab[] ={
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,000,000,
84 	000,000,000,000,000,000,000,000,
85 	000,'|',000,000,000,000,000,'`',
86 	'{','}',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,000,
91 	000,000,000,000,000,000,000,000,
92 	000,000,000,000,000,000,'~',000,
93 	000,'A','B','C','D','E','F','G',
94 	'H','I','J','K','L','M','N','O',
95 	'P','Q','R','S','T','U','V','W',
96 	'X','Y','Z',000,000,000,000,000,
97 };
98 
99 short	tthiwat[16] =
100    { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 };
101 short	ttlowat[16] =
102    {  30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
103 
104 struct	ttychars ttydefaults = {
105 	CERASE,	CKILL,	CINTR,	CQUIT,	CSTART,	CSTOP,	CEOF,
106 	CBRK,	CSUSP,	CDSUSP, CRPRNT, CFLUSH, CWERASE,CLNEXT
107 };
108 
109 extern struct tty *constty;		/* temporary virtual console */
110 
111 ttychars(tp)
112 	struct tty *tp;
113 {
114 
115 	tp->t_chars = ttydefaults;
116 }
117 
118 /*
119  * Wait for output to drain, then flush input waiting.
120  */
121 ttywflush(tp)
122 	register struct tty *tp;
123 {
124 
125 	ttywait(tp);
126 	ttyflush(tp, FREAD);
127 }
128 
129 ttywait(tp)
130 	register struct tty *tp;
131 {
132 	register int s = spltty();
133 
134 	while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) &&
135 	    tp->t_state&TS_CARR_ON) {
136 		(*tp->t_oproc)(tp);
137 		tp->t_state |= TS_ASLEEP;
138 		sleep((caddr_t)&tp->t_outq, TTOPRI);
139 	}
140 	splx(s);
141 }
142 
143 /*
144  * Flush all TTY queues
145  */
146 ttyflush(tp, rw)
147 	register struct tty *tp;
148 {
149 	register s;
150 
151 	s = spltty();
152 	if (rw & FREAD) {
153 		while (getc(&tp->t_canq) >= 0)
154 			;
155 		wakeup((caddr_t)&tp->t_rawq);
156 	}
157 	if (rw & FWRITE) {
158 		wakeup((caddr_t)&tp->t_outq);
159 		tp->t_state &= ~TS_TTSTOP;
160 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
161 		while (getc(&tp->t_outq) >= 0)
162 			;
163 	}
164 	if (rw & FREAD) {
165 		while (getc(&tp->t_rawq) >= 0)
166 			;
167 		tp->t_rocount = 0;
168 		tp->t_rocol = 0;
169 		tp->t_state &= ~TS_LOCAL;
170 	}
171 	splx(s);
172 }
173 
174 /*
175  * Send stop character on input overflow.
176  */
177 ttyblock(tp)
178 	register struct tty *tp;
179 {
180 	register x;
181 
182 	x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
183 	if (tp->t_rawq.c_cc > TTYHOG) {
184 		ttyflush(tp, FREAD|FWRITE);
185 		tp->t_state &= ~TS_TBLOCK;
186 	}
187 	/*
188 	 * Block further input iff:
189 	 * Current input > threshold AND input is available to user program
190 	 */
191 	if (x >= TTYHOG/2 &&
192 	    ((tp->t_flags & (RAW|CBREAK)) || (tp->t_canq.c_cc > 0))) {
193 		if (putc(tp->t_stopc, &tp->t_outq)==0) {
194 			tp->t_state |= TS_TBLOCK;
195 			ttstart(tp);
196 		}
197 	}
198 }
199 
200 /*
201  * Restart typewriter output following a delay
202  * timeout.
203  * The name of the routine is passed to the timeout
204  * subroutine and it is called during a clock interrupt.
205  */
206 ttrstrt(tp)
207 	register struct tty *tp;
208 {
209 
210 	if (tp == 0)
211 		panic("ttrstrt");
212 	tp->t_state &= ~TS_TIMEOUT;
213 	ttstart(tp);
214 }
215 
216 /*
217  * Start output on the typewriter. It is used from the top half
218  * after some characters have been put on the output queue,
219  * from the interrupt routine to transmit the next
220  * character, and after a timeout has finished.
221  */
222 ttstart(tp)
223 	register struct tty *tp;
224 {
225 	register s;
226 
227 	s = spltty();
228 	if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 &&
229 	    tp->t_oproc)		/* kludge for pty */
230 		(*tp->t_oproc)(tp);
231 	splx(s);
232 }
233 
234 /*
235  * Common code for tty ioctls.
236  */
237 /*ARGSUSED*/
238 ttioctl(tp, com, data, flag)
239 	register struct tty *tp;
240 	caddr_t data;
241 {
242 	int dev = tp->t_dev;
243 	extern int nldisp;
244 	int s;
245 	register int newflags;
246 
247 
248 	/*
249 	 * If the ioctl involves modification,
250 	 * hang if in the background.
251 	 */
252 	switch (com) {
253 
254 	case TIOCSETD:
255 	case TIOCSETP:
256 	case TIOCSETN:
257 	case TIOCFLUSH:
258 	case TIOCSETC:
259 	case TIOCSLTC:
260 	case TIOCSPGRP:
261 	case TIOCLBIS:
262 	case TIOCLBIC:
263 	case TIOCLSET:
264 	case TIOCSTI:
265 	case TIOCSWINSZ:
266 		while (tp->t_line == NTTYDISC &&
267 		   u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
268 		   (u.u_procp->p_flag&SVFORK) == 0 &&
269 		   !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) &&
270 		   !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) {
271 			gsignal(u.u_procp->p_pgrp, SIGTTOU);
272 			sleep((caddr_t)&lbolt, TTOPRI);
273 		}
274 		break;
275 	}
276 
277 	/*
278 	 * Process the ioctl.
279 	 */
280 	switch (com) {
281 
282 	/* get discipline number */
283 	case TIOCGETD:
284 		*(int *)data = tp->t_line;
285 		break;
286 
287 	/* set line discipline */
288 	case TIOCSETD: {
289 		register int t = *(int *)data;
290 		int error = 0;
291 
292 		if ((unsigned) t >= nldisp)
293 			return (ENXIO);
294 		if (t != tp->t_line) {
295 			s = spltty();
296 			(*linesw[tp->t_line].l_close)(tp);
297 			error = (*linesw[t].l_open)(dev, tp);
298 			if (error) {
299 				(void) (*linesw[tp->t_line].l_open)(dev, tp);
300 				splx(s);
301 				return (error);
302 			}
303 			tp->t_line = t;
304 			splx(s);
305 		}
306 		break;
307 	}
308 
309 	/* prevent more opens on channel */
310 	case TIOCEXCL:
311 		tp->t_state |= TS_XCLUDE;
312 		break;
313 
314 	case TIOCNXCL:
315 		tp->t_state &= ~TS_XCLUDE;
316 		break;
317 
318 	/* hang up line on last close */
319 	case TIOCHPCL:
320 		tp->t_state |= TS_HUPCLS;
321 		break;
322 
323 	case TIOCFLUSH: {
324 		register int flags = *(int *)data;
325 
326 		if (flags == 0)
327 			flags = FREAD|FWRITE;
328 		else
329 			flags &= FREAD|FWRITE;
330 		ttyflush(tp, flags);
331 		break;
332 	}
333 
334 	/* return number of characters immediately available */
335 	case FIONREAD:
336 		*(off_t *)data = ttnread(tp);
337 		break;
338 
339 	case TIOCOUTQ:
340 		*(int *)data = tp->t_outq.c_cc;
341 		break;
342 
343 	case TIOCSTOP:
344 		s = spltty();
345 		if ((tp->t_state&TS_TTSTOP) == 0) {
346 			tp->t_state |= TS_TTSTOP;
347 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
348 		}
349 		splx(s);
350 		break;
351 
352 	case TIOCSTART:
353 		s = spltty();
354 		if ((tp->t_state&TS_TTSTOP) || (tp->t_flags&FLUSHO)) {
355 			tp->t_state &= ~TS_TTSTOP;
356 			tp->t_flags &= ~FLUSHO;
357 			ttstart(tp);
358 		}
359 		splx(s);
360 		break;
361 
362 	/*
363 	 * Simulate typing of a character at the terminal.
364 	 */
365 	case TIOCSTI:
366 		if (u.u_uid && (flag & FREAD) == 0)
367 			return (EPERM);
368 		if (u.u_uid && u.u_ttyp != tp)
369 			return (EACCES);
370 		(*linesw[tp->t_line].l_rint)(*(char *)data, tp);
371 		break;
372 
373 	case TIOCSETP:
374 	case TIOCSETN: {
375 		register struct sgttyb *sg = (struct sgttyb *)data;
376 
377 		tp->t_erase = sg->sg_erase;
378 		tp->t_kill = sg->sg_kill;
379 		tp->t_ispeed = sg->sg_ispeed;
380 		tp->t_ospeed = sg->sg_ospeed;
381 		newflags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff);
382 		s = spltty();
383 		if (tp->t_flags&RAW || newflags&RAW || com == TIOCSETP) {
384 			ttywait(tp);
385 			ttyflush(tp, FREAD);
386 		} else if ((tp->t_flags&CBREAK) != (newflags&CBREAK)) {
387 			if (newflags&CBREAK) {
388 				struct clist tq;
389 
390 				catq(&tp->t_rawq, &tp->t_canq);
391 				tq = tp->t_rawq;
392 				tp->t_rawq = tp->t_canq;
393 				tp->t_canq = tq;
394 			} else {
395 				tp->t_flags |= PENDIN;
396 				newflags |= PENDIN;
397 				ttwakeup(tp);
398 			}
399 		}
400 		tp->t_flags = newflags;
401 		if (tp->t_flags&RAW) {
402 			tp->t_state &= ~TS_TTSTOP;
403 			ttstart(tp);
404 		}
405 		splx(s);
406 		break;
407 	}
408 
409 	/* send current parameters to user */
410 	case TIOCGETP: {
411 		register struct sgttyb *sg = (struct sgttyb *)data;
412 
413 		sg->sg_ispeed = tp->t_ispeed;
414 		sg->sg_ospeed = tp->t_ospeed;
415 		sg->sg_erase = tp->t_erase;
416 		sg->sg_kill = tp->t_kill;
417 		sg->sg_flags = tp->t_flags;
418 		break;
419 	}
420 
421 	case FIONBIO:
422 		if (*(int *)data)
423 			tp->t_state |= TS_NBIO;
424 		else
425 			tp->t_state &= ~TS_NBIO;
426 		break;
427 
428 	case FIOASYNC:
429 		if (*(int *)data)
430 			tp->t_state |= TS_ASYNC;
431 		else
432 			tp->t_state &= ~TS_ASYNC;
433 		break;
434 
435 	case TIOCGETC:
436 		bcopy((caddr_t)&tp->t_intrc, data, sizeof (struct tchars));
437 		break;
438 
439 	case TIOCSETC:
440 		bcopy(data, (caddr_t)&tp->t_intrc, sizeof (struct tchars));
441 		break;
442 
443 	/* set/get local special characters */
444 	case TIOCSLTC:
445 		bcopy(data, (caddr_t)&tp->t_suspc, sizeof (struct ltchars));
446 		break;
447 
448 	case TIOCGLTC:
449 		bcopy((caddr_t)&tp->t_suspc, data, sizeof (struct ltchars));
450 		break;
451 
452 	/*
453 	 * Modify local mode word.
454 	 */
455 	case TIOCLBIS:
456 		tp->t_flags |= *(int *)data << 16;
457 		break;
458 
459 	case TIOCLBIC:
460 		tp->t_flags &= ~(*(int *)data << 16);
461 		break;
462 
463 	case TIOCLSET:
464 		tp->t_flags &= 0xffff;
465 		tp->t_flags |= *(int *)data << 16;
466 		break;
467 
468 	case TIOCLGET:
469 		*(int *)data = ((unsigned)tp->t_flags) >> 16;
470 		break;
471 
472 	/*
473 	 * Allow SPGRP only if tty is open for reading.
474 	 * Quick check: if we can find a process in the new pgrp,
475 	 * this user must own that process.
476 	 * SHOULD VERIFY THAT PGRP IS IN USE AND IS THIS USER'S.
477 	 */
478 	case TIOCSPGRP: {
479 		struct proc *p;
480 		int pgrp = *(int *)data;
481 
482 		if (u.u_uid && (flag & FREAD) == 0)
483 			return (EPERM);
484 		p = pfind(pgrp);
485 		if (p && p->p_pgrp == pgrp &&
486 		    p->p_uid != u.u_uid && u.u_uid && !inferior(p))
487 			return (EPERM);
488 		tp->t_pgrp = pgrp;
489 		break;
490 	}
491 
492 	case TIOCGPGRP:
493 		*(int *)data = tp->t_pgrp;
494 		break;
495 
496 	case TIOCSWINSZ:
497 		if (bcmp((caddr_t)&tp->t_winsize, data,
498 		    sizeof (struct winsize))) {
499 			tp->t_winsize = *(struct winsize *)data;
500 			gsignal(tp->t_pgrp, SIGWINCH);
501 		}
502 		break;
503 
504 	case TIOCGWINSZ:
505 		*(struct winsize *)data = tp->t_winsize;
506 		break;
507 
508 	case TIOCCONS:
509 		if (*(int *)data) {
510 			if (constty != NULL)
511 				return (EBUSY);
512 #ifndef	UCONSOLE
513 			if (!suser())
514 				return (EPERM);
515 #endif
516 			constty = tp;
517 		} else if (tp == constty)
518 			constty == NULL;
519 		break;
520 
521 	default:
522 		return (-1);
523 	}
524 	return (0);
525 }
526 
527 ttnread(tp)
528 	struct tty *tp;
529 {
530 	int nread = 0;
531 
532 	if (tp->t_flags & PENDIN)
533 		ttypend(tp);
534 	nread = tp->t_canq.c_cc;
535 	if (tp->t_flags & (RAW|CBREAK))
536 		nread += tp->t_rawq.c_cc;
537 	return (nread);
538 }
539 
540 ttselect(dev, rw)
541 	dev_t dev;
542 	int rw;
543 {
544 	register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
545 	int nread;
546 	int s = spltty();
547 
548 	switch (rw) {
549 
550 	case FREAD:
551 		nread = ttnread(tp);
552 		if (nread > 0 || (tp->t_state & TS_CARR_ON) == 0)
553 			goto win;
554 		if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
555 			tp->t_state |= TS_RCOLL;
556 		else
557 			tp->t_rsel = u.u_procp;
558 		break;
559 
560 	case FWRITE:
561 		if (tp->t_outq.c_cc <= TTLOWAT(tp))
562 			goto win;
563 		if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
564 			tp->t_state |= TS_WCOLL;
565 		else
566 			tp->t_wsel = u.u_procp;
567 		break;
568 	}
569 	splx(s);
570 	return (0);
571 win:
572 	splx(s);
573 	return (1);
574 }
575 
576 /*
577  * Initial open of tty, or (re)entry to line discipline.
578  * Establish a process group for distribution of
579  * quits and interrupts from the tty.
580  */
581 ttyopen(dev, tp)
582 	dev_t dev;
583 	register struct tty *tp;
584 {
585 	register struct proc *pp;
586 
587 	pp = u.u_procp;
588 	tp->t_dev = dev;
589 	if (pp->p_pgrp == 0) {
590 		u.u_ttyp = tp;
591 		u.u_ttyd = dev;
592 		if (tp->t_pgrp == 0)
593 			tp->t_pgrp = pp->p_pid;
594 		pp->p_pgrp = tp->t_pgrp;
595 	}
596 	tp->t_state &= ~TS_WOPEN;
597 	if ((tp->t_state & TS_ISOPEN) == 0) {
598 		tp->t_state |= TS_ISOPEN;
599 		bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize));
600 		if (tp->t_line != NTTYDISC)
601 			ttywflush(tp);
602 	}
603 	return (0);
604 }
605 
606 /*
607  * "close" a line discipline
608  */
609 ttylclose(tp)
610 	register struct tty *tp;
611 {
612 
613 	ttywflush(tp);
614 	tp->t_line = 0;
615 }
616 
617 /*
618  * clean tp on last close
619  */
620 ttyclose(tp)
621 	register struct tty *tp;
622 {
623 
624 	if (constty == tp)
625 		constty = NULL;
626 	ttyflush(tp, FREAD|FWRITE);
627 	tp->t_pgrp = 0;
628 	tp->t_state = 0;
629 }
630 
631 /*
632  * Handle modem control transition on a tty.
633  * Flag indicates new state of carrier.
634  * Returns 0 if the line should be turned off, otherwise 1.
635  */
636 ttymodem(tp, flag)
637 	register struct tty *tp;
638 {
639 
640 	if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_flags & MDMBUF)) {
641 		/*
642 		 * MDMBUF: do flow control according to carrier flag
643 		 */
644 		if (flag) {
645 			tp->t_state &= ~TS_TTSTOP;
646 			ttstart(tp);
647 		} else if ((tp->t_state&TS_TTSTOP) == 0) {
648 			tp->t_state |= TS_TTSTOP;
649 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
650 		}
651 	} else if (flag == 0) {
652 		/*
653 		 * Lost carrier.
654 		 */
655 		tp->t_state &= ~TS_CARR_ON;
656 		if (tp->t_state & TS_ISOPEN) {
657 			if ((tp->t_flags & NOHANG) == 0) {
658 				gsignal(tp->t_pgrp, SIGHUP);
659 				gsignal(tp->t_pgrp, SIGCONT);
660 				ttyflush(tp, FREAD|FWRITE);
661 				return (0);
662 			}
663 		}
664 	} else {
665 		/*
666 		 * Carrier now on.
667 		 */
668 		tp->t_state |= TS_CARR_ON;
669 		wakeup((caddr_t)&tp->t_rawq);
670 	}
671 	return (1);
672 }
673 
674 /*
675  * Default modem control routine (for other line disciplines).
676  * Return argument flag, to turn off device on carrier drop.
677  */
678 nullmodem(tp, flag)
679 	register struct tty *tp;
680 	int flag;
681 {
682 
683 	if (flag)
684 		tp->t_state |= TS_CARR_ON;
685 	else
686 		tp->t_state &= ~TS_CARR_ON;
687 	return (flag);
688 }
689 
690 /*
691  * reinput pending characters after state switch
692  * call at spltty().
693  */
694 ttypend(tp)
695 	register struct tty *tp;
696 {
697 	struct clist tq;
698 	register c;
699 
700 	tp->t_flags &= ~PENDIN;
701 	tp->t_state |= TS_TYPEN;
702 	tq = tp->t_rawq;
703 	tp->t_rawq.c_cc = 0;
704 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
705 	while ((c = getc(&tq)) >= 0)
706 		ttyinput(c, tp);
707 	tp->t_state &= ~TS_TYPEN;
708 }
709 
710 /*
711  * Place a character on raw TTY input queue,
712  * putting in delimiters and waking up top
713  * half as needed.  Also echo if required.
714  * The arguments are the character and the
715  * appropriate tty structure.
716  */
717 ttyinput(c, tp)
718 	register c;
719 	register struct tty *tp;
720 {
721 	register int t_flags = tp->t_flags;
722 	int i;
723 
724 	/*
725 	 * If input is pending take it first.
726 	 */
727 	if (t_flags&PENDIN)
728 		ttypend(tp);
729 	tk_nin++;
730 	c &= 0377;
731 
732 	/*
733 	 * In tandem mode, check high water mark.
734 	 */
735 	if (t_flags&TANDEM)
736 		ttyblock(tp);
737 
738 	if (t_flags&RAW) {
739 		/*
740 		 * Raw mode, just put character
741 		 * in input q w/o interpretation.
742 		 */
743 		if (tp->t_rawq.c_cc > TTYHOG)
744 			ttyflush(tp, FREAD|FWRITE);
745 		else {
746 			if (putc(c, &tp->t_rawq) >= 0)
747 				ttwakeup(tp);
748 			ttyecho(c, tp);
749 		}
750 		goto endcase;
751 	}
752 
753 	/*
754 	 * Ignore any high bit added during
755 	 * previous ttyinput processing.
756 	 */
757 	if ((tp->t_state&TS_TYPEN) == 0 && (t_flags&PASS8) == 0)
758 		c &= 0177;
759 	/*
760 	 * Check for literal nexting very first
761 	 */
762 	if (tp->t_state&TS_LNCH) {
763 		c |= 0200;
764 		tp->t_state &= ~TS_LNCH;
765 	}
766 
767 	/*
768 	 * Scan for special characters.  This code
769 	 * is really just a big case statement with
770 	 * non-constant cases.  The bottom of the
771 	 * case statement is labeled ``endcase'', so goto
772 	 * it after a case match, or similar.
773 	 */
774 	if (tp->t_line == NTTYDISC) {
775 		if (c == tp->t_lnextc) {
776 			if (t_flags&ECHO)
777 				ttyout("^\b", tp);
778 			tp->t_state |= TS_LNCH;
779 			goto endcase;
780 		}
781 		if (c == tp->t_flushc) {
782 			if (t_flags&FLUSHO)
783 				tp->t_flags &= ~FLUSHO;
784 			else {
785 				ttyflush(tp, FWRITE);
786 				ttyecho(c, tp);
787 				if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
788 					ttyretype(tp);
789 				tp->t_flags |= FLUSHO;
790 			}
791 			goto startoutput;
792 		}
793 		if (c == tp->t_suspc) {
794 			if ((t_flags&NOFLSH) == 0)
795 				ttyflush(tp, FREAD);
796 			ttyecho(c, tp);
797 			gsignal(tp->t_pgrp, SIGTSTP);
798 			goto endcase;
799 		}
800 	}
801 
802 	/*
803 	 * Handle start/stop characters.
804 	 */
805 	if (c == tp->t_stopc) {
806 		if ((tp->t_state&TS_TTSTOP) == 0) {
807 			tp->t_state |= TS_TTSTOP;
808 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
809 			return;
810 		}
811 		if (c != tp->t_startc)
812 			return;
813 		goto endcase;
814 	}
815 	if (c == tp->t_startc)
816 		goto restartoutput;
817 
818 	/*
819 	 * Look for interrupt/quit chars.
820 	 */
821 	if (c == tp->t_intrc || c == tp->t_quitc) {
822 		if ((t_flags&NOFLSH) == 0)
823 			ttyflush(tp, FREAD|FWRITE);
824 		ttyecho(c, tp);
825 		gsignal(tp->t_pgrp, c == tp->t_intrc ? SIGINT : SIGQUIT);
826 		goto endcase;
827 	}
828 
829 	if (tp->t_flags & LCASE && c <= 0177) {
830 		if (tp->t_state&TS_BKSL) {
831 			ttyrub(unputc(&tp->t_rawq), tp);
832 			if (maptab[c])
833 				c = maptab[c];
834 			c |= 0200;
835 			tp->t_state &= ~(TS_BKSL|TS_QUOT);
836 		} else if (c >= 'A' && c <= 'Z')
837 			c += 'a' - 'A';
838 		else if (c == '\\')
839 			tp->t_state |= TS_BKSL;
840 	}
841 
842 	/*
843 	 * Cbreak mode, don't process line editing
844 	 * characters; check high water mark for wakeup.
845 	 */
846 	if (t_flags&CBREAK) {
847 		if (tp->t_rawq.c_cc > TTYHOG) {
848 			if (tp->t_outq.c_cc < TTHIWAT(tp) &&
849 			    tp->t_line == NTTYDISC)
850 				(void) ttyoutput(CTRL(g), tp);
851 		} else if (putc(c, &tp->t_rawq) >= 0) {
852 			ttwakeup(tp);
853 			ttyecho(c, tp);
854 		}
855 		goto endcase;
856 	}
857 
858 	/*
859 	 * From here on down cooked mode character
860 	 * processing takes place.
861 	 */
862 	if ((tp->t_state&TS_QUOT) &&
863 	    (c == tp->t_erase || c == tp->t_kill)) {
864 		ttyrub(unputc(&tp->t_rawq), tp);
865 		c |= 0200;
866 	}
867 	if (c == tp->t_erase) {
868 		if (tp->t_rawq.c_cc)
869 			ttyrub(unputc(&tp->t_rawq), tp);
870 		goto endcase;
871 	}
872 	if (c == tp->t_kill) {
873 		if (t_flags&CRTKIL &&
874 		    tp->t_rawq.c_cc == tp->t_rocount) {
875 			while (tp->t_rawq.c_cc)
876 				ttyrub(unputc(&tp->t_rawq), tp);
877 		} else {
878 			ttyecho(c, tp);
879 			ttyecho('\n', tp);
880 			while (getc(&tp->t_rawq) > 0)
881 				;
882 			tp->t_rocount = 0;
883 		}
884 		tp->t_state &= ~TS_LOCAL;
885 		goto endcase;
886 	}
887 
888 	/*
889 	 * New line discipline,
890 	 * check word erase/reprint line.
891 	 */
892 	if (tp->t_line == NTTYDISC) {
893 		if (c == tp->t_werasc) {
894 			if (tp->t_rawq.c_cc == 0)
895 				goto endcase;
896 			do {
897 				c = unputc(&tp->t_rawq);
898 				if (c != ' ' && c != '\t')
899 					goto erasenb;
900 				ttyrub(c, tp);
901 			} while (tp->t_rawq.c_cc);
902 			goto endcase;
903 	erasenb:
904 			do {
905 				ttyrub(c, tp);
906 				if (tp->t_rawq.c_cc == 0)
907 					goto endcase;
908 				c = unputc(&tp->t_rawq);
909 			} while (c != ' ' && c != '\t');
910 			(void) putc(c, &tp->t_rawq);
911 			goto endcase;
912 		}
913 		if (c == tp->t_rprntc) {
914 			ttyretype(tp);
915 			goto endcase;
916 		}
917 	}
918 
919 	/*
920 	 * Check for input buffer overflow
921 	 */
922 	if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
923 		if (tp->t_line == NTTYDISC)
924 			(void) ttyoutput(CTRL(g), tp);
925 		goto endcase;
926 	}
927 
928 	/*
929 	 * Put data char in q for user and
930 	 * wakeup on seeing a line delimiter.
931 	 */
932 	if (putc(c, &tp->t_rawq) >= 0) {
933 		if (ttbreakc(c, tp)) {
934 			tp->t_rocount = 0;
935 			catq(&tp->t_rawq, &tp->t_canq);
936 			ttwakeup(tp);
937 		} else if (tp->t_rocount++ == 0)
938 			tp->t_rocol = tp->t_col;
939 		tp->t_state &= ~TS_QUOT;
940 		if (c == '\\')
941 			tp->t_state |= TS_QUOT;
942 		if (tp->t_state&TS_ERASE) {
943 			tp->t_state &= ~TS_ERASE;
944 			(void) ttyoutput('/', tp);
945 		}
946 		i = tp->t_col;
947 		ttyecho(c, tp);
948 		if (c == tp->t_eofc && t_flags&ECHO) {
949 			i = MIN(2, tp->t_col - i);
950 			while (i > 0) {
951 				(void) ttyoutput('\b', tp);
952 				i--;
953 			}
954 		}
955 	}
956 endcase:
957 	/*
958 	 * If DEC-style start/stop is enabled don't restart
959 	 * output until seeing the start character.
960 	 */
961 	if (t_flags&DECCTQ && tp->t_state&TS_TTSTOP &&
962 	    tp->t_startc != tp->t_stopc)
963 		return;
964 restartoutput:
965 	tp->t_state &= ~TS_TTSTOP;
966 	tp->t_flags &= ~FLUSHO;
967 startoutput:
968 	ttstart(tp);
969 }
970 
971 /*
972  * Put character on TTY output queue, adding delays,
973  * expanding tabs, and handling the CR/NL bit.
974  * This is called both from the top half for output,
975  * and from interrupt level for echoing.
976  * The arguments are the character and the tty structure.
977  * Returns < 0 if putc succeeds, otherwise returns char to resend
978  * Must be recursive.
979  */
980 ttyoutput(c, tp)
981 	register c;
982 	register struct tty *tp;
983 {
984 	register char *colp;
985 	register ctype;
986 
987 	if (tp->t_flags & (RAW|LITOUT)) {
988 		if (tp->t_flags&FLUSHO)
989 			return (-1);
990 		if (putc(c, &tp->t_outq))
991 			return (c);
992 		tk_nout++;
993 		return (-1);
994 	}
995 
996 	/*
997 	 * Ignore EOT in normal mode to avoid
998 	 * hanging up certain terminals.
999 	 */
1000 	c &= 0177;
1001 	if (c == CEOT && (tp->t_flags&CBREAK) == 0)
1002 		return (-1);
1003 	/*
1004 	 * Turn tabs to spaces as required
1005 	 */
1006 	if (c == '\t' && (tp->t_flags&TBDELAY) == XTABS) {
1007 		register int s;
1008 
1009 		c = 8 - (tp->t_col&7);
1010 		if ((tp->t_flags&FLUSHO) == 0) {
1011 			s = spltty();		/* don't interrupt tabs */
1012 			c -= b_to_q("        ", c, &tp->t_outq);
1013 			tk_nout += c;
1014 			splx(s);
1015 		}
1016 		tp->t_col += c;
1017 		return (c ? -1 : '\t');
1018 	}
1019 	tk_nout++;
1020 	/*
1021 	 * for upper-case-only terminals,
1022 	 * generate escapes.
1023 	 */
1024 	if (tp->t_flags&LCASE) {
1025 		colp = "({)}!|^~'`";
1026 		while (*colp++)
1027 			if (c == *colp++) {
1028 				if (ttyoutput('\\', tp) >= 0)
1029 					return (c);
1030 				c = colp[-2];
1031 				break;
1032 			}
1033 		if ('A' <= c && c <= 'Z') {
1034 			if (ttyoutput('\\', tp) >= 0)
1035 				return (c);
1036 		} else if ('a' <= c && c <= 'z')
1037 			c += 'A' - 'a';
1038 	}
1039 
1040 	/*
1041 	 * turn <nl> to <cr><lf> if desired.
1042 	 */
1043 	if (c == '\n' && tp->t_flags&CRMOD)
1044 		if (ttyoutput('\r', tp) >= 0)
1045 			return (c);
1046 	if (c == '~' && tp->t_flags&TILDE)
1047 		c = '`';
1048 	if ((tp->t_flags&FLUSHO) == 0 && putc(c, &tp->t_outq))
1049 		return (c);
1050 	/*
1051 	 * Calculate delays.
1052 	 * The numbers here represent clock ticks
1053 	 * and are not necessarily optimal for all terminals.
1054 	 * The delays are indicated by characters above 0200.
1055 	 * In raw mode there are no delays and the
1056 	 * transmission path is 8 bits wide.
1057 	 *
1058 	 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS
1059 	 */
1060 	colp = &tp->t_col;
1061 	ctype = partab[c];
1062 	c = 0;
1063 	switch (ctype&077) {
1064 
1065 	case ORDINARY:
1066 		(*colp)++;
1067 
1068 	case CONTROL:
1069 		break;
1070 
1071 	case BACKSPACE:
1072 		if (*colp)
1073 			(*colp)--;
1074 		break;
1075 
1076 	/*
1077 	 * This macro is close enough to the correct thing;
1078 	 * it should be replaced by real user settable delays
1079 	 * in any event...
1080 	 */
1081 #define	mstohz(ms)	(((ms) * hz) >> 10)
1082 	case NEWLINE:
1083 		ctype = (tp->t_flags >> 8) & 03;
1084 		if (ctype == 1) { /* tty 37 */
1085 			if (*colp > 0) {
1086 				c = (((unsigned)*colp) >> 4) + 3;
1087 				if ((unsigned)c > 6)
1088 					c = 6;
1089 			}
1090 		} else if (ctype == 2) /* vt05 */
1091 			c = mstohz(100);
1092 		*colp = 0;
1093 		break;
1094 
1095 	case TAB:
1096 		ctype = (tp->t_flags >> 10) & 03;
1097 		if (ctype == 1) { /* tty 37 */
1098 			c = 1 - (*colp | ~07);
1099 			if (c < 5)
1100 				c = 0;
1101 		}
1102 		*colp |= 07;
1103 		(*colp)++;
1104 		break;
1105 
1106 	case VTAB:
1107 		if (tp->t_flags&VTDELAY) /* tty 37 */
1108 			c = 0177;
1109 		break;
1110 
1111 	case RETURN:
1112 		ctype = (tp->t_flags >> 12) & 03;
1113 		if (ctype == 1) /* tn 300 */
1114 			c = mstohz(83);
1115 		else if (ctype == 2) /* ti 700 */
1116 			c = mstohz(166);
1117 		else if (ctype == 3) { /* concept 100 */
1118 			int i;
1119 
1120 			if ((i = *colp) >= 0)
1121 				for (; i < 9; i++)
1122 					(void) putc(0177, &tp->t_outq);
1123 		}
1124 		*colp = 0;
1125 	}
1126 	if (c && (tp->t_flags&FLUSHO) == 0)
1127 		(void) putc(c|0200, &tp->t_outq);
1128 	return (-1);
1129 }
1130 #undef mstohz
1131 
1132 /*
1133  * Called from device's read routine after it has
1134  * calculated the tty-structure given as argument.
1135  */
1136 ttread(tp, uio)
1137 	register struct tty *tp;
1138 	struct uio *uio;
1139 {
1140 	register struct clist *qp;
1141 	register c, t_flags;
1142 	int s, first, error = 0;
1143 
1144 loop:
1145 	/*
1146 	 * Take any pending input first.
1147 	 */
1148 	s = spltty();
1149 	if (tp->t_flags&PENDIN)
1150 		ttypend(tp);
1151 	splx(s);
1152 
1153 	if ((tp->t_state&TS_CARR_ON)==0)
1154 		return (EIO);
1155 
1156 	/*
1157 	 * Hang process if it's in the background.
1158 	 */
1159 	if (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) {
1160 		if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) ||
1161 		   (u.u_procp->p_sigmask & sigmask(SIGTTIN)) ||
1162 		    u.u_procp->p_flag&SVFORK)
1163 			return (EIO);
1164 		gsignal(u.u_procp->p_pgrp, SIGTTIN);
1165 		sleep((caddr_t)&lbolt, TTIPRI);
1166 		goto loop;
1167 	}
1168 	t_flags = tp->t_flags;
1169 
1170 	/*
1171 	 * In raw mode take characters directly from the
1172 	 * raw queue w/o processing.  Interlock against
1173 	 * device interrupts when interrogating rawq.
1174 	 */
1175 	if (t_flags&RAW) {
1176 		s = spltty();
1177 		if (tp->t_rawq.c_cc <= 0) {
1178 			if ((tp->t_state&TS_CARR_ON) == 0 ||
1179 			    (tp->t_state&TS_NBIO)) {
1180 				splx(s);
1181 				return (EWOULDBLOCK);
1182 			}
1183 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
1184 			splx(s);
1185 			goto loop;
1186 		}
1187 		splx(s);
1188  		while (!error && tp->t_rawq.c_cc && uio->uio_resid)
1189  			error = ureadc(getc(&tp->t_rawq), uio);
1190 		goto checktandem;
1191 	}
1192 
1193 	/*
1194 	 * In cbreak mode use the rawq, otherwise
1195 	 * take characters from the canonicalized q.
1196 	 */
1197 	qp = t_flags&CBREAK ? &tp->t_rawq : &tp->t_canq;
1198 
1199 	/*
1200 	 * No input, sleep on rawq awaiting hardware
1201 	 * receipt and notification.
1202 	 */
1203 	s = spltty();
1204 	if (qp->c_cc <= 0) {
1205 		if ((tp->t_state&TS_CARR_ON) == 0 ||
1206 		    (tp->t_state&TS_NBIO)) {
1207 			splx(s);
1208 			return (EWOULDBLOCK);
1209 		}
1210 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
1211 		splx(s);
1212 		goto loop;
1213 	}
1214 	splx(s);
1215 
1216 	/*
1217 	 * Input present, perform input mapping
1218 	 * and processing (we're not in raw mode).
1219 	 */
1220 	first = 1;
1221 	while ((c = getc(qp)) >= 0) {
1222 		if (t_flags&CRMOD && c == '\r')
1223 			c = '\n';
1224 		/*
1225 		 * Check for delayed suspend character.
1226 		 */
1227 		if (tp->t_line == NTTYDISC && c == tp->t_dsuspc) {
1228 			gsignal(tp->t_pgrp, SIGTSTP);
1229 			if (first) {
1230 				sleep((caddr_t)&lbolt, TTIPRI);
1231 				goto loop;
1232 			}
1233 			break;
1234 		}
1235 		/*
1236 		 * Interpret EOF only in cooked mode.
1237 		 */
1238 		if (c == tp->t_eofc && (t_flags&CBREAK) == 0)
1239 			break;
1240 		/*
1241 		 * Give user character.
1242 		 */
1243  		error = ureadc(t_flags&PASS8 ? c : c & 0177, uio);
1244 		if (error)
1245 			break;
1246  		if (uio->uio_resid == 0)
1247 			break;
1248 		/*
1249 		 * In cooked mode check for a "break character"
1250 		 * marking the end of a "line of input".
1251 		 */
1252 		if ((t_flags&CBREAK) == 0 && ttbreakc(c, tp))
1253 			break;
1254 		first = 0;
1255 	}
1256 
1257 checktandem:
1258 	/*
1259 	 * Look to unblock output now that (presumably)
1260 	 * the input queue has gone down.
1261 	 */
1262 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5)
1263 		if (putc(tp->t_startc, &tp->t_outq) == 0) {
1264 			tp->t_state &= ~TS_TBLOCK;
1265 			ttstart(tp);
1266 		}
1267 	return (error);
1268 }
1269 
1270 /*
1271  * Check the output queue on tp for space for a kernel message
1272  * (from uprintf/tprintf).  Allow some space over the normal
1273  * hiwater mark so we don't lose messages due to normal flow
1274  * control, but don't let the tty run amok.
1275  * Sleeps here are not interruptible, but we return prematurely
1276  * if new signals come in.
1277  */
1278 ttycheckoutq(tp, wait)
1279 	register struct tty *tp;
1280 	int wait;
1281 {
1282 	int hiwat, s, oldsig;
1283 
1284 	hiwat = TTHIWAT(tp);
1285 	s = spltty();
1286 	oldsig = u.u_procp->p_sig;
1287 	if (tp->t_outq.c_cc > hiwat + 200)
1288 		while (tp->t_outq.c_cc > hiwat) {
1289 			ttstart(tp);
1290 			if (wait == 0 || u.u_procp->p_sig != oldsig) {
1291 				splx(s);
1292 				return (0);
1293 			}
1294 			timeout(wakeup, (caddr_t)&tp->t_outq, hz);
1295 			tp->t_state |= TS_ASLEEP;
1296 			sleep((caddr_t)&tp->t_outq, PZERO - 1);
1297 		}
1298 	splx(s);
1299 	return (1);
1300 }
1301 
1302 /*
1303  * Called from the device's write routine after it has
1304  * calculated the tty-structure given as argument.
1305  */
1306 ttwrite(tp, uio)
1307 	register struct tty *tp;
1308 	register struct uio *uio;
1309 {
1310 	register char *cp;
1311 	register int cc, ce, c;
1312 	int i, hiwat, cnt, error, s;
1313 	char obuf[OBUFSIZ];
1314 
1315 	hiwat = TTHIWAT(tp);
1316 	cnt = uio->uio_resid;
1317 	error = 0;
1318 loop:
1319 	if ((tp->t_state&TS_CARR_ON) == 0)
1320 		return (EIO);
1321 	/*
1322 	 * Hang the process if it's in the background.
1323 	 */
1324 	if (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
1325 	    (tp->t_flags&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
1326 	    !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) &&
1327 	    !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) {
1328 		gsignal(u.u_procp->p_pgrp, SIGTTOU);
1329 		sleep((caddr_t)&lbolt, TTIPRI);
1330 		goto loop;
1331 	}
1332 
1333 	/*
1334 	 * Process the user's data in at most OBUFSIZ
1335 	 * chunks.  Perform lower case simulation and
1336 	 * similar hacks.  Keep track of high water
1337 	 * mark, sleep on overflow awaiting device aid
1338 	 * in acquiring new space.
1339 	 */
1340 	while (uio->uio_resid > 0) {
1341 		/*
1342 		 * Grab a hunk of data from the user.
1343 		 */
1344 		cc = uio->uio_iov->iov_len;
1345 		if (cc == 0) {
1346 			uio->uio_iovcnt--;
1347 			uio->uio_iov++;
1348 			if (uio->uio_iovcnt <= 0)
1349 				panic("ttwrite");
1350 			continue;
1351 		}
1352 		if (cc > OBUFSIZ)
1353 			cc = OBUFSIZ;
1354 		cp = obuf;
1355 		error = uiomove(cp, cc, UIO_WRITE, uio);
1356 		if (error)
1357 			break;
1358 		if (tp->t_outq.c_cc > hiwat)
1359 			goto ovhiwat;
1360 		if (tp->t_flags&FLUSHO)
1361 			continue;
1362 		/*
1363 		 * If we're mapping lower case or kludging tildes,
1364 		 * then we've got to look at each character, so
1365 		 * just feed the stuff to ttyoutput...
1366 		 */
1367 		if (tp->t_flags & (LCASE|TILDE)) {
1368 			while (cc > 0) {
1369 				c = *cp++;
1370 				tp->t_rocount = 0;
1371 				while ((c = ttyoutput(c, tp)) >= 0) {
1372 					/* out of clists, wait a bit */
1373 					ttstart(tp);
1374 					sleep((caddr_t)&lbolt, TTOPRI);
1375 					tp->t_rocount = 0;
1376 					if (cc != 0) {
1377 						uio->uio_iov->iov_base -= cc;
1378 						uio->uio_iov->iov_len += cc;
1379 						uio->uio_resid += cc;
1380 						uio->uio_offset -= cc;
1381 					}
1382 					goto loop;
1383 				}
1384 				--cc;
1385 				if (tp->t_outq.c_cc > hiwat)
1386 					goto ovhiwat;
1387 			}
1388 			continue;
1389 		}
1390 		/*
1391 		 * If nothing fancy need be done, grab those characters we
1392 		 * can handle without any of ttyoutput's processing and
1393 		 * just transfer them to the output q.  For those chars
1394 		 * which require special processing (as indicated by the
1395 		 * bits in partab), call ttyoutput.  After processing
1396 		 * a hunk of data, look for FLUSHO so ^O's will take effect
1397 		 * immediately.
1398 		 */
1399 		while (cc > 0) {
1400 			if (tp->t_flags & (RAW|LITOUT))
1401 				ce = cc;
1402 			else {
1403 				ce = cc - scanc((unsigned)cc, (caddr_t)cp,
1404 				   (caddr_t)partab, 077);
1405 				/*
1406 				 * If ce is zero, then we're processing
1407 				 * a special character through ttyoutput.
1408 				 */
1409 				if (ce == 0) {
1410 					tp->t_rocount = 0;
1411 					if (ttyoutput(*cp, tp) >= 0) {
1412 					    /* no c-lists, wait a bit */
1413 					    ttstart(tp);
1414 					    sleep((caddr_t)&lbolt, TTOPRI);
1415 					    if (cc != 0) {
1416 					        uio->uio_iov->iov_base -= cc;
1417 					        uio->uio_iov->iov_len += cc;
1418 					        uio->uio_resid += cc;
1419 						uio->uio_offset -= cc;
1420 					    }
1421 					    goto loop;
1422 					}
1423 					cp++, cc--;
1424 					if (tp->t_flags&FLUSHO ||
1425 					    tp->t_outq.c_cc > hiwat)
1426 						goto ovhiwat;
1427 					continue;
1428 				}
1429 			}
1430 			/*
1431 			 * A bunch of normal characters have been found,
1432 			 * transfer them en masse to the output queue and
1433 			 * continue processing at the top of the loop.
1434 			 * If there are any further characters in this
1435 			 * <= OBUFSIZ chunk, the first should be a character
1436 			 * requiring special handling by ttyoutput.
1437 			 */
1438 			tp->t_rocount = 0;
1439 			i = b_to_q(cp, ce, &tp->t_outq);
1440 			ce -= i;
1441 			tp->t_col += ce;
1442 			cp += ce, cc -= ce, tk_nout += ce;
1443 			if (i > 0) {
1444 				/* out of c-lists, wait a bit */
1445 				ttstart(tp);
1446 				sleep((caddr_t)&lbolt, TTOPRI);
1447 				uio->uio_iov->iov_base -= cc;
1448 				uio->uio_iov->iov_len += cc;
1449 				uio->uio_resid += cc;
1450 				uio->uio_offset -= cc;
1451 				goto loop;
1452 			}
1453 			if (tp->t_flags&FLUSHO || tp->t_outq.c_cc > hiwat)
1454 				goto ovhiwat;
1455 		}
1456 	}
1457 	ttstart(tp);
1458 	return (error);
1459 
1460 ovhiwat:
1461 	s = spltty();
1462 	if (cc != 0) {
1463 		uio->uio_iov->iov_base -= cc;
1464 		uio->uio_iov->iov_len += cc;
1465 		uio->uio_resid += cc;
1466 		uio->uio_offset -= cc;
1467 	}
1468 	/*
1469 	 * This can only occur if FLUSHO
1470 	 * is also set in t_flags.
1471 	 */
1472 	if (tp->t_outq.c_cc <= hiwat) {
1473 		splx(s);
1474 		goto loop;
1475 	}
1476 	ttstart(tp);
1477 	if (tp->t_state&TS_NBIO) {
1478 		splx(s);
1479 		if (uio->uio_resid == cnt)
1480 			return (EWOULDBLOCK);
1481 		return (0);
1482 	}
1483 	tp->t_state |= TS_ASLEEP;
1484 	sleep((caddr_t)&tp->t_outq, TTOPRI);
1485 	splx(s);
1486 	goto loop;
1487 }
1488 
1489 /*
1490  * Rubout one character from the rawq of tp
1491  * as cleanly as possible.
1492  */
1493 ttyrub(c, tp)
1494 	register c;
1495 	register struct tty *tp;
1496 {
1497 	register char *cp;
1498 	register int savecol;
1499 	int s;
1500 	char *nextc();
1501 
1502 	if ((tp->t_flags&ECHO) == 0)
1503 		return;
1504 	tp->t_flags &= ~FLUSHO;
1505 	c &= 0377;
1506 	if (tp->t_flags&CRTBS) {
1507 		if (tp->t_rocount == 0) {
1508 			/*
1509 			 * Screwed by ttwrite; retype
1510 			 */
1511 			ttyretype(tp);
1512 			return;
1513 		}
1514 		if (c == ('\t'|0200) || c == ('\n'|0200))
1515 			ttyrubo(tp, 2);
1516 		else switch (partab[c&=0177]&0177) {
1517 
1518 		case ORDINARY:
1519 			if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z')
1520 				ttyrubo(tp, 2);
1521 			else
1522 				ttyrubo(tp, 1);
1523 			break;
1524 
1525 		case VTAB:
1526 		case BACKSPACE:
1527 		case CONTROL:
1528 		case RETURN:
1529 			if (tp->t_flags&CTLECH)
1530 				ttyrubo(tp, 2);
1531 			break;
1532 
1533 		case TAB:
1534 			if (tp->t_rocount < tp->t_rawq.c_cc) {
1535 				ttyretype(tp);
1536 				return;
1537 			}
1538 			s = spltty();
1539 			savecol = tp->t_col;
1540 			tp->t_state |= TS_CNTTB;
1541 			tp->t_flags |= FLUSHO;
1542 			tp->t_col = tp->t_rocol;
1543 			cp = tp->t_rawq.c_cf;
1544 			for (; cp; cp = nextc(&tp->t_rawq, cp))
1545 				ttyecho(*cp, tp);
1546 			tp->t_flags &= ~FLUSHO;
1547 			tp->t_state &= ~TS_CNTTB;
1548 			splx(s);
1549 			/*
1550 			 * savecol will now be length of the tab
1551 			 */
1552 			savecol -= tp->t_col;
1553 			tp->t_col += savecol;
1554 			if (savecol > 8)
1555 				savecol = 8;		/* overflow screw */
1556 			while (--savecol >= 0)
1557 				(void) ttyoutput('\b', tp);
1558 			break;
1559 
1560 		default:
1561 			panic("ttyrub");
1562 		}
1563 	} else if (tp->t_flags&PRTERA) {
1564 		if ((tp->t_state&TS_ERASE) == 0) {
1565 			(void) ttyoutput('\\', tp);
1566 			tp->t_state |= TS_ERASE;
1567 		}
1568 		ttyecho(c, tp);
1569 	} else
1570 		ttyecho(tp->t_erase, tp);
1571 	tp->t_rocount--;
1572 }
1573 
1574 /*
1575  * Crt back over cnt chars perhaps
1576  * erasing them.
1577  */
1578 ttyrubo(tp, cnt)
1579 	register struct tty *tp;
1580 	int cnt;
1581 {
1582 	register char *rubostring = tp->t_flags&CRTERA ? "\b \b" : "\b";
1583 
1584 	while (--cnt >= 0)
1585 		ttyout(rubostring, tp);
1586 }
1587 
1588 /*
1589  * Reprint the rawq line.
1590  * We assume c_cc has already been checked.
1591  */
1592 ttyretype(tp)
1593 	register struct tty *tp;
1594 {
1595 	register char *cp;
1596 	char *nextc();
1597 	int s;
1598 
1599 	if (tp->t_rprntc != 0377)
1600 		ttyecho(tp->t_rprntc, tp);
1601 	(void) ttyoutput('\n', tp);
1602 	s = spltty();
1603 	for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp))
1604 		ttyecho(*cp, tp);
1605 	for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1606 		ttyecho(*cp, tp);
1607 	tp->t_state &= ~TS_ERASE;
1608 	splx(s);
1609 	tp->t_rocount = tp->t_rawq.c_cc;
1610 	tp->t_rocol = 0;
1611 }
1612 
1613 /*
1614  * Echo a typed character to the terminal
1615  */
1616 ttyecho(c, tp)
1617 	register c;
1618 	register struct tty *tp;
1619 {
1620 
1621 	if ((tp->t_state&TS_CNTTB) == 0)
1622 		tp->t_flags &= ~FLUSHO;
1623 	if ((tp->t_flags&ECHO) == 0)
1624 		return;
1625 	c &= 0377;
1626 	if (tp->t_flags&RAW) {
1627 		(void) ttyoutput(c, tp);
1628 		return;
1629 	}
1630 	if (c == '\r' && tp->t_flags&CRMOD)
1631 		c = '\n';
1632 	if (tp->t_flags&CTLECH) {
1633 		if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) {
1634 			(void) ttyoutput('^', tp);
1635 			c &= 0177;
1636 			if (c == 0177)
1637 				c = '?';
1638 			else if (tp->t_flags&LCASE)
1639 				c += 'a' - 1;
1640 			else
1641 				c += 'A' - 1;
1642 		}
1643 	}
1644 	(void) ttyoutput(c&0177, tp);
1645 }
1646 
1647 /*
1648  * Is c a break char for tp?
1649  */
1650 ttbreakc(c, tp)
1651 	register c;
1652 	register struct tty *tp;
1653 {
1654 	return (c == '\n' || c == tp->t_eofc || c == tp->t_brkc ||
1655 		c == '\r' && (tp->t_flags&CRMOD));
1656 }
1657 
1658 /*
1659  * send string cp to tp
1660  */
1661 ttyout(cp, tp)
1662 	register char *cp;
1663 	register struct tty *tp;
1664 {
1665 	register char c;
1666 
1667 	while (c = *cp++)
1668 		(void) ttyoutput(c, tp);
1669 }
1670 
1671 ttwakeup(tp)
1672 	struct tty *tp;
1673 {
1674 
1675 	if (tp->t_rsel) {
1676 		selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1677 		tp->t_state &= ~TS_RCOLL;
1678 		tp->t_rsel = 0;
1679 	}
1680 	if (tp->t_state & TS_ASYNC)
1681 		gsignal(tp->t_pgrp, SIGIO);
1682 	wakeup((caddr_t)&tp->t_rawq);
1683 }
1684