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