Home | History | Annotate | Line # | Download | only in kern
tty.c revision 1.63
      1 /*	$NetBSD: tty.c,v 1.63 1995/10/10 01:26:57 mycroft Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1982, 1986, 1990, 1991, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  * (c) UNIX System Laboratories, Inc.
      7  * All or some portions of this file are derived from material licensed
      8  * to the University of California by American Telephone and Telegraph
      9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
     10  * the permission of UNIX System Laboratories, Inc.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  * 3. All advertising materials mentioning features or use of this software
     21  *    must display the following acknowledgement:
     22  *	This product includes software developed by the University of
     23  *	California, Berkeley and its contributors.
     24  * 4. Neither the name of the University nor the names of its contributors
     25  *    may be used to endorse or promote products derived from this software
     26  *    without specific prior written permission.
     27  *
     28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     38  * SUCH DAMAGE.
     39  *
     40  *	@(#)tty.c	8.8 (Berkeley) 1/21/94
     41  */
     42 
     43 #include <sys/param.h>
     44 #include <sys/systm.h>
     45 #include <sys/ioctl.h>
     46 #include <sys/proc.h>
     47 #define	TTYDEFCHARS
     48 #include <sys/tty.h>
     49 #undef	TTYDEFCHARS
     50 #include <sys/file.h>
     51 #include <sys/conf.h>
     52 #include <sys/dkstat.h>
     53 #include <sys/uio.h>
     54 #include <sys/kernel.h>
     55 #include <sys/vnode.h>
     56 #include <sys/syslog.h>
     57 #include <sys/malloc.h>
     58 
     59 #include <vm/vm.h>
     60 
     61 static int	proc_compare __P((struct proc *p1, struct proc *p2));
     62 static int	ttnread __P((struct tty *));
     63 static void	ttyblock __P((struct tty *tp));
     64 static void	ttyecho __P((int, struct tty *tp));
     65 static void	ttyrubo __P((struct tty *, int));
     66 
     67 /* Symbolic sleep message strings. */
     68 char ttclos[]	= "ttycls";
     69 char ttopen[]	= "ttyopn";
     70 char ttybg[]	= "ttybg";
     71 #ifdef REAL_CLISTS
     72 char ttybuf[]	= "ttybuf";
     73 #endif
     74 char ttyin[]	= "ttyin";
     75 char ttyout[]	= "ttyout";
     76 
     77 /*
     78  * Table with character classes and parity. The 8th bit indicates parity,
     79  * the 7th bit indicates the character is an alphameric or underscore (for
     80  * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
     81  * are 0 then the character needs no special processing on output; classes
     82  * other than 0 might be translated or (not currently) require delays.
     83  */
     84 #define	E	0x00	/* Even parity. */
     85 #define	O	0x80	/* Odd parity. */
     86 #define	PARITY(c)	(char_type[c] & O)
     87 
     88 #define	ALPHA	0x40	/* Alpha or underscore. */
     89 #define	ISALPHA(c)	(char_type[(c) & TTY_CHARMASK] & ALPHA)
     90 
     91 #define	CCLASSMASK	0x3f
     92 #define	CCLASS(c)	(char_type[c] & CCLASSMASK)
     93 
     94 #define	BS	BACKSPACE
     95 #define	CC	CONTROL
     96 #define	CR	RETURN
     97 #define	NA	ORDINARY | ALPHA
     98 #define	NL	NEWLINE
     99 #define	NO	ORDINARY
    100 #define	TB	TAB
    101 #define	VT	VTAB
    102 
    103 char const char_type[] = {
    104 	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC,	/* nul - bel */
    105 	O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
    106 	O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
    107 	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
    108 	O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
    109 	E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
    110 	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
    111 	O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
    112 	O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
    113 	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
    114 	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
    115 	O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
    116 	E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
    117 	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
    118 	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
    119 	E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
    120 	/*
    121 	 * Meta chars; should be settable per character set;
    122 	 * for now, treat them all as normal characters.
    123 	 */
    124 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    125 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    126 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    127 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    128 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    129 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    130 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    131 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    132 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    133 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    134 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    135 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    136 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    137 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    138 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    139 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
    140 };
    141 #undef	BS
    142 #undef	CC
    143 #undef	CR
    144 #undef	NA
    145 #undef	NL
    146 #undef	NO
    147 #undef	TB
    148 #undef	VT
    149 
    150 /* Macros to clear/set/test flags. */
    151 #define	SET(t, f)	(t) |= (f)
    152 #define	CLR(t, f)	(t) &= ~(f)
    153 #define	ISSET(t, f)	((t) & (f))
    154 
    155 /*
    156  * Initial open of tty, or (re)entry to standard tty line discipline.
    157  */
    158 int
    159 ttyopen(device, tp)
    160 	dev_t device;
    161 	register struct tty *tp;
    162 {
    163 	int s;
    164 
    165 	s = spltty();
    166 	tp->t_dev = device;
    167 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
    168 		SET(tp->t_state, TS_ISOPEN);
    169 		bzero(&tp->t_winsize, sizeof(tp->t_winsize));
    170 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_SVR4) || \
    171     defined(COMPAT_FREEBSD)
    172 		tp->t_flags = 0;
    173 #endif
    174 	}
    175 	CLR(tp->t_state, TS_WOPEN);
    176 	splx(s);
    177 	return (0);
    178 }
    179 
    180 /*
    181  * Handle close() on a tty line: flush and set to initial state,
    182  * bumping generation number so that pending read/write calls
    183  * can detect recycling of the tty.
    184  */
    185 int
    186 ttyclose(tp)
    187 	register struct tty *tp;
    188 {
    189 	extern struct tty *constty;	/* Temporary virtual console. */
    190 
    191 	if (constty == tp)
    192 		constty = NULL;
    193 
    194 	ttyflush(tp, FREAD | FWRITE);
    195 
    196 	tp->t_gen++;
    197 	tp->t_pgrp = NULL;
    198 	tp->t_session = NULL;
    199 	tp->t_state = 0;
    200 	return (0);
    201 }
    202 
    203 #define	FLUSHQ(q) {							\
    204 	if ((q)->c_cc)							\
    205 		ndflush(q, (q)->c_cc);					\
    206 }
    207 
    208 /* Is 'c' a line delimiter ("break" character)? */
    209 #define	TTBREAKC(c)							\
    210 	((c) == '\n' || ((c) == cc[VEOF] ||				\
    211 	(c) == cc[VEOL] || (c) == cc[VEOL2]) && (c) != _POSIX_VDISABLE)
    212 
    213 
    214 /*
    215  * Process input of a single character received on a tty.
    216  */
    217 int
    218 ttyinput(c, tp)
    219 	register int c;
    220 	register struct tty *tp;
    221 {
    222 	register int iflag, lflag;
    223 	register u_char *cc;
    224 	int i, err;
    225 
    226 	/*
    227 	 * If input is pending take it first.
    228 	 */
    229 	lflag = tp->t_lflag;
    230 	if (ISSET(lflag, PENDIN))
    231 		ttypend(tp);
    232 	/*
    233 	 * Gather stats.
    234 	 */
    235 	if (ISSET(lflag, ICANON)) {
    236 		++tk_cancc;
    237 		++tp->t_cancc;
    238 	} else {
    239 		++tk_rawcc;
    240 		++tp->t_rawcc;
    241 	}
    242 	++tk_nin;
    243 
    244 	/* Handle exceptional conditions (break, parity, framing). */
    245 	cc = tp->t_cc;
    246 	iflag = tp->t_iflag;
    247 	if (err = (ISSET(c, TTY_ERRORMASK))) {
    248 		CLR(c, TTY_ERRORMASK);
    249 		if (ISSET(err, TTY_FE) && !c) {	/* Break. */
    250 			if (ISSET(iflag, IGNBRK))
    251 				goto endcase;
    252 			else if (ISSET(iflag, BRKINT) &&
    253 			    ISSET(lflag, ISIG) &&
    254 			    (cc[VINTR] != _POSIX_VDISABLE))
    255 				c = cc[VINTR];
    256 			else if (ISSET(iflag, PARMRK))
    257 				goto parmrk;
    258 		} else if (ISSET(err, TTY_PE) &&
    259 		    ISSET(iflag, INPCK) || ISSET(err, TTY_FE)) {
    260 			if (ISSET(iflag, IGNPAR))
    261 				goto endcase;
    262 			else if (ISSET(iflag, PARMRK)) {
    263 parmrk:				(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
    264 				(void)putc(0 | TTY_QUOTE, &tp->t_rawq);
    265 				(void)putc(c | TTY_QUOTE, &tp->t_rawq);
    266 				goto endcase;
    267 			} else
    268 				c = 0;
    269 		}
    270 	}
    271 	/*
    272 	 * In tandem mode, check high water mark.
    273 	 */
    274 	if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW))
    275 		ttyblock(tp);
    276 	if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
    277 		CLR(c, 0x80);
    278 	if (!ISSET(lflag, EXTPROC)) {
    279 		/*
    280 		 * Check for literal nexting very first
    281 		 */
    282 		if (ISSET(tp->t_state, TS_LNCH)) {
    283 			SET(c, TTY_QUOTE);
    284 			CLR(tp->t_state, TS_LNCH);
    285 		}
    286 		/*
    287 		 * Scan for special characters.  This code
    288 		 * is really just a big case statement with
    289 		 * non-constant cases.  The bottom of the
    290 		 * case statement is labeled ``endcase'', so goto
    291 		 * it after a case match, or similar.
    292 		 */
    293 
    294 		/*
    295 		 * Control chars which aren't controlled
    296 		 * by ICANON, ISIG, or IXON.
    297 		 */
    298 		if (ISSET(lflag, IEXTEN)) {
    299 			if (CCEQ(cc[VLNEXT], c)) {
    300 				if (ISSET(lflag, ECHO)) {
    301 					if (ISSET(lflag, ECHOE)) {
    302 						(void)ttyoutput('^', tp);
    303 						(void)ttyoutput('\b', tp);
    304 					} else
    305 						ttyecho(c, tp);
    306 				}
    307 				SET(tp->t_state, TS_LNCH);
    308 				goto endcase;
    309 			}
    310 			if (CCEQ(cc[VDISCARD], c)) {
    311 				if (ISSET(lflag, FLUSHO))
    312 					CLR(tp->t_lflag, FLUSHO);
    313 				else {
    314 					ttyflush(tp, FWRITE);
    315 					ttyecho(c, tp);
    316 					if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
    317 						ttyretype(tp);
    318 					SET(tp->t_lflag, FLUSHO);
    319 				}
    320 				goto startoutput;
    321 			}
    322 		}
    323 		/*
    324 		 * Signals.
    325 		 */
    326 		if (ISSET(lflag, ISIG)) {
    327 			if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
    328 				if (!ISSET(lflag, NOFLSH))
    329 					ttyflush(tp, FREAD | FWRITE);
    330 				ttyecho(c, tp);
    331 				pgsignal(tp->t_pgrp,
    332 				    CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
    333 				goto endcase;
    334 			}
    335 			if (CCEQ(cc[VSUSP], c)) {
    336 				if (!ISSET(lflag, NOFLSH))
    337 					ttyflush(tp, FREAD);
    338 				ttyecho(c, tp);
    339 				pgsignal(tp->t_pgrp, SIGTSTP, 1);
    340 				goto endcase;
    341 			}
    342 		}
    343 		/*
    344 		 * Handle start/stop characters.
    345 		 */
    346 		if (ISSET(iflag, IXON)) {
    347 			if (CCEQ(cc[VSTOP], c)) {
    348 				if (!ISSET(tp->t_state, TS_TTSTOP)) {
    349 					SET(tp->t_state, TS_TTSTOP);
    350 					(*cdevsw[major(tp->t_dev)].d_stop)(tp,
    351 					   0);
    352 					return (0);
    353 				}
    354 				if (!CCEQ(cc[VSTART], c))
    355 					return (0);
    356 				/*
    357 				 * if VSTART == VSTOP then toggle
    358 				 */
    359 				goto endcase;
    360 			}
    361 			if (CCEQ(cc[VSTART], c))
    362 				goto restartoutput;
    363 		}
    364 		/*
    365 		 * IGNCR, ICRNL, & INLCR
    366 		 */
    367 		if (c == '\r') {
    368 			if (ISSET(iflag, IGNCR))
    369 				goto endcase;
    370 			else if (ISSET(iflag, ICRNL))
    371 				c = '\n';
    372 		} else if (c == '\n' && ISSET(iflag, INLCR))
    373 			c = '\r';
    374 	}
    375 	if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
    376 		/*
    377 		 * From here on down canonical mode character
    378 		 * processing takes place.
    379 		 */
    380 		/*
    381 		 * erase (^H / ^?)
    382 		 */
    383 		if (CCEQ(cc[VERASE], c)) {
    384 			if (tp->t_rawq.c_cc)
    385 				ttyrub(unputc(&tp->t_rawq), tp);
    386 			goto endcase;
    387 		}
    388 		/*
    389 		 * kill (^U)
    390 		 */
    391 		if (CCEQ(cc[VKILL], c)) {
    392 			if (ISSET(lflag, ECHOKE) &&
    393 			    tp->t_rawq.c_cc == tp->t_rocount &&
    394 			    !ISSET(lflag, ECHOPRT))
    395 				while (tp->t_rawq.c_cc)
    396 					ttyrub(unputc(&tp->t_rawq), tp);
    397 			else {
    398 				ttyecho(c, tp);
    399 				if (ISSET(lflag, ECHOK) ||
    400 				    ISSET(lflag, ECHOKE))
    401 					ttyecho('\n', tp);
    402 				FLUSHQ(&tp->t_rawq);
    403 				tp->t_rocount = 0;
    404 			}
    405 			CLR(tp->t_state, TS_LOCAL);
    406 			goto endcase;
    407 		}
    408 		/*
    409 		 * word erase (^W)
    410 		 */
    411 		if (CCEQ(cc[VWERASE], c)) {
    412 			int alt = ISSET(lflag, ALTWERASE);
    413 			int ctype;
    414 
    415 			/*
    416 			 * erase whitespace
    417 			 */
    418 			while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
    419 				ttyrub(c, tp);
    420 			if (c == -1)
    421 				goto endcase;
    422 			/*
    423 			 * erase last char of word and remember the
    424 			 * next chars type (for ALTWERASE)
    425 			 */
    426 			ttyrub(c, tp);
    427 			c = unputc(&tp->t_rawq);
    428 			if (c == -1)
    429 				goto endcase;
    430 			if (c == ' ' || c == '\t') {
    431 				(void)putc(c, &tp->t_rawq);
    432 				goto endcase;
    433 			}
    434 			ctype = ISALPHA(c);
    435 			/*
    436 			 * erase rest of word
    437 			 */
    438 			do {
    439 				ttyrub(c, tp);
    440 				c = unputc(&tp->t_rawq);
    441 				if (c == -1)
    442 					goto endcase;
    443 			} while (c != ' ' && c != '\t' &&
    444 			    (alt == 0 || ISALPHA(c) == ctype));
    445 			(void)putc(c, &tp->t_rawq);
    446 			goto endcase;
    447 		}
    448 		/*
    449 		 * reprint line (^R)
    450 		 */
    451 		if (CCEQ(cc[VREPRINT], c)) {
    452 			ttyretype(tp);
    453 			goto endcase;
    454 		}
    455 		/*
    456 		 * ^T - kernel info and generate SIGINFO
    457 		 */
    458 		if (CCEQ(cc[VSTATUS], c)) {
    459 			if (ISSET(lflag, ISIG))
    460 				pgsignal(tp->t_pgrp, SIGINFO, 1);
    461 			if (!ISSET(lflag, NOKERNINFO))
    462 				ttyinfo(tp);
    463 			goto endcase;
    464 		}
    465 	}
    466 	/*
    467 	 * Check for input buffer overflow
    468 	 */
    469 	if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
    470 		if (ISSET(iflag, IMAXBEL)) {
    471 			if (tp->t_outq.c_cc < tp->t_hiwat)
    472 				(void)ttyoutput(CTRL('g'), tp);
    473 		} else
    474 			ttyflush(tp, FREAD | FWRITE);
    475 		goto endcase;
    476 	}
    477 	/*
    478 	 * Put data char in q for user and
    479 	 * wakeup on seeing a line delimiter.
    480 	 */
    481 	if (putc(c, &tp->t_rawq) >= 0) {
    482 		if (!ISSET(lflag, ICANON)) {
    483 			ttwakeup(tp);
    484 			ttyecho(c, tp);
    485 			goto endcase;
    486 		}
    487 		if (TTBREAKC(c)) {
    488 			tp->t_rocount = 0;
    489 			catq(&tp->t_rawq, &tp->t_canq);
    490 			ttwakeup(tp);
    491 		} else if (tp->t_rocount++ == 0)
    492 			tp->t_rocol = tp->t_column;
    493 		if (ISSET(tp->t_state, TS_ERASE)) {
    494 			/*
    495 			 * end of prterase \.../
    496 			 */
    497 			CLR(tp->t_state, TS_ERASE);
    498 			(void)ttyoutput('/', tp);
    499 		}
    500 		i = tp->t_column;
    501 		ttyecho(c, tp);
    502 		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
    503 			/*
    504 			 * Place the cursor over the '^' of the ^D.
    505 			 */
    506 			i = min(2, tp->t_column - i);
    507 			while (i > 0) {
    508 				(void)ttyoutput('\b', tp);
    509 				i--;
    510 			}
    511 		}
    512 	}
    513 endcase:
    514 	/*
    515 	 * IXANY means allow any character to restart output.
    516 	 */
    517 	if (ISSET(tp->t_state, TS_TTSTOP) &&
    518 	    !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
    519 		return (0);
    520 restartoutput:
    521 	CLR(tp->t_lflag, FLUSHO);
    522 	CLR(tp->t_state, TS_TTSTOP);
    523 startoutput:
    524 	return (ttstart(tp));
    525 }
    526 
    527 /*
    528  * Output a single character on a tty, doing output processing
    529  * as needed (expanding tabs, newline processing, etc.).
    530  * Returns < 0 if succeeds, otherwise returns char to resend.
    531  * Must be recursive.
    532  */
    533 int
    534 ttyoutput(c, tp)
    535 	register int c;
    536 	register struct tty *tp;
    537 {
    538 	register long oflag;
    539 	register int col, notout, s;
    540 
    541 	oflag = tp->t_oflag;
    542 	if (!ISSET(oflag, OPOST)) {
    543 		if (ISSET(tp->t_lflag, FLUSHO))
    544 			return (-1);
    545 		if (putc(c, &tp->t_outq))
    546 			return (c);
    547 		tk_nout++;
    548 		tp->t_outcc++;
    549 		return (-1);
    550 	}
    551 	/*
    552 	 * Do tab expansion if OXTABS is set.  Special case if we external
    553 	 * processing, we don't do the tab expansion because we'll probably
    554 	 * get it wrong.  If tab expansion needs to be done, let it happen
    555 	 * externally.
    556 	 */
    557 	CLR(c, ~TTY_CHARMASK);
    558 	if (c == '\t' &&
    559 	    ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
    560 		c = 8 - (tp->t_column & 7);
    561 		if (ISSET(tp->t_lflag, FLUSHO)) {
    562 			notout = 0;
    563 		} else {
    564 			s = spltty();		/* Don't interrupt tabs. */
    565 			notout = b_to_q("        ", c, &tp->t_outq);
    566 			c -= notout;
    567 			tk_nout += c;
    568 			tp->t_outcc += c;
    569 			splx(s);
    570 		}
    571 		tp->t_column += c;
    572 		return (notout ? '\t' : -1);
    573 	}
    574 	if (c == CEOT && ISSET(oflag, ONOEOT))
    575 		return (-1);
    576 
    577 	/*
    578 	 * Newline translation: if ONLCR is set,
    579 	 * translate newline into "\r\n".
    580 	 */
    581 	if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
    582 		tk_nout++;
    583 		tp->t_outcc++;
    584 		if (putc('\r', &tp->t_outq))
    585 			return (c);
    586 	}
    587 	tk_nout++;
    588 	tp->t_outcc++;
    589 	if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
    590 		return (c);
    591 
    592 	col = tp->t_column;
    593 	switch (CCLASS(c)) {
    594 	case BACKSPACE:
    595 		if (col > 0)
    596 			--col;
    597 		break;
    598 	case CONTROL:
    599 		break;
    600 	case NEWLINE:
    601 	case RETURN:
    602 		col = 0;
    603 		break;
    604 	case ORDINARY:
    605 		++col;
    606 		break;
    607 	case TAB:
    608 		col = (col + 8) & ~7;
    609 		break;
    610 	}
    611 	tp->t_column = col;
    612 	return (-1);
    613 }
    614 
    615 /*
    616  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
    617  * has been called to do discipline-specific functions and/or reject any
    618  * of these ioctl commands.
    619  */
    620 /* ARGSUSED */
    621 int
    622 ttioctl(tp, cmd, data, flag, p)
    623 	register struct tty *tp;
    624 	u_long cmd;
    625 	caddr_t data;
    626 	int flag;
    627 	struct proc *p;
    628 {
    629 	extern struct tty *constty;	/* Temporary virtual console. */
    630 	extern int nlinesw;
    631 	int s, error;
    632 
    633 	/* If the ioctl involves modification, hang if in the background. */
    634 	switch (cmd) {
    635 	case  TIOCFLUSH:
    636 	case  TIOCSETA:
    637 	case  TIOCSETD:
    638 	case  TIOCSETAF:
    639 	case  TIOCSETAW:
    640 #ifdef notdef
    641 	case  TIOCSPGRP:
    642 #endif
    643 	case  TIOCSTAT:
    644 	case  TIOCSTI:
    645 	case  TIOCSWINSZ:
    646 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_SVR4) || \
    647     defined(COMPAT_FREEBSD)
    648 	case  TIOCLBIC:
    649 	case  TIOCLBIS:
    650 	case  TIOCLSET:
    651 	case  TIOCSETC:
    652 	case OTIOCSETD:
    653 	case  TIOCSETN:
    654 	case  TIOCSETP:
    655 	case  TIOCSLTC:
    656 #endif
    657 		while (isbackground(curproc, tp) &&
    658 		    p->p_pgrp->pg_jobc && (p->p_flag & P_PPWAIT) == 0 &&
    659 		    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
    660 		    (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
    661 			pgsignal(p->p_pgrp, SIGTTOU, 1);
    662 			if (error = ttysleep(tp,
    663 			    &lbolt, TTOPRI | PCATCH, ttybg, 0))
    664 				return (error);
    665 		}
    666 		break;
    667 	}
    668 
    669 	switch (cmd) {			/* Process the ioctl. */
    670 	case FIOASYNC:			/* set/clear async i/o */
    671 		s = spltty();
    672 		if (*(int *)data)
    673 			SET(tp->t_state, TS_ASYNC);
    674 		else
    675 			CLR(tp->t_state, TS_ASYNC);
    676 		splx(s);
    677 		break;
    678 	case FIONBIO:			/* set/clear non-blocking i/o */
    679 		break;			/* XXX: delete. */
    680 	case FIONREAD:			/* get # bytes to read */
    681 		*(int *)data = ttnread(tp);
    682 		break;
    683 	case TIOCEXCL:			/* set exclusive use of tty */
    684 		s = spltty();
    685 		SET(tp->t_state, TS_XCLUDE);
    686 		splx(s);
    687 		break;
    688 	case TIOCFLUSH: {		/* flush buffers */
    689 		register int flags = *(int *)data;
    690 
    691 		if (flags == 0)
    692 			flags = FREAD | FWRITE;
    693 		else
    694 			flags &= FREAD | FWRITE;
    695 		ttyflush(tp, flags);
    696 		break;
    697 	}
    698 	case TIOCCONS:			/* become virtual console */
    699 		if (*(int *)data) {
    700 			if (constty && constty != tp &&
    701 			    ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
    702 			    (TS_CARR_ON | TS_ISOPEN))
    703 				return (EBUSY);
    704 #ifndef	UCONSOLE
    705 			if (error = suser(p->p_ucred, &p->p_acflag))
    706 				return (error);
    707 #endif
    708 			constty = tp;
    709 		} else if (tp == constty)
    710 			constty = NULL;
    711 		break;
    712 	case TIOCDRAIN:			/* wait till output drained */
    713 		if (error = ttywait(tp))
    714 			return (error);
    715 		break;
    716 	case TIOCGETA: {		/* get termios struct */
    717 		struct termios *t = (struct termios *)data;
    718 
    719 		bcopy(&tp->t_termios, t, sizeof(struct termios));
    720 		break;
    721 	}
    722 	case TIOCGETD:			/* get line discipline */
    723 		*(int *)data = tp->t_line;
    724 		break;
    725 	case TIOCGWINSZ:		/* get window size */
    726 		*(struct winsize *)data = tp->t_winsize;
    727 		break;
    728 	case TIOCGPGRP:			/* get pgrp of tty */
    729 		if (!isctty(p, tp))
    730 			return (ENOTTY);
    731 		*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
    732 		break;
    733 #ifdef TIOCHPCL
    734 	case TIOCHPCL:			/* hang up on last close */
    735 		s = spltty();
    736 		SET(tp->t_cflag, HUPCL);
    737 		splx(s);
    738 		break;
    739 #endif
    740 	case TIOCNXCL:			/* reset exclusive use of tty */
    741 		s = spltty();
    742 		CLR(tp->t_state, TS_XCLUDE);
    743 		splx(s);
    744 		break;
    745 	case TIOCOUTQ:			/* output queue size */
    746 		*(int *)data = tp->t_outq.c_cc;
    747 		break;
    748 	case TIOCSETA:			/* set termios struct */
    749 	case TIOCSETAW:			/* drain output, set */
    750 	case TIOCSETAF: {		/* drn out, fls in, set */
    751 		register struct termios *t = (struct termios *)data;
    752 
    753 		s = spltty();
    754 		if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
    755 			if (error = ttywait(tp)) {
    756 				splx(s);
    757 				return (error);
    758 			}
    759 			if (cmd == TIOCSETAF)
    760 				ttyflush(tp, FREAD);
    761 		}
    762 		if (!ISSET(t->c_cflag, CIGNORE)) {
    763 			/*
    764 			 * Set device hardware.
    765 			 */
    766 			if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
    767 				splx(s);
    768 				return (error);
    769 			} else {
    770 				if (!ISSET(tp->t_state, TS_CARR_ON) &&
    771 				    ISSET(tp->t_cflag, CLOCAL) &&
    772 				    !ISSET(t->c_cflag, CLOCAL)) {
    773 					CLR(tp->t_state, TS_ISOPEN);
    774 					SET(tp->t_state, TS_WOPEN);
    775 					ttwakeup(tp);
    776 				}
    777 				tp->t_cflag = t->c_cflag;
    778 				tp->t_ispeed = t->c_ispeed;
    779 				tp->t_ospeed = t->c_ospeed;
    780 				if (t->c_ospeed == 0 && tp->t_session &&
    781 				    tp->t_session->s_leader)
    782 					psignal(tp->t_session->s_leader,
    783 					    SIGHUP);
    784 			}
    785 			ttsetwater(tp);
    786 		}
    787 		if (cmd != TIOCSETAF) {
    788 			if (ISSET(t->c_lflag, ICANON) !=
    789 			    ISSET(tp->t_lflag, ICANON))
    790 				if (ISSET(t->c_lflag, ICANON)) {
    791 					SET(tp->t_lflag, PENDIN);
    792 					ttwakeup(tp);
    793 				} else {
    794 					struct clist tq;
    795 
    796 					catq(&tp->t_rawq, &tp->t_canq);
    797 					tq = tp->t_rawq;
    798 					tp->t_rawq = tp->t_canq;
    799 					tp->t_canq = tq;
    800 					CLR(tp->t_lflag, PENDIN);
    801 				}
    802 		}
    803 		tp->t_iflag = t->c_iflag;
    804 		tp->t_oflag = t->c_oflag;
    805 		/*
    806 		 * Make the EXTPROC bit read only.
    807 		 */
    808 		if (ISSET(tp->t_lflag, EXTPROC))
    809 			SET(t->c_lflag, EXTPROC);
    810 		else
    811 			CLR(t->c_lflag, EXTPROC);
    812 		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
    813 		bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
    814 		splx(s);
    815 		break;
    816 	}
    817 	case TIOCSETD: {		/* set line discipline */
    818 		register int t = *(int *)data;
    819 		dev_t device = tp->t_dev;
    820 
    821 		if ((u_int)t >= nlinesw)
    822 			return (ENXIO);
    823 		if (t != tp->t_line) {
    824 			s = spltty();
    825 			(*linesw[tp->t_line].l_close)(tp, flag);
    826 			error = (*linesw[t].l_open)(device, tp);
    827 			if (error) {
    828 				(void)(*linesw[tp->t_line].l_open)(device, tp);
    829 				splx(s);
    830 				return (error);
    831 			}
    832 			tp->t_line = t;
    833 			splx(s);
    834 		}
    835 		break;
    836 	}
    837 	case TIOCSTART:			/* start output, like ^Q */
    838 		s = spltty();
    839 		if (ISSET(tp->t_state, TS_TTSTOP) ||
    840 		    ISSET(tp->t_lflag, FLUSHO)) {
    841 			CLR(tp->t_lflag, FLUSHO);
    842 			CLR(tp->t_state, TS_TTSTOP);
    843 			ttstart(tp);
    844 		}
    845 		splx(s);
    846 		break;
    847 	case TIOCSTI:			/* simulate terminal input */
    848 		if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
    849 			return (EPERM);
    850 		if (p->p_ucred->cr_uid && !isctty(p, tp))
    851 			return (EACCES);
    852 		(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
    853 		break;
    854 	case TIOCSTOP:			/* stop output, like ^S */
    855 		s = spltty();
    856 		if (!ISSET(tp->t_state, TS_TTSTOP)) {
    857 			SET(tp->t_state, TS_TTSTOP);
    858 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
    859 		}
    860 		splx(s);
    861 		break;
    862 	case TIOCSCTTY:			/* become controlling tty */
    863 		/* Session ctty vnode pointer set in vnode layer. */
    864 		if (!SESS_LEADER(p) ||
    865 		    (p->p_session->s_ttyvp || tp->t_session) &&
    866 		    (tp->t_session != p->p_session))
    867 			return (EPERM);
    868 		tp->t_session = p->p_session;
    869 		tp->t_pgrp = p->p_pgrp;
    870 		p->p_session->s_ttyp = tp;
    871 		p->p_flag |= P_CONTROLT;
    872 		break;
    873 	case TIOCSPGRP: {		/* set pgrp of tty */
    874 		register struct pgrp *pgrp = pgfind(*(int *)data);
    875 
    876 		if (!isctty(p, tp))
    877 			return (ENOTTY);
    878 		else if (pgrp == NULL || pgrp->pg_session != p->p_session)
    879 			return (EPERM);
    880 		tp->t_pgrp = pgrp;
    881 		break;
    882 	}
    883 	case TIOCSTAT:			/* get load avg stats */
    884 		ttyinfo(tp);
    885 		break;
    886 	case TIOCSWINSZ:		/* set window size */
    887 		if (bcmp((caddr_t)&tp->t_winsize, data,
    888 		    sizeof (struct winsize))) {
    889 			tp->t_winsize = *(struct winsize *)data;
    890 			pgsignal(tp->t_pgrp, SIGWINCH, 1);
    891 		}
    892 		break;
    893 	default:
    894 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_SVR4) || \
    895     defined(COMPAT_FREEBSD)
    896 		return (ttcompat(tp, cmd, data, flag, p));
    897 #else
    898 		return (-1);
    899 #endif
    900 	}
    901 	return (0);
    902 }
    903 
    904 int
    905 ttselect(device, rw, p)
    906 	dev_t device;
    907 	int rw;
    908 	struct proc *p;
    909 {
    910 	register struct tty *tp;
    911 	int nread, s;
    912 
    913 	tp = (*cdevsw[major(device)].d_tty)(device);
    914 
    915 	s = spltty();
    916 	switch (rw) {
    917 	case FREAD:
    918 		nread = ttnread(tp);
    919 		if (nread > 0 || !ISSET(tp->t_cflag, CLOCAL) &&
    920 		    !ISSET(tp->t_state, TS_CARR_ON))
    921 			goto win;
    922 		selrecord(p, &tp->t_rsel);
    923 		break;
    924 	case FWRITE:
    925 		if (tp->t_outq.c_cc <= tp->t_lowat) {
    926 win:			splx(s);
    927 			return (1);
    928 		}
    929 		selrecord(p, &tp->t_wsel);
    930 		break;
    931 	}
    932 	splx(s);
    933 	return (0);
    934 }
    935 
    936 static int
    937 ttnread(tp)
    938 	struct tty *tp;
    939 {
    940 	int nread;
    941 
    942 	if (ISSET(tp->t_lflag, PENDIN))
    943 		ttypend(tp);
    944 	nread = tp->t_canq.c_cc;
    945 	if (!ISSET(tp->t_lflag, ICANON)) {
    946 		nread += tp->t_rawq.c_cc;
    947 		if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
    948 			nread = 0;
    949 	}
    950 	return (nread);
    951 }
    952 
    953 /*
    954  * Wait for output to drain.
    955  */
    956 int
    957 ttywait(tp)
    958 	register struct tty *tp;
    959 {
    960 	int error, s;
    961 
    962 	error = 0;
    963 	s = spltty();
    964 	while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
    965 	    (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
    966 	    && tp->t_oproc) {
    967 		(*tp->t_oproc)(tp);
    968 		SET(tp->t_state, TS_ASLEEP);
    969 		if (error = ttysleep(tp,
    970 		    &tp->t_outq, TTOPRI | PCATCH, ttyout, 0))
    971 			break;
    972 	}
    973 	splx(s);
    974 	return (error);
    975 }
    976 
    977 /*
    978  * Flush if successfully wait.
    979  */
    980 int
    981 ttywflush(tp)
    982 	struct tty *tp;
    983 {
    984 	int error;
    985 
    986 	if ((error = ttywait(tp)) == 0)
    987 		ttyflush(tp, FREAD);
    988 	return (error);
    989 }
    990 
    991 /*
    992  * Flush tty read and/or write queues, notifying anyone waiting.
    993  */
    994 void
    995 ttyflush(tp, rw)
    996 	register struct tty *tp;
    997 	int rw;
    998 {
    999 	register int s;
   1000 
   1001 	s = spltty();
   1002 	if (rw & FREAD) {
   1003 		FLUSHQ(&tp->t_canq);
   1004 		FLUSHQ(&tp->t_rawq);
   1005 		tp->t_rocount = 0;
   1006 		tp->t_rocol = 0;
   1007 		CLR(tp->t_state, TS_LOCAL);
   1008 		ttwakeup(tp);
   1009 	}
   1010 	if (rw & FWRITE) {
   1011 		CLR(tp->t_state, TS_TTSTOP);
   1012 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
   1013 		FLUSHQ(&tp->t_outq);
   1014 		wakeup((caddr_t)&tp->t_outq);
   1015 		selwakeup(&tp->t_wsel);
   1016 	}
   1017 	splx(s);
   1018 }
   1019 
   1020 /*
   1021  * Copy in the default termios characters.
   1022  */
   1023 void
   1024 ttychars(tp)
   1025 	struct tty *tp;
   1026 {
   1027 
   1028 	bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
   1029 }
   1030 
   1031 /*
   1032  * Send stop character on input overflow.
   1033  */
   1034 static void
   1035 ttyblock(tp)
   1036 	register struct tty *tp;
   1037 {
   1038 	register int total;
   1039 
   1040 	total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
   1041 	if (tp->t_rawq.c_cc > TTYHOG) {
   1042 		ttyflush(tp, FREAD | FWRITE);
   1043 		CLR(tp->t_state, TS_TBLOCK);
   1044 	}
   1045 	/*
   1046 	 * Block further input iff: current input > threshold
   1047 	 * AND input is available to user program.
   1048 	 */
   1049 	if (total >= TTYHOG / 2 &&
   1050 	    !ISSET(tp->t_state, TS_TBLOCK) &&
   1051 	    !ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0) {
   1052 		if (ISSET(tp->t_iflag, IXOFF) &&
   1053 		    tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
   1054 		    putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
   1055 			SET(tp->t_state, TS_TBLOCK);
   1056 			ttstart(tp);
   1057 		}
   1058 		/* Try to block remote output via hardware flow control. */
   1059 		if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
   1060 		    (*tp->t_hwiflow)(tp, 1) != 0)
   1061 			SET(tp->t_state, TS_TBLOCK);
   1062 	}
   1063 }
   1064 
   1065 void
   1066 ttrstrt(tp_arg)
   1067 	void *tp_arg;
   1068 {
   1069 	struct tty *tp;
   1070 	int s;
   1071 
   1072 #ifdef DIAGNOSTIC
   1073 	if (tp_arg == NULL)
   1074 		panic("ttrstrt");
   1075 #endif
   1076 	tp = tp_arg;
   1077 	s = spltty();
   1078 
   1079 	CLR(tp->t_state, TS_TIMEOUT);
   1080 	ttstart(tp);
   1081 
   1082 	splx(s);
   1083 }
   1084 
   1085 int
   1086 ttstart(tp)
   1087 	struct tty *tp;
   1088 {
   1089 
   1090 	if (tp->t_oproc != NULL)	/* XXX: Kludge for pty. */
   1091 		(*tp->t_oproc)(tp);
   1092 	return (0);
   1093 }
   1094 
   1095 /*
   1096  * "close" a line discipline
   1097  */
   1098 int
   1099 ttylclose(tp, flag)
   1100 	struct tty *tp;
   1101 	int flag;
   1102 {
   1103 
   1104 	if (flag & FNONBLOCK)
   1105 		ttyflush(tp, FREAD | FWRITE);
   1106 	else
   1107 		ttywflush(tp);
   1108 	return (0);
   1109 }
   1110 
   1111 /*
   1112  * Handle modem control transition on a tty.
   1113  * Flag indicates new state of carrier.
   1114  * Returns 0 if the line should be turned off, otherwise 1.
   1115  */
   1116 int
   1117 ttymodem(tp, flag)
   1118 	register struct tty *tp;
   1119 	int flag;
   1120 {
   1121 
   1122 	if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
   1123 		/*
   1124 		 * MDMBUF: do flow control according to carrier flag
   1125 		 */
   1126 		if (flag) {
   1127 			CLR(tp->t_state, TS_TTSTOP);
   1128 			ttstart(tp);
   1129 		} else if (!ISSET(tp->t_state, TS_TTSTOP)) {
   1130 			SET(tp->t_state, TS_TTSTOP);
   1131 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
   1132 		}
   1133 	} else if (flag == 0) {
   1134 		/*
   1135 		 * Lost carrier.
   1136 		 */
   1137 		CLR(tp->t_state, TS_CARR_ON);
   1138 		if (ISSET(tp->t_state, TS_ISOPEN) &&
   1139 		    !ISSET(tp->t_cflag, CLOCAL)) {
   1140 			if (tp->t_session && tp->t_session->s_leader)
   1141 				psignal(tp->t_session->s_leader, SIGHUP);
   1142 			ttyflush(tp, FREAD | FWRITE);
   1143 			return (0);
   1144 		}
   1145 	} else {
   1146 		/*
   1147 		 * Carrier now on.
   1148 		 */
   1149 		SET(tp->t_state, TS_CARR_ON);
   1150 		ttwakeup(tp);
   1151 	}
   1152 	return (1);
   1153 }
   1154 
   1155 /*
   1156  * Default modem control routine (for other line disciplines).
   1157  * Return argument flag, to turn off device on carrier drop.
   1158  */
   1159 int
   1160 nullmodem(tp, flag)
   1161 	register struct tty *tp;
   1162 	int flag;
   1163 {
   1164 
   1165 	if (flag)
   1166 		SET(tp->t_state, TS_CARR_ON);
   1167 	else {
   1168 		CLR(tp->t_state, TS_CARR_ON);
   1169 		if (!ISSET(tp->t_cflag, CLOCAL)) {
   1170 			if (tp->t_session && tp->t_session->s_leader)
   1171 				psignal(tp->t_session->s_leader, SIGHUP);
   1172 			return (0);
   1173 		}
   1174 	}
   1175 	return (1);
   1176 }
   1177 
   1178 /*
   1179  * Reinput pending characters after state switch
   1180  * call at spltty().
   1181  */
   1182 void
   1183 ttypend(tp)
   1184 	register struct tty *tp;
   1185 {
   1186 	struct clist tq;
   1187 	register c;
   1188 
   1189 	CLR(tp->t_lflag, PENDIN);
   1190 	SET(tp->t_state, TS_TYPEN);
   1191 	tq = tp->t_rawq;
   1192 	tp->t_rawq.c_cc = 0;
   1193 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
   1194 	while ((c = getc(&tq)) >= 0)
   1195 		ttyinput(c, tp);
   1196 	CLR(tp->t_state, TS_TYPEN);
   1197 }
   1198 
   1199 /*
   1200  * Process a read call on a tty device.
   1201  */
   1202 int
   1203 ttread(tp, uio, flag)
   1204 	register struct tty *tp;
   1205 	struct uio *uio;
   1206 	int flag;
   1207 {
   1208 	register struct clist *qp;
   1209 	register int c;
   1210 	register long lflag;
   1211 	register u_char *cc = tp->t_cc;
   1212 	register struct proc *p = curproc;
   1213 	int s, first, error = 0;
   1214 	struct timeval stime;
   1215 	int has_stime = 0, last_cc;
   1216 	long slp = 0;
   1217 
   1218 loop:	lflag = tp->t_lflag;
   1219 	s = spltty();
   1220 	/*
   1221 	 * take pending input first
   1222 	 */
   1223 	if (ISSET(lflag, PENDIN))
   1224 		ttypend(tp);
   1225 	splx(s);
   1226 
   1227 	/*
   1228 	 * Hang process if it's in the background.
   1229 	 */
   1230 	if (isbackground(p, tp)) {
   1231 		if ((p->p_sigignore & sigmask(SIGTTIN)) ||
   1232 		   (p->p_sigmask & sigmask(SIGTTIN)) ||
   1233 		    p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0)
   1234 			return (EIO);
   1235 		pgsignal(p->p_pgrp, SIGTTIN, 1);
   1236 		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
   1237 			return (error);
   1238 		goto loop;
   1239 	}
   1240 
   1241 	s = spltty();
   1242 	if (!ISSET(lflag, ICANON)) {
   1243 		int m = cc[VMIN];
   1244 		long t = cc[VTIME];
   1245 
   1246 		qp = &tp->t_rawq;
   1247 		/*
   1248 		 * Check each of the four combinations.
   1249 		 * (m > 0 && t == 0) is the normal read case.
   1250 		 * It should be fairly efficient, so we check that and its
   1251 		 * companion case (m == 0 && t == 0) first.
   1252 		 * For the other two cases, we compute the target sleep time
   1253 		 * into slp.
   1254 		 */
   1255 		if (t == 0) {
   1256 			if (qp->c_cc < m)
   1257 				goto sleep;
   1258 			goto read;
   1259 		}
   1260 		t *= 100000;		/* time in us */
   1261 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
   1262 			 ((t1).tv_usec - (t2).tv_usec))
   1263 		if (m > 0) {
   1264 			if (qp->c_cc <= 0)
   1265 				goto sleep;
   1266 			if (qp->c_cc >= m)
   1267 				goto read;
   1268 			if (!has_stime) {
   1269 				/* first character, start timer */
   1270 				has_stime = 1;
   1271 				stime = time;
   1272 				slp = t;
   1273 			} else if (qp->c_cc > last_cc) {
   1274 				/* got a character, restart timer */
   1275 				stime = time;
   1276 				slp = t;
   1277 			} else {
   1278 				/* nothing, check expiration */
   1279 				slp = t - diff(time, stime);
   1280 			}
   1281 		} else {	/* m == 0 */
   1282 			if (qp->c_cc > 0)
   1283 				goto read;
   1284 			if (!has_stime) {
   1285 				has_stime = 1;
   1286 				stime = time;
   1287 				slp = t;
   1288 			} else
   1289 				slp = t - diff(time, stime);
   1290 		}
   1291 		last_cc = qp->c_cc;
   1292 #undef diff
   1293 		if (slp > 0) {
   1294 			/*
   1295 			 * Rounding down may make us wake up just short
   1296 			 * of the target, so we round up.
   1297 			 * The formula is ceiling(slp * hz/1000000).
   1298 			 * 32-bit arithmetic is enough for hz < 169.
   1299 			 *
   1300 			 * Also, use plain wakeup() not ttwakeup().
   1301 			 */
   1302 			slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
   1303 			goto sleep;
   1304 		}
   1305 	} else if ((qp = &tp->t_canq)->c_cc <= 0) {
   1306 		int carrier;
   1307 
   1308 sleep:
   1309 		/*
   1310 		 * If there is no input, sleep on rawq
   1311 		 * awaiting hardware receipt and notification.
   1312 		 * If we have data, we don't need to check for carrier.
   1313 		 */
   1314 		carrier = ISSET(tp->t_state, TS_CARR_ON) ||
   1315 		    ISSET(tp->t_cflag, CLOCAL);
   1316 		if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
   1317 			splx(s);
   1318 			return (0);	/* EOF */
   1319 		}
   1320 		if (flag & IO_NDELAY) {
   1321 			splx(s);
   1322 			return (EWOULDBLOCK);
   1323 		}
   1324 		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
   1325 		    carrier ? ttyin : ttopen, slp);
   1326 		splx(s);
   1327 		if (error && error != EWOULDBLOCK)
   1328 			return (error);
   1329 		goto loop;
   1330 	}
   1331 read:
   1332 	splx(s);
   1333 
   1334 	/*
   1335 	 * Input present, check for input mapping and processing.
   1336 	 */
   1337 	first = 1;
   1338 	while ((c = getc(qp)) >= 0) {
   1339 		/*
   1340 		 * delayed suspend (^Y)
   1341 		 */
   1342 		if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) {
   1343 			pgsignal(tp->t_pgrp, SIGTSTP, 1);
   1344 			if (first) {
   1345 				if (error = ttysleep(tp,
   1346 				    &lbolt, TTIPRI | PCATCH, ttybg, 0))
   1347 					break;
   1348 				goto loop;
   1349 			}
   1350 			break;
   1351 		}
   1352 		/*
   1353 		 * Interpret EOF only in canonical mode.
   1354 		 */
   1355 		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
   1356 			break;
   1357 		/*
   1358 		 * Give user character.
   1359 		 */
   1360  		error = ureadc(c, uio);
   1361 		if (error)
   1362 			break;
   1363  		if (uio->uio_resid == 0)
   1364 			break;
   1365 		/*
   1366 		 * In canonical mode check for a "break character"
   1367 		 * marking the end of a "line of input".
   1368 		 */
   1369 		if (ISSET(lflag, ICANON) && TTBREAKC(c))
   1370 			break;
   1371 		first = 0;
   1372 	}
   1373 	/*
   1374 	 * Look to unblock output now that (presumably)
   1375 	 * the input queue has gone down.
   1376 	 */
   1377 	s = spltty();
   1378 	if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
   1379 		if (ISSET(tp->t_iflag, IXOFF) &&
   1380 		    cc[VSTART] != _POSIX_VDISABLE &&
   1381 		    putc(cc[VSTART], &tp->t_outq) == 0) {
   1382 			CLR(tp->t_state, TS_TBLOCK);
   1383 			ttstart(tp);
   1384 		}
   1385 		/* Try to unblock remote output via hardware flow control. */
   1386 		if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
   1387 		    (*tp->t_hwiflow)(tp, 0) != 0)
   1388 			CLR(tp->t_state, TS_TBLOCK);
   1389 	}
   1390 	splx(s);
   1391 	return (error);
   1392 }
   1393 
   1394 /*
   1395  * Check the output queue on tp for space for a kernel message (from uprintf
   1396  * or tprintf).  Allow some space over the normal hiwater mark so we don't
   1397  * lose messages due to normal flow control, but don't let the tty run amok.
   1398  * Sleeps here are not interruptible, but we return prematurely if new signals
   1399  * arrive.
   1400  */
   1401 int
   1402 ttycheckoutq(tp, wait)
   1403 	register struct tty *tp;
   1404 	int wait;
   1405 {
   1406 	int hiwat, s, oldsig;
   1407 
   1408 	hiwat = tp->t_hiwat;
   1409 	s = spltty();
   1410 	oldsig = wait ? curproc->p_siglist : 0;
   1411 	if (tp->t_outq.c_cc > hiwat + 200)
   1412 		while (tp->t_outq.c_cc > hiwat) {
   1413 			ttstart(tp);
   1414 			if (wait == 0 || curproc->p_siglist != oldsig) {
   1415 				splx(s);
   1416 				return (0);
   1417 			}
   1418 			timeout((void (*)__P((void *)))wakeup,
   1419 			    (void *)&tp->t_outq, hz);
   1420 			SET(tp->t_state, TS_ASLEEP);
   1421 			tsleep(&tp->t_outq, PZERO - 1, "ttckoutq", 0);
   1422 		}
   1423 	splx(s);
   1424 	return (1);
   1425 }
   1426 
   1427 /*
   1428  * Process a write call on a tty device.
   1429  */
   1430 int
   1431 ttwrite(tp, uio, flag)
   1432 	register struct tty *tp;
   1433 	register struct uio *uio;
   1434 	int flag;
   1435 {
   1436 	register u_char *cp;
   1437 	register int cc, ce;
   1438 	register struct proc *p;
   1439 	int i, hiwat, cnt, error, s;
   1440 	u_char obuf[OBUFSIZ];
   1441 
   1442 	hiwat = tp->t_hiwat;
   1443 	cnt = uio->uio_resid;
   1444 	error = 0;
   1445 	cc = 0;
   1446 loop:
   1447 	s = spltty();
   1448 	if (!ISSET(tp->t_state, TS_CARR_ON) &&
   1449 	    !ISSET(tp->t_cflag, CLOCAL)) {
   1450 		if (ISSET(tp->t_state, TS_ISOPEN)) {
   1451 			splx(s);
   1452 			return (EIO);
   1453 		} else if (flag & IO_NDELAY) {
   1454 			splx(s);
   1455 			error = EWOULDBLOCK;
   1456 			goto out;
   1457 		} else {
   1458 			/* Sleep awaiting carrier. */
   1459 			error = ttysleep(tp,
   1460 			    &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
   1461 			splx(s);
   1462 			if (error)
   1463 				goto out;
   1464 			goto loop;
   1465 		}
   1466 	}
   1467 	splx(s);
   1468 	/*
   1469 	 * Hang the process if it's in the background.
   1470 	 */
   1471 	p = curproc;
   1472 	if (isbackground(p, tp) &&
   1473 	    ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
   1474 	    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
   1475 	    (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
   1476 	     p->p_pgrp->pg_jobc) {
   1477 		pgsignal(p->p_pgrp, SIGTTOU, 1);
   1478 		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
   1479 			goto out;
   1480 		goto loop;
   1481 	}
   1482 	/*
   1483 	 * Process the user's data in at most OBUFSIZ chunks.  Perform any
   1484 	 * output translation.  Keep track of high water mark, sleep on
   1485 	 * overflow awaiting device aid in acquiring new space.
   1486 	 */
   1487 	while (uio->uio_resid > 0 || cc > 0) {
   1488 		if (ISSET(tp->t_lflag, FLUSHO)) {
   1489 			uio->uio_resid = 0;
   1490 			return (0);
   1491 		}
   1492 		if (tp->t_outq.c_cc > hiwat)
   1493 			goto ovhiwat;
   1494 		/*
   1495 		 * Grab a hunk of data from the user, unless we have some
   1496 		 * leftover from last time.
   1497 		 */
   1498 		if (cc == 0) {
   1499 			cc = min(uio->uio_resid, OBUFSIZ);
   1500 			cp = obuf;
   1501 			error = uiomove(cp, cc, uio);
   1502 			if (error) {
   1503 				cc = 0;
   1504 				break;
   1505 			}
   1506 		}
   1507 		/*
   1508 		 * If nothing fancy need be done, grab those characters we
   1509 		 * can handle without any of ttyoutput's processing and
   1510 		 * just transfer them to the output q.  For those chars
   1511 		 * which require special processing (as indicated by the
   1512 		 * bits in char_type), call ttyoutput.  After processing
   1513 		 * a hunk of data, look for FLUSHO so ^O's will take effect
   1514 		 * immediately.
   1515 		 */
   1516 		while (cc > 0) {
   1517 			if (!ISSET(tp->t_oflag, OPOST))
   1518 				ce = cc;
   1519 			else {
   1520 				ce = cc - scanc((u_int)cc, cp,
   1521 				   (u_char *)char_type, CCLASSMASK);
   1522 				/*
   1523 				 * If ce is zero, then we're processing
   1524 				 * a special character through ttyoutput.
   1525 				 */
   1526 				if (ce == 0) {
   1527 					tp->t_rocount = 0;
   1528 					if (ttyoutput(*cp, tp) >= 0) {
   1529 #ifdef REAL_CLISTS
   1530 						/* No Clists, wait a bit. */
   1531 						ttstart(tp);
   1532 						if (error = ttysleep(tp, &lbolt,
   1533 						    TTOPRI | PCATCH, ttybuf, 0))
   1534 							break;
   1535 						goto loop;
   1536 #else
   1537 						/* out of space */
   1538 						goto overfull;
   1539 #endif
   1540 					}
   1541 					cp++;
   1542 					cc--;
   1543 					if (ISSET(tp->t_lflag, FLUSHO) ||
   1544 					    tp->t_outq.c_cc > hiwat)
   1545 						goto ovhiwat;
   1546 					continue;
   1547 				}
   1548 			}
   1549 			/*
   1550 			 * A bunch of normal characters have been found.
   1551 			 * Transfer them en masse to the output queue and
   1552 			 * continue processing at the top of the loop.
   1553 			 * If there are any further characters in this
   1554 			 * <= OBUFSIZ chunk, the first should be a character
   1555 			 * requiring special handling by ttyoutput.
   1556 			 */
   1557 			tp->t_rocount = 0;
   1558 			i = b_to_q(cp, ce, &tp->t_outq);
   1559 			ce -= i;
   1560 			tp->t_column += ce;
   1561 			cp += ce, cc -= ce, tk_nout += ce;
   1562 			tp->t_outcc += ce;
   1563 			if (i > 0) {
   1564 #ifdef REAL_CLISTS
   1565 				/* No Clists, wait a bit. */
   1566 				ttstart(tp);
   1567 				if (error = ttysleep(tp,
   1568 				    &lbolt, TTOPRI | PCATCH, ttybuf, 0))
   1569 					break;
   1570 				goto loop;
   1571 #else
   1572 				/* out of space */
   1573 				goto overfull;
   1574 #endif
   1575 			}
   1576 			if (ISSET(tp->t_lflag, FLUSHO) ||
   1577 			    tp->t_outq.c_cc > hiwat)
   1578 				break;
   1579 		}
   1580 		ttstart(tp);
   1581 	}
   1582 out:
   1583 	/*
   1584 	 * If cc is nonzero, we leave the uio structure inconsistent, as the
   1585 	 * offset and iov pointers have moved forward, but it doesn't matter
   1586 	 * (the call will either return short or restart with a new uio).
   1587 	 */
   1588 	uio->uio_resid += cc;
   1589 	return (error);
   1590 
   1591 #ifndef REAL_CLISTS
   1592 overfull:
   1593 	/*
   1594 	 * Since we are using ring buffers, if we can't insert any more into
   1595 	 * the output queue, we can assume the ring is full and that someone
   1596 	 * forgot to set the high water mark correctly.  We set it and then
   1597 	 * proceed as normal.
   1598 	 */
   1599 	hiwat = tp->t_outq.c_cc - 1;
   1600 #endif
   1601 
   1602 ovhiwat:
   1603 	ttstart(tp);
   1604 	s = spltty();
   1605 	/*
   1606 	 * This can only occur if FLUSHO is set in t_lflag,
   1607 	 * or if ttstart/oproc is synchronous (or very fast).
   1608 	 */
   1609 	if (tp->t_outq.c_cc <= hiwat) {
   1610 		splx(s);
   1611 		goto loop;
   1612 	}
   1613 	if (flag & IO_NDELAY) {
   1614 		splx(s);
   1615 		uio->uio_resid += cc;
   1616 		return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
   1617 	}
   1618 	SET(tp->t_state, TS_ASLEEP);
   1619 	error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
   1620 	splx(s);
   1621 	if (error)
   1622 		goto out;
   1623 	goto loop;
   1624 }
   1625 
   1626 /*
   1627  * Rubout one character from the rawq of tp
   1628  * as cleanly as possible.
   1629  */
   1630 void
   1631 ttyrub(c, tp)
   1632 	int c;
   1633 	register struct tty *tp;
   1634 {
   1635 	register u_char *cp;
   1636 	register int savecol;
   1637 	int tabc, s;
   1638 
   1639 	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
   1640 		return;
   1641 	CLR(tp->t_lflag, FLUSHO);
   1642 	if (ISSET(tp->t_lflag, ECHOE)) {
   1643 		if (tp->t_rocount == 0) {
   1644 			/*
   1645 			 * Screwed by ttwrite; retype
   1646 			 */
   1647 			ttyretype(tp);
   1648 			return;
   1649 		}
   1650 		if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
   1651 			ttyrubo(tp, 2);
   1652 		else {
   1653 			CLR(c, ~TTY_CHARMASK);
   1654 			switch (CCLASS(c)) {
   1655 			case ORDINARY:
   1656 				ttyrubo(tp, 1);
   1657 				break;
   1658 			case BACKSPACE:
   1659 			case CONTROL:
   1660 			case NEWLINE:
   1661 			case RETURN:
   1662 			case VTAB:
   1663 				if (ISSET(tp->t_lflag, ECHOCTL))
   1664 					ttyrubo(tp, 2);
   1665 				break;
   1666 			case TAB:
   1667 				if (tp->t_rocount < tp->t_rawq.c_cc) {
   1668 					ttyretype(tp);
   1669 					return;
   1670 				}
   1671 				s = spltty();
   1672 				savecol = tp->t_column;
   1673 				SET(tp->t_state, TS_CNTTB);
   1674 				SET(tp->t_lflag, FLUSHO);
   1675 				tp->t_column = tp->t_rocol;
   1676 				for (cp = firstc(&tp->t_rawq, &tabc); cp;
   1677 				    cp = nextc(&tp->t_rawq, cp, &tabc))
   1678 					ttyecho(tabc, tp);
   1679 				CLR(tp->t_lflag, FLUSHO);
   1680 				CLR(tp->t_state, TS_CNTTB);
   1681 				splx(s);
   1682 
   1683 				/* savecol will now be length of the tab. */
   1684 				savecol -= tp->t_column;
   1685 				tp->t_column += savecol;
   1686 				if (savecol > 8)
   1687 					savecol = 8;	/* overflow screw */
   1688 				while (--savecol >= 0)
   1689 					(void)ttyoutput('\b', tp);
   1690 				break;
   1691 			default:			/* XXX */
   1692 #define	PANICSTR	"ttyrub: would panic c = %d, val = %d\n"
   1693 				(void)printf(PANICSTR, c, CCLASS(c));
   1694 #ifdef notdef
   1695 				panic(PANICSTR, c, CCLASS(c));
   1696 #endif
   1697 			}
   1698 		}
   1699 	} else if (ISSET(tp->t_lflag, ECHOPRT)) {
   1700 		if (!ISSET(tp->t_state, TS_ERASE)) {
   1701 			SET(tp->t_state, TS_ERASE);
   1702 			(void)ttyoutput('\\', tp);
   1703 		}
   1704 		ttyecho(c, tp);
   1705 	} else
   1706 		ttyecho(tp->t_cc[VERASE], tp);
   1707 	--tp->t_rocount;
   1708 }
   1709 
   1710 /*
   1711  * Back over cnt characters, erasing them.
   1712  */
   1713 static void
   1714 ttyrubo(tp, cnt)
   1715 	register struct tty *tp;
   1716 	int cnt;
   1717 {
   1718 
   1719 	while (cnt-- > 0) {
   1720 		(void)ttyoutput('\b', tp);
   1721 		(void)ttyoutput(' ', tp);
   1722 		(void)ttyoutput('\b', tp);
   1723 	}
   1724 }
   1725 
   1726 /*
   1727  * ttyretype --
   1728  *	Reprint the rawq line.  Note, it is assumed that c_cc has already
   1729  *	been checked.
   1730  */
   1731 void
   1732 ttyretype(tp)
   1733 	register struct tty *tp;
   1734 {
   1735 	register u_char *cp;
   1736 	int s, c;
   1737 
   1738 	/* Echo the reprint character. */
   1739 	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
   1740 		ttyecho(tp->t_cc[VREPRINT], tp);
   1741 
   1742 	(void)ttyoutput('\n', tp);
   1743 
   1744 	s = spltty();
   1745 	for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
   1746 		ttyecho(c, tp);
   1747 	for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
   1748 		ttyecho(c, tp);
   1749 	CLR(tp->t_state, TS_ERASE);
   1750 	splx(s);
   1751 
   1752 	tp->t_rocount = tp->t_rawq.c_cc;
   1753 	tp->t_rocol = 0;
   1754 }
   1755 
   1756 /*
   1757  * Echo a typed character to the terminal.
   1758  */
   1759 static void
   1760 ttyecho(c, tp)
   1761 	register int c;
   1762 	register struct tty *tp;
   1763 {
   1764 
   1765 	if (!ISSET(tp->t_state, TS_CNTTB))
   1766 		CLR(tp->t_lflag, FLUSHO);
   1767 	if ((!ISSET(tp->t_lflag, ECHO) &&
   1768 	    (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) ||
   1769 	    ISSET(tp->t_lflag, EXTPROC))
   1770 		return;
   1771 	if (ISSET(tp->t_lflag, ECHOCTL) &&
   1772 	    (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' ||
   1773 	    ISSET(c, TTY_CHARMASK) == 0177)) {
   1774 		(void)ttyoutput('^', tp);
   1775 		CLR(c, ~TTY_CHARMASK);
   1776 		if (c == 0177)
   1777 			c = '?';
   1778 		else
   1779 			c += 'A' - 1;
   1780 	}
   1781 	(void)ttyoutput(c, tp);
   1782 }
   1783 
   1784 /*
   1785  * Wake up any readers on a tty.
   1786  */
   1787 void
   1788 ttwakeup(tp)
   1789 	register struct tty *tp;
   1790 {
   1791 
   1792 	selwakeup(&tp->t_rsel);
   1793 	if (ISSET(tp->t_state, TS_ASYNC))
   1794 		pgsignal(tp->t_pgrp, SIGIO, 1);
   1795 	wakeup((caddr_t)&tp->t_rawq);
   1796 }
   1797 
   1798 /*
   1799  * Look up a code for a specified speed in a conversion table;
   1800  * used by drivers to map software speed values to hardware parameters.
   1801  */
   1802 int
   1803 ttspeedtab(speed, table)
   1804 	int speed;
   1805 	register struct speedtab *table;
   1806 {
   1807 
   1808 	for ( ; table->sp_speed != -1; table++)
   1809 		if (table->sp_speed == speed)
   1810 			return (table->sp_code);
   1811 	return (-1);
   1812 }
   1813 
   1814 /*
   1815  * Set tty hi and low water marks.
   1816  *
   1817  * Try to arrange the dynamics so there's about one second
   1818  * from hi to low water.
   1819  */
   1820 void
   1821 ttsetwater(tp)
   1822 	struct tty *tp;
   1823 {
   1824 	register int cps, x;
   1825 
   1826 #define CLAMP(x, h, l)	((x) > h ? h : ((x) < l) ? l : (x))
   1827 
   1828 	cps = tp->t_ospeed / 10;
   1829 	tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
   1830 	x += cps;
   1831 	x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
   1832 	tp->t_hiwat = roundup(x, CBSIZE);
   1833 #undef	CLAMP
   1834 }
   1835 
   1836 /*
   1837  * Report on state of foreground process group.
   1838  */
   1839 void
   1840 ttyinfo(tp)
   1841 	register struct tty *tp;
   1842 {
   1843 	register struct proc *p, *pick;
   1844 	struct timeval utime, stime;
   1845 	int tmp;
   1846 
   1847 	if (ttycheckoutq(tp,0) == 0)
   1848 		return;
   1849 
   1850 	/* Print load average. */
   1851 	tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
   1852 	ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
   1853 
   1854 	if (tp->t_session == NULL)
   1855 		ttyprintf(tp, "not a controlling terminal\n");
   1856 	else if (tp->t_pgrp == NULL)
   1857 		ttyprintf(tp, "no foreground process group\n");
   1858 	else if ((p = tp->t_pgrp->pg_members.lh_first) == 0)
   1859 		ttyprintf(tp, "empty foreground process group\n");
   1860 	else {
   1861 		/* Pick interesting process. */
   1862 		for (pick = NULL; p != 0; p = p->p_pglist.le_next)
   1863 			if (proc_compare(pick, p))
   1864 				pick = p;
   1865 
   1866 		ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
   1867 		    pick->p_stat == SRUN ? "running" :
   1868 		    pick->p_wmesg ? pick->p_wmesg : "iowait");
   1869 
   1870 		calcru(pick, &utime, &stime, NULL);
   1871 
   1872 		/* Round up and print user time. */
   1873 		utime.tv_usec += 5000;
   1874 		if (utime.tv_usec >= 1000000) {
   1875 			utime.tv_sec += 1;
   1876 			utime.tv_usec -= 1000000;
   1877 		}
   1878 		ttyprintf(tp, "%d.%02du ", utime.tv_sec,
   1879 		    utime.tv_usec / 10000);
   1880 
   1881 		/* Round up and print system time. */
   1882 		stime.tv_usec += 5000;
   1883 		if (stime.tv_usec >= 1000000) {
   1884 			stime.tv_sec += 1;
   1885 			stime.tv_usec -= 1000000;
   1886 		}
   1887 		ttyprintf(tp, "%d.%02ds ", stime.tv_sec,
   1888 		    stime.tv_usec / 10000);
   1889 
   1890 #define	pgtok(a)	(((a) * NBPG) / 1024)
   1891 		/* Print percentage cpu, resident set size. */
   1892 		tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT;
   1893 		ttyprintf(tp, "%d%% %dk\n",
   1894 		    tmp / 100,
   1895 		    pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
   1896 #ifdef pmap_resident_count
   1897 			pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap))
   1898 #else
   1899 			pgtok(pick->p_vmspace->vm_rssize)
   1900 #endif
   1901 			);
   1902 	}
   1903 	tp->t_rocount = 0;	/* so pending input will be retyped if BS */
   1904 }
   1905 
   1906 /*
   1907  * Returns 1 if p2 is "better" than p1
   1908  *
   1909  * The algorithm for picking the "interesting" process is thus:
   1910  *
   1911  *	1) Only foreground processes are eligible - implied.
   1912  *	2) Runnable processes are favored over anything else.  The runner
   1913  *	   with the highest cpu utilization is picked (p_estcpu).  Ties are
   1914  *	   broken by picking the highest pid.
   1915  *	3) The sleeper with the shortest sleep time is next.  With ties,
   1916  *	   we pick out just "short-term" sleepers (P_SINTR == 0).
   1917  *	4) Further ties are broken by picking the highest pid.
   1918  */
   1919 #define ISRUN(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
   1920 #define TESTAB(a, b)    ((a)<<1 | (b))
   1921 #define ONLYA   2
   1922 #define ONLYB   1
   1923 #define BOTH    3
   1924 
   1925 static int
   1926 proc_compare(p1, p2)
   1927 	register struct proc *p1, *p2;
   1928 {
   1929 
   1930 	if (p1 == NULL)
   1931 		return (1);
   1932 	/*
   1933 	 * see if at least one of them is runnable
   1934 	 */
   1935 	switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
   1936 	case ONLYA:
   1937 		return (0);
   1938 	case ONLYB:
   1939 		return (1);
   1940 	case BOTH:
   1941 		/*
   1942 		 * tie - favor one with highest recent cpu utilization
   1943 		 */
   1944 		if (p2->p_estcpu > p1->p_estcpu)
   1945 			return (1);
   1946 		if (p1->p_estcpu > p2->p_estcpu)
   1947 			return (0);
   1948 		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
   1949 	}
   1950 	/*
   1951  	 * weed out zombies
   1952 	 */
   1953 	switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
   1954 	case ONLYA:
   1955 		return (1);
   1956 	case ONLYB:
   1957 		return (0);
   1958 	case BOTH:
   1959 		return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
   1960 	}
   1961 	/*
   1962 	 * pick the one with the smallest sleep time
   1963 	 */
   1964 	if (p2->p_slptime > p1->p_slptime)
   1965 		return (0);
   1966 	if (p1->p_slptime > p2->p_slptime)
   1967 		return (1);
   1968 	/*
   1969 	 * favor one sleeping in a non-interruptible sleep
   1970 	 */
   1971 	if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
   1972 		return (1);
   1973 	if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
   1974 		return (0);
   1975 	return (p2->p_pid > p1->p_pid);		/* tie - return highest pid */
   1976 }
   1977 
   1978 /*
   1979  * Output char to tty; console putchar style.
   1980  */
   1981 int
   1982 tputchar(c, tp)
   1983 	int c;
   1984 	struct tty *tp;
   1985 {
   1986 	register int s;
   1987 
   1988 	s = spltty();
   1989 	if (ISSET(tp->t_state,
   1990 	    TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
   1991 		splx(s);
   1992 		return (-1);
   1993 	}
   1994 	if (c == '\n')
   1995 		(void)ttyoutput('\r', tp);
   1996 	(void)ttyoutput(c, tp);
   1997 	ttstart(tp);
   1998 	splx(s);
   1999 	return (0);
   2000 }
   2001 
   2002 /*
   2003  * Sleep on chan, returning ERESTART if tty changed while we napped and
   2004  * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep.  If
   2005  * the tty is revoked, restarting a pending call will redo validation done
   2006  * at the start of the call.
   2007  */
   2008 int
   2009 ttysleep(tp, chan, pri, wmesg, timo)
   2010 	struct tty *tp;
   2011 	void *chan;
   2012 	int pri, timo;
   2013 	char *wmesg;
   2014 {
   2015 	int error;
   2016 	short gen;
   2017 
   2018 	gen = tp->t_gen;
   2019 	if (error = tsleep(chan, pri, wmesg, timo))
   2020 		return (error);
   2021 	return (tp->t_gen == gen ? 0 : ERESTART);
   2022 }
   2023 
   2024 /*
   2025  * Allocate a tty structure and its associated buffers.
   2026  */
   2027 struct tty *
   2028 ttymalloc()
   2029 {
   2030 	struct tty *tp;
   2031 
   2032 	MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
   2033 	bzero(tp, sizeof *tp);
   2034 	/* XXX: default to 1024 chars for now */
   2035 	clalloc(&tp->t_rawq, 1024, 1);
   2036 	clalloc(&tp->t_canq, 1024, 1);
   2037 	/* output queue doesn't need quoting */
   2038 	clalloc(&tp->t_outq, 1024, 0);
   2039 	return(tp);
   2040 }
   2041 
   2042 /*
   2043  * Free a tty structure and its buffers.
   2044  */
   2045 void
   2046 ttyfree(tp)
   2047 struct tty *tp;
   2048 {
   2049 	clfree(&tp->t_rawq);
   2050 	clfree(&tp->t_canq);
   2051 	clfree(&tp->t_outq);
   2052 	FREE(tp, M_TTYS);
   2053 }
   2054