tty.c revision 86472
129415Sjmg/*- 250723Scg * Copyright (c) 1982, 1986, 1990, 1991, 1993 339899Sluigi * The Regents of the University of California. All rights reserved. 429415Sjmg * (c) UNIX System Laboratories, Inc. 529415Sjmg * All or some portions of this file are derived from material licensed 629415Sjmg * to the University of California by American Telephone and Telegraph 729415Sjmg * Co. or Unix System Laboratories, Inc. and are reproduced herein with 850723Scg * the permission of UNIX System Laboratories, Inc. 950723Scg * 1029415Sjmg * Redistribution and use in source and binary forms, with or without 1129415Sjmg * modification, are permitted provided that the following conditions 1230869Sjmg * are met: 1330869Sjmg * 1. Redistributions of source code must retain the above copyright 1430869Sjmg * notice, this list of conditions and the following disclaimer. 1530869Sjmg * 2. Redistributions in binary form must reproduce the above copyright 1650723Scg * notice, this list of conditions and the following disclaimer in the 1750723Scg * documentation and/or other materials provided with the distribution. 1830869Sjmg * 3. All advertising materials mentioning features or use of this software 1950723Scg * must display the following acknowledgement: 2050723Scg * This product includes software developed by the University of 2150723Scg * California, Berkeley and its contributors. 2250723Scg * 4. Neither the name of the University nor the names of its contributors 2350723Scg * may be used to endorse or promote products derived from this software 2450723Scg * without specific prior written permission. 2550723Scg * 2650723Scg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2750723Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2850723Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2950723Scg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3050723Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3150959Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3229415Sjmg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3329415Sjmg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3453465Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3529415Sjmg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3653553Stanimura * SUCH DAMAGE. 3753553Stanimura * 3829415Sjmg * @(#)tty.c 8.8 (Berkeley) 1/21/94 3953465Scg * $FreeBSD: head/sys/kern/tty.c 86472 2001-11-16 23:53:48Z peter $ 4053553Stanimura */ 4129415Sjmg 4255254Scg/*- 4355706Scg * TODO: 4455254Scg * o Fix races for sending the start char in ttyflush(). 4550723Scg * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect(). 4650723Scg * With luck, there will be MIN chars before select() returns(). 4750723Scg * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it. 4850723Scg * o Don't allow input in TS_ZOMBIE case. It would be visible through 4950723Scg * FIONREAD. 5050723Scg * o Do the new sio locking stuff here and use it to avoid special 5150723Scg * case for EXTPROC? 5250723Scg * o Lock PENDIN too? 5350723Scg * o Move EXTPROC and/or PENDIN to t_state? 5429415Sjmg * o Wrap most of ttioctl in spltty/splx. 5550925Scg * o Implement TIOCNOTTY or remove it from <sys/ioctl.h>. 5650925Scg * o Send STOP if IXOFF is toggled off while TS_TBLOCK is set. 5750925Scg * o Don't allow certain termios flags to affect disciplines other 5850925Scg * than TTYDISC. Cancel their effects before switch disciplines 5950925Scg * and ignore them if they are set while we are in another 6050925Scg * discipline. 6150925Scg * o Now that historical speed conversions are handled here, don't 6250925Scg * do them in drivers. 6350925Scg * o Check for TS_CARR_ON being set while everything is closed and not 6454462Scg * waiting for carrier. TS_CARR_ON isn't cleared if nothing is open, 6550723Scg * so it would live until the next open even if carrier drops. 6650723Scg * o Restore TS_WOPEN since it is useful in pstat. It must be cleared 6750723Scg * only when _all_ openers leave open(). 6850723Scg */ 6950723Scg 7029415Sjmg#include "opt_compat.h" 7150723Scg#include "opt_uconsole.h" 7250723Scg 7350723Scg#include <sys/param.h> 7450723Scg#include <sys/systm.h> 7550723Scg#include <sys/filio.h> 7629415Sjmg#include <sys/lock.h> 7750723Scg#include <sys/mutex.h> 7850723Scg#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 7950723Scg#include <sys/ioctl_compat.h> 8050723Scg#endif 8150723Scg#include <sys/proc.h> 8229415Sjmg#define TTYDEFCHARS 8350723Scg#include <sys/tty.h> 8450723Scg#undef TTYDEFCHARS 8550723Scg#include <sys/fcntl.h> 8650723Scg#include <sys/conf.h> 8750723Scg#include <sys/dkstat.h> 8829415Sjmg#include <sys/poll.h> 8954462Scg#include <sys/kernel.h> 9050723Scg#include <sys/vnode.h> 9150723Scg#include <sys/signalvar.h> 9250723Scg#include <sys/resourcevar.h> 9350723Scg#include <sys/malloc.h> 9429415Sjmg#include <sys/filedesc.h> 9554462Scg#include <sys/sysctl.h> 9650723Scg 9750723Scg#include <vm/vm.h> 9850723Scg#include <vm/pmap.h> 9950723Scg#include <vm/vm_map.h> 10029415Sjmg 10154462ScgMALLOC_DEFINE(M_TTYS, "ttys", "tty data structures"); 10254462Scg 10354823Scgstatic int proc_compare __P((struct proc *p1, struct proc *p2)); 10454823Scgstatic int ttnread __P((struct tty *tp)); 10554462Scgstatic void ttyecho __P((int c, struct tty *tp)); 10654462Scgstatic int ttyoutput __P((int c, register struct tty *tp)); 10750723Scgstatic void ttypend __P((struct tty *tp)); 10850723Scgstatic void ttyretype __P((struct tty *tp)); 10950723Scgstatic void ttyrub __P((int c, struct tty *tp)); 11050723Scgstatic void ttyrubo __P((struct tty *tp, int cnt)); 11150723Scgstatic void ttyunblock __P((struct tty *tp)); 11229415Sjmgstatic int ttywflush __P((struct tty *tp)); 11350723Scgstatic int filt_ttyread __P((struct knote *kn, long hint)); 11450723Scgstatic void filt_ttyrdetach __P((struct knote *kn)); 11550723Scgstatic int filt_ttywrite __P((struct knote *kn, long hint)); 11650723Scgstatic void filt_ttywdetach __P((struct knote *kn)); 11750723Scg 11829415Sjmg/* 11950723Scg * Table with character classes and parity. The 8th bit indicates parity, 12050723Scg * the 7th bit indicates the character is an alphameric or underscore (for 12150723Scg * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits 12250723Scg * are 0 then the character needs no special processing on output; classes 12350723Scg * other than 0 might be translated or (not currently) require delays. 12450723Scg */ 12550723Scg#define E 0x00 /* Even parity. */ 12650723Scg#define O 0x80 /* Odd parity. */ 12750723Scg#define PARITY(c) (char_type[c] & O) 12850723Scg 12929415Sjmg#define ALPHA 0x40 /* Alpha or underscore. */ 13050925Scg#define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA) 13155254Scg 13250925Scg#define CCLASSMASK 0x3f 13350925Scg#define CCLASS(c) (char_type[c] & CCLASSMASK) 13450925Scg 13550925Scg#define BS BACKSPACE 13650925Scg#define CC CONTROL 13750925Scg#define CR RETURN 13850925Scg#define NA ORDINARY | ALPHA 13950925Scg#define NL NEWLINE 14029415Sjmg#define NO ORDINARY 14150723Scg#define TB TAB 14229415Sjmg#define VT VTAB 14350723Scg 14450723Scgstatic u_char const char_type[] = { 14550723Scg E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */ 14650723Scg O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */ 14750723Scg O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */ 14855706Scg E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */ 14950925Scg O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */ 15050723Scg E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */ 15129415Sjmg E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */ 15250723Scg O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */ 15350723Scg O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */ 15450723Scg E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */ 15554462Scg E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */ 15654462Scg O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */ 15755706Scg E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */ 15829415Sjmg O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */ 15950723Scg O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */ 16050723Scg E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */ 16150723Scg /* 16250723Scg * Meta chars; should be settable per character set; 16350723Scg * for now, treat them all as normal characters. 16450723Scg */ 16550723Scg NA, NA, NA, NA, NA, NA, NA, NA, 16650723Scg NA, NA, NA, NA, NA, NA, NA, NA, 16750723Scg NA, NA, NA, NA, NA, NA, NA, NA, 16850723Scg NA, NA, NA, NA, NA, NA, NA, NA, 16950723Scg NA, NA, NA, NA, NA, NA, NA, NA, 17050723Scg NA, NA, NA, NA, NA, NA, NA, NA, 17150723Scg NA, NA, NA, NA, NA, NA, NA, NA, 17250723Scg NA, NA, NA, NA, NA, NA, NA, NA, 17354462Scg NA, NA, NA, NA, NA, NA, NA, NA, 17429415Sjmg NA, NA, NA, NA, NA, NA, NA, NA, 17550723Scg NA, NA, NA, NA, NA, NA, NA, NA, 17655706Scg NA, NA, NA, NA, NA, NA, NA, NA, 17750723Scg NA, NA, NA, NA, NA, NA, NA, NA, 17850723Scg NA, NA, NA, NA, NA, NA, NA, NA, 17950723Scg NA, NA, NA, NA, NA, NA, NA, NA, 18054462Scg NA, NA, NA, NA, NA, NA, NA, NA, 18154462Scg}; 18254462Scg#undef BS 18350925Scg#undef CC 18450925Scg#undef CR 18550925Scg#undef NA 18650925Scg#undef NL 18750925Scg#undef NO 18854462Scg#undef TB 18950723Scg#undef VT 19050723Scg 19150723Scg/* Macros to clear/set/test flags. */ 19250723Scg#define SET(t, f) (t) |= (f) 19350723Scg#define CLR(t, f) (t) &= ~(f) 19450723Scg#define ISSET(t, f) ((t) & (f)) 19550723Scg 19650723Scg#undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */ 19750723Scg#define MAX_INPUT TTYHOG /* XXX limit is usually larger for !ICANON */ 19850723Scg 19950723Scg/* 20050723Scg * list of struct tty where pstat(8) can pick it up with sysctl 20150723Scg */ 20229415Sjmgstatic SLIST_HEAD(, tty) tty_list; 20350723Scg 20429415Sjmgstatic int drainwait = 5*60; 20550723ScgSYSCTL_INT(_kern, OID_AUTO, drainwait, CTLFLAG_RW, &drainwait, 20650723Scg 0, "Output drain timeout in seconds"); 20750723Scg 20850723Scg/* 20950723Scg * Initial open of tty, or (re)entry to standard tty line discipline. 21050723Scg */ 21150723Scgint 21229415Sjmgttyopen(device, tp) 21329415Sjmg dev_t device; 21429415Sjmg register struct tty *tp; 21550723Scg{ 21629415Sjmg int s; 21750723Scg 21850723Scg s = spltty(); 21950723Scg tp->t_dev = device; 22050723Scg if (!ISSET(tp->t_state, TS_ISOPEN)) { 22129415Sjmg SET(tp->t_state, TS_ISOPEN); 22250723Scg if (ISSET(tp->t_cflag, CLOCAL)) 22350723Scg SET(tp->t_state, TS_CONNECTED); 22450723Scg bzero(&tp->t_winsize, sizeof(tp->t_winsize)); 22550723Scg } 22650723Scg /* XXX don't hang forever on output */ 22750723Scg if (tp->t_timeout < 0) 22829415Sjmg tp->t_timeout = drainwait*hz; 22929415Sjmg ttsetwater(tp); 23029415Sjmg splx(s); 23150723Scg return (0); 23229415Sjmg} 23350723Scg 23450723Scg/* 23529415Sjmg * Handle close() on a tty line: flush and set to initial state, 23650723Scg * bumping generation number so that pending read/write calls 23750723Scg * can detect recycling of the tty. 23850723Scg * XXX our caller should have done `spltty(); l_close(); ttyclose();' 23950723Scg * and l_close() should have flushed, but we repeat the spltty() and 24029415Sjmg * the flush in case there are buggy callers. 24129415Sjmg */ 24250723Scgint 24350723Scgttyclose(tp) 24450723Scg register struct tty *tp; 24550723Scg{ 24650723Scg int s; 24729415Sjmg 24829415Sjmg funsetown(tp->t_sigio); 24950723Scg s = spltty(); 25029415Sjmg if (constty == tp) 25150723Scg constty = NULL; 25229415Sjmg 25350723Scg ttyflush(tp, FREAD | FWRITE); 25450723Scg clist_free_cblocks(&tp->t_canq); 25550723Scg clist_free_cblocks(&tp->t_outq); 25650723Scg clist_free_cblocks(&tp->t_rawq); 25750723Scg 25850723Scg tp->t_gen++; 25950723Scg tp->t_line = TTYDISC; 26050723Scg tp->t_pgrp = NULL; 26150723Scg tp->t_session = NULL; 26250723Scg tp->t_state = 0; 26329415Sjmg splx(s); 26450723Scg return (0); 26550723Scg} 26650723Scg 26750723Scg#define FLUSHQ(q) { \ 26850723Scg if ((q)->c_cc) \ 26950723Scg ndflush(q, (q)->c_cc); \ 27050723Scg} 27150723Scg 27229415Sjmg/* Is 'c' a line delimiter ("break" character)? */ 27350723Scg#define TTBREAKC(c, lflag) \ 27450723Scg ((c) == '\n' || (((c) == cc[VEOF] || \ 27550723Scg (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \ 27650723Scg (c) != _POSIX_VDISABLE)) 27750723Scg 27850723Scg/* 27950723Scg * Process input of a single character received on a tty. 28050723Scg */ 28150723Scgint 28250723Scgttyinput(c, tp) 28329415Sjmg register int c; 28450723Scg register struct tty *tp; 28550723Scg{ 28650723Scg register tcflag_t iflag, lflag; 28750723Scg register cc_t *cc; 28850723Scg int i, err; 28950723Scg 29050723Scg /* 29150723Scg * If input is pending take it first. 29250723Scg */ 29350723Scg lflag = tp->t_lflag; 29450723Scg if (ISSET(lflag, PENDIN)) 29529415Sjmg ttypend(tp); 29650723Scg /* 29750723Scg * Gather stats. 29850723Scg */ 29950723Scg if (ISSET(lflag, ICANON)) { 30050723Scg ++tk_cancc; 30150723Scg ++tp->t_cancc; 30250723Scg } else { 30350723Scg ++tk_rawcc; 30429415Sjmg ++tp->t_rawcc; 30550723Scg } 30650723Scg ++tk_nin; 30750723Scg 30850723Scg /* 30950723Scg * Block further input iff: 31050723Scg * current input > threshold AND input is available to user program 31150723Scg * AND input flow control is enabled and not yet invoked. 31231361Sjmg * The 3 is slop for PARMRK. 31350723Scg */ 31450723Scg iflag = tp->t_iflag; 31550723Scg if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 && 31650723Scg (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) && 31750723Scg (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) && 31829415Sjmg !ISSET(tp->t_state, TS_TBLOCK)) 31950723Scg ttyblock(tp); 32050723Scg 32150723Scg /* Handle exceptional conditions (break, parity, framing). */ 32250723Scg cc = tp->t_cc; 32350723Scg err = (ISSET(c, TTY_ERRORMASK)); 32450723Scg if (err) { 32529415Sjmg CLR(c, TTY_ERRORMASK); 32650723Scg if (ISSET(err, TTY_BI)) { 32750723Scg if (ISSET(iflag, IGNBRK)) 32829415Sjmg return (0); 32950723Scg if (ISSET(iflag, BRKINT)) { 33050723Scg ttyflush(tp, FREAD | FWRITE); 33150723Scg pgsignal(tp->t_pgrp, SIGINT, 1); 33250723Scg goto endcase; 33329415Sjmg } 33450723Scg if (ISSET(iflag, PARMRK)) 33550723Scg goto parmrk; 33650723Scg } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK)) 33750723Scg || ISSET(err, TTY_FE)) { 33850723Scg if (ISSET(iflag, IGNPAR)) 33950723Scg return (0); 34050723Scg else if (ISSET(iflag, PARMRK)) { 34150723Scgparmrk: 34229415Sjmg if (tp->t_rawq.c_cc + tp->t_canq.c_cc > 34350723Scg MAX_INPUT - 3) 34450723Scg goto input_overflow; 34550723Scg (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 34650723Scg (void)putc(0 | TTY_QUOTE, &tp->t_rawq); 34729415Sjmg (void)putc(c | TTY_QUOTE, &tp->t_rawq); 34829415Sjmg goto endcase; 34929415Sjmg } else 35050723Scg c = 0; 35129415Sjmg } 35250723Scg } 35329415Sjmg 35429415Sjmg if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP)) 35529415Sjmg CLR(c, 0x80); 35650723Scg if (!ISSET(lflag, EXTPROC)) { 35729415Sjmg /* 35850723Scg * Check for literal nexting very first 35950723Scg */ 36050723Scg if (ISSET(tp->t_state, TS_LNCH)) { 36150723Scg SET(c, TTY_QUOTE); 36250723Scg CLR(tp->t_state, TS_LNCH); 36350723Scg } 36450723Scg /* 36550723Scg * Scan for special characters. This code 36655706Scg * is really just a big case statement with 36755706Scg * non-constant cases. The bottom of the 36850723Scg * case statement is labeled ``endcase'', so goto 36929415Sjmg * it after a case match, or similar. 37029415Sjmg */ 37129415Sjmg 37250723Scg /* 37329415Sjmg * Control chars which aren't controlled 37450723Scg * by ICANON, ISIG, or IXON. 37550723Scg */ 37654462Scg if (ISSET(lflag, IEXTEN)) { 37750723Scg if (CCEQ(cc[VLNEXT], c)) { 37850723Scg if (ISSET(lflag, ECHO)) { 37950723Scg if (ISSET(lflag, ECHOE)) { 38054462Scg (void)ttyoutput('^', tp); 38150723Scg (void)ttyoutput('\b', tp); 38250723Scg } else 38350723Scg ttyecho(c, tp); 38454462Scg } 38550723Scg SET(tp->t_state, TS_LNCH); 38650723Scg goto endcase; 38750723Scg } 38854462Scg if (CCEQ(cc[VDISCARD], c)) { 38950723Scg if (ISSET(lflag, FLUSHO)) 39050723Scg CLR(tp->t_lflag, FLUSHO); 39150723Scg else { 39250723Scg ttyflush(tp, FWRITE); 39329415Sjmg ttyecho(c, tp); 39450723Scg if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 39550723Scg ttyretype(tp); 39650723Scg SET(tp->t_lflag, FLUSHO); 39754462Scg } 39854462Scg goto startoutput; 39954462Scg } 40050723Scg } 40150723Scg /* 40254462Scg * Signals. 40350723Scg */ 40454462Scg if (ISSET(lflag, ISIG)) { 40550723Scg if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) { 40650723Scg if (!ISSET(lflag, NOFLSH)) 40754462Scg ttyflush(tp, FREAD | FWRITE); 40850723Scg ttyecho(c, tp); 40954462Scg pgsignal(tp->t_pgrp, 41050723Scg CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1); 41150723Scg goto endcase; 41254462Scg } 41350723Scg if (CCEQ(cc[VSUSP], c)) { 41454462Scg if (!ISSET(lflag, NOFLSH)) 41554845Scg ttyflush(tp, FREAD); 41650723Scg ttyecho(c, tp); 41754462Scg pgsignal(tp->t_pgrp, SIGTSTP, 1); 41850723Scg goto endcase; 41929415Sjmg } 42050723Scg } 42155424Scg /* 42255424Scg * Handle start/stop characters. 42354462Scg */ 42455424Scg if (ISSET(iflag, IXON)) { 42529415Sjmg if (CCEQ(cc[VSTOP], c)) { 42650723Scg if (!ISSET(tp->t_state, TS_TTSTOP)) { 42754462Scg SET(tp->t_state, TS_TTSTOP); 42855424Scg (*tp->t_stop)(tp, 0); 42954462Scg return (0); 43050723Scg } 43150723Scg if (!CCEQ(cc[VSTART], c)) 43250723Scg return (0); 43329415Sjmg /* 43429415Sjmg * if VSTART == VSTOP then toggle 43554462Scg */ 43654462Scg goto endcase; 43729415Sjmg } 43854462Scg if (CCEQ(cc[VSTART], c)) 43954462Scg goto restartoutput; 44054462Scg } 44154462Scg /* 44254462Scg * IGNCR, ICRNL, & INLCR 44354462Scg */ 44429415Sjmg if (c == '\r') { 44554462Scg if (ISSET(iflag, IGNCR)) 44655706Scg return (0); 44755706Scg else if (ISSET(iflag, ICRNL)) 44855706Scg c = '\n'; 44955706Scg } else if (c == '\n' && ISSET(iflag, INLCR)) 45055706Scg c = '\r'; 45155706Scg } 45255706Scg if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) { 45354462Scg /* 45454462Scg * From here on down canonical mode character 45529415Sjmg * processing takes place. 45654462Scg */ 45754462Scg /* 45854462Scg * erase or erase2 (^H / ^?) 45954462Scg */ 46054462Scg if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c) ) { 46131361Sjmg if (tp->t_rawq.c_cc) 46254462Scg ttyrub(unputc(&tp->t_rawq), tp); 46350723Scg goto endcase; 46441653Sbrian } 46550723Scg /* 46650723Scg * kill (^U) 46729415Sjmg */ 46850723Scg if (CCEQ(cc[VKILL], c)) { 46950723Scg if (ISSET(lflag, ECHOKE) && 47050723Scg tp->t_rawq.c_cc == tp->t_rocount && 47155428Scg !ISSET(lflag, ECHOPRT)) 47229415Sjmg while (tp->t_rawq.c_cc) 47355706Scg ttyrub(unputc(&tp->t_rawq), tp); 47455706Scg else { 47555706Scg ttyecho(c, tp); 47655706Scg if (ISSET(lflag, ECHOK) || 47754462Scg ISSET(lflag, ECHOKE)) 47829415Sjmg ttyecho('\n', tp); 47950925Scg FLUSHQ(&tp->t_rawq); 48050925Scg tp->t_rocount = 0; 48150925Scg } 48250925Scg CLR(tp->t_state, TS_LOCAL); 48354462Scg goto endcase; 48454462Scg } 48554462Scg /* 48654462Scg * word erase (^W) 48729415Sjmg */ 48850723Scg if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) { 48950723Scg int ctype; 49050723Scg 49150723Scg /* 49255428Scg * erase whitespace 49350723Scg */ 49450723Scg while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t') 49550723Scg ttyrub(c, tp); 49650723Scg if (c == -1) 49750723Scg goto endcase; 49829415Sjmg /* 49954462Scg * erase last char of word and remember the 50050723Scg * next chars type (for ALTWERASE) 50154462Scg */ 50255706Scg ttyrub(c, tp); 50355706Scg c = unputc(&tp->t_rawq); 50455706Scg if (c == -1) 50529415Sjmg goto endcase; 50655706Scg if (c == ' ' || c == '\t') { 50755706Scg (void)putc(c, &tp->t_rawq); 50850925Scg goto endcase; 50950925Scg } 51050925Scg ctype = ISALPHA(c); 51150925Scg /* 51250925Scg * erase rest of word 51350925Scg */ 51450925Scg do { 51550723Scg ttyrub(c, tp); 51629415Sjmg c = unputc(&tp->t_rawq); 51750723Scg if (c == -1) 51829415Sjmg goto endcase; 51950723Scg } while (c != ' ' && c != '\t' && 52050723Scg (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype)); 52150723Scg (void)putc(c, &tp->t_rawq); 52250723Scg goto endcase; 52329415Sjmg } 52450723Scg /* 52550723Scg * reprint line (^R) 52650723Scg */ 52750723Scg if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) { 52850723Scg ttyretype(tp); 52929415Sjmg goto endcase; 53050723Scg } 53150723Scg /* 53250723Scg * ^T - kernel info and generate SIGINFO 53350723Scg */ 53450723Scg if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) { 53550723Scg if (ISSET(lflag, ISIG)) 53650723Scg pgsignal(tp->t_pgrp, SIGINFO, 1); 53750723Scg if (!ISSET(lflag, NOKERNINFO)) 53850723Scg ttyinfo(tp); 53950723Scg goto endcase; 54050723Scg } 54150723Scg } 54250723Scg /* 54350723Scg * Check for input buffer overflow 54455706Scg */ 54555706Scg if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) { 54655706Scginput_overflow: 54755706Scg if (ISSET(iflag, IMAXBEL)) { 54850723Scg if (tp->t_outq.c_cc < tp->t_ohiwat) 54950723Scg (void)ttyoutput(CTRL('g'), tp); 55055706Scg } 55155706Scg goto endcase; 55255706Scg } 55355706Scg 55450723Scg if ( c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP) 55550723Scg && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR)) 55650723Scg (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 55750723Scg 55850723Scg /* 55950723Scg * Put data char in q for user and 56050723Scg * wakeup on seeing a line delimiter. 56150723Scg */ 56250723Scg if (putc(c, &tp->t_rawq) >= 0) { 56355706Scg if (!ISSET(lflag, ICANON)) { 56455706Scg ttwakeup(tp); 56555706Scg ttyecho(c, tp); 56655706Scg goto endcase; 56750723Scg } 56831361Sjmg if (TTBREAKC(c, lflag)) { 56950925Scg tp->t_rocount = 0; 57050925Scg catq(&tp->t_rawq, &tp->t_canq); 57150925Scg ttwakeup(tp); 57255706Scg } else if (tp->t_rocount++ == 0) 57355706Scg tp->t_rocol = tp->t_column; 57455706Scg if (ISSET(tp->t_state, TS_ERASE)) { 57550925Scg /* 57655706Scg * end of prterase \.../ 57755706Scg */ 57855706Scg CLR(tp->t_state, TS_ERASE); 57955706Scg (void)ttyoutput('/', tp); 58055706Scg } 58150925Scg i = tp->t_column; 58255706Scg ttyecho(c, tp); 58355706Scg if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) { 58455706Scg /* 58555706Scg * Place the cursor over the '^' of the ^D. 58655706Scg */ 58755706Scg i = imin(2, tp->t_column - i); 58855706Scg while (i > 0) { 58955706Scg (void)ttyoutput('\b', tp); 59055706Scg i--; 59155706Scg } 59255706Scg } 59355706Scg } 59450925Scgendcase: 59551768Scg /* 59650723Scg * IXANY means allow any character to restart output. 59755706Scg */ 59850723Scg if (ISSET(tp->t_state, TS_TTSTOP) && 59950723Scg !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) 60050723Scg return (0); 60150723Scgrestartoutput: 60255706Scg CLR(tp->t_lflag, FLUSHO); 60329415Sjmg CLR(tp->t_state, TS_TTSTOP); 60450723Scgstartoutput: 60550723Scg return (ttstart(tp)); 60650723Scg} 60750723Scg 60850723Scg/* 60950723Scg * Output a single character on a tty, doing output processing 61050723Scg * as needed (expanding tabs, newline processing, etc.). 61150723Scg * Returns < 0 if succeeds, otherwise returns char to resend. 61250723Scg * Must be recursive. 61329415Sjmg */ 61450723Scgstatic int 61555706Scgttyoutput(c, tp) 61655706Scg register int c; 61729415Sjmg register struct tty *tp; 61850723Scg{ 61950723Scg register tcflag_t oflag; 62050723Scg register int col, s; 62150723Scg 62250723Scg oflag = tp->t_oflag; 62350723Scg if (!ISSET(oflag, OPOST)) { 62455706Scg if (ISSET(tp->t_lflag, FLUSHO)) 62555706Scg return (-1); 62655706Scg if (putc(c, &tp->t_outq)) 62755706Scg return (c); 62855706Scg tk_nout++; 62950723Scg tp->t_outcc++; 63050723Scg return (-1); 63155706Scg } 63255706Scg /* 63329415Sjmg * Do tab expansion if OXTABS is set. Special case if we external 63450723Scg * processing, we don't do the tab expansion because we'll probably 63550723Scg * get it wrong. If tab expansion needs to be done, let it happen 63650723Scg * externally. 63750723Scg */ 63850723Scg CLR(c, ~TTY_CHARMASK); 63950723Scg if (c == '\t' && 64050723Scg ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) { 64150723Scg c = 8 - (tp->t_column & 7); 64250723Scg if (!ISSET(tp->t_lflag, FLUSHO)) { 64350723Scg s = spltty(); /* Don't interrupt tabs. */ 64450723Scg c -= b_to_q(" ", c, &tp->t_outq); 64550723Scg tk_nout += c; 64650723Scg tp->t_outcc += c; 64750723Scg splx(s); 64850723Scg } 64950723Scg tp->t_column += c; 65050723Scg return (c ? -1 : '\t'); 65150723Scg } 65250723Scg if (c == CEOT && ISSET(oflag, ONOEOT)) 65350723Scg return (-1); 65455706Scg 65555706Scg /* 65650723Scg * Newline translation: if ONLCR is set, 65755706Scg * translate newline into "\r\n". 65850723Scg */ 65929415Sjmg if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) { 66029415Sjmg tk_nout++; 66150723Scg tp->t_outcc++; 66250723Scg if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq)) 66350723Scg return (c); 66450723Scg } 66550723Scg /* If OCRNL is set, translate "\r" into "\n". */ 66650723Scg else if (c == '\r' && ISSET(tp->t_oflag, OCRNL)) 66750723Scg c = '\n'; 66850723Scg /* If ONOCR is set, don't transmit CRs when on column 0. */ 66954462Scg else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0) 67054791Scg return (-1); 67129415Sjmg 67255706Scg tk_nout++; 67355706Scg tp->t_outcc++; 67450723Scg if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) 67555706Scg return (c); 67655706Scg 67755706Scg col = tp->t_column; 67855706Scg switch (CCLASS(c)) { 67950723Scg case BACKSPACE: 68055706Scg if (col > 0) 68155706Scg --col; 68255706Scg break; 68355706Scg case CONTROL: 68455706Scg break; 68555706Scg case NEWLINE: 68650723Scg if (ISSET(tp->t_oflag, ONLCR | ONLRET)) 68755706Scg col = 0; 68855706Scg break; 68955706Scg case RETURN: 69055706Scg col = 0; 69155706Scg break; 69255706Scg case ORDINARY: 69355706Scg ++col; 69450723Scg break; 69550723Scg case TAB: 69650723Scg col = (col + 8) & ~7; 69750723Scg break; 69850723Scg } 69950723Scg tp->t_column = col; 70050723Scg return (-1); 70129415Sjmg} 70250723Scg 70350723Scg/* 70450723Scg * Ioctls for all tty devices. Called after line-discipline specific ioctl 70529415Sjmg * has been called to do discipline-specific functions and/or reject any 70655706Scg * of these ioctl commands. 70755706Scg */ 70850723Scg/* ARGSUSED */ 70950723Scgint 71050723Scgttioctl(tp, cmd, data, flag) 71150723Scg register struct tty *tp; 71250723Scg u_long cmd; 71350723Scg int flag; 71450723Scg void *data; 71550723Scg{ 71650723Scg register struct proc *p; 71729415Sjmg int s, error; 71855706Scg 71955706Scg p = curproc; /* XXX */ 72050723Scg 72150723Scg /* If the ioctl involves modification, hang if in the background. */ 72250723Scg switch (cmd) { 72329415Sjmg case TIOCCBRK: 72455706Scg case TIOCCONS: 72555706Scg case TIOCDRAIN: 72655706Scg case TIOCEXCL: 72755706Scg case TIOCFLUSH: 72855706Scg#ifdef TIOCHPCL 72955706Scg case TIOCHPCL: 73055706Scg#endif 73155706Scg case TIOCNXCL: 73255706Scg case TIOCSBRK: 73355706Scg case TIOCSCTTY: 73455706Scg case TIOCSDRAINWAIT: 73555706Scg case TIOCSETA: 73655706Scg case TIOCSETAF: 73755706Scg case TIOCSETAW: 73855706Scg case TIOCSETD: 73955706Scg case TIOCSPGRP: 74055706Scg case TIOCSTART: 74155706Scg case TIOCSTAT: 74255706Scg case TIOCSTI: 74355706Scg case TIOCSTOP: 74455706Scg case TIOCSWINSZ: 74555706Scg#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 74655706Scg case TIOCLBIC: 74755706Scg case TIOCLBIS: 74855706Scg case TIOCLSET: 74955706Scg case TIOCSETC: 75055706Scg case OTIOCSETD: 75155706Scg case TIOCSETN: 75255706Scg case TIOCSETP: 75355706Scg case TIOCSLTC: 75455706Scg#endif 75555706Scg while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) && 75655706Scg !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 75755706Scg !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { 75855706Scg if (p->p_pgrp->pg_jobc == 0) 75955706Scg return (EIO); 76055706Scg pgsignal(p->p_pgrp, SIGTTOU, 1); 76155706Scg error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1", 76255706Scg 0); 76355706Scg if (error) 76455706Scg return (error); 76555706Scg } 76655706Scg break; 76755706Scg } 76855706Scg 76955706Scg switch (cmd) { /* Process the ioctl. */ 77055706Scg case FIOASYNC: /* set/clear async i/o */ 77155706Scg s = spltty(); 77255706Scg if (*(int *)data) 77355706Scg SET(tp->t_state, TS_ASYNC); 77455706Scg else 77555706Scg CLR(tp->t_state, TS_ASYNC); 77655706Scg splx(s); 77755706Scg break; 77855706Scg case FIONBIO: /* set/clear non-blocking i/o */ 77955706Scg break; /* XXX: delete. */ 78055706Scg case FIONREAD: /* get # bytes to read */ 78155706Scg s = spltty(); 78255706Scg *(int *)data = ttnread(tp); 78355706Scg splx(s); 78455706Scg break; 78555706Scg 78655706Scg case FIOSETOWN: 78755706Scg /* 78855706Scg * Policy -- Don't allow FIOSETOWN on someone else's 78955706Scg * controlling tty 79055706Scg */ 79155706Scg if (tp->t_session != NULL && !isctty(p, tp)) 79255706Scg return (ENOTTY); 79355706Scg 79455706Scg error = fsetown(*(int *)data, &tp->t_sigio); 79555706Scg if (error) 79655706Scg return (error); 79755706Scg break; 79855706Scg case FIOGETOWN: 79955706Scg if (tp->t_session != NULL && !isctty(p, tp)) 80055706Scg return (ENOTTY); 80155706Scg *(int *)data = fgetown(tp->t_sigio); 80255706Scg break; 80355706Scg 80455706Scg case TIOCEXCL: /* set exclusive use of tty */ 80555706Scg s = spltty(); 80655706Scg SET(tp->t_state, TS_XCLUDE); 80755706Scg splx(s); 80855706Scg break; 80955706Scg case TIOCFLUSH: { /* flush buffers */ 81055706Scg register int flags = *(int *)data; 81155706Scg 81255706Scg if (flags == 0) 81355706Scg flags = FREAD | FWRITE; 81455706Scg else 81555706Scg flags &= FREAD | FWRITE; 81655706Scg ttyflush(tp, flags); 81755706Scg break; 81855706Scg } 81955706Scg case TIOCCONS: /* become virtual console */ 82050925Scg if (*(int *)data) { 82150925Scg if (constty && constty != tp && 82250925Scg ISSET(constty->t_state, TS_CONNECTED)) 82350925Scg return (EBUSY); 82450925Scg#ifndef UCONSOLE 82550925Scg if ((error = suser_xxx(p->p_ucred, NULL, 0)) != 0) 82653126Sdfr return (error); 82753126Sdfr#endif 82850925Scg constty = tp; 82955706Scg } else if (tp == constty) 83050925Scg constty = NULL; 83150925Scg break; 83254845Scg case TIOCDRAIN: /* wait till output drained */ 83354845Scg error = ttywait(tp); 83450925Scg if (error) 83550925Scg return (error); 83655706Scg break; 83755706Scg case TIOCGETA: { /* get termios struct */ 83850925Scg struct termios *t = (struct termios *)data; 83950925Scg 84050925Scg bcopy(&tp->t_termios, t, sizeof(struct termios)); 84150925Scg break; 84255706Scg } 84355706Scg case TIOCGETD: /* get line discipline */ 84450925Scg *(int *)data = tp->t_line; 84550925Scg break; 84650925Scg case TIOCGWINSZ: /* get window size */ 84750925Scg *(struct winsize *)data = tp->t_winsize; 84850925Scg break; 84950925Scg case TIOCGPGRP: /* get pgrp of tty */ 85050925Scg if (!isctty(p, tp)) 85150925Scg return (ENOTTY); 85250925Scg *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 85350925Scg break; 85450925Scg#ifdef TIOCHPCL 85550925Scg case TIOCHPCL: /* hang up on last close */ 85650925Scg s = spltty(); 85755706Scg SET(tp->t_cflag, HUPCL); 85850925Scg splx(s); 85950925Scg break; 86050925Scg#endif 86150925Scg case TIOCNXCL: /* reset exclusive use of tty */ 86253126Sdfr s = spltty(); 86350925Scg CLR(tp->t_state, TS_XCLUDE); 86450925Scg splx(s); 86550925Scg break; 86650925Scg case TIOCOUTQ: /* output queue size */ 86750925Scg *(int *)data = tp->t_outq.c_cc; 86850925Scg break; 86950925Scg case TIOCSETA: /* set termios struct */ 87050925Scg case TIOCSETAW: /* drain output, set */ 87150925Scg case TIOCSETAF: { /* drn out, fls in, set */ 87250925Scg register struct termios *t = (struct termios *)data; 87350925Scg 87450925Scg if (t->c_ispeed == 0) 87550925Scg t->c_ispeed = t->c_ospeed; 87650925Scg if (t->c_ispeed == 0) 87750925Scg t->c_ispeed = tp->t_ospeed; 87850925Scg if (t->c_ispeed == 0) 87950925Scg return (EINVAL); 88050925Scg s = spltty(); 88150925Scg if (cmd == TIOCSETAW || cmd == TIOCSETAF) { 88250925Scg error = ttywait(tp); 88350925Scg if (error) { 88450925Scg splx(s); 88555706Scg return (error); 88650925Scg } 88750925Scg if (cmd == TIOCSETAF) 88850925Scg ttyflush(tp, FREAD); 88950925Scg } 89054845Scg if (!ISSET(t->c_cflag, CIGNORE)) { 89150925Scg /* 89250925Scg * Set device hardware. 89350925Scg */ 89450925Scg if (tp->t_param && (error = (*tp->t_param)(tp, t))) { 89550925Scg splx(s); 89650925Scg return (error); 89750925Scg } 89850925Scg if (ISSET(t->c_cflag, CLOCAL) && 89950925Scg !ISSET(tp->t_cflag, CLOCAL)) { 90050925Scg /* 90150925Scg * XXX disconnections would be too hard to 90250925Scg * get rid of without this kludge. The only 90350925Scg * way to get rid of controlling terminals 90450925Scg * is to exit from the session leader. 90550925Scg */ 90650925Scg CLR(tp->t_state, TS_ZOMBIE); 90750925Scg 90850925Scg wakeup(TSA_CARR_ON(tp)); 90950925Scg ttwakeup(tp); 91050925Scg ttwwakeup(tp); 91150925Scg } 91250925Scg if ((ISSET(tp->t_state, TS_CARR_ON) || 91350925Scg ISSET(t->c_cflag, CLOCAL)) && 91450925Scg !ISSET(tp->t_state, TS_ZOMBIE)) 91550925Scg SET(tp->t_state, TS_CONNECTED); 91650925Scg else 91750925Scg CLR(tp->t_state, TS_CONNECTED); 91850925Scg tp->t_cflag = t->c_cflag; 91950925Scg tp->t_ispeed = t->c_ispeed; 92050925Scg if (t->c_ospeed != 0) 92150925Scg tp->t_ospeed = t->c_ospeed; 92250925Scg ttsetwater(tp); 92350925Scg } 92450925Scg if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) && 92550925Scg cmd != TIOCSETAF) { 92650925Scg if (ISSET(t->c_lflag, ICANON)) 92750925Scg SET(tp->t_lflag, PENDIN); 92855706Scg else { 92955706Scg /* 93055706Scg * XXX we really shouldn't allow toggling 93150925Scg * ICANON while we're in a non-termios line 93250925Scg * discipline. Now we have to worry about 93350925Scg * panicing for a null queue. 93450925Scg */ 93550925Scg if (tp->t_canq.c_cbreserved > 0 && 93650925Scg tp->t_rawq.c_cbreserved > 0) { 93750925Scg catq(&tp->t_rawq, &tp->t_canq); 93850925Scg /* 93950925Scg * XXX the queue limits may be 94050925Scg * different, so the old queue 94155254Scg * swapping method no longer works. 94255254Scg */ 94355254Scg catq(&tp->t_canq, &tp->t_rawq); 94455254Scg } 94555254Scg CLR(tp->t_lflag, PENDIN); 94655254Scg } 94755254Scg ttwakeup(tp); 94855706Scg } 94955706Scg tp->t_iflag = t->c_iflag; 95055254Scg tp->t_oflag = t->c_oflag; 95155254Scg /* 95250925Scg * Make the EXTPROC bit read only. 95333474Sscrappy */ 95450925Scg if (ISSET(tp->t_lflag, EXTPROC)) 95550925Scg SET(t->c_lflag, EXTPROC); 95650925Scg else 95750925Scg CLR(t->c_lflag, EXTPROC); 95855706Scg tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN); 95950925Scg if (t->c_cc[VMIN] != tp->t_cc[VMIN] || 96050925Scg t->c_cc[VTIME] != tp->t_cc[VTIME]) 96150925Scg ttwakeup(tp); 96250925Scg bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc)); 96350925Scg splx(s); 96450925Scg break; 96550925Scg } 96650925Scg case TIOCSETD: { /* set line discipline */ 96755706Scg register int t = *(int *)data; 96850925Scg dev_t device = tp->t_dev; 96950925Scg 97050925Scg if ((u_int)t >= nlinesw) 97150925Scg return (ENXIO); 97250925Scg if (t != tp->t_line) { 97350925Scg s = spltty(); 97450925Scg (*linesw[tp->t_line].l_close)(tp, flag); 97550925Scg error = (*linesw[t].l_open)(device, tp); 97655706Scg if (error) { 97750925Scg (void)(*linesw[tp->t_line].l_open)(device, tp); 97850925Scg splx(s); 97950925Scg return (error); 98050925Scg } 98150925Scg tp->t_line = t; 98250925Scg splx(s); 98350925Scg } 98450925Scg break; 98550925Scg } 98650925Scg case TIOCSTART: /* start output, like ^Q */ 98750925Scg s = spltty(); 98850925Scg if (ISSET(tp->t_state, TS_TTSTOP) || 98950925Scg ISSET(tp->t_lflag, FLUSHO)) { 99055706Scg CLR(tp->t_lflag, FLUSHO); 99155706Scg CLR(tp->t_state, TS_TTSTOP); 99255706Scg ttstart(tp); 99350925Scg } 99450925Scg splx(s); 99550925Scg break; 99650925Scg case TIOCSTI: /* simulate terminal input */ 99750925Scg if ((flag & FREAD) == 0 && suser_xxx(p->p_ucred, NULL, 0)) 99850925Scg return (EPERM); 99950925Scg if (!isctty(p, tp) && suser_xxx(p->p_ucred, NULL, 0)) 100050925Scg return (EACCES); 100150925Scg s = spltty(); 100250925Scg (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp); 100350925Scg splx(s); 100450925Scg break; 100550925Scg case TIOCSTOP: /* stop output, like ^S */ 100650925Scg s = spltty(); 100750925Scg if (!ISSET(tp->t_state, TS_TTSTOP)) { 100850925Scg SET(tp->t_state, TS_TTSTOP); 100950925Scg (*tp->t_stop)(tp, 0); 101050925Scg } 101150925Scg splx(s); 101250925Scg break; 101350925Scg case TIOCSCTTY: /* become controlling tty */ 101450925Scg /* Session ctty vnode pointer set in vnode layer. */ 101550925Scg if (!SESS_LEADER(p) || 101650925Scg ((p->p_session->s_ttyvp || tp->t_session) && 101750925Scg (tp->t_session != p->p_session))) 101850925Scg return (EPERM); 101950925Scg tp->t_session = p->p_session; 102050925Scg tp->t_pgrp = p->p_pgrp; 102155706Scg p->p_session->s_ttyp = tp; 102250925Scg p->p_flag |= P_CONTROLT; 102350925Scg break; 102450925Scg case TIOCSPGRP: { /* set pgrp of tty */ 102550925Scg register struct pgrp *pgrp = pgfind(*(int *)data); 102650925Scg 102750925Scg if (!isctty(p, tp)) 102850925Scg return (ENOTTY); 102955706Scg else if (pgrp == NULL || pgrp->pg_session != p->p_session) 103050925Scg return (EPERM); 103150925Scg tp->t_pgrp = pgrp; 103250925Scg break; 103350723Scg } 103439899Sluigi case TIOCSTAT: /* simulate control-T */ 103529415Sjmg s = spltty(); 103650723Scg ttyinfo(tp); 103729415Sjmg splx(s); 103850723Scg break; 103929415Sjmg case TIOCSWINSZ: /* set window size */ 104050723Scg if (bcmp((caddr_t)&tp->t_winsize, data, 104150723Scg sizeof (struct winsize))) { 104250723Scg tp->t_winsize = *(struct winsize *)data; 104350723Scg pgsignal(tp->t_pgrp, SIGWINCH, 1); 104450723Scg } 104554930Scg break; 104654930Scg case TIOCSDRAINWAIT: 104750723Scg error = suser_xxx(p->p_ucred, NULL, 0); 104850723Scg if (error) 104950723Scg return (error); 105031361Sjmg tp->t_timeout = *(int *)data * hz; 105150723Scg wakeup(TSA_OCOMPLETE(tp)); 105250723Scg wakeup(TSA_OLOWAT(tp)); 105350723Scg break; 105450723Scg case TIOCGDRAINWAIT: 105550723Scg *(int *)data = tp->t_timeout / hz; 105650723Scg break; 105750723Scg default: 105850723Scg#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 105950723Scg return (ttcompat(tp, cmd, data, flag)); 106031361Sjmg#else 106150723Scg return (ENOIOCTL); 106250723Scg#endif 106350723Scg } 106450723Scg return (0); 106550723Scg} 106650723Scg 106750723Scgint 106829415Sjmgttypoll(dev, events, td) 106950723Scg dev_t dev; 107050723Scg int events; 107153126Sdfr struct thread *td; 107253126Sdfr{ 107353126Sdfr int s; 107453126Sdfr int revents = 0; 107550723Scg struct tty *tp; 107629415Sjmg 107750723Scg tp = dev->si_tty; 107850723Scg if (tp == NULL) /* XXX used to return ENXIO, but that means true! */ 107950723Scg return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)) 108029415Sjmg | POLLHUP); 108150723Scg 108250723Scg s = spltty(); 108350723Scg if (events & (POLLIN | POLLRDNORM)) { 108453126Sdfr if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE)) 108553126Sdfr revents |= events & (POLLIN | POLLRDNORM); 108650723Scg else 108753126Sdfr selrecord(td, &tp->t_rsel); 108853126Sdfr } 108953126Sdfr if (events & (POLLOUT | POLLWRNORM)) { 109053126Sdfr if ((tp->t_outq.c_cc <= tp->t_olowat && 109153126Sdfr ISSET(tp->t_state, TS_CONNECTED)) 109253126Sdfr || ISSET(tp->t_state, TS_ZOMBIE)) 109353126Sdfr revents |= events & (POLLOUT | POLLWRNORM); 109453126Sdfr else 109553126Sdfr selrecord(td, &tp->t_wsel); 109653126Sdfr } 109753126Sdfr splx(s); 109853126Sdfr return (revents); 109953126Sdfr} 110053126Sdfr 110153126Sdfrstatic struct filterops ttyread_filtops = 110250723Scg { 1, NULL, filt_ttyrdetach, filt_ttyread }; 110329415Sjmgstatic struct filterops ttywrite_filtops = 110429415Sjmg { 1, NULL, filt_ttywdetach, filt_ttywrite }; 110550723Scg 110650723Scgint 110729415Sjmgttykqfilter(dev, kn) 110850723Scg dev_t dev; 110950723Scg struct knote *kn; 111029415Sjmg{ 111150723Scg struct tty *tp = dev->si_tty; 111250723Scg struct klist *klist; 111355706Scg int s; 111455706Scg 111555706Scg switch (kn->kn_filter) { 111655706Scg case EVFILT_READ: 111750723Scg klist = &tp->t_rsel.si_note; 111850723Scg kn->kn_fop = &ttyread_filtops; 111950723Scg break; 112050723Scg case EVFILT_WRITE: 112150723Scg klist = &tp->t_wsel.si_note; 112250723Scg kn->kn_fop = &ttywrite_filtops; 112350723Scg break; 112429415Sjmg default: 112550723Scg return (1); 112650723Scg } 112755706Scg 112855706Scg kn->kn_hook = (caddr_t)dev; 112955706Scg 113055706Scg s = spltty(); 113155706Scg SLIST_INSERT_HEAD(klist, kn, kn_selnext); 113255706Scg splx(s); 113355706Scg 113455706Scg return (0); 113550723Scg} 113650723Scg 113750723Scgstatic void 113850723Scgfilt_ttyrdetach(struct knote *kn) 113950723Scg{ 114050723Scg struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 114150723Scg int s = spltty(); 114250723Scg 114350723Scg SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext); 114450723Scg splx(s); 114550723Scg} 114650723Scg 114751768Scgstatic int 114850723Scgfilt_ttyread(struct knote *kn, long hint) 114929415Sjmg{ 115029415Sjmg struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 115129415Sjmg 115253553Stanimura kn->kn_data = ttnread(tp); 115353553Stanimura if (ISSET(tp->t_state, TS_ZOMBIE)) { 115454462Scg kn->kn_flags |= EV_EOF; 115555092Sdfr return (1); 115653553Stanimura } 115753553Stanimura return (kn->kn_data > 0); 115854462Scg} 115954462Scg 116053553Stanimurastatic void 116153553Stanimurafilt_ttywdetach(struct knote *kn) 116254462Scg{ 116354791Scg struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 116454462Scg int s = spltty(); 116555092Sdfr 116654793Scg SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext); 116754793Scg splx(s); 116854462Scg} 116953553Stanimura 117053553Stanimurastatic int 117153553Stanimurafilt_ttywrite(kn, hint) 117253553Stanimura struct knote *kn; 117353553Stanimura long hint; 117453553Stanimura{ 117553553Stanimura struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 117653553Stanimura 117755092Sdfr kn->kn_data = tp->t_outq.c_cc; 117853553Stanimura if (ISSET(tp->t_state, TS_ZOMBIE)) 117953553Stanimura return (1); 118055706Scg return (kn->kn_data <= tp->t_olowat && 118155706Scg ISSET(tp->t_state, TS_CONNECTED)); 118253553Stanimura} 118353553Stanimura 118454462Scg/* 118554462Scg * Must be called at spltty(). 118654462Scg */ 118754462Scgstatic int 118853553Stanimurattnread(tp) 118953553Stanimura struct tty *tp; 119053553Stanimura{ 119153553Stanimura int nread; 119253553Stanimura 119353553Stanimura if (ISSET(tp->t_lflag, PENDIN)) 119453553Stanimura ttypend(tp); 119553553Stanimura nread = tp->t_canq.c_cc; 119653553Stanimura if (!ISSET(tp->t_lflag, ICANON)) { 119753553Stanimura nread += tp->t_rawq.c_cc; 119853553Stanimura if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0) 119953553Stanimura nread = 0; 120053553Stanimura } 120153553Stanimura return (nread); 120253553Stanimura} 120353553Stanimura 120453553Stanimura/* 120553553Stanimura * Wait for output to drain. 120653553Stanimura */ 120754462Scgint 120854462Scgttywait(tp) 1209 register struct tty *tp; 1210{ 1211 int error, s; 1212 1213 error = 0; 1214 s = spltty(); 1215 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 1216 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) { 1217 (*tp->t_oproc)(tp); 1218 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 1219 ISSET(tp->t_state, TS_CONNECTED)) { 1220 SET(tp->t_state, TS_SO_OCOMPLETE); 1221 error = ttysleep(tp, TSA_OCOMPLETE(tp), 1222 TTOPRI | PCATCH, "ttywai", 1223 tp->t_timeout); 1224 if (error) { 1225 if (error == EWOULDBLOCK) 1226 error = EIO; 1227 break; 1228 } 1229 } else 1230 break; 1231 } 1232 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY))) 1233 error = EIO; 1234 splx(s); 1235 return (error); 1236} 1237 1238/* 1239 * Flush if successfully wait. 1240 */ 1241static int 1242ttywflush(tp) 1243 struct tty *tp; 1244{ 1245 int error; 1246 1247 if ((error = ttywait(tp)) == 0) 1248 ttyflush(tp, FREAD); 1249 return (error); 1250} 1251 1252/* 1253 * Flush tty read and/or write queues, notifying anyone waiting. 1254 */ 1255void 1256ttyflush(tp, rw) 1257 register struct tty *tp; 1258 int rw; 1259{ 1260 register int s; 1261 1262 s = spltty(); 1263#if 0 1264again: 1265#endif 1266 if (rw & FWRITE) { 1267 FLUSHQ(&tp->t_outq); 1268 CLR(tp->t_state, TS_TTSTOP); 1269 } 1270 (*tp->t_stop)(tp, rw); 1271 if (rw & FREAD) { 1272 FLUSHQ(&tp->t_canq); 1273 FLUSHQ(&tp->t_rawq); 1274 CLR(tp->t_lflag, PENDIN); 1275 tp->t_rocount = 0; 1276 tp->t_rocol = 0; 1277 CLR(tp->t_state, TS_LOCAL); 1278 ttwakeup(tp); 1279 if (ISSET(tp->t_state, TS_TBLOCK)) { 1280 if (rw & FWRITE) 1281 FLUSHQ(&tp->t_outq); 1282 ttyunblock(tp); 1283 1284 /* 1285 * Don't let leave any state that might clobber the 1286 * next line discipline (although we should do more 1287 * to send the START char). Not clearing the state 1288 * may have caused the "putc to a clist with no 1289 * reserved cblocks" panic/printf. 1290 */ 1291 CLR(tp->t_state, TS_TBLOCK); 1292 1293#if 0 /* forget it, sleeping isn't always safe and we don't know when it is */ 1294 if (ISSET(tp->t_iflag, IXOFF)) { 1295 /* 1296 * XXX wait a bit in the hope that the stop 1297 * character (if any) will go out. Waiting 1298 * isn't good since it allows races. This 1299 * will be fixed when the stop character is 1300 * put in a special queue. Don't bother with 1301 * the checks in ttywait() since the timeout 1302 * will save us. 1303 */ 1304 SET(tp->t_state, TS_SO_OCOMPLETE); 1305 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI, 1306 "ttyfls", hz / 10); 1307 /* 1308 * Don't try sending the stop character again. 1309 */ 1310 CLR(tp->t_state, TS_TBLOCK); 1311 goto again; 1312 } 1313#endif 1314 } 1315 } 1316 if (rw & FWRITE) { 1317 FLUSHQ(&tp->t_outq); 1318 ttwwakeup(tp); 1319 } 1320 splx(s); 1321} 1322 1323/* 1324 * Copy in the default termios characters. 1325 */ 1326void 1327termioschars(t) 1328 struct termios *t; 1329{ 1330 1331 bcopy(ttydefchars, t->c_cc, sizeof t->c_cc); 1332} 1333 1334/* 1335 * Old interface. 1336 */ 1337void 1338ttychars(tp) 1339 struct tty *tp; 1340{ 1341 1342 termioschars(&tp->t_termios); 1343} 1344 1345/* 1346 * Handle input high water. Send stop character for the IXOFF case. Turn 1347 * on our input flow control bit and propagate the changes to the driver. 1348 * XXX the stop character should be put in a special high priority queue. 1349 */ 1350void 1351ttyblock(tp) 1352 struct tty *tp; 1353{ 1354 1355 SET(tp->t_state, TS_TBLOCK); 1356 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE && 1357 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0) 1358 CLR(tp->t_state, TS_TBLOCK); /* try again later */ 1359 ttstart(tp); 1360} 1361 1362/* 1363 * Handle input low water. Send start character for the IXOFF case. Turn 1364 * off our input flow control bit and propagate the changes to the driver. 1365 * XXX the start character should be put in a special high priority queue. 1366 */ 1367static void 1368ttyunblock(tp) 1369 struct tty *tp; 1370{ 1371 1372 CLR(tp->t_state, TS_TBLOCK); 1373 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE && 1374 putc(tp->t_cc[VSTART], &tp->t_outq) != 0) 1375 SET(tp->t_state, TS_TBLOCK); /* try again later */ 1376 ttstart(tp); 1377} 1378 1379#ifdef notyet 1380/* Not used by any current (i386) drivers. */ 1381/* 1382 * Restart after an inter-char delay. 1383 */ 1384void 1385ttrstrt(tp_arg) 1386 void *tp_arg; 1387{ 1388 struct tty *tp; 1389 int s; 1390 1391 KASSERT(tp_arg != NULL, ("ttrstrt")); 1392 1393 tp = tp_arg; 1394 s = spltty(); 1395 1396 CLR(tp->t_state, TS_TIMEOUT); 1397 ttstart(tp); 1398 1399 splx(s); 1400} 1401#endif 1402 1403int 1404ttstart(tp) 1405 struct tty *tp; 1406{ 1407 1408 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */ 1409 (*tp->t_oproc)(tp); 1410 return (0); 1411} 1412 1413/* 1414 * "close" a line discipline 1415 */ 1416int 1417ttylclose(tp, flag) 1418 struct tty *tp; 1419 int flag; 1420{ 1421 1422 if (flag & FNONBLOCK || ttywflush(tp)) 1423 ttyflush(tp, FREAD | FWRITE); 1424 return (0); 1425} 1426 1427/* 1428 * Handle modem control transition on a tty. 1429 * Flag indicates new state of carrier. 1430 * Returns 0 if the line should be turned off, otherwise 1. 1431 */ 1432int 1433ttymodem(tp, flag) 1434 register struct tty *tp; 1435 int flag; 1436{ 1437 1438 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) { 1439 /* 1440 * MDMBUF: do flow control according to carrier flag 1441 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP 1442 * works if IXON and IXANY are clear. 1443 */ 1444 if (flag) { 1445 CLR(tp->t_state, TS_CAR_OFLOW); 1446 CLR(tp->t_state, TS_TTSTOP); 1447 ttstart(tp); 1448 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) { 1449 SET(tp->t_state, TS_CAR_OFLOW); 1450 SET(tp->t_state, TS_TTSTOP); 1451 (*tp->t_stop)(tp, 0); 1452 } 1453 } else if (flag == 0) { 1454 /* 1455 * Lost carrier. 1456 */ 1457 CLR(tp->t_state, TS_CARR_ON); 1458 if (ISSET(tp->t_state, TS_ISOPEN) && 1459 !ISSET(tp->t_cflag, CLOCAL)) { 1460 SET(tp->t_state, TS_ZOMBIE); 1461 CLR(tp->t_state, TS_CONNECTED); 1462 if (tp->t_session && tp->t_session->s_leader) { 1463 struct proc *p; 1464 1465 p = tp->t_session->s_leader; 1466 PROC_LOCK(p); 1467 psignal(p, SIGHUP); 1468 PROC_UNLOCK(p); 1469 } 1470 ttyflush(tp, FREAD | FWRITE); 1471 return (0); 1472 } 1473 } else { 1474 /* 1475 * Carrier now on. 1476 */ 1477 SET(tp->t_state, TS_CARR_ON); 1478 if (!ISSET(tp->t_state, TS_ZOMBIE)) 1479 SET(tp->t_state, TS_CONNECTED); 1480 wakeup(TSA_CARR_ON(tp)); 1481 ttwakeup(tp); 1482 ttwwakeup(tp); 1483 } 1484 return (1); 1485} 1486 1487/* 1488 * Reinput pending characters after state switch 1489 * call at spltty(). 1490 */ 1491static void 1492ttypend(tp) 1493 register struct tty *tp; 1494{ 1495 struct clist tq; 1496 register int c; 1497 1498 CLR(tp->t_lflag, PENDIN); 1499 SET(tp->t_state, TS_TYPEN); 1500 /* 1501 * XXX this assumes too much about clist internals. It may even 1502 * fail if the cblock slush pool is empty. We can't allocate more 1503 * cblocks here because we are called from an interrupt handler 1504 * and clist_alloc_cblocks() can wait. 1505 */ 1506 tq = tp->t_rawq; 1507 bzero(&tp->t_rawq, sizeof tp->t_rawq); 1508 tp->t_rawq.c_cbmax = tq.c_cbmax; 1509 tp->t_rawq.c_cbreserved = tq.c_cbreserved; 1510 while ((c = getc(&tq)) >= 0) 1511 ttyinput(c, tp); 1512 CLR(tp->t_state, TS_TYPEN); 1513} 1514 1515/* 1516 * Process a read call on a tty device. 1517 */ 1518int 1519ttread(tp, uio, flag) 1520 register struct tty *tp; 1521 struct uio *uio; 1522 int flag; 1523{ 1524 register struct clist *qp; 1525 register int c; 1526 register tcflag_t lflag; 1527 register cc_t *cc = tp->t_cc; 1528 register struct proc *p = curproc; 1529 int s, first, error = 0; 1530 int has_stime = 0, last_cc = 0; 1531 long slp = 0; /* XXX this should be renamed `timo'. */ 1532 struct timeval stime; 1533 1534loop: 1535 s = spltty(); 1536 lflag = tp->t_lflag; 1537 /* 1538 * take pending input first 1539 */ 1540 if (ISSET(lflag, PENDIN)) { 1541 ttypend(tp); 1542 splx(s); /* reduce latency */ 1543 s = spltty(); 1544 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */ 1545 } 1546 1547 /* 1548 * Hang process if it's in the background. 1549 */ 1550 if (isbackground(p, tp)) { 1551 splx(s); 1552 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) || 1553 SIGISMEMBER(p->p_sigmask, SIGTTIN) || 1554 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) 1555 return (EIO); 1556 pgsignal(p->p_pgrp, SIGTTIN, 1); 1557 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0); 1558 if (error) 1559 return (error); 1560 goto loop; 1561 } 1562 1563 if (ISSET(tp->t_state, TS_ZOMBIE)) { 1564 splx(s); 1565 return (0); /* EOF */ 1566 } 1567 1568 /* 1569 * If canonical, use the canonical queue, 1570 * else use the raw queue. 1571 * 1572 * (should get rid of clists...) 1573 */ 1574 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq; 1575 1576 if (flag & IO_NDELAY) { 1577 if (qp->c_cc > 0) 1578 goto read; 1579 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) { 1580 splx(s); 1581 return (0); 1582 } 1583 splx(s); 1584 return (EWOULDBLOCK); 1585 } 1586 if (!ISSET(lflag, ICANON)) { 1587 int m = cc[VMIN]; 1588 long t = cc[VTIME]; 1589 struct timeval timecopy; 1590 1591 /* 1592 * Check each of the four combinations. 1593 * (m > 0 && t == 0) is the normal read case. 1594 * It should be fairly efficient, so we check that and its 1595 * companion case (m == 0 && t == 0) first. 1596 * For the other two cases, we compute the target sleep time 1597 * into slp. 1598 */ 1599 if (t == 0) { 1600 if (qp->c_cc < m) 1601 goto sleep; 1602 if (qp->c_cc > 0) 1603 goto read; 1604 1605 /* m, t and qp->c_cc are all 0. 0 is enough input. */ 1606 splx(s); 1607 return (0); 1608 } 1609 t *= 100000; /* time in us */ 1610#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \ 1611 ((t1).tv_usec - (t2).tv_usec)) 1612 if (m > 0) { 1613 if (qp->c_cc <= 0) 1614 goto sleep; 1615 if (qp->c_cc >= m) 1616 goto read; 1617 getmicrotime(&timecopy); 1618 if (!has_stime) { 1619 /* first character, start timer */ 1620 has_stime = 1; 1621 stime = timecopy; 1622 slp = t; 1623 } else if (qp->c_cc > last_cc) { 1624 /* got a character, restart timer */ 1625 stime = timecopy; 1626 slp = t; 1627 } else { 1628 /* nothing, check expiration */ 1629 slp = t - diff(timecopy, stime); 1630 if (slp <= 0) 1631 goto read; 1632 } 1633 last_cc = qp->c_cc; 1634 } else { /* m == 0 */ 1635 if (qp->c_cc > 0) 1636 goto read; 1637 getmicrotime(&timecopy); 1638 if (!has_stime) { 1639 has_stime = 1; 1640 stime = timecopy; 1641 slp = t; 1642 } else { 1643 slp = t - diff(timecopy, stime); 1644 if (slp <= 0) { 1645 /* Timed out, but 0 is enough input. */ 1646 splx(s); 1647 return (0); 1648 } 1649 } 1650 } 1651#undef diff 1652 /* 1653 * Rounding down may make us wake up just short 1654 * of the target, so we round up. 1655 * The formula is ceiling(slp * hz/1000000). 1656 * 32-bit arithmetic is enough for hz < 169. 1657 * XXX see tvtohz() for how to avoid overflow if hz 1658 * is large (divide by `tick' and/or arrange to 1659 * use tvtohz() if hz is large). 1660 */ 1661 slp = (long) (((u_long)slp * hz) + 999999) / 1000000; 1662 goto sleep; 1663 } 1664 if (qp->c_cc <= 0) { 1665sleep: 1666 /* 1667 * There is no input, or not enough input and we can block. 1668 */ 1669 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH, 1670 ISSET(tp->t_state, TS_CONNECTED) ? 1671 "ttyin" : "ttyhup", (int)slp); 1672 splx(s); 1673 if (error == EWOULDBLOCK) 1674 error = 0; 1675 else if (error) 1676 return (error); 1677 /* 1678 * XXX what happens if another process eats some input 1679 * while we are asleep (not just here)? It would be 1680 * safest to detect changes and reset our state variables 1681 * (has_stime and last_cc). 1682 */ 1683 slp = 0; 1684 goto loop; 1685 } 1686read: 1687 splx(s); 1688 /* 1689 * Input present, check for input mapping and processing. 1690 */ 1691 first = 1; 1692 if (ISSET(lflag, ICANON | ISIG)) 1693 goto slowcase; 1694 for (;;) { 1695 char ibuf[IBUFSIZ]; 1696 int icc; 1697 1698 icc = imin(uio->uio_resid, IBUFSIZ); 1699 icc = q_to_b(qp, ibuf, icc); 1700 if (icc <= 0) { 1701 if (first) 1702 goto loop; 1703 break; 1704 } 1705 error = uiomove(ibuf, icc, uio); 1706 /* 1707 * XXX if there was an error then we should ungetc() the 1708 * unmoved chars and reduce icc here. 1709 */ 1710 if (error) 1711 break; 1712 if (uio->uio_resid == 0) 1713 break; 1714 first = 0; 1715 } 1716 goto out; 1717slowcase: 1718 for (;;) { 1719 c = getc(qp); 1720 if (c < 0) { 1721 if (first) 1722 goto loop; 1723 break; 1724 } 1725 /* 1726 * delayed suspend (^Y) 1727 */ 1728 if (CCEQ(cc[VDSUSP], c) && 1729 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) { 1730 pgsignal(tp->t_pgrp, SIGTSTP, 1); 1731 if (first) { 1732 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, 1733 "ttybg3", 0); 1734 if (error) 1735 break; 1736 goto loop; 1737 } 1738 break; 1739 } 1740 /* 1741 * Interpret EOF only in canonical mode. 1742 */ 1743 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) 1744 break; 1745 /* 1746 * Give user character. 1747 */ 1748 error = ureadc(c, uio); 1749 if (error) 1750 /* XXX should ungetc(c, qp). */ 1751 break; 1752 if (uio->uio_resid == 0) 1753 break; 1754 /* 1755 * In canonical mode check for a "break character" 1756 * marking the end of a "line of input". 1757 */ 1758 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag)) 1759 break; 1760 first = 0; 1761 } 1762 1763out: 1764 /* 1765 * Look to unblock input now that (presumably) 1766 * the input queue has gone down. 1767 */ 1768 s = spltty(); 1769 if (ISSET(tp->t_state, TS_TBLOCK) && 1770 tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat) 1771 ttyunblock(tp); 1772 splx(s); 1773 1774 return (error); 1775} 1776 1777/* 1778 * Check the output queue on tp for space for a kernel message (from uprintf 1779 * or tprintf). Allow some space over the normal hiwater mark so we don't 1780 * lose messages due to normal flow control, but don't let the tty run amok. 1781 * Sleeps here are not interruptible, but we return prematurely if new signals 1782 * arrive. 1783 */ 1784int 1785ttycheckoutq(tp, wait) 1786 register struct tty *tp; 1787 int wait; 1788{ 1789 int hiwat, s; 1790 sigset_t oldmask; 1791 1792 hiwat = tp->t_ohiwat; 1793 SIGEMPTYSET(oldmask); 1794 s = spltty(); 1795 if (wait) 1796 oldmask = curproc->p_siglist; 1797 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) 1798 while (tp->t_outq.c_cc > hiwat) { 1799 ttstart(tp); 1800 if (tp->t_outq.c_cc <= hiwat) 1801 break; 1802 if (!(wait && SIGSETEQ(curproc->p_siglist, oldmask))) { 1803 splx(s); 1804 return (0); 1805 } 1806 SET(tp->t_state, TS_SO_OLOWAT); 1807 tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz); 1808 } 1809 splx(s); 1810 return (1); 1811} 1812 1813/* 1814 * Process a write call on a tty device. 1815 */ 1816int 1817ttwrite(tp, uio, flag) 1818 register struct tty *tp; 1819 register struct uio *uio; 1820 int flag; 1821{ 1822 register char *cp = NULL; 1823 register int cc, ce; 1824 register struct proc *p; 1825 int i, hiwat, cnt, error, s; 1826 char obuf[OBUFSIZ]; 1827 1828 hiwat = tp->t_ohiwat; 1829 cnt = uio->uio_resid; 1830 error = 0; 1831 cc = 0; 1832loop: 1833 s = spltty(); 1834 if (ISSET(tp->t_state, TS_ZOMBIE)) { 1835 splx(s); 1836 if (uio->uio_resid == cnt) 1837 error = EIO; 1838 goto out; 1839 } 1840 if (!ISSET(tp->t_state, TS_CONNECTED)) { 1841 if (flag & IO_NDELAY) { 1842 splx(s); 1843 error = EWOULDBLOCK; 1844 goto out; 1845 } 1846 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH, 1847 "ttydcd", 0); 1848 splx(s); 1849 if (error) 1850 goto out; 1851 goto loop; 1852 } 1853 splx(s); 1854 /* 1855 * Hang the process if it's in the background. 1856 */ 1857 p = curproc; 1858 if (isbackground(p, tp) && 1859 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) && 1860 !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 1861 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { 1862 if (p->p_pgrp->pg_jobc == 0) { 1863 error = EIO; 1864 goto out; 1865 } 1866 pgsignal(p->p_pgrp, SIGTTOU, 1); 1867 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0); 1868 if (error) 1869 goto out; 1870 goto loop; 1871 } 1872 /* 1873 * Process the user's data in at most OBUFSIZ chunks. Perform any 1874 * output translation. Keep track of high water mark, sleep on 1875 * overflow awaiting device aid in acquiring new space. 1876 */ 1877 while (uio->uio_resid > 0 || cc > 0) { 1878 if (ISSET(tp->t_lflag, FLUSHO)) { 1879 uio->uio_resid = 0; 1880 return (0); 1881 } 1882 if (tp->t_outq.c_cc > hiwat) 1883 goto ovhiwat; 1884 /* 1885 * Grab a hunk of data from the user, unless we have some 1886 * leftover from last time. 1887 */ 1888 if (cc == 0) { 1889 cc = imin(uio->uio_resid, OBUFSIZ); 1890 cp = obuf; 1891 error = uiomove(cp, cc, uio); 1892 if (error) { 1893 cc = 0; 1894 break; 1895 } 1896 } 1897 /* 1898 * If nothing fancy need be done, grab those characters we 1899 * can handle without any of ttyoutput's processing and 1900 * just transfer them to the output q. For those chars 1901 * which require special processing (as indicated by the 1902 * bits in char_type), call ttyoutput. After processing 1903 * a hunk of data, look for FLUSHO so ^O's will take effect 1904 * immediately. 1905 */ 1906 while (cc > 0) { 1907 if (!ISSET(tp->t_oflag, OPOST)) 1908 ce = cc; 1909 else { 1910 ce = cc - scanc((u_int)cc, (u_char *)cp, 1911 char_type, CCLASSMASK); 1912 /* 1913 * If ce is zero, then we're processing 1914 * a special character through ttyoutput. 1915 */ 1916 if (ce == 0) { 1917 tp->t_rocount = 0; 1918 if (ttyoutput(*cp, tp) >= 0) { 1919 /* No Clists, wait a bit. */ 1920 ttstart(tp); 1921 if (flag & IO_NDELAY) { 1922 error = EWOULDBLOCK; 1923 goto out; 1924 } 1925 error = ttysleep(tp, &lbolt, 1926 TTOPRI|PCATCH, 1927 "ttybf1", 0); 1928 if (error) 1929 goto out; 1930 goto loop; 1931 } 1932 cp++; 1933 cc--; 1934 if (ISSET(tp->t_lflag, FLUSHO) || 1935 tp->t_outq.c_cc > hiwat) 1936 goto ovhiwat; 1937 continue; 1938 } 1939 } 1940 /* 1941 * A bunch of normal characters have been found. 1942 * Transfer them en masse to the output queue and 1943 * continue processing at the top of the loop. 1944 * If there are any further characters in this 1945 * <= OBUFSIZ chunk, the first should be a character 1946 * requiring special handling by ttyoutput. 1947 */ 1948 tp->t_rocount = 0; 1949 i = b_to_q(cp, ce, &tp->t_outq); 1950 ce -= i; 1951 tp->t_column += ce; 1952 cp += ce, cc -= ce, tk_nout += ce; 1953 tp->t_outcc += ce; 1954 if (i > 0) { 1955 /* No Clists, wait a bit. */ 1956 ttstart(tp); 1957 if (flag & IO_NDELAY) { 1958 error = EWOULDBLOCK; 1959 goto out; 1960 } 1961 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, 1962 "ttybf2", 0); 1963 if (error) 1964 goto out; 1965 goto loop; 1966 } 1967 if (ISSET(tp->t_lflag, FLUSHO) || 1968 tp->t_outq.c_cc > hiwat) 1969 break; 1970 } 1971 ttstart(tp); 1972 } 1973out: 1974 /* 1975 * If cc is nonzero, we leave the uio structure inconsistent, as the 1976 * offset and iov pointers have moved forward, but it doesn't matter 1977 * (the call will either return short or restart with a new uio). 1978 */ 1979 uio->uio_resid += cc; 1980 return (error); 1981 1982ovhiwat: 1983 ttstart(tp); 1984 s = spltty(); 1985 /* 1986 * This can only occur if FLUSHO is set in t_lflag, 1987 * or if ttstart/oproc is synchronous (or very fast). 1988 */ 1989 if (tp->t_outq.c_cc <= hiwat) { 1990 splx(s); 1991 goto loop; 1992 } 1993 if (flag & IO_NDELAY) { 1994 splx(s); 1995 uio->uio_resid += cc; 1996 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0); 1997 } 1998 SET(tp->t_state, TS_SO_OLOWAT); 1999 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri", 2000 tp->t_timeout); 2001 splx(s); 2002 if (error == EWOULDBLOCK) 2003 error = EIO; 2004 if (error) 2005 goto out; 2006 goto loop; 2007} 2008 2009/* 2010 * Rubout one character from the rawq of tp 2011 * as cleanly as possible. 2012 */ 2013static void 2014ttyrub(c, tp) 2015 register int c; 2016 register struct tty *tp; 2017{ 2018 register char *cp; 2019 register int savecol; 2020 int tabc, s; 2021 2022 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 2023 return; 2024 CLR(tp->t_lflag, FLUSHO); 2025 if (ISSET(tp->t_lflag, ECHOE)) { 2026 if (tp->t_rocount == 0) { 2027 /* 2028 * Screwed by ttwrite; retype 2029 */ 2030 ttyretype(tp); 2031 return; 2032 } 2033 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 2034 ttyrubo(tp, 2); 2035 else { 2036 CLR(c, ~TTY_CHARMASK); 2037 switch (CCLASS(c)) { 2038 case ORDINARY: 2039 ttyrubo(tp, 1); 2040 break; 2041 case BACKSPACE: 2042 case CONTROL: 2043 case NEWLINE: 2044 case RETURN: 2045 case VTAB: 2046 if (ISSET(tp->t_lflag, ECHOCTL)) 2047 ttyrubo(tp, 2); 2048 break; 2049 case TAB: 2050 if (tp->t_rocount < tp->t_rawq.c_cc) { 2051 ttyretype(tp); 2052 return; 2053 } 2054 s = spltty(); 2055 savecol = tp->t_column; 2056 SET(tp->t_state, TS_CNTTB); 2057 SET(tp->t_lflag, FLUSHO); 2058 tp->t_column = tp->t_rocol; 2059 cp = tp->t_rawq.c_cf; 2060 if (cp) 2061 tabc = *cp; /* XXX FIX NEXTC */ 2062 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc)) 2063 ttyecho(tabc, tp); 2064 CLR(tp->t_lflag, FLUSHO); 2065 CLR(tp->t_state, TS_CNTTB); 2066 splx(s); 2067 2068 /* savecol will now be length of the tab. */ 2069 savecol -= tp->t_column; 2070 tp->t_column += savecol; 2071 if (savecol > 8) 2072 savecol = 8; /* overflow screw */ 2073 while (--savecol >= 0) 2074 (void)ttyoutput('\b', tp); 2075 break; 2076 default: /* XXX */ 2077#define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 2078 (void)printf(PANICSTR, c, CCLASS(c)); 2079#ifdef notdef 2080 panic(PANICSTR, c, CCLASS(c)); 2081#endif 2082 } 2083 } 2084 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 2085 if (!ISSET(tp->t_state, TS_ERASE)) { 2086 SET(tp->t_state, TS_ERASE); 2087 (void)ttyoutput('\\', tp); 2088 } 2089 ttyecho(c, tp); 2090 } else { 2091 ttyecho(tp->t_cc[VERASE], tp); 2092 /* 2093 * This code may be executed not only when an ERASE key 2094 * is pressed, but also when ^U (KILL) or ^W (WERASE) are. 2095 * So, I didn't think it was worthwhile to pass the extra 2096 * information (which would need an extra parameter, 2097 * changing every call) needed to distinguish the ERASE2 2098 * case from the ERASE. 2099 */ 2100 } 2101 --tp->t_rocount; 2102} 2103 2104/* 2105 * Back over cnt characters, erasing them. 2106 */ 2107static void 2108ttyrubo(tp, cnt) 2109 register struct tty *tp; 2110 int cnt; 2111{ 2112 2113 while (cnt-- > 0) { 2114 (void)ttyoutput('\b', tp); 2115 (void)ttyoutput(' ', tp); 2116 (void)ttyoutput('\b', tp); 2117 } 2118} 2119 2120/* 2121 * ttyretype -- 2122 * Reprint the rawq line. Note, it is assumed that c_cc has already 2123 * been checked. 2124 */ 2125static void 2126ttyretype(tp) 2127 register struct tty *tp; 2128{ 2129 register char *cp; 2130 int s, c; 2131 2132 /* Echo the reprint character. */ 2133 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 2134 ttyecho(tp->t_cc[VREPRINT], tp); 2135 2136 (void)ttyoutput('\n', tp); 2137 2138 /* 2139 * XXX 2140 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE 2141 * BIT OF FIRST CHAR. 2142 */ 2143 s = spltty(); 2144 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0); 2145 cp != NULL; cp = nextc(&tp->t_canq, cp, &c)) 2146 ttyecho(c, tp); 2147 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0); 2148 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c)) 2149 ttyecho(c, tp); 2150 CLR(tp->t_state, TS_ERASE); 2151 splx(s); 2152 2153 tp->t_rocount = tp->t_rawq.c_cc; 2154 tp->t_rocol = 0; 2155} 2156 2157/* 2158 * Echo a typed character to the terminal. 2159 */ 2160static void 2161ttyecho(c, tp) 2162 register int c; 2163 register struct tty *tp; 2164{ 2165 2166 if (!ISSET(tp->t_state, TS_CNTTB)) 2167 CLR(tp->t_lflag, FLUSHO); 2168 if ((!ISSET(tp->t_lflag, ECHO) && 2169 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) || 2170 ISSET(tp->t_lflag, EXTPROC)) 2171 return; 2172 if (ISSET(tp->t_lflag, ECHOCTL) && 2173 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') || 2174 ISSET(c, TTY_CHARMASK) == 0177)) { 2175 (void)ttyoutput('^', tp); 2176 CLR(c, ~TTY_CHARMASK); 2177 if (c == 0177) 2178 c = '?'; 2179 else 2180 c += 'A' - 1; 2181 } 2182 (void)ttyoutput(c, tp); 2183} 2184 2185/* 2186 * Wake up any readers on a tty. 2187 */ 2188void 2189ttwakeup(tp) 2190 register struct tty *tp; 2191{ 2192 2193 if (tp->t_rsel.si_pid != 0) 2194 selwakeup(&tp->t_rsel); 2195 if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL) 2196 pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL)); 2197 wakeup(TSA_HUP_OR_INPUT(tp)); 2198 KNOTE(&tp->t_rsel.si_note, 0); 2199} 2200 2201/* 2202 * Wake up any writers on a tty. 2203 */ 2204void 2205ttwwakeup(tp) 2206 register struct tty *tp; 2207{ 2208 2209 if (tp->t_wsel.si_pid != 0 && tp->t_outq.c_cc <= tp->t_olowat) 2210 selwakeup(&tp->t_wsel); 2211 if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL) 2212 pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL)); 2213 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) == 2214 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) { 2215 CLR(tp->t_state, TS_SO_OCOMPLETE); 2216 wakeup(TSA_OCOMPLETE(tp)); 2217 } 2218 if (ISSET(tp->t_state, TS_SO_OLOWAT) && 2219 tp->t_outq.c_cc <= tp->t_olowat) { 2220 CLR(tp->t_state, TS_SO_OLOWAT); 2221 wakeup(TSA_OLOWAT(tp)); 2222 } 2223 KNOTE(&tp->t_wsel.si_note, 0); 2224} 2225 2226/* 2227 * Look up a code for a specified speed in a conversion table; 2228 * used by drivers to map software speed values to hardware parameters. 2229 */ 2230int 2231ttspeedtab(speed, table) 2232 int speed; 2233 register struct speedtab *table; 2234{ 2235 2236 for ( ; table->sp_speed != -1; table++) 2237 if (table->sp_speed == speed) 2238 return (table->sp_code); 2239 return (-1); 2240} 2241 2242/* 2243 * Set input and output watermarks and buffer sizes. For input, the 2244 * high watermark is about one second's worth of input above empty, the 2245 * low watermark is slightly below high water, and the buffer size is a 2246 * driver-dependent amount above high water. For output, the watermarks 2247 * are near the ends of the buffer, with about 1 second's worth of input 2248 * between them. All this only applies to the standard line discipline. 2249 */ 2250void 2251ttsetwater(tp) 2252 struct tty *tp; 2253{ 2254 register int cps, ttmaxhiwat, x; 2255 2256 /* Input. */ 2257 clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512); 2258 switch (tp->t_ispeedwat) { 2259 case (speed_t)-1: 2260 cps = tp->t_ispeed / 10; 2261 break; 2262 case 0: 2263 /* 2264 * This case is for old drivers that don't know about 2265 * t_ispeedwat. Arrange for them to get the old buffer 2266 * sizes and watermarks. 2267 */ 2268 cps = TTYHOG - 2 * 256; 2269 tp->t_ififosize = 2 * 256; 2270 break; 2271 default: 2272 cps = tp->t_ispeedwat / 10; 2273 break; 2274 } 2275 tp->t_ihiwat = cps; 2276 tp->t_ilowat = 7 * cps / 8; 2277 x = cps + tp->t_ififosize; 2278 clist_alloc_cblocks(&tp->t_rawq, x, x); 2279 2280 /* Output. */ 2281 switch (tp->t_ospeedwat) { 2282 case (speed_t)-1: 2283 cps = tp->t_ospeed / 10; 2284 ttmaxhiwat = 2 * TTMAXHIWAT; 2285 break; 2286 case 0: 2287 cps = tp->t_ospeed / 10; 2288 ttmaxhiwat = TTMAXHIWAT; 2289 break; 2290 default: 2291 cps = tp->t_ospeedwat / 10; 2292 ttmaxhiwat = 8 * TTMAXHIWAT; 2293 break; 2294 } 2295#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 2296 tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 2297 x += cps; 2298 x = CLAMP(x, ttmaxhiwat, TTMINHIWAT); /* XXX clamps are too magic */ 2299 tp->t_ohiwat = roundup(x, CBSIZE); /* XXX for compat */ 2300 x = imax(tp->t_ohiwat, TTMAXHIWAT); /* XXX for compat/safety */ 2301 x += OBUFSIZ + 100; 2302 clist_alloc_cblocks(&tp->t_outq, x, x); 2303#undef CLAMP 2304} 2305 2306/* 2307 * Report on state of foreground process group. 2308 */ 2309void 2310ttyinfo(tp) 2311 register struct tty *tp; 2312{ 2313 register struct proc *p, *pick; 2314 struct timeval utime, stime; 2315 const char *stmp; 2316 long ltmp; 2317 int tmp; 2318 2319 if (ttycheckoutq(tp,0) == 0) 2320 return; 2321 2322 /* Print load average. */ 2323 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 2324 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 2325 2326 if (tp->t_session == NULL) 2327 ttyprintf(tp, "not a controlling terminal\n"); 2328 else if (tp->t_pgrp == NULL) 2329 ttyprintf(tp, "no foreground process group\n"); 2330 else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) 2331 ttyprintf(tp, "empty foreground process group\n"); 2332 else { 2333 mtx_lock_spin(&sched_lock); 2334 2335 /* Pick interesting process. */ 2336 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist)) 2337 if (proc_compare(pick, p)) 2338 pick = p; 2339 2340 stmp = pick->p_stat == SRUN ? "running" : /* XXXKSE */ 2341 pick->p_thread.td_wmesg ? pick->p_thread.td_wmesg : "iowait"; 2342 calcru(pick, &utime, &stime, NULL); 2343 ltmp = pick->p_stat == SIDL || pick->p_stat == SWAIT || 2344 pick->p_stat == SZOMB ? 0 : 2345 pgtok(vmspace_resident_count(pick->p_vmspace)); 2346 mtx_unlock_spin(&sched_lock); 2347 2348 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid, 2349 stmp); 2350 2351 /* Print user time. */ 2352 ttyprintf(tp, "%lld.%02ldu ", 2353 (long long)utime.tv_sec, utime.tv_usec / 10000); 2354 2355 /* Print system time. */ 2356 ttyprintf(tp, "%lld.%02lds ", 2357 (long long)stime.tv_sec, stime.tv_usec / 10000); 2358 2359 /* Print percentage cpu, resident set size. */ 2360 ttyprintf(tp, "%d%% %ldk\n", tmp / 100, ltmp); 2361 } 2362 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 2363} 2364 2365/* 2366 * Returns 1 if p2 is "better" than p1 2367 * 2368 * The algorithm for picking the "interesting" process is thus: 2369 * 2370 * 1) Only foreground processes are eligible - implied. 2371 * 2) Runnable processes are favored over anything else. The runner 2372 * with the highest cpu utilization is picked (p_estcpu). Ties are 2373 * broken by picking the highest pid. 2374 * 3) The sleeper with the shortest sleep time is next. With ties, 2375 * we pick out just "short-term" sleepers (P_SINTR == 0). 2376 * 4) Further ties are broken by picking the highest pid. 2377 */ 2378#define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 2379#define TESTAB(a, b) ((a)<<1 | (b)) 2380#define ONLYA 2 2381#define ONLYB 1 2382#define BOTH 3 2383 2384static int 2385proc_compare(p1, p2) 2386 register struct proc *p1, *p2; 2387{ 2388 2389 int esta, estb; 2390 struct ksegrp *kg; 2391 mtx_assert(&sched_lock, MA_OWNED); 2392 if (p1 == NULL) 2393 return (1); 2394 2395 /* 2396 * see if at least one of them is runnable 2397 */ 2398 switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 2399 case ONLYA: 2400 return (0); 2401 case ONLYB: 2402 return (1); 2403 case BOTH: 2404 /* 2405 * tie - favor one with highest recent cpu utilization 2406 */ 2407 esta = estb = 0; 2408 FOREACH_KSEGRP_IN_PROC(p1,kg) { 2409 esta += kg->kg_estcpu; 2410 } 2411 FOREACH_KSEGRP_IN_PROC(p2,kg) { 2412 estb += kg->kg_estcpu; 2413 } 2414 if (estb > esta) 2415 return (1); 2416 if (esta > estb) 2417 return (0); 2418 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2419 } 2420 /* 2421 * weed out zombies 2422 */ 2423 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 2424 case ONLYA: 2425 return (1); 2426 case ONLYB: 2427 return (0); 2428 case BOTH: 2429 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2430 } 2431 2432#if 0 /* XXXKSE */ 2433 /* 2434 * pick the one with the smallest sleep time 2435 */ 2436 if (p2->p_slptime > p1->p_slptime) 2437 return (0); 2438 if (p1->p_slptime > p2->p_slptime) 2439 return (1); 2440 /* 2441 * favor one sleeping in a non-interruptible sleep 2442 */ 2443 if (p1->p_sflag & PS_SINTR && (p2->p_sflag & PS_SINTR) == 0) 2444 return (1); 2445 if (p2->p_sflag & PS_SINTR && (p1->p_sflag & PS_SINTR) == 0) 2446 return (0); 2447#endif 2448 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2449} 2450 2451/* 2452 * Output char to tty; console putchar style. 2453 */ 2454int 2455tputchar(c, tp) 2456 int c; 2457 struct tty *tp; 2458{ 2459 register int s; 2460 2461 s = spltty(); 2462 if (!ISSET(tp->t_state, TS_CONNECTED)) { 2463 splx(s); 2464 return (-1); 2465 } 2466 if (c == '\n') 2467 (void)ttyoutput('\r', tp); 2468 (void)ttyoutput(c, tp); 2469 ttstart(tp); 2470 splx(s); 2471 return (0); 2472} 2473 2474/* 2475 * Sleep on chan, returning ERESTART if tty changed while we napped and 2476 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep. If 2477 * the tty is revoked, restarting a pending call will redo validation done 2478 * at the start of the call. 2479 */ 2480int 2481ttysleep(tp, chan, pri, wmesg, timo) 2482 struct tty *tp; 2483 void *chan; 2484 int pri, timo; 2485 char *wmesg; 2486{ 2487 int error; 2488 int gen; 2489 2490 gen = tp->t_gen; 2491 error = tsleep(chan, pri, wmesg, timo); 2492 if (error) 2493 return (error); 2494 return (tp->t_gen == gen ? 0 : ERESTART); 2495} 2496 2497/* 2498 * Allocate a tty struct. Clists in the struct will be allocated by 2499 * ttyopen(). 2500 */ 2501struct tty * 2502ttymalloc(tp) 2503 struct tty *tp; 2504{ 2505 2506 if (tp) 2507 return(tp); 2508 tp = malloc(sizeof *tp, M_TTYS, M_WAITOK | M_ZERO); 2509 ttyregister(tp); 2510 return (tp); 2511} 2512 2513#if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */ 2514/* 2515 * Free a tty struct. Clists in the struct should have been freed by 2516 * ttyclose(). 2517 */ 2518void 2519ttyfree(tp) 2520 struct tty *tp; 2521{ 2522 free(tp, M_TTYS); 2523} 2524#endif /* 0 */ 2525 2526void 2527ttyregister(tp) 2528 struct tty *tp; 2529{ 2530 tp->t_timeout = -1; 2531 SLIST_INSERT_HEAD(&tty_list, tp, t_list); 2532} 2533 2534static int 2535sysctl_kern_ttys(SYSCTL_HANDLER_ARGS) 2536{ 2537 int error; 2538 struct tty *tp, t; 2539 SLIST_FOREACH(tp, &tty_list, t_list) { 2540 t = *tp; 2541 if (t.t_dev) 2542 t.ttyu.t_udev = dev2udev(t.t_dev); 2543 error = SYSCTL_OUT(req, (caddr_t)&t, sizeof(t)); 2544 if (error) 2545 return (error); 2546 } 2547 return (0); 2548} 2549 2550SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD, 2551 0, 0, sysctl_kern_ttys, "S,tty", "All struct ttys"); 2552SYSCTL_LONG(_kern, OID_AUTO, tty_nin, CTLFLAG_RD, 2553 &tk_nin, 0, "Total TTY in characters"); 2554SYSCTL_LONG(_kern, OID_AUTO, tty_nout, CTLFLAG_RD, 2555 &tk_nout, 0, "Total TTY out characters"); 2556 2557void 2558nottystop(tp, rw) 2559 struct tty *tp; 2560 int rw; 2561{ 2562 2563 return; 2564} 2565 2566int 2567ttyread(dev, uio, flag) 2568 dev_t dev; 2569 struct uio *uio; 2570 int flag; 2571{ 2572 struct tty *tp; 2573 2574 tp = dev->si_tty; 2575 if (tp == NULL) 2576 return (ENODEV); 2577 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 2578} 2579 2580int 2581ttywrite(dev, uio, flag) 2582 dev_t dev; 2583 struct uio *uio; 2584 int flag; 2585{ 2586 struct tty *tp; 2587 2588 tp = dev->si_tty; 2589 if (tp == NULL) 2590 return (ENODEV); 2591 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 2592} 2593