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