Home | History | Annotate | Line # | Download | only in kern
tty.c revision 1.1.1.2
      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.8 (Berkeley) 1/21/94
     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 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 			s = spltty();		/* Don't interrupt tabs. */
    558 			c -= b_to_q("        ", c, &tp->t_outq);
    559 			tk_nout += c;
    560 			tp->t_outcc += c;
    561 			splx(s);
    562 		}
    563 		tp->t_column += c;
    564 		return (c ? -1 : '\t');
    565 	}
    566 	if (c == CEOT && ISSET(oflag, ONOEOT))
    567 		return (-1);
    568 
    569 	/*
    570 	 * Newline translation: if ONLCR is set,
    571 	 * translate newline into "\r\n".
    572 	 */
    573 	if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
    574 		tk_nout++;
    575 		tp->t_outcc++;
    576 		if (putc('\r', &tp->t_outq))
    577 			return (c);
    578 	}
    579 	tk_nout++;
    580 	tp->t_outcc++;
    581 	if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
    582 		return (c);
    583 
    584 	col = tp->t_column;
    585 	switch (CCLASS(c)) {
    586 	case BACKSPACE:
    587 		if (col > 0)
    588 			--col;
    589 		break;
    590 	case CONTROL:
    591 		break;
    592 	case NEWLINE:
    593 	case RETURN:
    594 		col = 0;
    595 		break;
    596 	case ORDINARY:
    597 		++col;
    598 		break;
    599 	case TAB:
    600 		col = (col + 8) & ~7;
    601 		break;
    602 	}
    603 	tp->t_column = col;
    604 	return (-1);
    605 }
    606 
    607 /*
    608  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
    609  * has been called to do discipline-specific functions and/or reject any
    610  * of these ioctl commands.
    611  */
    612 /* ARGSUSED */
    613 int
    614 ttioctl(tp, cmd, data, flag)
    615 	register struct tty *tp;
    616 	int cmd, flag;
    617 	void *data;
    618 {
    619 	extern struct tty *constty;	/* Temporary virtual console. */
    620 	extern int nlinesw;
    621 	register struct proc *p;
    622 	int s, error;
    623 
    624 	p = curproc;			/* XXX */
    625 
    626 	/* If the ioctl involves modification, hang if in the background. */
    627 	switch (cmd) {
    628 	case  TIOCFLUSH:
    629 	case  TIOCSETA:
    630 	case  TIOCSETD:
    631 	case  TIOCSETAF:
    632 	case  TIOCSETAW:
    633 #ifdef notdef
    634 	case  TIOCSPGRP:
    635 #endif
    636 	case  TIOCSTI:
    637 	case  TIOCSWINSZ:
    638 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
    639 	case  TIOCLBIC:
    640 	case  TIOCLBIS:
    641 	case  TIOCLSET:
    642 	case  TIOCSETC:
    643 	case OTIOCSETD:
    644 	case  TIOCSETN:
    645 	case  TIOCSETP:
    646 	case  TIOCSLTC:
    647 #endif
    648 		while (isbackground(curproc, tp) &&
    649 		    p->p_pgrp->pg_jobc && (p->p_flag & P_PPWAIT) == 0 &&
    650 		    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
    651 		    (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
    652 			pgsignal(p->p_pgrp, SIGTTOU, 1);
    653 			if (error = ttysleep(tp,
    654 			    &lbolt, TTOPRI | PCATCH, ttybg, 0))
    655 				return (error);
    656 		}
    657 		break;
    658 	}
    659 
    660 	switch (cmd) {			/* Process the ioctl. */
    661 	case FIOASYNC:			/* set/clear async i/o */
    662 		s = spltty();
    663 		if (*(int *)data)
    664 			SET(tp->t_state, TS_ASYNC);
    665 		else
    666 			CLR(tp->t_state, TS_ASYNC);
    667 		splx(s);
    668 		break;
    669 	case FIONBIO:			/* set/clear non-blocking i/o */
    670 		break;			/* XXX: delete. */
    671 	case FIONREAD:			/* get # bytes to read */
    672 		*(int *)data = ttnread(tp);
    673 		break;
    674 	case TIOCEXCL:			/* set exclusive use of tty */
    675 		s = spltty();
    676 		SET(tp->t_state, TS_XCLUDE);
    677 		splx(s);
    678 		break;
    679 	case TIOCFLUSH: {		/* flush buffers */
    680 		register int flags = *(int *)data;
    681 
    682 		if (flags == 0)
    683 			flags = FREAD | FWRITE;
    684 		else
    685 			flags &= FREAD | FWRITE;
    686 		ttyflush(tp, flags);
    687 		break;
    688 	}
    689 	case TIOCCONS:			/* become virtual console */
    690 		if (*(int *)data) {
    691 			if (constty && constty != tp &&
    692 			    ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
    693 			    (TS_CARR_ON | TS_ISOPEN))
    694 				return (EBUSY);
    695 #ifndef	UCONSOLE
    696 			if (error = suser(p->p_ucred, &p->p_acflag))
    697 				return (error);
    698 #endif
    699 			constty = tp;
    700 		} else if (tp == constty)
    701 			constty = NULL;
    702 		break;
    703 	case TIOCDRAIN:			/* wait till output drained */
    704 		if (error = ttywait(tp))
    705 			return (error);
    706 		break;
    707 	case TIOCGETA: {		/* get termios struct */
    708 		struct termios *t = (struct termios *)data;
    709 
    710 		bcopy(&tp->t_termios, t, sizeof(struct termios));
    711 		break;
    712 	}
    713 	case TIOCGETD:			/* get line discipline */
    714 		*(int *)data = tp->t_line;
    715 		break;
    716 	case TIOCGWINSZ:		/* get window size */
    717 		*(struct winsize *)data = tp->t_winsize;
    718 		break;
    719 	case TIOCGPGRP:			/* get pgrp of tty */
    720 		if (!isctty(p, tp))
    721 			return (ENOTTY);
    722 		*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
    723 		break;
    724 #ifdef TIOCHPCL
    725 	case TIOCHPCL:			/* hang up on last close */
    726 		s = spltty();
    727 		SET(tp->t_cflag, HUPCL);
    728 		splx(s);
    729 		break;
    730 #endif
    731 	case TIOCNXCL:			/* reset exclusive use of tty */
    732 		s = spltty();
    733 		CLR(tp->t_state, TS_XCLUDE);
    734 		splx(s);
    735 		break;
    736 	case TIOCOUTQ:			/* output queue size */
    737 		*(int *)data = tp->t_outq.c_cc;
    738 		break;
    739 	case TIOCSETA:			/* set termios struct */
    740 	case TIOCSETAW:			/* drain output, set */
    741 	case TIOCSETAF: {		/* drn out, fls in, set */
    742 		register struct termios *t = (struct termios *)data;
    743 
    744 		s = spltty();
    745 		if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
    746 			if (error = ttywait(tp)) {
    747 				splx(s);
    748 				return (error);
    749 			}
    750 			if (cmd == TIOCSETAF)
    751 				ttyflush(tp, FREAD);
    752 		}
    753 		if (!ISSET(t->c_cflag, CIGNORE)) {
    754 			/*
    755 			 * Set device hardware.
    756 			 */
    757 			if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
    758 				splx(s);
    759 				return (error);
    760 			} else {
    761 				if (!ISSET(tp->t_state, TS_CARR_ON) &&
    762 				    ISSET(tp->t_cflag, CLOCAL) &&
    763 				    !ISSET(t->c_cflag, CLOCAL)) {
    764 					CLR(tp->t_state, TS_ISOPEN);
    765 					SET(tp->t_state, TS_WOPEN);
    766 					ttwakeup(tp);
    767 				}
    768 				tp->t_cflag = t->c_cflag;
    769 				tp->t_ispeed = t->c_ispeed;
    770 				tp->t_ospeed = t->c_ospeed;
    771 			}
    772 			ttsetwater(tp);
    773 		}
    774 		if (cmd != TIOCSETAF) {
    775 			if (ISSET(t->c_lflag, ICANON) !=
    776 			    ISSET(tp->t_lflag, ICANON))
    777 				if (ISSET(t->c_lflag, ICANON)) {
    778 					SET(tp->t_lflag, PENDIN);
    779 					ttwakeup(tp);
    780 				} else {
    781 					struct clist tq;
    782 
    783 					catq(&tp->t_rawq, &tp->t_canq);
    784 					tq = tp->t_rawq;
    785 					tp->t_rawq = tp->t_canq;
    786 					tp->t_canq = tq;
    787 					CLR(tp->t_lflag, PENDIN);
    788 				}
    789 		}
    790 		tp->t_iflag = t->c_iflag;
    791 		tp->t_oflag = t->c_oflag;
    792 		/*
    793 		 * Make the EXTPROC bit read only.
    794 		 */
    795 		if (ISSET(tp->t_lflag, EXTPROC))
    796 			SET(t->c_lflag, EXTPROC);
    797 		else
    798 			CLR(t->c_lflag, EXTPROC);
    799 		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
    800 		bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
    801 		splx(s);
    802 		break;
    803 	}
    804 	case TIOCSETD: {		/* set line discipline */
    805 		register int t = *(int *)data;
    806 		dev_t device = tp->t_dev;
    807 
    808 		if ((u_int)t >= nlinesw)
    809 			return (ENXIO);
    810 		if (t != tp->t_line) {
    811 			s = spltty();
    812 			(*linesw[tp->t_line].l_close)(tp, flag);
    813 			error = (*linesw[t].l_open)(device, tp);
    814 			if (error) {
    815 				(void)(*linesw[tp->t_line].l_open)(device, tp);
    816 				splx(s);
    817 				return (error);
    818 			}
    819 			tp->t_line = t;
    820 			splx(s);
    821 		}
    822 		break;
    823 	}
    824 	case TIOCSTART:			/* start output, like ^Q */
    825 		s = spltty();
    826 		if (ISSET(tp->t_state, TS_TTSTOP) ||
    827 		    ISSET(tp->t_lflag, FLUSHO)) {
    828 			CLR(tp->t_lflag, FLUSHO);
    829 			CLR(tp->t_state, TS_TTSTOP);
    830 			ttstart(tp);
    831 		}
    832 		splx(s);
    833 		break;
    834 	case TIOCSTI:			/* simulate terminal input */
    835 		if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
    836 			return (EPERM);
    837 		if (p->p_ucred->cr_uid && !isctty(p, tp))
    838 			return (EACCES);
    839 		(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
    840 		break;
    841 	case TIOCSTOP:			/* stop output, like ^S */
    842 		s = spltty();
    843 		if (!ISSET(tp->t_state, TS_TTSTOP)) {
    844 			SET(tp->t_state, TS_TTSTOP);
    845 #ifdef sun4c				/* XXX */
    846 			(*tp->t_stop)(tp, 0);
    847 #else
    848 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
    849 #endif
    850 		}
    851 		splx(s);
    852 		break;
    853 	case TIOCSCTTY:			/* become controlling tty */
    854 		/* Session ctty vnode pointer set in vnode layer. */
    855 		if (!SESS_LEADER(p) ||
    856 		    (p->p_session->s_ttyvp || tp->t_session) &&
    857 		    (tp->t_session != p->p_session))
    858 			return (EPERM);
    859 		tp->t_session = p->p_session;
    860 		tp->t_pgrp = p->p_pgrp;
    861 		p->p_session->s_ttyp = tp;
    862 		p->p_flag |= P_CONTROLT;
    863 		break;
    864 	case TIOCSPGRP: {		/* set pgrp of tty */
    865 		register struct pgrp *pgrp = pgfind(*(int *)data);
    866 
    867 		if (!isctty(p, tp))
    868 			return (ENOTTY);
    869 		else if (pgrp == NULL || pgrp->pg_session != p->p_session)
    870 			return (EPERM);
    871 		tp->t_pgrp = pgrp;
    872 		break;
    873 	}
    874 	case TIOCSWINSZ:		/* set window size */
    875 		if (bcmp((caddr_t)&tp->t_winsize, data,
    876 		    sizeof (struct winsize))) {
    877 			tp->t_winsize = *(struct winsize *)data;
    878 			pgsignal(tp->t_pgrp, SIGWINCH, 1);
    879 		}
    880 		break;
    881 	default:
    882 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
    883 		return (ttcompat(tp, cmd, data, flag));
    884 #else
    885 		return (-1);
    886 #endif
    887 	}
    888 	return (0);
    889 }
    890 
    891 int
    892 ttselect(device, rw, p)
    893 	dev_t device;
    894 	int rw;
    895 	struct proc *p;
    896 {
    897 	register struct tty *tp;
    898 	int nread, s;
    899 
    900 	tp = &cdevsw[major(device)].d_ttys[minor(device)];
    901 
    902 	s = spltty();
    903 	switch (rw) {
    904 	case FREAD:
    905 		nread = ttnread(tp);
    906 		if (nread > 0 || !ISSET(tp->t_cflag, CLOCAL) &&
    907 		    !ISSET(tp->t_state, TS_CARR_ON))
    908 			goto win;
    909 		selrecord(p, &tp->t_rsel);
    910 		break;
    911 	case FWRITE:
    912 		if (tp->t_outq.c_cc <= tp->t_lowat) {
    913 win:			splx(s);
    914 			return (1);
    915 		}
    916 		selrecord(p, &tp->t_wsel);
    917 		break;
    918 	}
    919 	splx(s);
    920 	return (0);
    921 }
    922 
    923 static int
    924 ttnread(tp)
    925 	struct tty *tp;
    926 {
    927 	int nread;
    928 
    929 	if (ISSET(tp->t_lflag, PENDIN))
    930 		ttypend(tp);
    931 	nread = tp->t_canq.c_cc;
    932 	if (!ISSET(tp->t_lflag, ICANON))
    933 		nread += tp->t_rawq.c_cc;
    934 	return (nread);
    935 }
    936 
    937 /*
    938  * Wait for output to drain.
    939  */
    940 int
    941 ttywait(tp)
    942 	register struct tty *tp;
    943 {
    944 	int error, s;
    945 
    946 	error = 0;
    947 	s = spltty();
    948 	while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
    949 	    (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
    950 	    && tp->t_oproc) {
    951 		(*tp->t_oproc)(tp);
    952 		SET(tp->t_state, TS_ASLEEP);
    953 		if (error = ttysleep(tp,
    954 		    &tp->t_outq, TTOPRI | PCATCH, ttyout, 0))
    955 			break;
    956 	}
    957 	splx(s);
    958 	return (error);
    959 }
    960 
    961 /*
    962  * Flush if successfully wait.
    963  */
    964 int
    965 ttywflush(tp)
    966 	struct tty *tp;
    967 {
    968 	int error;
    969 
    970 	if ((error = ttywait(tp)) == 0)
    971 		ttyflush(tp, FREAD);
    972 	return (error);
    973 }
    974 
    975 /*
    976  * Flush tty read and/or write queues, notifying anyone waiting.
    977  */
    978 void
    979 ttyflush(tp, rw)
    980 	register struct tty *tp;
    981 	int rw;
    982 {
    983 	register int s;
    984 
    985 	s = spltty();
    986 	if (rw & FREAD) {
    987 		FLUSHQ(&tp->t_canq);
    988 		FLUSHQ(&tp->t_rawq);
    989 		tp->t_rocount = 0;
    990 		tp->t_rocol = 0;
    991 		CLR(tp->t_state, TS_LOCAL);
    992 		ttwakeup(tp);
    993 	}
    994 	if (rw & FWRITE) {
    995 		CLR(tp->t_state, TS_TTSTOP);
    996 #ifdef sun4c						/* XXX */
    997 		(*tp->t_stop)(tp, rw);
    998 #else
    999 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
   1000 #endif
   1001 		FLUSHQ(&tp->t_outq);
   1002 		wakeup((caddr_t)&tp->t_outq);
   1003 		selwakeup(&tp->t_wsel);
   1004 	}
   1005 	splx(s);
   1006 }
   1007 
   1008 /*
   1009  * Copy in the default termios characters.
   1010  */
   1011 void
   1012 ttychars(tp)
   1013 	struct tty *tp;
   1014 {
   1015 
   1016 	bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
   1017 }
   1018 
   1019 /*
   1020  * Send stop character on input overflow.
   1021  */
   1022 static void
   1023 ttyblock(tp)
   1024 	register struct tty *tp;
   1025 {
   1026 	register int total;
   1027 
   1028 	total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
   1029 	if (tp->t_rawq.c_cc > TTYHOG) {
   1030 		ttyflush(tp, FREAD | FWRITE);
   1031 		CLR(tp->t_state, TS_TBLOCK);
   1032 	}
   1033 	/*
   1034 	 * Block further input iff: current input > threshold
   1035 	 * AND input is available to user program.
   1036 	 */
   1037 	if (total >= TTYHOG / 2 &&
   1038 	    !ISSET(tp->t_state, TS_TBLOCK) &&
   1039 	    !ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0 &&
   1040 	    tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
   1041 		if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
   1042 			SET(tp->t_state, TS_TBLOCK);
   1043 			ttstart(tp);
   1044 		}
   1045 	}
   1046 }
   1047 
   1048 void
   1049 ttrstrt(tp_arg)
   1050 	void *tp_arg;
   1051 {
   1052 	struct tty *tp;
   1053 	int s;
   1054 
   1055 #ifdef DIAGNOSTIC
   1056 	if (tp_arg == NULL)
   1057 		panic("ttrstrt");
   1058 #endif
   1059 	tp = tp_arg;
   1060 	s = spltty();
   1061 
   1062 	CLR(tp->t_state, TS_TIMEOUT);
   1063 	ttstart(tp);
   1064 
   1065 	splx(s);
   1066 }
   1067 
   1068 int
   1069 ttstart(tp)
   1070 	struct tty *tp;
   1071 {
   1072 
   1073 	if (tp->t_oproc != NULL)	/* XXX: Kludge for pty. */
   1074 		(*tp->t_oproc)(tp);
   1075 	return (0);
   1076 }
   1077 
   1078 /*
   1079  * "close" a line discipline
   1080  */
   1081 int
   1082 ttylclose(tp, flag)
   1083 	struct tty *tp;
   1084 	int flag;
   1085 {
   1086 
   1087 	if (flag & IO_NDELAY)
   1088 		ttyflush(tp, FREAD | FWRITE);
   1089 	else
   1090 		ttywflush(tp);
   1091 	return (0);
   1092 }
   1093 
   1094 /*
   1095  * Handle modem control transition on a tty.
   1096  * Flag indicates new state of carrier.
   1097  * Returns 0 if the line should be turned off, otherwise 1.
   1098  */
   1099 int
   1100 ttymodem(tp, flag)
   1101 	register struct tty *tp;
   1102 	int flag;
   1103 {
   1104 
   1105 	if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
   1106 		/*
   1107 		 * MDMBUF: do flow control according to carrier flag
   1108 		 */
   1109 		if (flag) {
   1110 			CLR(tp->t_state, TS_TTSTOP);
   1111 			ttstart(tp);
   1112 		} else if (!ISSET(tp->t_state, TS_TTSTOP)) {
   1113 			SET(tp->t_state, TS_TTSTOP);
   1114 #ifdef sun4c						/* XXX */
   1115 			(*tp->t_stop)(tp, 0);
   1116 #else
   1117 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
   1118 #endif
   1119 		}
   1120 	} else if (flag == 0) {
   1121 		/*
   1122 		 * Lost carrier.
   1123 		 */
   1124 		CLR(tp->t_state, TS_CARR_ON);
   1125 		if (ISSET(tp->t_state, TS_ISOPEN) &&
   1126 		    !ISSET(tp->t_cflag, CLOCAL)) {
   1127 			if (tp->t_session && tp->t_session->s_leader)
   1128 				psignal(tp->t_session->s_leader, SIGHUP);
   1129 			ttyflush(tp, FREAD | FWRITE);
   1130 			return (0);
   1131 		}
   1132 	} else {
   1133 		/*
   1134 		 * Carrier now on.
   1135 		 */
   1136 		SET(tp->t_state, TS_CARR_ON);
   1137 		ttwakeup(tp);
   1138 	}
   1139 	return (1);
   1140 }
   1141 
   1142 /*
   1143  * Default modem control routine (for other line disciplines).
   1144  * Return argument flag, to turn off device on carrier drop.
   1145  */
   1146 int
   1147 nullmodem(tp, flag)
   1148 	register struct tty *tp;
   1149 	int flag;
   1150 {
   1151 
   1152 	if (flag)
   1153 		SET(tp->t_state, TS_CARR_ON);
   1154 	else {
   1155 		CLR(tp->t_state, TS_CARR_ON);
   1156 		if (!ISSET(tp->t_cflag, CLOCAL)) {
   1157 			if (tp->t_session && tp->t_session->s_leader)
   1158 				psignal(tp->t_session->s_leader, SIGHUP);
   1159 			return (0);
   1160 		}
   1161 	}
   1162 	return (1);
   1163 }
   1164 
   1165 /*
   1166  * Reinput pending characters after state switch
   1167  * call at spltty().
   1168  */
   1169 void
   1170 ttypend(tp)
   1171 	register struct tty *tp;
   1172 {
   1173 	struct clist tq;
   1174 	register c;
   1175 
   1176 	CLR(tp->t_lflag, PENDIN);
   1177 	SET(tp->t_state, TS_TYPEN);
   1178 	tq = tp->t_rawq;
   1179 	tp->t_rawq.c_cc = 0;
   1180 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
   1181 	while ((c = getc(&tq)) >= 0)
   1182 		ttyinput(c, tp);
   1183 	CLR(tp->t_state, TS_TYPEN);
   1184 }
   1185 
   1186 /*
   1187  * Process a read call on a tty device.
   1188  */
   1189 int
   1190 ttread(tp, uio, flag)
   1191 	register struct tty *tp;
   1192 	struct uio *uio;
   1193 	int flag;
   1194 {
   1195 	register struct clist *qp;
   1196 	register int c;
   1197 	register long lflag;
   1198 	register u_char *cc = tp->t_cc;
   1199 	register struct proc *p = curproc;
   1200 	int s, first, error = 0;
   1201 
   1202 loop:	lflag = tp->t_lflag;
   1203 	s = spltty();
   1204 	/*
   1205 	 * take pending input first
   1206 	 */
   1207 	if (ISSET(lflag, PENDIN))
   1208 		ttypend(tp);
   1209 	splx(s);
   1210 
   1211 	/*
   1212 	 * Hang process if it's in the background.
   1213 	 */
   1214 	if (isbackground(p, tp)) {
   1215 		if ((p->p_sigignore & sigmask(SIGTTIN)) ||
   1216 		   (p->p_sigmask & sigmask(SIGTTIN)) ||
   1217 		    p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0)
   1218 			return (EIO);
   1219 		pgsignal(p->p_pgrp, SIGTTIN, 1);
   1220 		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
   1221 			return (error);
   1222 		goto loop;
   1223 	}
   1224 
   1225 	/*
   1226 	 * If canonical, use the canonical queue,
   1227 	 * else use the raw queue.
   1228 	 *
   1229 	 * (should get rid of clists...)
   1230 	 */
   1231 	qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
   1232 
   1233 	/*
   1234 	 * If there is no input, sleep on rawq
   1235 	 * awaiting hardware receipt and notification.
   1236 	 * If we have data, we don't need to check for carrier.
   1237 	 */
   1238 	s = spltty();
   1239 	if (qp->c_cc <= 0) {
   1240 		int carrier;
   1241 
   1242 		carrier = ISSET(tp->t_state, TS_CARR_ON) ||
   1243 		    ISSET(tp->t_cflag, CLOCAL);
   1244 		if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
   1245 			splx(s);
   1246 			return (0);	/* EOF */
   1247 		}
   1248 		if (flag & IO_NDELAY) {
   1249 			splx(s);
   1250 			return (EWOULDBLOCK);
   1251 		}
   1252 		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
   1253 		    carrier ? ttyin : ttopen, 0);
   1254 		splx(s);
   1255 		if (error)
   1256 			return (error);
   1257 		goto loop;
   1258 	}
   1259 	splx(s);
   1260 
   1261 	/*
   1262 	 * Input present, check for input mapping and processing.
   1263 	 */
   1264 	first = 1;
   1265 	while ((c = getc(qp)) >= 0) {
   1266 		/*
   1267 		 * delayed suspend (^Y)
   1268 		 */
   1269 		if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) {
   1270 			pgsignal(tp->t_pgrp, SIGTSTP, 1);
   1271 			if (first) {
   1272 				if (error = ttysleep(tp,
   1273 				    &lbolt, TTIPRI | PCATCH, ttybg, 0))
   1274 					break;
   1275 				goto loop;
   1276 			}
   1277 			break;
   1278 		}
   1279 		/*
   1280 		 * Interpret EOF only in canonical mode.
   1281 		 */
   1282 		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
   1283 			break;
   1284 		/*
   1285 		 * Give user character.
   1286 		 */
   1287  		error = ureadc(c, uio);
   1288 		if (error)
   1289 			break;
   1290  		if (uio->uio_resid == 0)
   1291 			break;
   1292 		/*
   1293 		 * In canonical mode check for a "break character"
   1294 		 * marking the end of a "line of input".
   1295 		 */
   1296 		if (ISSET(lflag, ICANON) && TTBREAKC(c))
   1297 			break;
   1298 		first = 0;
   1299 	}
   1300 	/*
   1301 	 * Look to unblock output now that (presumably)
   1302 	 * the input queue has gone down.
   1303 	 */
   1304 	s = spltty();
   1305 	if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
   1306 		if (cc[VSTART] != _POSIX_VDISABLE &&
   1307 		    putc(cc[VSTART], &tp->t_outq) == 0) {
   1308 			CLR(tp->t_state, TS_TBLOCK);
   1309 			ttstart(tp);
   1310 		}
   1311 	}
   1312 	splx(s);
   1313 	return (error);
   1314 }
   1315 
   1316 /*
   1317  * Check the output queue on tp for space for a kernel message (from uprintf
   1318  * or tprintf).  Allow some space over the normal hiwater mark so we don't
   1319  * lose messages due to normal flow control, but don't let the tty run amok.
   1320  * Sleeps here are not interruptible, but we return prematurely if new signals
   1321  * arrive.
   1322  */
   1323 int
   1324 ttycheckoutq(tp, wait)
   1325 	register struct tty *tp;
   1326 	int wait;
   1327 {
   1328 	int hiwat, s, oldsig;
   1329 
   1330 	hiwat = tp->t_hiwat;
   1331 	s = spltty();
   1332 	oldsig = wait ? curproc->p_siglist : 0;
   1333 	if (tp->t_outq.c_cc > hiwat + 200)
   1334 		while (tp->t_outq.c_cc > hiwat) {
   1335 			ttstart(tp);
   1336 			if (wait == 0 || curproc->p_siglist != oldsig) {
   1337 				splx(s);
   1338 				return (0);
   1339 			}
   1340 			timeout((void (*)__P((void *)))wakeup,
   1341 			    (void *)&tp->t_outq, hz);
   1342 			SET(tp->t_state, TS_ASLEEP);
   1343 			sleep((caddr_t)&tp->t_outq, PZERO - 1);
   1344 		}
   1345 	splx(s);
   1346 	return (1);
   1347 }
   1348 
   1349 /*
   1350  * Process a write call on a tty device.
   1351  */
   1352 int
   1353 ttwrite(tp, uio, flag)
   1354 	register struct tty *tp;
   1355 	register struct uio *uio;
   1356 	int flag;
   1357 {
   1358 	register char *cp;
   1359 	register int cc, ce;
   1360 	register struct proc *p;
   1361 	int i, hiwat, cnt, error, s;
   1362 	char obuf[OBUFSIZ];
   1363 
   1364 	hiwat = tp->t_hiwat;
   1365 	cnt = uio->uio_resid;
   1366 	error = 0;
   1367 	cc = 0;
   1368 loop:
   1369 	s = spltty();
   1370 	if (!ISSET(tp->t_state, TS_CARR_ON) &&
   1371 	    !ISSET(tp->t_cflag, CLOCAL)) {
   1372 		if (ISSET(tp->t_state, TS_ISOPEN)) {
   1373 			splx(s);
   1374 			return (EIO);
   1375 		} else if (flag & IO_NDELAY) {
   1376 			splx(s);
   1377 			error = EWOULDBLOCK;
   1378 			goto out;
   1379 		} else {
   1380 			/* Sleep awaiting carrier. */
   1381 			error = ttysleep(tp,
   1382 			    &tp->t_rawq, TTIPRI | PCATCH,ttopen, 0);
   1383 			splx(s);
   1384 			if (error)
   1385 				goto out;
   1386 			goto loop;
   1387 		}
   1388 	}
   1389 	splx(s);
   1390 	/*
   1391 	 * Hang the process if it's in the background.
   1392 	 */
   1393 	p = curproc;
   1394 	if (isbackground(p, tp) &&
   1395 	    ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
   1396 	    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
   1397 	    (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
   1398 	     p->p_pgrp->pg_jobc) {
   1399 		pgsignal(p->p_pgrp, SIGTTOU, 1);
   1400 		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
   1401 			goto out;
   1402 		goto loop;
   1403 	}
   1404 	/*
   1405 	 * Process the user's data in at most OBUFSIZ chunks.  Perform any
   1406 	 * output translation.  Keep track of high water mark, sleep on
   1407 	 * overflow awaiting device aid in acquiring new space.
   1408 	 */
   1409 	while (uio->uio_resid > 0 || cc > 0) {
   1410 		if (ISSET(tp->t_lflag, FLUSHO)) {
   1411 			uio->uio_resid = 0;
   1412 			return (0);
   1413 		}
   1414 		if (tp->t_outq.c_cc > hiwat)
   1415 			goto ovhiwat;
   1416 		/*
   1417 		 * Grab a hunk of data from the user, unless we have some
   1418 		 * leftover from last time.
   1419 		 */
   1420 		if (cc == 0) {
   1421 			cc = min(uio->uio_resid, OBUFSIZ);
   1422 			cp = obuf;
   1423 			error = uiomove(cp, cc, uio);
   1424 			if (error) {
   1425 				cc = 0;
   1426 				break;
   1427 			}
   1428 		}
   1429 		/*
   1430 		 * If nothing fancy need be done, grab those characters we
   1431 		 * can handle without any of ttyoutput's processing and
   1432 		 * just transfer them to the output q.  For those chars
   1433 		 * which require special processing (as indicated by the
   1434 		 * bits in char_type), call ttyoutput.  After processing
   1435 		 * a hunk of data, look for FLUSHO so ^O's will take effect
   1436 		 * immediately.
   1437 		 */
   1438 		while (cc > 0) {
   1439 			if (!ISSET(tp->t_oflag, OPOST))
   1440 				ce = cc;
   1441 			else {
   1442 				ce = cc - scanc((u_int)cc, (u_char *)cp,
   1443 				   (u_char *)char_type, CCLASSMASK);
   1444 				/*
   1445 				 * If ce is zero, then we're processing
   1446 				 * a special character through ttyoutput.
   1447 				 */
   1448 				if (ce == 0) {
   1449 					tp->t_rocount = 0;
   1450 					if (ttyoutput(*cp, tp) >= 0) {
   1451 						/* No Clists, wait a bit. */
   1452 						ttstart(tp);
   1453 						if (error = ttysleep(tp, &lbolt,
   1454 						    TTOPRI | PCATCH, ttybuf, 0))
   1455 							break;
   1456 						goto loop;
   1457 					}
   1458 					cp++;
   1459 					cc--;
   1460 					if (ISSET(tp->t_lflag, FLUSHO) ||
   1461 					    tp->t_outq.c_cc > hiwat)
   1462 						goto ovhiwat;
   1463 					continue;
   1464 				}
   1465 			}
   1466 			/*
   1467 			 * A bunch of normal characters have been found.
   1468 			 * Transfer them en masse to the output queue and
   1469 			 * continue processing at the top of the loop.
   1470 			 * If there are any further characters in this
   1471 			 * <= OBUFSIZ chunk, the first should be a character
   1472 			 * requiring special handling by ttyoutput.
   1473 			 */
   1474 			tp->t_rocount = 0;
   1475 			i = b_to_q(cp, ce, &tp->t_outq);
   1476 			ce -= i;
   1477 			tp->t_column += ce;
   1478 			cp += ce, cc -= ce, tk_nout += ce;
   1479 			tp->t_outcc += ce;
   1480 			if (i > 0) {
   1481 				/* No Clists, wait a bit. */
   1482 				ttstart(tp);
   1483 				if (error = ttysleep(tp,
   1484 				    &lbolt, TTOPRI | PCATCH, ttybuf, 0))
   1485 					break;
   1486 				goto loop;
   1487 			}
   1488 			if (ISSET(tp->t_lflag, FLUSHO) ||
   1489 			    tp->t_outq.c_cc > hiwat)
   1490 				break;
   1491 		}
   1492 		ttstart(tp);
   1493 	}
   1494 out:
   1495 	/*
   1496 	 * If cc is nonzero, we leave the uio structure inconsistent, as the
   1497 	 * offset and iov pointers have moved forward, but it doesn't matter
   1498 	 * (the call will either return short or restart with a new uio).
   1499 	 */
   1500 	uio->uio_resid += cc;
   1501 	return (error);
   1502 
   1503 ovhiwat:
   1504 	ttstart(tp);
   1505 	s = spltty();
   1506 	/*
   1507 	 * This can only occur if FLUSHO is set in t_lflag,
   1508 	 * or if ttstart/oproc is synchronous (or very fast).
   1509 	 */
   1510 	if (tp->t_outq.c_cc <= hiwat) {
   1511 		splx(s);
   1512 		goto loop;
   1513 	}
   1514 	if (flag & IO_NDELAY) {
   1515 		splx(s);
   1516 		uio->uio_resid += cc;
   1517 		return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
   1518 	}
   1519 	SET(tp->t_state, TS_ASLEEP);
   1520 	error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
   1521 	splx(s);
   1522 	if (error)
   1523 		goto out;
   1524 	goto loop;
   1525 }
   1526 
   1527 /*
   1528  * Rubout one character from the rawq of tp
   1529  * as cleanly as possible.
   1530  */
   1531 void
   1532 ttyrub(c, tp)
   1533 	register int c;
   1534 	register struct tty *tp;
   1535 {
   1536 	register char *cp;
   1537 	register int savecol;
   1538 	int tabc, s;
   1539 
   1540 	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
   1541 		return;
   1542 	CLR(tp->t_lflag, FLUSHO);
   1543 	if (ISSET(tp->t_lflag, ECHOE)) {
   1544 		if (tp->t_rocount == 0) {
   1545 			/*
   1546 			 * Screwed by ttwrite; retype
   1547 			 */
   1548 			ttyretype(tp);
   1549 			return;
   1550 		}
   1551 		if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
   1552 			ttyrubo(tp, 2);
   1553 		else {
   1554 			CLR(c, ~TTY_CHARMASK);
   1555 			switch (CCLASS(c)) {
   1556 			case ORDINARY:
   1557 				ttyrubo(tp, 1);
   1558 				break;
   1559 			case BACKSPACE:
   1560 			case CONTROL:
   1561 			case NEWLINE:
   1562 			case RETURN:
   1563 			case VTAB:
   1564 				if (ISSET(tp->t_lflag, ECHOCTL))
   1565 					ttyrubo(tp, 2);
   1566 				break;
   1567 			case TAB:
   1568 				if (tp->t_rocount < tp->t_rawq.c_cc) {
   1569 					ttyretype(tp);
   1570 					return;
   1571 				}
   1572 				s = spltty();
   1573 				savecol = tp->t_column;
   1574 				SET(tp->t_state, TS_CNTTB);
   1575 				SET(tp->t_lflag, FLUSHO);
   1576 				tp->t_column = tp->t_rocol;
   1577 				cp = tp->t_rawq.c_cf;
   1578 				if (cp)
   1579 					tabc = *cp;	/* XXX FIX NEXTC */
   1580 				for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
   1581 					ttyecho(tabc, tp);
   1582 				CLR(tp->t_lflag, FLUSHO);
   1583 				CLR(tp->t_state, TS_CNTTB);
   1584 				splx(s);
   1585 
   1586 				/* savecol will now be length of the tab. */
   1587 				savecol -= tp->t_column;
   1588 				tp->t_column += savecol;
   1589 				if (savecol > 8)
   1590 					savecol = 8;	/* overflow screw */
   1591 				while (--savecol >= 0)
   1592 					(void)ttyoutput('\b', tp);
   1593 				break;
   1594 			default:			/* XXX */
   1595 #define	PANICSTR	"ttyrub: would panic c = %d, val = %d\n"
   1596 				(void)printf(PANICSTR, c, CCLASS(c));
   1597 #ifdef notdef
   1598 				panic(PANICSTR, c, CCLASS(c));
   1599 #endif
   1600 			}
   1601 		}
   1602 	} else if (ISSET(tp->t_lflag, ECHOPRT)) {
   1603 		if (!ISSET(tp->t_state, TS_ERASE)) {
   1604 			SET(tp->t_state, TS_ERASE);
   1605 			(void)ttyoutput('\\', tp);
   1606 		}
   1607 		ttyecho(c, tp);
   1608 	} else
   1609 		ttyecho(tp->t_cc[VERASE], tp);
   1610 	--tp->t_rocount;
   1611 }
   1612 
   1613 /*
   1614  * Back over cnt characters, erasing them.
   1615  */
   1616 static void
   1617 ttyrubo(tp, cnt)
   1618 	register struct tty *tp;
   1619 	int cnt;
   1620 {
   1621 
   1622 	while (cnt-- > 0) {
   1623 		(void)ttyoutput('\b', tp);
   1624 		(void)ttyoutput(' ', tp);
   1625 		(void)ttyoutput('\b', tp);
   1626 	}
   1627 }
   1628 
   1629 /*
   1630  * ttyretype --
   1631  *	Reprint the rawq line.  Note, it is assumed that c_cc has already
   1632  *	been checked.
   1633  */
   1634 void
   1635 ttyretype(tp)
   1636 	register struct tty *tp;
   1637 {
   1638 	register char *cp;
   1639 	int s, c;
   1640 
   1641 	/* Echo the reprint character. */
   1642 	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
   1643 		ttyecho(tp->t_cc[VREPRINT], tp);
   1644 
   1645 	(void)ttyoutput('\n', tp);
   1646 
   1647 	/*
   1648 	 * XXX
   1649 	 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
   1650 	 * BIT OF FIRST CHAR.
   1651 	 */
   1652 	s = spltty();
   1653 	for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
   1654 	    cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
   1655 		ttyecho(c, tp);
   1656 	for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
   1657 	    cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
   1658 		ttyecho(c, tp);
   1659 	CLR(tp->t_state, TS_ERASE);
   1660 	splx(s);
   1661 
   1662 	tp->t_rocount = tp->t_rawq.c_cc;
   1663 	tp->t_rocol = 0;
   1664 }
   1665 
   1666 /*
   1667  * Echo a typed character to the terminal.
   1668  */
   1669 static void
   1670 ttyecho(c, tp)
   1671 	register int c;
   1672 	register struct tty *tp;
   1673 {
   1674 
   1675 	if (!ISSET(tp->t_state, TS_CNTTB))
   1676 		CLR(tp->t_lflag, FLUSHO);
   1677 	if ((!ISSET(tp->t_lflag, ECHO) &&
   1678 	    (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) ||
   1679 	    ISSET(tp->t_lflag, EXTPROC))
   1680 		return;
   1681 	if (ISSET(tp->t_lflag, ECHOCTL) &&
   1682 	    (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' ||
   1683 	    ISSET(c, TTY_CHARMASK) == 0177)) {
   1684 		(void)ttyoutput('^', tp);
   1685 		CLR(c, ~TTY_CHARMASK);
   1686 		if (c == 0177)
   1687 			c = '?';
   1688 		else
   1689 			c += 'A' - 1;
   1690 	}
   1691 	(void)ttyoutput(c, tp);
   1692 }
   1693 
   1694 /*
   1695  * Wake up any readers on a tty.
   1696  */
   1697 void
   1698 ttwakeup(tp)
   1699 	register struct tty *tp;
   1700 {
   1701 
   1702 	selwakeup(&tp->t_rsel);
   1703 	if (ISSET(tp->t_state, TS_ASYNC))
   1704 		pgsignal(tp->t_pgrp, SIGIO, 1);
   1705 	wakeup((caddr_t)&tp->t_rawq);
   1706 }
   1707 
   1708 /*
   1709  * Look up a code for a specified speed in a conversion table;
   1710  * used by drivers to map software speed values to hardware parameters.
   1711  */
   1712 int
   1713 ttspeedtab(speed, table)
   1714 	int speed;
   1715 	register struct speedtab *table;
   1716 {
   1717 
   1718 	for ( ; table->sp_speed != -1; table++)
   1719 		if (table->sp_speed == speed)
   1720 			return (table->sp_code);
   1721 	return (-1);
   1722 }
   1723 
   1724 /*
   1725  * Set tty hi and low water marks.
   1726  *
   1727  * Try to arrange the dynamics so there's about one second
   1728  * from hi to low water.
   1729  *
   1730  */
   1731 void
   1732 ttsetwater(tp)
   1733 	struct tty *tp;
   1734 {
   1735 	register int cps, x;
   1736 
   1737 #define CLAMP(x, h, l)	((x) > h ? h : ((x) < l) ? l : (x))
   1738 
   1739 	cps = tp->t_ospeed / 10;
   1740 	tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
   1741 	x += cps;
   1742 	x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
   1743 	tp->t_hiwat = roundup(x, CBSIZE);
   1744 #undef	CLAMP
   1745 }
   1746 
   1747 /*
   1748  * Report on state of foreground process group.
   1749  */
   1750 void
   1751 ttyinfo(tp)
   1752 	register struct tty *tp;
   1753 {
   1754 	register struct proc *p, *pick;
   1755 	struct timeval utime, stime;
   1756 	int tmp;
   1757 
   1758 	if (ttycheckoutq(tp,0) == 0)
   1759 		return;
   1760 
   1761 	/* Print load average. */
   1762 	tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
   1763 	ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
   1764 
   1765 	if (tp->t_session == NULL)
   1766 		ttyprintf(tp, "not a controlling terminal\n");
   1767 	else if (tp->t_pgrp == NULL)
   1768 		ttyprintf(tp, "no foreground process group\n");
   1769 	else if ((p = tp->t_pgrp->pg_mem) == NULL)
   1770 		ttyprintf(tp, "empty foreground process group\n");
   1771 	else {
   1772 		/* Pick interesting process. */
   1773 		for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
   1774 			if (proc_compare(pick, p))
   1775 				pick = p;
   1776 
   1777 		ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
   1778 		    pick->p_stat == SRUN ? "running" :
   1779 		    pick->p_wmesg ? pick->p_wmesg : "iowait");
   1780 
   1781 		calcru(pick, &utime, &stime, NULL);
   1782 
   1783 		/* Print user time. */
   1784 		ttyprintf(tp, "%d.%02du ",
   1785 		    utime.tv_sec, (utime.tv_usec + 5000) / 10000);
   1786 
   1787 		/* Print system time. */
   1788 		ttyprintf(tp, "%d.%02ds ",
   1789 		    stime.tv_sec, (stime.tv_usec + 5000) / 10000);
   1790 
   1791 #define	pgtok(a)	(((a) * NBPG) / 1024)
   1792 		/* Print percentage cpu, resident set size. */
   1793 		tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT;
   1794 		ttyprintf(tp, "%d%% %dk\n",
   1795 		    tmp / 100,
   1796 		    pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
   1797 #ifdef pmap_resident_count
   1798 			pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap))
   1799 #else
   1800 			pgtok(pick->p_vmspace->vm_rssize)
   1801 #endif
   1802 			);
   1803 	}
   1804 	tp->t_rocount = 0;	/* so pending input will be retyped if BS */
   1805 }
   1806 
   1807 /*
   1808  * Returns 1 if p2 is "better" than p1
   1809  *
   1810  * The algorithm for picking the "interesting" process is thus:
   1811  *
   1812  *	1) Only foreground processes are eligible - implied.
   1813  *	2) Runnable processes are favored over anything else.  The runner
   1814  *	   with the highest cpu utilization is picked (p_estcpu).  Ties are
   1815  *	   broken by picking the highest pid.
   1816  *	3) The sleeper with the shortest sleep time is next.  With ties,
   1817  *	   we pick out just "short-term" sleepers (P_SINTR == 0).
   1818  *	4) Further ties are broken by picking the highest pid.
   1819  */
   1820 #define ISRUN(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
   1821 #define TESTAB(a, b)    ((a)<<1 | (b))
   1822 #define ONLYA   2
   1823 #define ONLYB   1
   1824 #define BOTH    3
   1825 
   1826 static int
   1827 proc_compare(p1, p2)
   1828 	register struct proc *p1, *p2;
   1829 {
   1830 
   1831 	if (p1 == NULL)
   1832 		return (1);
   1833 	/*
   1834 	 * see if at least one of them is runnable
   1835 	 */
   1836 	switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
   1837 	case ONLYA:
   1838 		return (0);
   1839 	case ONLYB:
   1840 		return (1);
   1841 	case BOTH:
   1842 		/*
   1843 		 * tie - favor one with highest recent cpu utilization
   1844 		 */
   1845 		if (p2->p_estcpu > p1->p_estcpu)
   1846 			return (1);
   1847 		if (p1->p_estcpu > p2->p_estcpu)
   1848 			return (0);
   1849 		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
   1850 	}
   1851 	/*
   1852  	 * weed out zombies
   1853 	 */
   1854 	switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
   1855 	case ONLYA:
   1856 		return (1);
   1857 	case ONLYB:
   1858 		return (0);
   1859 	case BOTH:
   1860 		return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
   1861 	}
   1862 	/*
   1863 	 * pick the one with the smallest sleep time
   1864 	 */
   1865 	if (p2->p_slptime > p1->p_slptime)
   1866 		return (0);
   1867 	if (p1->p_slptime > p2->p_slptime)
   1868 		return (1);
   1869 	/*
   1870 	 * favor one sleeping in a non-interruptible sleep
   1871 	 */
   1872 	if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
   1873 		return (1);
   1874 	if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
   1875 		return (0);
   1876 	return (p2->p_pid > p1->p_pid);		/* tie - return highest pid */
   1877 }
   1878 
   1879 /*
   1880  * Output char to tty; console putchar style.
   1881  */
   1882 int
   1883 tputchar(c, tp)
   1884 	int c;
   1885 	struct tty *tp;
   1886 {
   1887 	register int s;
   1888 
   1889 	s = spltty();
   1890 	if (ISSET(tp->t_state,
   1891 	    TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
   1892 		splx(s);
   1893 		return (-1);
   1894 	}
   1895 	if (c == '\n')
   1896 		(void)ttyoutput('\r', tp);
   1897 	(void)ttyoutput(c, tp);
   1898 	ttstart(tp);
   1899 	splx(s);
   1900 	return (0);
   1901 }
   1902 
   1903 /*
   1904  * Sleep on chan, returning ERESTART if tty changed while we napped and
   1905  * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep.  If
   1906  * the tty is revoked, restarting a pending call will redo validation done
   1907  * at the start of the call.
   1908  */
   1909 int
   1910 ttysleep(tp, chan, pri, wmesg, timo)
   1911 	struct tty *tp;
   1912 	void *chan;
   1913 	int pri, timo;
   1914 	char *wmesg;
   1915 {
   1916 	int error;
   1917 	short gen;
   1918 
   1919 	gen = tp->t_gen;
   1920 	if (error = tsleep(chan, pri, wmesg, timo))
   1921 		return (error);
   1922 	return (tp->t_gen == gen ? 0 : ERESTART);
   1923 }
   1924