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