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