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