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