xref: /csrg-svn/sys/kern/tty.c (revision 37584)
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.16 (Berkeley) 05/01/89
7  */
8 
9 #include "param.h"
10 #include "systm.h"
11 #include "dir.h"
12 #include "user.h"
13 #include "ioctl.h"
14 #include "tty.h"
15 #define TTYDEFCHARS
16 #include "ttydefaults.h"
17 #undef TTYDEFCHARS
18 #include "termios.h"
19 #include "proc.h"
20 #include "file.h"
21 #include "conf.h"
22 #include "dkstat.h"
23 #include "uio.h"
24 #include "kernel.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 	register struct proc *pp;
573 
574 	tp->t_dev = dev;
575 
576 	tp->t_state &= ~TS_WOPEN;
577 	if ((tp->t_state & TS_ISOPEN) == 0) {
578 		tp->t_state |= TS_ISOPEN;
579 		bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize));
580 	}
581 	return (0);
582 }
583 
584 /*
585  * "close" a line discipline
586  */
587 ttylclose(tp)
588 	register struct tty *tp;
589 {
590 
591 	ttywflush(tp);
592 }
593 
594 /*
595  * clean tp on last close
596  */
597 ttyclose(tp)
598 	register struct tty *tp;
599 {
600 	if (constty == tp)
601 		constty = NULL;
602 	ttyflush(tp, FREAD|FWRITE);
603 	tp->t_pgid = 0;
604 	tp->t_state = 0;
605 }
606 
607 /*
608  * Handle modem control transition on a tty.
609  * Flag indicates new state of carrier.
610  * Returns 0 if the line should be turned off, otherwise 1.
611  */
612 ttymodem(tp, flag)
613 	register struct tty *tp;
614 {
615 
616 	if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag & MDMBUF)) {
617 		/*
618 		 * MDMBUF: do flow control according to carrier flag
619 		 */
620 		if (flag) {
621 			tp->t_state &= ~TS_TTSTOP;
622 			ttstart(tp);
623 		} else if ((tp->t_state&TS_TTSTOP) == 0) {
624 			tp->t_state |= TS_TTSTOP;
625 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
626 		}
627 	} else if (flag == 0) {
628 		/*
629 		 * Lost carrier.
630 		 */
631 		tp->t_state &= ~TS_CARR_ON;
632 		if (tp->t_state & TS_ISOPEN) {
633 			if ((tp->t_lflag & NOHANG) == 0) {
634 				gsignal(tp->t_pgid, SIGHUP);
635 				gsignal(tp->t_pgid, SIGCONT);
636 				ttyflush(tp, FREAD|FWRITE);
637 				return (0);
638 			}
639 		}
640 	} else {
641 		/*
642 		 * Carrier now on.
643 		 */
644 		tp->t_state |= TS_CARR_ON;
645 		ttwakeup(tp);
646 	}
647 	return (1);
648 }
649 
650 /*
651  * Default modem control routine (for other line disciplines).
652  * Return argument flag, to turn off device on carrier drop.
653  */
654 nullmodem(tp, flag)
655 	register struct tty *tp;
656 	int flag;
657 {
658 
659 	if (flag)
660 		tp->t_state |= TS_CARR_ON;
661 	else
662 		tp->t_state &= ~TS_CARR_ON;
663 	return (flag);
664 }
665 
666 /*
667  * reinput pending characters after state switch
668  * call at spltty().
669  */
670 ttypend(tp)
671 	register struct tty *tp;
672 {
673 	struct clist tq;
674 	register c;
675 
676 	tp->t_lflag &= ~PENDIN;
677 	tp->t_state |= TS_TYPEN;
678 	tq = tp->t_rawq;
679 	tp->t_rawq.c_cc = 0;
680 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
681 	while ((c = getc(&tq)) >= 0)
682 		ttyinput(c, tp);
683 	tp->t_state &= ~TS_TYPEN;
684 }
685 
686 /*
687  *
688  * Place a character on raw TTY input queue,
689  * putting in delimiters and waking up top
690  * half as needed.  Also echo if required.
691  * The arguments are the character and the
692  * appropriate tty structure.
693  */
694 ttyinput(c, tp)
695 	register c;
696 	register struct tty *tp;
697 {
698 	register int iflag = tp->t_iflag;
699 	register int lflag = tp->t_lflag;
700 	register u_char *cc = tp->t_cc;
701 	int i, err;
702 
703 	/*
704 	 * If input is pending take it first.
705 	 */
706 	if (lflag&PENDIN)
707 		ttypend(tp);
708 	/*
709 	 * Gather stats.
710 	 */
711 	tk_nin++;
712 	if (lflag&ICANON) {
713 		tk_cancc++;
714 		tp->t_cancc++;
715 	} else {
716 		tk_rawcc++;
717 		tp->t_rawcc++;
718 	}
719 	/*
720 	 * Handle exceptional conditions (break, parity, framing).
721 	 */
722 	if (err = (c&TTY_ERRORMASK)) {
723 		c &= ~TTY_ERRORMASK;
724 		if (err&TTY_FE && !c) {		/* break */
725 			if (iflag&IGNBRK)
726 				goto endcase;
727 			else if (iflag&BRKINT && lflag&ISIG &&
728 				(cc[VINTR] != _POSIX_VDISABLE))
729 				c = cc[VINTR];
730 			else {
731 				c = 0;
732 				if (iflag&PARMRK)
733 					goto parmrk;
734 			}
735 		} else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) {
736 			if (iflag&IGNPAR)
737 				goto endcase;
738 			else if (iflag&PARMRK) {
739 parmrk:
740 				putc(0377|TTY_QUOTE, &tp->t_rawq);
741 				putc(0|TTY_QUOTE, &tp->t_rawq);
742 				putc(c|TTY_QUOTE, &tp->t_rawq);
743 				goto endcase;
744 			} else
745 				c = 0;
746 		}
747 	}
748 	/*
749 	 * In tandem mode, check high water mark.
750 	 */
751 	if (iflag&IXOFF)
752 		ttyblock(tp);
753 	if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP))
754 		c &= 0177;
755 	/*
756 	 * Check for literal nexting very first
757 	 */
758 	if (tp->t_state&TS_LNCH) {
759 		c |= TTY_QUOTE;
760 		tp->t_state &= ~TS_LNCH;
761 	}
762 	/*
763 	 * Scan for special characters.  This code
764 	 * is really just a big case statement with
765 	 * non-constant cases.  The bottom of the
766 	 * case statement is labeled ``endcase'', so goto
767 	 * it after a case match, or similar.
768 	 */
769 	/*
770 	 * Control chars which aren't controlled
771 	 * by ICANON, ISIG, or IXON.
772 	 */
773 	if (iflag&IEXTEN) {
774 		if (CCEQ(cc[VLNEXT],c)) {
775 			if (lflag&ECHO) {
776 				if (lflag&ECHOE)
777 					ttyout("^\b", tp);
778 				else
779 					ttyecho(c, tp);
780 			}
781 			tp->t_state |= TS_LNCH;
782 			goto endcase;
783 		}
784 		if (CCEQ(cc[VFLUSHO],c)) {
785 			if (lflag&FLUSHO)
786 				tp->t_lflag &= ~FLUSHO;
787 			else {
788 				ttyflush(tp, FWRITE);
789 				ttyecho(c, tp);
790 				if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
791 					ttyretype(tp);
792 				tp->t_lflag |= FLUSHO;
793 			}
794 			goto startoutput;
795 		}
796 	}
797 	/*
798 	 * Signals.
799 	 */
800 	if (lflag&ISIG) {
801 		if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
802 			if ((lflag&NOFLSH) == 0)
803 				ttyflush(tp, FREAD|FWRITE);
804 			ttyecho(c, tp);
805 			gsignal(tp->t_pgid, CCEQ(cc[VINTR],c) ?
806 				SIGINT : SIGQUIT);
807 			goto endcase;
808 		}
809 		if (CCEQ(cc[VSUSP],c)) {
810 			if ((lflag&NOFLSH) == 0)
811 				ttyflush(tp, FREAD);
812 			ttyecho(c, tp);
813 			gsignal(tp->t_pgid, SIGTSTP);
814 			goto endcase;
815 		}
816 	}
817 	/*
818 	 * Handle start/stop characters.
819 	 */
820 	if (iflag&IXON) {
821 		if (CCEQ(cc[VSTOP],c)) {
822 			if ((tp->t_state&TS_TTSTOP) == 0) {
823 				tp->t_state |= TS_TTSTOP;
824 				(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
825 				return;
826 			}
827 			if (!CCEQ(cc[VSTART], c))
828 				return;
829 			/*
830 			 * if VSTART == VSTOP then toggle
831 			 */
832 			goto endcase;
833 		}
834 		if (CCEQ(cc[VSTART], c))
835 			goto restartoutput;
836 	}
837 	/*
838 	 * IGNCR, ICRNL, & INLCR
839 	 */
840 	if (c == '\r') {
841 		if (iflag&IGNCR)
842 			goto endcase;
843 		else if (iflag&ICRNL)
844 			c = '\n';
845 	}
846 	else if (c == '\n' && iflag&INLCR)
847 		c = '\r';
848 	/*
849 	 * Non canonical mode; don't process line editing
850 	 * characters; check high water mark for wakeup.
851 	 *
852 	 */
853 	if (!(lflag&ICANON)) {
854 		if (tp->t_rawq.c_cc > TTYHOG) {
855 			if (iflag&IMAXBEL) {
856 				if (tp->t_outq.c_cc < tp->t_hiwat)
857 					(void) ttyoutput(CTRL('g'), tp);
858 			} else
859 				ttyflush(tp, FREAD | FWRITE);
860 		} else {
861 			if (putc(c, &tp->t_rawq) >= 0) {
862 				ttwakeup(tp);
863 				ttyecho(c, tp);
864 			}
865 		}
866 		goto endcase;
867 	}
868 	/*
869 	 * From here on down canonical mode character
870 	 * processing takes place.
871 	 */
872 	/*
873 	 * erase (^H / ^?)
874 	 */
875 	if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c)) {
876 		if (tp->t_rawq.c_cc)
877 			ttyrub(unputc(&tp->t_rawq), tp);
878 		goto endcase;
879 	}
880 	/*
881 	 * kill (^U)
882 	 */
883 	if (CCEQ(cc[VKILL], c)) {
884 		if (lflag&ECHOKE && tp->t_rawq.c_cc == tp->t_rocount &&
885 		    !(lflag&ECHOPRT)) {
886 			while (tp->t_rawq.c_cc)
887 				ttyrub(unputc(&tp->t_rawq), tp);
888 		} else {
889 			ttyecho(c, tp);
890 			if (lflag&ECHOK || lflag&ECHOKE)
891 				ttyecho('\n', tp);
892 			while (getc(&tp->t_rawq) > 0)
893 				;
894 			tp->t_rocount = 0;
895 		}
896 		tp->t_state &= ~TS_LOCAL;
897 		goto endcase;
898 	}
899 	/*
900 	 * word erase (^W)
901 	 */
902 	if (CCEQ(cc[VWERASE], c)) {
903 		int ctype;
904 
905 #define CTYPE(c) ((lflag&ALTWERASE) ? (partab[(c)&TTY_CHARMASK]&0100) : 0)
906 		/*
907 		 * erase whitespace
908 		 */
909 		while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
910 			ttyrub(c, tp);
911 		if (c == -1)
912 			goto endcase;
913 		/*
914 		 * special case last char of token
915 		 */
916 		ttyrub(c, tp);
917 		c = unputc(&tp->t_rawq);
918 		if (c == -1 || c == ' ' || c == '\t') {
919 			if (c != -1)
920 				(void) putc(c, &tp->t_rawq);
921 			goto endcase;
922 		}
923 		/*
924 		 * erase rest of token
925 		 */
926 		ctype = CTYPE(c);
927 		do {
928 			ttyrub(c, tp);
929 			c = unputc(&tp->t_rawq);
930 			if (c == -1)
931 				goto endcase;
932 		} while (c != ' ' && c != '\t' && CTYPE(c) == ctype);
933 		(void) putc(c, &tp->t_rawq);
934 		goto endcase;
935 #undef CTYPE
936 	}
937 	/*
938 	 * reprint line (^R)
939 	 */
940 	if (CCEQ(cc[VREPRINT], c)) {
941 		ttyretype(tp);
942 		goto endcase;
943 	}
944 	/*
945 	 * Check for input buffer overflow
946 	 */
947 	if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
948 		if (iflag&IMAXBEL) {
949 			if (tp->t_outq.c_cc < tp->t_hiwat)
950 				(void) ttyoutput(CTRL('g'), tp);
951 		} else
952 			ttyflush(tp, FREAD | FWRITE);
953 		goto endcase;
954 	}
955 	/*
956 	 * Put data char in q for user and
957 	 * wakeup on seeing a line delimiter.
958 	 */
959 	if (putc(c, &tp->t_rawq) >= 0) {
960 		if (ttbreakc(c)) {
961 			tp->t_rocount = 0;
962 			catq(&tp->t_rawq, &tp->t_canq);
963 			ttwakeup(tp);
964 		} else if (tp->t_rocount++ == 0)
965 			tp->t_rocol = tp->t_col;
966 		if (tp->t_state&TS_ERASE) {
967 			/*
968 			 * end of prterase \.../
969 			 */
970 			tp->t_state &= ~TS_ERASE;
971 			(void) ttyoutput('/', tp);
972 		}
973 		i = tp->t_col;
974 		ttyecho(c, tp);
975 		if (CCEQ(cc[VEOF], c) && lflag&ECHO) {
976 			/*
977 			 * Place the cursor over the '^' of the ^D.
978 			 */
979 			i = MIN(2, tp->t_col - i);
980 			while (i > 0) {
981 				(void) ttyoutput('\b', tp);
982 				i--;
983 			}
984 		}
985 	}
986 endcase:
987 	/*
988 	 * IXANY means allow any character to restart output.
989 	 */
990 	if ((tp->t_state&TS_TTSTOP) && !(iflag&IXANY)
991 	    && cc[VSTART] != cc[VSTOP])
992 		return;
993 restartoutput:
994 	tp->t_state &= ~TS_TTSTOP;
995 	tp->t_lflag &= ~FLUSHO;
996 startoutput:
997 	ttstart(tp);
998 }
999 
1000 /*
1001  * Put character on TTY output queue, adding delays,
1002  * expanding tabs, and handling the CR/NL bit.
1003  * This is called both from the top half for output,
1004  * and from interrupt level for echoing.
1005  * The arguments are the character and the tty structure.
1006  * Returns < 0 if putc succeeds, otherwise returns char to resend
1007  * Must be recursive.
1008  */
1009 ttyoutput(c, tp)
1010 	register c;
1011 	register struct tty *tp;
1012 {
1013 	register char *colp;
1014 	register ctype;
1015 	register long oflag = tp->t_oflag;
1016 
1017 	if (!(oflag&OPOST)) {
1018 		if (tp->t_lflag&FLUSHO)
1019 			return (-1);
1020 		if (putc(c, &tp->t_outq))
1021 			return (c);
1022 		tk_nout++;
1023 		tp->t_outcc++;
1024 		return (-1);
1025 	}
1026 	c &= TTY_CHARMASK;
1027 	/*
1028 	 * Turn tabs to spaces as required
1029 	 */
1030 	if (c == '\t' && oflag&OXTABS ) {
1031 		register int s;
1032 
1033 		c = 8 - (tp->t_col&7);
1034 		if ((tp->t_lflag&FLUSHO) == 0) {
1035 			s = spltty();		/* don't interrupt tabs */
1036 			c -= b_to_q("        ", c, &tp->t_outq);
1037 			tk_nout += c;
1038 			tp->t_outcc += c;
1039 			splx(s);
1040 		}
1041 		tp->t_col += c;
1042 		return (c ? -1 : '\t');
1043 	}
1044 	if (c == CEOT && oflag&ONOEOT)
1045 		return(-1);
1046 	tk_nout++;
1047 	tp->t_outcc++;
1048 	/*
1049 	 * turn <nl> to <cr><lf> if desired.
1050 	 */
1051 	if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0)
1052 		return (c);
1053 	if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_outq))
1054 		return (c);
1055 	/*
1056 	 * Calculate delays.
1057 	 * The numbers here represent clock ticks
1058 	 * and are not necessarily optimal for all terminals.
1059 	 *
1060 	 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS
1061 	 *
1062 	 * (actually, should THROW AWAY terminals which need delays)
1063 	 */
1064 	colp = &tp->t_col;
1065 	ctype = partab[c];
1066 	c = 0;
1067 	switch (ctype&077) {
1068 
1069 	case ORDINARY:
1070 		(*colp)++;
1071 
1072 	case CONTROL:
1073 		break;
1074 
1075 	case BACKSPACE:
1076 		if (*colp)
1077 			(*colp)--;
1078 		break;
1079 
1080 	/*
1081 	 * This macro is close enough to the correct thing;
1082 	 * it should be replaced by real user settable delays
1083 	 * in any event...
1084 	 */
1085 #define	mstohz(ms)	(((ms) * hz) >> 10)
1086 	case NEWLINE:
1087 		ctype = (tp->t_flags >> 8) & 03;
1088 		if (ctype == 1) { /* tty 37 */
1089 			if (*colp > 0) {
1090 				c = (((unsigned)*colp) >> 4) + 3;
1091 				if ((unsigned)c > 6)
1092 					c = 6;
1093 			}
1094 		} else if (ctype == 2) /* vt05 */
1095 			c = mstohz(100);
1096 		*colp = 0;
1097 		break;
1098 
1099 	case TAB:
1100 		ctype = (tp->t_flags >> 10) & 03;
1101 		if (ctype == 1) { /* tty 37 */
1102 			c = 1 - (*colp | ~07);
1103 			if (c < 5)
1104 				c = 0;
1105 		}
1106 		*colp |= 07;
1107 		(*colp)++;
1108 		break;
1109 
1110 	case VTAB:
1111 		if (tp->t_flags&VTDELAY) /* tty 37 */
1112 			c = 0177;
1113 		break;
1114 
1115 	case RETURN:
1116 		ctype = (tp->t_flags >> 12) & 03;
1117 		if (ctype == 1) /* tn 300 */
1118 			c = mstohz(83);
1119 		else if (ctype == 2) /* ti 700 */
1120 			c = mstohz(166);
1121 		else if (ctype == 3) { /* concept 100 */
1122 			int i;
1123 
1124 			if ((i = *colp) >= 0)
1125 				for (; i < 9; i++)
1126 					(void) putc(0177, &tp->t_outq);
1127 		}
1128 		*colp = 0;
1129 	}
1130 	if (c && (tp->t_lflag&FLUSHO) == 0)
1131 		(void) putc(c|TTY_QUOTE, &tp->t_outq);
1132 	return (-1);
1133 }
1134 #undef mstohz
1135 
1136 /*
1137  * Called from device's read routine after it has
1138  * calculated the tty-structure given as argument.
1139  */
1140 ttread(tp, uio, flag)
1141 	register struct tty *tp;
1142 	struct uio *uio;
1143 {
1144 	register struct clist *qp;
1145 	register int c;
1146 	register long lflag = tp->t_lflag;
1147 	register long iflag = tp->t_iflag;
1148 	register u_char *cc = tp->t_cc;
1149 	int s, first, error = 0;
1150 
1151 loop:
1152 	s = spltty();
1153 	/*
1154 	 * take pending input first
1155 	 */
1156 	if (lflag&PENDIN)
1157 		ttypend(tp);
1158 	/*
1159 	 * Handle carrier.
1160 	 */
1161 	if (!(tp->t_state&TS_CARR_ON) && !(tp->t_cflag&CLOCAL)) {
1162 		if (tp->t_state&TS_ISOPEN) {
1163 			splx(s);
1164 			return (0);	/* EOF */
1165 		} else if (flag&FNDELAY) {
1166 			splx(s);
1167 			return (EWOULDBLOCK);
1168 		} else {
1169 			/*
1170 			 * sleep awaiting carrier
1171 			 */
1172 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
1173 			splx(s);
1174 			goto loop;
1175 		}
1176 	}
1177 	splx(s);
1178 	/*
1179 	 * Hang process if it's in the background.
1180 	 */
1181 	if (u.u_ttyp == tp && u.u_procp->p_pgid != tp->t_pgid) {
1182 		if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) ||
1183 		   (u.u_procp->p_sigmask & sigmask(SIGTTIN)) ||
1184 		    u.u_procp->p_flag&SVFORK || u.u_procp->p_pgrp->pg_jobc == 0)
1185 			return (EIO);
1186 		pgsignal(u.u_procp->p_pgrp, SIGTTIN);
1187 		sleep((caddr_t)&lbolt, TTIPRI);
1188 		goto loop;
1189 	}
1190 	/*
1191 	 * If canonical, use the canonical queue,
1192 	 * else use the raw queue.
1193 	 *
1194 	 * XXX - should get rid of canonical queue.
1195 	 * (actually, should get rid of clists...)
1196 	 */
1197 	qp = lflag&ICANON ? &tp->t_canq : &tp->t_rawq;
1198 	/*
1199 	 * No input, sleep on rawq awaiting hardware
1200 	 * receipt and notification.
1201 	 */
1202 	s = spltty();
1203 	if (qp->c_cc <= 0) {
1204 		/** XXX ??? ask mike why TS_CARR_ON was (once) necessary here
1205 		if ((tp->t_state&TS_CARR_ON) == 0 ||
1206 		    (tp->t_state&TS_NBIO)) {
1207 			splx(s);
1208 			return (EWOULDBLOCK);
1209 		}
1210 		**/
1211 		if (flag&FNDELAY) {
1212 			splx(s);
1213 			return (EWOULDBLOCK);
1214 		}
1215 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
1216 		splx(s);
1217 		goto loop;
1218 	}
1219 	splx(s);
1220 	/*
1221 	 * Input present, check for input mapping and processing.
1222 	 */
1223 	first = 1;
1224 	while ((c = getc(qp)) >= 0) {
1225 		/*
1226 		 * delayed suspend (^Y)
1227 		 */
1228 		if (CCEQ(cc[VDSUSP], c) && lflag&ISIG) {
1229 			gsignal(tp->t_pgid, SIGTSTP);
1230 			if (first) {
1231 				sleep((caddr_t)&lbolt, TTIPRI);
1232 				goto loop;
1233 			}
1234 			break;
1235 		}
1236 		/*
1237 		 * Interpret EOF only in canonical mode.
1238 		 */
1239 		if (CCEQ(cc[VEOF], c) && lflag&ICANON)
1240 			break;
1241 		/*
1242 		 * Give user character.
1243 		 */
1244  		error = ureadc(c , uio);
1245 		if (error)
1246 			break;
1247  		if (uio->uio_resid == 0)
1248 			break;
1249 		/*
1250 		 * In canonical mode check for a "break character"
1251 		 * marking the end of a "line of input".
1252 		 */
1253 		if (lflag&ICANON && ttbreakc(c)) {
1254 			break;
1255 		}
1256 		first = 0;
1257 	}
1258 checktandem:
1259 	/*
1260 	 * Look to unblock output now that (presumably)
1261 	 * the input queue has gone down.
1262 	 */
1263 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
1264 		if (cc[VSTART] != _POSIX_VDISABLE
1265 		   && putc(cc[VSTART], &tp->t_outq) == 0) {
1266 			tp->t_state &= ~TS_TBLOCK;
1267 			ttstart(tp);
1268 		}
1269 	}
1270 	return (error);
1271 }
1272 
1273 /*
1274  * Check the output queue on tp for space for a kernel message
1275  * (from uprintf/tprintf).  Allow some space over the normal
1276  * hiwater mark so we don't lose messages due to normal flow
1277  * control, but don't let the tty run amok.
1278  * Sleeps here are not interruptible, but we return prematurely
1279  * if new signals come in.
1280  */
1281 ttycheckoutq(tp, wait)
1282 	register struct tty *tp;
1283 	int wait;
1284 {
1285 	int hiwat, s, oldsig;
1286 
1287 	hiwat = tp->t_hiwat;
1288 	s = spltty();
1289 	oldsig = u.u_procp->p_sig;
1290 	if (tp->t_outq.c_cc > hiwat + 200)
1291 		while (tp->t_outq.c_cc > hiwat) {
1292 			ttstart(tp);
1293 			if (wait == 0 || u.u_procp->p_sig != oldsig) {
1294 				splx(s);
1295 				return (0);
1296 			}
1297 			timeout(wakeup, (caddr_t)&tp->t_outq, hz);
1298 			tp->t_state |= TS_ASLEEP;
1299 			sleep((caddr_t)&tp->t_outq, PZERO - 1);
1300 		}
1301 	splx(s);
1302 	return (1);
1303 }
1304 
1305 /*
1306  * Called from the device's write routine after it has
1307  * calculated the tty-structure given as argument.
1308  */
1309 ttwrite(tp, uio, flag)
1310 	register struct tty *tp;
1311 	register struct uio *uio;
1312 {
1313 	register char *cp;
1314 	register int cc, ce, c;
1315 	int i, hiwat, cnt, error, s;
1316 	char obuf[OBUFSIZ];
1317 
1318 	hiwat = tp->t_hiwat;
1319 	cnt = uio->uio_resid;
1320 	error = 0;
1321 loop:
1322 	s = spltty();
1323 	if (!(tp->t_state&TS_CARR_ON) && !(tp->t_cflag&CLOCAL)) {
1324 		if (tp->t_state&TS_ISOPEN) {
1325 			splx(s);
1326 			return (EIO);
1327 		} else if (flag&FNDELAY) {
1328 			splx(s);
1329 			return (EWOULDBLOCK);
1330 		} else {
1331 			/*
1332 			 * sleep awaiting carrier
1333 			 */
1334 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
1335 			splx(s);
1336 			goto loop;
1337 		}
1338 	}
1339 	splx(s);
1340 	/*
1341 	 * Hang the process if it's in the background.
1342 	 */
1343 	if (u.u_ttyp == tp &&
1344 	    u.u_procp->p_pgid != tp->t_pgid &&
1345 	    (tp->t_lflag&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
1346 	    !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) &&
1347 	    !(u.u_procp->p_sigmask & sigmask(SIGTTOU)) &&
1348 	     u.u_procp->p_pgrp->pg_jobc) {
1349 		pgsignal(u.u_procp->p_pgrp, SIGTTOU);
1350 		sleep((caddr_t)&lbolt, TTIPRI);
1351 		goto loop;
1352 	}
1353 	/*
1354 	 * Process the user's data in at most OBUFSIZ
1355 	 * chunks.  Perform lower case simulation and
1356 	 * similar hacks.  Keep track of high water
1357 	 * mark, sleep on overflow awaiting device aid
1358 	 * in acquiring new space.
1359 	 */
1360 	while (uio->uio_resid > 0) {
1361 		if (tp->t_outq.c_cc > hiwat) {
1362 			cc = 0;
1363 			goto ovhiwat;
1364 		}
1365 		/*
1366 		 * Grab a hunk of data from the user.
1367 		 */
1368 		cc = uio->uio_iov->iov_len;
1369 		if (cc == 0) {
1370 			uio->uio_iovcnt--;
1371 			uio->uio_iov++;
1372 			if (uio->uio_iovcnt <= 0)
1373 				panic("ttwrite");
1374 			continue;
1375 		}
1376 		if (cc > OBUFSIZ)
1377 			cc = OBUFSIZ;
1378 		cp = obuf;
1379 		error = uiomove(cp, cc, UIO_WRITE, uio);
1380 		if (error)
1381 			break;
1382 		if (tp->t_lflag&FLUSHO)
1383 			continue;
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_oflag&OPOST))
1395 				ce = cc;
1396 			else {
1397 				ce = cc - scanc((unsigned)cc, (u_char *)cp,
1398 				   (u_char *)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_lflag&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 			tp->t_outcc += ce;
1438 			if (i > 0) {
1439 				/* out of c-lists, wait a bit */
1440 				ttstart(tp);
1441 				sleep((caddr_t)&lbolt, TTOPRI);
1442 				uio->uio_iov->iov_base -= cc;
1443 				uio->uio_iov->iov_len += cc;
1444 				uio->uio_resid += cc;
1445 				uio->uio_offset -= cc;
1446 				goto loop;
1447 			}
1448 			if (tp->t_lflag&FLUSHO || tp->t_outq.c_cc > hiwat)
1449 				goto ovhiwat;
1450 		}
1451 		ttstart(tp);
1452 	}
1453 	return (error);
1454 ovhiwat:
1455 	if (cc != 0) {
1456 		uio->uio_iov->iov_base -= cc;
1457 		uio->uio_iov->iov_len += cc;
1458 		uio->uio_resid += cc;
1459 		uio->uio_offset -= cc;
1460 	}
1461 	ttstart(tp);
1462 	s = spltty();
1463 	/*
1464 	 * This can only occur if FLUSHO is set in t_lflag,
1465 	 * or if ttstart/oproc is synchronous (or very fast).
1466 	 */
1467 	if (tp->t_outq.c_cc <= hiwat) {
1468 		splx(s);
1469 		goto loop;
1470 	}
1471 	if (flag&FNDELAY) {
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_lflag&ECHO) == 0)
1497 		return;
1498 	tp->t_lflag &= ~FLUSHO;
1499 	if (tp->t_lflag&ECHOE) {
1500 		if (tp->t_rocount == 0) {
1501 			/*
1502 			 * Screwed by ttwrite; retype
1503 			 */
1504 			ttyretype(tp);
1505 			return;
1506 		}
1507 		if (c == ('\t'|TTY_QUOTE) || c == ('\n'|TTY_QUOTE))
1508 			ttyrubo(tp, 2);
1509 		else switch (partab[c&=0377]&077) {
1510 
1511 		case ORDINARY:
1512 			ttyrubo(tp, 1);
1513 			break;
1514 
1515 		case VTAB:
1516 		case BACKSPACE:
1517 		case CONTROL:
1518 		case RETURN:
1519 			if (tp->t_lflag&ECHOCTL)
1520 				ttyrubo(tp, 2);
1521 			break;
1522 
1523 		case TAB: {
1524 			int c;
1525 
1526 			if (tp->t_rocount < tp->t_rawq.c_cc) {
1527 				ttyretype(tp);
1528 				return;
1529 			}
1530 			s = spltty();
1531 			savecol = tp->t_col;
1532 			tp->t_state |= TS_CNTTB;
1533 			tp->t_lflag |= FLUSHO;
1534 			tp->t_col = tp->t_rocol;
1535 			cp = tp->t_rawq.c_cf;
1536 			c = *cp;	/* XXX FIX NEXTC */
1537 			for (; cp; cp = nextc(&tp->t_rawq, cp, &c))
1538 				ttyecho(c, tp);
1539 			tp->t_lflag &= ~FLUSHO;
1540 			tp->t_state &= ~TS_CNTTB;
1541 			splx(s);
1542 			/*
1543 			 * savecol will now be length of the tab
1544 			 */
1545 			savecol -= tp->t_col;
1546 			tp->t_col += savecol;
1547 			if (savecol > 8)
1548 				savecol = 8;		/* overflow screw */
1549 			while (--savecol >= 0)
1550 				(void) ttyoutput('\b', tp);
1551 			break;
1552 		}
1553 
1554 		default:
1555 			/* XXX */
1556 			printf("ttyrub: would panic c = %d, val = %d\n",
1557 				c, partab[c&=0377]&077);
1558 			/*panic("ttyrub");*/
1559 		}
1560 	} else if (tp->t_lflag&ECHOPRT) {
1561 		if ((tp->t_state&TS_ERASE) == 0) {
1562 			(void) ttyoutput('\\', tp);
1563 			tp->t_state |= TS_ERASE;
1564 		}
1565 		ttyecho(c, tp);
1566 	} else
1567 		ttyecho(tp->t_cc[VERASE], tp);
1568 	tp->t_rocount--;
1569 }
1570 
1571 /*
1572  * Crt back over cnt chars perhaps
1573  * erasing them.
1574  */
1575 ttyrubo(tp, cnt)
1576 	register struct tty *tp;
1577 	int cnt;
1578 {
1579 
1580 	while (--cnt >= 0)
1581 		ttyout("\b \b", tp);
1582 }
1583 
1584 /*
1585  * Reprint the rawq line.
1586  * We assume c_cc has already been checked.
1587  */
1588 ttyretype(tp)
1589 	register struct tty *tp;
1590 {
1591 	register char *cp;
1592 	char *nextc();
1593 	int s, c;
1594 
1595 	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
1596 		ttyecho(tp->t_cc[VREPRINT], tp);
1597 	(void) ttyoutput('\n', tp);
1598 	s = spltty();
1599 	/*** XXX *** FIX *** NEXTC IS BROKEN - DOESN'T CHECK QUOTE
1600 	  BIT OF FIRST CHAR ****/
1601 	for (cp = tp->t_canq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_canq, cp, &c)) {
1602 		ttyecho(c, tp);
1603 	}
1604 	for (cp = tp->t_rawq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_rawq, cp, &c)) {
1605 		ttyecho(c, tp);
1606 	}
1607 	tp->t_state &= ~TS_ERASE;
1608 	splx(s);
1609 	tp->t_rocount = tp->t_rawq.c_cc;
1610 	tp->t_rocol = 0;
1611 }
1612 
1613 /*
1614  * Echo a typed character to the terminal.
1615  */
1616 ttyecho(c, tp)
1617 	register c;
1618 	register struct tty *tp;
1619 {
1620 	if ((tp->t_state&TS_CNTTB) == 0)
1621 		tp->t_lflag &= ~FLUSHO;
1622 	if ((tp->t_lflag&ECHO) == 0 && !(tp->t_lflag&ECHONL && c == '\n'))
1623 		return;
1624 	if (tp->t_lflag&ECHOCTL) {
1625 		if ((c&TTY_CHARMASK)<=037 && c!='\t' && c!='\n' || c==0177) {
1626 			(void) ttyoutput('^', tp);
1627 			c &= TTY_CHARMASK;
1628 			if (c == 0177)
1629 				c = '?';
1630 			else
1631 				c += 'A' - 1;
1632 		}
1633 	}
1634 	(void) ttyoutput(c, tp);
1635 }
1636 
1637 /*
1638  * send string cp to tp
1639  */
1640 ttyout(cp, tp)
1641 	register char *cp;
1642 	register struct tty *tp;
1643 {
1644 	register char c;
1645 
1646 	while (c = *cp++)
1647 		(void) ttyoutput(c, tp);
1648 }
1649 
1650 ttwakeup(tp)
1651 	struct tty *tp;
1652 {
1653 
1654 	if (tp->t_rsel) {
1655 		selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1656 		tp->t_state &= ~TS_RCOLL;
1657 		tp->t_rsel = 0;
1658 	}
1659 	if (tp->t_state & TS_ASYNC)
1660 		gsignal(tp->t_pgid, SIGIO);
1661 	wakeup((caddr_t)&tp->t_rawq);
1662 }
1663 
1664 /*
1665  * set tty hi and low water marks
1666  *
1667  * Try to arrange the dynamics so there's about one second
1668  * from hi to low water.
1669  *
1670  */
1671 ttsetwater(tp)
1672 	struct tty *tp;
1673 {
1674 	register cps = tp->t_ospeed / 10;
1675 	register x;
1676 
1677 #define clamp(x, h, l) ((x)>h ? h : ((x)<l) ? l : (x))
1678 	tp->t_lowat = x = clamp(cps/2, TTMAXLOWAT, TTMINLOWAT);
1679 	x += cps;
1680 	x = clamp(x, TTMAXHIWAT, TTMINHIWAT);
1681 	tp->t_hiwat = roundup(x, CBSIZE);
1682 #undef clamp
1683 }
1684 
1685 ttspeedtab(speed, table)
1686 	struct speedtab table[];
1687 {
1688 	register int i;
1689 
1690 	for (i = 0; table[i].sp_speed != -1; i++)
1691 		if (table[i].sp_speed == speed)
1692 			return(table[i].sp_code);
1693 	return(-1);
1694 }
1695