tty.c revision 98493
11541Srgrimes/*- 21541Srgrimes * Copyright (c) 1982, 1986, 1990, 1991, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * (c) UNIX System Laboratories, Inc. 51541Srgrimes * All or some portions of this file are derived from material licensed 61541Srgrimes * to the University of California by American Telephone and Telegraph 71541Srgrimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 81541Srgrimes * the permission of UNIX System Laboratories, Inc. 91541Srgrimes * 101541Srgrimes * Copyright (c) 2002 Networks Associates Technologies, Inc. 111541Srgrimes * All rights reserved. 121541Srgrimes * 131541Srgrimes * Portions of this software were developed for the FreeBSD Project by 141541Srgrimes * ThinkSec AS and NAI Labs, the Security Research Division of Network 151541Srgrimes * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 161541Srgrimes * ("CBOSS"), as part of the DARPA CHATS research program. 171541Srgrimes * 181541Srgrimes * Redistribution and use in source and binary forms, with or without 191541Srgrimes * modification, are permitted provided that the following conditions 201541Srgrimes * are met: 211541Srgrimes * 1. Redistributions of source code must retain the above copyright 221541Srgrimes * notice, this list of conditions and the following disclaimer. 231541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 241541Srgrimes * notice, this list of conditions and the following disclaimer in the 251541Srgrimes * documentation and/or other materials provided with the distribution. 261541Srgrimes * 3. All advertising materials mentioning features or use of this software 271541Srgrimes * must display the following acknowledgement: 281541Srgrimes * This product includes software developed by the University of 291541Srgrimes * California, Berkeley and its contributors. 301541Srgrimes * 4. Neither the name of the University nor the names of its contributors 311541Srgrimes * may be used to endorse or promote products derived from this software 321541Srgrimes * without specific prior written permission. 331541Srgrimes * 3450477Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 351541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 361541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 371541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 381541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 391541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 401541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 411541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 421541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4332350Seivind * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 4441793Sluigi * SUCH DAMAGE. 4532350Seivind * 461541Srgrimes * @(#)tty.c 8.8 (Berkeley) 1/21/94 4712693Sphk * $FreeBSD: head/sys/kern/tty.c 98493 2002-06-20 14:03:36Z iedowse $ 4844078Sdfr */ 4912693Sphk 501541Srgrimes/*- 5112693Sphk * TODO: 521541Srgrimes * o Fix races for sending the start char in ttyflush(). 5318892Sbde * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect(). 541541Srgrimes * With luck, there will be MIN chars before select() returns(). 551541Srgrimes * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it. 561541Srgrimes * o Don't allow input in TS_ZOMBIE case. It would be visible through 571541Srgrimes * FIONREAD. 5844165Sjulian * o Do the new sio locking stuff here and use it to avoid special 591541Srgrimes * case for EXTPROC? 608426Swollman * o Lock PENDIN too? 6158313Slile * o Move EXTPROC and/or PENDIN to t_state? 6271963Sjulian * o Wrap most of ttioctl in spltty/splx. 6371963Sjulian * o Implement TIOCNOTTY or remove it from <sys/ioctl.h>. 6471963Sjulian * o Send STOP if IXOFF is toggled off while TS_TBLOCK is set. 6571963Sjulian * o Don't allow certain termios flags to affect disciplines other 661541Srgrimes * than TTYDISC. Cancel their effects before switch disciplines 671541Srgrimes * and ignore them if they are set while we are in another 681541Srgrimes * discipline. 691541Srgrimes * o Now that historical speed conversions are handled here, don't 701541Srgrimes * do them in drivers. 7184931Sfjoe * o Check for TS_CARR_ON being set while everything is closed and not 7244627Sjulian * waiting for carrier. TS_CARR_ON isn't cleared if nothing is open, 7344627Sjulian * so it would live until the next open even if carrier drops. 741541Srgrimes * o Restore TS_WOPEN since it is useful in pstat. It must be cleared 751541Srgrimes * only when _all_ openers leave open(). 761541Srgrimes */ 7744078Sdfr 7812942Swollman#include "opt_compat.h" 791541Srgrimes 8012693Sphk#include <sys/param.h> 8112942Swollman#include <sys/systm.h> 8212942Swollman#include <sys/filio.h> 8312942Swollman#include <sys/lock.h> 841541Srgrimes#include <sys/mutex.h> 8512942Swollman#include <sys/namei.h> 8612942Swollman#include <sys/sx.h> 8712942Swollman#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 8812942Swollman#include <sys/ioctl_compat.h> 8912942Swollman#endif 9012942Swollman#include <sys/proc.h> 9112693Sphk#define TTYDEFCHARS 921541Srgrimes#include <sys/tty.h> 931541Srgrimes#undef TTYDEFCHARS 9411225Swollman#include <sys/fcntl.h> 9560938Sjake#include <sys/conf.h> 9611225Swollman#include <sys/dkstat.h> 9711225Swollman#include <sys/poll.h> 9811225Swollman#include <sys/kernel.h> 9911225Swollman#include <sys/vnode.h> 10011225Swollman#include <sys/signalvar.h> 10112693Sphk#include <sys/resourcevar.h> 10260938Sjake#include <sys/malloc.h> 10311225Swollman#include <sys/filedesc.h> 10469152Sjlemon#include <sys/sysctl.h> 10512820Sphk 1061541Srgrimes#include <vm/vm.h> 10712693Sphk#include <vm/pmap.h> 10812942Swollman#include <vm/vm_map.h> 10912942Swollman 1103282SwollmanMALLOC_DEFINE(M_TTYS, "ttys", "tty data structures"); 11112942Swollman 11212942Swollmanstatic int proc_compare(struct proc *p1, struct proc *p2); 11312942Swollmanstatic int ttnread(struct tty *tp); 11412942Swollmanstatic void ttyecho(int c, struct tty *tp); 11512942Swollmanstatic int ttyoutput(int c, struct tty *tp); 11612942Swollmanstatic void ttypend(struct tty *tp); 11712693Sphkstatic void ttyretype(struct tty *tp); 11892723Salfredstatic void ttyrub(int c, struct tty *tp); 11992723Salfredstatic void ttyrubo(struct tty *tp, int cnt); 12092723Salfredstatic void ttyunblock(struct tty *tp); 12192723Salfredstatic int ttywflush(struct tty *tp); 12292723Salfredstatic int filt_ttyread(struct knote *kn, long hint); 12392723Salfredstatic void filt_ttyrdetach(struct knote *kn); 12492723Salfredstatic int filt_ttywrite(struct knote *kn, long hint); 12512693Sphkstatic void filt_ttywdetach(struct knote *kn); 12692723Salfred 12732350Seivind/* 12892723Salfred * Table with character classes and parity. The 8th bit indicates parity, 12932350Seivind * the 7th bit indicates the character is an alphameric or underscore (for 13012693Sphk * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits 1311541Srgrimes * are 0 then the character needs no special processing on output; classes 1321541Srgrimes * other than 0 might be translated or (not currently) require delays. 1331541Srgrimes */ 1341541Srgrimes#define E 0x00 /* Even parity. */ 1351541Srgrimes#define O 0x80 /* Odd parity. */ 1361541Srgrimes#define PARITY(c) (char_type[c] & O) 1371541Srgrimes 1381541Srgrimes#define ALPHA 0x40 /* Alpha or underscore. */ 1391541Srgrimes#define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA) 14071999Sphk 14111225Swollman#define CCLASSMASK 0x3f 1421541Srgrimes#define CCLASS(c) (char_type[c] & CCLASSMASK) 1431541Srgrimes 14411225Swollman#define BS BACKSPACE 1451541Srgrimes#define CC CONTROL 14671999Sphk#define CR RETURN 14734961Sphk#define NA ORDINARY | ALPHA 14811225Swollman#define NL NEWLINE 1491541Srgrimes#define NO ORDINARY 1501541Srgrimes#define TB TAB 1511541Srgrimes#define VT VTAB 1521541Srgrimes 1531541Srgrimesstatic u_char const char_type[] = { 1541541Srgrimes E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */ 1551541Srgrimes O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */ 1565196Swollman O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */ 15785074Sru E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */ 1581541Srgrimes O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */ 1591541Srgrimes E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */ 16085074Sru E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */ 1611541Srgrimes O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */ 1621541Srgrimes O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */ 1631541Srgrimes E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */ 1641541Srgrimes E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */ 16512693Sphk O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */ 1661541Srgrimes E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */ 1671541Srgrimes O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */ 1681541Srgrimes O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */ 16911225Swollman E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */ 1701541Srgrimes /* 17157178Speter * Meta chars; should be settable per character set; 1721541Srgrimes * for now, treat them all as normal characters. 1731541Srgrimes */ 1741541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1751541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1761541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1771541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1781541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1791541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1801541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1811541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1821541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1831541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1841541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1851541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1861541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1871541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1881541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1891541Srgrimes NA, NA, NA, NA, NA, NA, NA, NA, 1901541Srgrimes}; 1911541Srgrimes#undef BS 1921541Srgrimes#undef CC 1931541Srgrimes#undef CR 1941541Srgrimes#undef NA 19534961Sphk#undef NL 1961541Srgrimes#undef NO 1971541Srgrimes#undef TB 1981541Srgrimes#undef VT 1991541Srgrimes 20084931Sfjoe/* Macros to clear/set/test flags. */ 20136908Sjulian#define SET(t, f) (t) |= (f) 20236908Sjulian#define CLR(t, f) (t) &= ~(f) 2031541Srgrimes#define ISSET(t, f) ((t) & (f)) 2041541Srgrimes 2051541Srgrimes#undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */ 2061541Srgrimes#define MAX_INPUT TTYHOG /* XXX limit is usually larger for !ICANON */ 2071541Srgrimes 2086568Sdg/* 2091541Srgrimes * list of struct tty where pstat(8) can pick it up with sysctl 2101541Srgrimes */ 2111541Srgrimesstatic SLIST_HEAD(, tty) tty_list; 2121541Srgrimes 2131541Srgrimesstatic int drainwait = 5*60; 2141541SrgrimesSYSCTL_INT(_kern, OID_AUTO, drainwait, CTLFLAG_RW, &drainwait, 2151541Srgrimes 0, "Output drain timeout in seconds"); 2161541Srgrimes 2171541Srgrimes/* 2181541Srgrimes * Initial open of tty, or (re)entry to standard tty line discipline. 2191541Srgrimes */ 2201541Srgrimesint 2211541Srgrimesttyopen(dev_t device, struct tty *tp) 2221541Srgrimes{ 2231541Srgrimes int s; 2241541Srgrimes 2251541Srgrimes s = spltty(); 2261541Srgrimes tp->t_dev = device; 2271541Srgrimes if (!ISSET(tp->t_state, TS_ISOPEN)) { 2281541Srgrimes SET(tp->t_state, TS_ISOPEN); 22911225Swollman if (ISSET(tp->t_cflag, CLOCAL)) 23013926Swollman SET(tp->t_state, TS_CONNECTED); 23132350Seivind bzero(&tp->t_winsize, sizeof(tp->t_winsize)); 23213926Swollman } 23313926Swollman /* XXX don't hang forever on output */ 23413926Swollman if (tp->t_timeout < 0) 23513926Swollman tp->t_timeout = drainwait*hz; 23613926Swollman ttsetwater(tp); 23787776Sjlemon splx(s); 23887776Sjlemon return (0); 23913926Swollman} 24013926Swollman 24113926Swollman/* 24216576Speter * Handle close() on a tty line: flush and set to initial state, 24313926Swollman * bumping generation number so that pending read/write calls 24413926Swollman * can detect recycling of the tty. 24584931Sfjoe * XXX our caller should have done `spltty(); l_close(); ttyclose();' 24684931Sfjoe * and l_close() should have flushed, but we repeat the spltty() and 24784931Sfjoe * the flush in case there are buggy callers. 24816576Speter */ 24913926Swollmanint 25032350Seivindttyclose(struct tty *tp) 25113926Swollman{ 2521541Srgrimes int s; 2531541Srgrimes 2541541Srgrimes funsetown(&tp->t_sigio); 2551541Srgrimes s = spltty(); 2561541Srgrimes if (constty == tp) 2571541Srgrimes constty = NULL; 2581541Srgrimes 2591541Srgrimes ttyflush(tp, FREAD | FWRITE); 2601541Srgrimes clist_free_cblocks(&tp->t_canq); 2611541Srgrimes clist_free_cblocks(&tp->t_outq); 2621541Srgrimes clist_free_cblocks(&tp->t_rawq); 2631541Srgrimes 2641541Srgrimes tp->t_gen++; 26584931Sfjoe tp->t_line = TTYDISC; 26684931Sfjoe tp->t_pgrp = NULL; 2671541Srgrimes tp->t_session = NULL; 2688090Spst tp->t_state = 0; 2691541Srgrimes splx(s); 2701541Srgrimes return (0); 2711541Srgrimes} 2721541Srgrimes 2731541Srgrimes#define FLUSHQ(q) { \ 2741541Srgrimes if ((q)->c_cc) \ 2751541Srgrimes ndflush(q, (q)->c_cc); \ 2761541Srgrimes} 27711225Swollman 2781541Srgrimes/* Is 'c' a line delimiter ("break" character)? */ 2791541Srgrimes#define TTBREAKC(c, lflag) \ 2801541Srgrimes ((c) == '\n' || (((c) == cc[VEOF] || \ 2811541Srgrimes (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \ 2821541Srgrimes (c) != _POSIX_VDISABLE)) 2831541Srgrimes 2841541Srgrimes/* 2851541Srgrimes * Process input of a single character received on a tty. 2861541Srgrimes */ 2871541Srgrimesint 2881541Srgrimesttyinput(int c, struct tty *tp) 2891541Srgrimes{ 2901541Srgrimes tcflag_t iflag, lflag; 2911541Srgrimes cc_t *cc; 2921541Srgrimes int i, err; 29384931Sfjoe 29484931Sfjoe /* 29536908Sjulian * If input is pending take it first. 2961541Srgrimes */ 2971541Srgrimes lflag = tp->t_lflag; 2981541Srgrimes if (ISSET(lflag, PENDIN)) 2991541Srgrimes ttypend(tp); 30084931Sfjoe /* 30184931Sfjoe * Gather stats. 3021541Srgrimes */ 30358313Slile if (ISSET(lflag, ICANON)) { 30458313Slile ++tk_cancc; 30584931Sfjoe ++tp->t_cancc; 3061541Srgrimes } else { 3071541Srgrimes ++tk_rawcc; 3081541Srgrimes ++tp->t_rawcc; 30944456Swpaul } 31084931Sfjoe ++tk_nin; 31184931Sfjoe 31284931Sfjoe /* 31384931Sfjoe * Block further input iff: 31484931Sfjoe * current input > threshold AND input is available to user program 31584931Sfjoe * AND input flow control is enabled and not yet invoked. 31684931Sfjoe * The 3 is slop for PARMRK. 31784931Sfjoe */ 31884931Sfjoe iflag = tp->t_iflag; 31984931Sfjoe if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 && 32084931Sfjoe (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) && 32184931Sfjoe (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) && 32284931Sfjoe !ISSET(tp->t_state, TS_TBLOCK)) 32384931Sfjoe ttyblock(tp); 32484931Sfjoe 32544627Sjulian /* Handle exceptional conditions (break, parity, framing). */ 32684931Sfjoe cc = tp->t_cc; 32784931Sfjoe err = (ISSET(c, TTY_ERRORMASK)); 32884931Sfjoe if (err) { 32984931Sfjoe CLR(c, TTY_ERRORMASK); 33084931Sfjoe if (ISSET(err, TTY_BI)) { 33184931Sfjoe if (ISSET(iflag, IGNBRK)) 33284931Sfjoe return (0); 33358313Slile if (ISSET(iflag, BRKINT)) { 33484931Sfjoe ttyflush(tp, FREAD | FWRITE); 33544627Sjulian if (tp->t_pgrp != NULL) { 33658313Slile PGRP_LOCK(tp->t_pgrp); 33758313Slile pgsignal(tp->t_pgrp, SIGINT, 1); 33858313Slile PGRP_UNLOCK(tp->t_pgrp); 33984931Sfjoe } 34084931Sfjoe goto endcase; 34144627Sjulian } 34251320Slile if (ISSET(iflag, PARMRK)) 34351320Slile goto parmrk; 34451320Slile } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK)) 34551320Slile || ISSET(err, TTY_FE)) { 34651320Slile if (ISSET(iflag, IGNPAR)) 34751320Slile return (0); 34844627Sjulian else if (ISSET(iflag, PARMRK)) { 34984931Sfjoeparmrk: 35084931Sfjoe if (tp->t_rawq.c_cc + tp->t_canq.c_cc > 35184931Sfjoe MAX_INPUT - 3) 35284931Sfjoe goto input_overflow; 35384931Sfjoe (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 35484931Sfjoe (void)putc(0 | TTY_QUOTE, &tp->t_rawq); 35551320Slile (void)putc(c | TTY_QUOTE, &tp->t_rawq); 35651320Slile goto endcase; 35751320Slile } else 35884931Sfjoe c = 0; 35951320Slile } 36084931Sfjoe } 36184931Sfjoe 36251320Slile if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP)) 36344627Sjulian CLR(c, 0x80); 36484931Sfjoe if (!ISSET(lflag, EXTPROC)) { 36584931Sfjoe /* 36684931Sfjoe * Check for literal nexting very first 36784931Sfjoe */ 36884931Sfjoe if (ISSET(tp->t_state, TS_LNCH)) { 36984931Sfjoe SET(c, TTY_QUOTE); 37084931Sfjoe CLR(tp->t_state, TS_LNCH); 37184931Sfjoe } 37284931Sfjoe /* 37384931Sfjoe * Scan for special characters. This code 3741541Srgrimes * is really just a big case statement with 3751541Srgrimes * non-constant cases. The bottom of the 37684931Sfjoe * case statement is labeled ``endcase'', so goto 3771541Srgrimes * it after a case match, or similar. 3781541Srgrimes */ 3791541Srgrimes 3801541Srgrimes /* 3811541Srgrimes * Control chars which aren't controlled 3821541Srgrimes * by ICANON, ISIG, or IXON. 3831541Srgrimes */ 3841541Srgrimes if (ISSET(lflag, IEXTEN)) { 3851541Srgrimes if (CCEQ(cc[VLNEXT], c)) { 3861541Srgrimes if (ISSET(lflag, ECHO)) { 3871541Srgrimes if (ISSET(lflag, ECHOE)) { 3881541Srgrimes (void)ttyoutput('^', tp); 3891541Srgrimes (void)ttyoutput('\b', tp); 39084931Sfjoe } else 39184931Sfjoe ttyecho(c, tp); 3921541Srgrimes } 3931541Srgrimes SET(tp->t_state, TS_LNCH); 3941541Srgrimes goto endcase; 3951541Srgrimes } 3963514Swollman if (CCEQ(cc[VDISCARD], c)) { 3971541Srgrimes if (ISSET(lflag, FLUSHO)) 39878295Sjlemon CLR(tp->t_lflag, FLUSHO); 3991541Srgrimes else { 4001541Srgrimes ttyflush(tp, FWRITE); 4011541Srgrimes ttyecho(c, tp); 40284931Sfjoe if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 4031541Srgrimes ttyretype(tp); 4041541Srgrimes SET(tp->t_lflag, FLUSHO); 40584931Sfjoe } 4061541Srgrimes goto startoutput; 4071541Srgrimes } 4081541Srgrimes } 4091541Srgrimes /* 4101541Srgrimes * Signals. 41142775Sfenner */ 4123311Sphk if (ISSET(lflag, ISIG)) { 4133311Sphk if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) { 4141541Srgrimes if (!ISSET(lflag, NOFLSH)) 4151541Srgrimes ttyflush(tp, FREAD | FWRITE); 4161541Srgrimes ttyecho(c, tp); 41736308Sphk if (tp->t_pgrp != NULL) { 41836308Sphk PGRP_LOCK(tp->t_pgrp); 41936308Sphk pgsignal(tp->t_pgrp, 4201541Srgrimes CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1); 4211541Srgrimes PGRP_UNLOCK(tp->t_pgrp); 4221541Srgrimes } 4231541Srgrimes goto endcase; 4241541Srgrimes } 4251541Srgrimes if (CCEQ(cc[VSUSP], c)) { 4261541Srgrimes if (!ISSET(lflag, NOFLSH)) 4271541Srgrimes ttyflush(tp, FREAD); 42834961Sphk ttyecho(c, tp); 4291541Srgrimes if (tp->t_pgrp != NULL) { 43016206Sbde PGRP_LOCK(tp->t_pgrp); 4311541Srgrimes pgsignal(tp->t_pgrp, SIGTSTP, 1); 4321541Srgrimes PGRP_UNLOCK(tp->t_pgrp); 4331541Srgrimes } 43478295Sjlemon goto endcase; 43578295Sjlemon } 43678295Sjlemon } 43778295Sjlemon /* 43878295Sjlemon * Handle start/stop characters. 43987410Sru */ 44087410Sru if (ISSET(iflag, IXON)) { 44178295Sjlemon if (CCEQ(cc[VSTOP], c)) { 44287410Sru if (!ISSET(tp->t_state, TS_TTSTOP)) { 44378295Sjlemon SET(tp->t_state, TS_TTSTOP); 4441541Srgrimes (*tp->t_stop)(tp, 0); 4451541Srgrimes return (0); 4461541Srgrimes } 4471541Srgrimes if (!CCEQ(cc[VSTART], c)) 4481541Srgrimes return (0); 4491541Srgrimes /* 4501541Srgrimes * if VSTART == VSTOP then toggle 4511541Srgrimes */ 4521541Srgrimes goto endcase; 45334961Sphk } 45434961Sphk if (CCEQ(cc[VSTART], c)) 4551541Srgrimes goto restartoutput; 45684931Sfjoe } 45736908Sjulian /* 45884931Sfjoe * IGNCR, ICRNL, & INLCR 45984931Sfjoe */ 4601541Srgrimes if (c == '\r') { 4611541Srgrimes if (ISSET(iflag, IGNCR)) 4621541Srgrimes return (0); 4631541Srgrimes else if (ISSET(iflag, ICRNL)) 4641541Srgrimes c = '\n'; 4651541Srgrimes } else if (c == '\n' && ISSET(iflag, INLCR)) 4661541Srgrimes c = '\r'; 4671541Srgrimes } 4681541Srgrimes if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) { 4691541Srgrimes /* 4701541Srgrimes * From here on down canonical mode character 4711541Srgrimes * processing takes place. 4721541Srgrimes */ 4731541Srgrimes /* 4741541Srgrimes * erase or erase2 (^H / ^?) 47512693Sphk */ 47631884Sbde if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c) ) { 4771541Srgrimes if (tp->t_rawq.c_cc) 47859143Swes ttyrub(unputc(&tp->t_rawq), tp); 4791541Srgrimes goto endcase; 48059143Swes } 4811541Srgrimes /* 4821541Srgrimes * kill (^U) 4831541Srgrimes */ 4841541Srgrimes if (CCEQ(cc[VKILL], c)) { 4851541Srgrimes if (ISSET(lflag, ECHOKE) && 4861541Srgrimes tp->t_rawq.c_cc == tp->t_rocount && 4871541Srgrimes !ISSET(lflag, ECHOPRT)) 48857900Srwatson while (tp->t_rawq.c_cc) 48957900Srwatson ttyrub(unputc(&tp->t_rawq), tp); 49058499Sdillon else { 49158758Sjoerg ttyecho(c, tp); 49257900Srwatson if (ISSET(lflag, ECHOK) || 49357900Srwatson ISSET(lflag, ECHOKE)) 49457900Srwatson ttyecho('\n', tp); 4951541Srgrimes FLUSHQ(&tp->t_rawq); 49657900Srwatson tp->t_rocount = 0; 49784931Sfjoe } 49884931Sfjoe CLR(tp->t_state, TS_LOCAL); 49957900Srwatson goto endcase; 50058758Sjoerg } 50157900Srwatson /* 50257900Srwatson * word erase (^W) 50357900Srwatson */ 50457900Srwatson if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) { 5051541Srgrimes int ctype; 50684931Sfjoe 50784931Sfjoe /* 50858770Sjoerg * erase whitespace 50957900Srwatson */ 51057900Srwatson while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t') 51157900Srwatson ttyrub(c, tp); 51257900Srwatson if (c == -1) 51357900Srwatson goto endcase; 51432350Seivind /* 51557900Srwatson * erase last char of word and remember the 51657900Srwatson * next chars type (for ALTWERASE) 51757900Srwatson */ 51832350Seivind ttyrub(c, tp); 51957900Srwatson c = unputc(&tp->t_rawq); 5201541Srgrimes if (c == -1) 5211541Srgrimes goto endcase; 5221541Srgrimes if (c == ' ' || c == '\t') { 5231541Srgrimes (void)putc(c, &tp->t_rawq); 52432350Seivind goto endcase; 5251541Srgrimes } 5261541Srgrimes ctype = ISALPHA(c); 5271541Srgrimes /* 5281541Srgrimes * erase rest of word 5291541Srgrimes */ 5301541Srgrimes do { 5311541Srgrimes ttyrub(c, tp); 5321541Srgrimes c = unputc(&tp->t_rawq); 5331541Srgrimes if (c == -1) 5341541Srgrimes goto endcase; 5351541Srgrimes } while (c != ' ' && c != '\t' && 5361541Srgrimes (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype)); 5371541Srgrimes (void)putc(c, &tp->t_rawq); 5381541Srgrimes goto endcase; 53970699Salfred } 54082893Salfred /* 54170699Salfred * reprint line (^R) 54270699Salfred */ 54370699Salfred if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) { 54470699Salfred ttyretype(tp); 54582893Salfred goto endcase; 54682893Salfred } 54782966Salfred /* 54870699Salfred * ^T - kernel info and generate SIGINFO 54982893Salfred */ 5501541Srgrimes if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) { 5511541Srgrimes if (ISSET(lflag, ISIG) && tp->t_pgrp != NULL) { 5521541Srgrimes PGRP_LOCK(tp->t_pgrp); 5531541Srgrimes pgsignal(tp->t_pgrp, SIGINFO, 1); 55484931Sfjoe PGRP_UNLOCK(tp->t_pgrp); 55584931Sfjoe } 5561541Srgrimes if (!ISSET(lflag, NOKERNINFO)) 55784931Sfjoe ttyinfo(tp); 55844627Sjulian goto endcase; 5591541Srgrimes } 5601541Srgrimes } 56184102Sjlemon /* 56284102Sjlemon * Check for input buffer overflow 5631541Srgrimes */ 5641541Srgrimes if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) { 5651541Srgrimesinput_overflow: 56658313Slile if (ISSET(iflag, IMAXBEL)) { 56784931Sfjoe if (tp->t_outq.c_cc < tp->t_ohiwat) 5681541Srgrimes (void)ttyoutput(CTRL('g'), tp); 56984931Sfjoe } 57084931Sfjoe goto endcase; 57174851Syar } 57274851Syar 57374851Syar if ( c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP) 57474851Syar && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR)) 57584931Sfjoe (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 57684931Sfjoe 57784931Sfjoe /* 57884931Sfjoe * Put data char in q for user and 57972056Sjulian * wakeup on seeing a line delimiter. 58072056Sjulian */ 58171963Sjulian if (putc(c, &tp->t_rawq) >= 0) { 58272056Sjulian if (!ISSET(lflag, ICANON)) { 58341793Sluigi ttwakeup(tp); 58484102Sjlemon ttyecho(c, tp); 58584102Sjlemon goto endcase; 58684102Sjlemon } 58784102Sjlemon if (TTBREAKC(c, lflag)) { 58884102Sjlemon tp->t_rocount = 0; 58984102Sjlemon catq(&tp->t_rawq, &tp->t_canq); 59084931Sfjoe ttwakeup(tp); 59184102Sjlemon } else if (tp->t_rocount++ == 0) 59284102Sjlemon tp->t_rocol = tp->t_column; 59384102Sjlemon if (ISSET(tp->t_state, TS_ERASE)) { 59484931Sfjoe /* 59584102Sjlemon * end of prterase \.../ 59684102Sjlemon */ 59784102Sjlemon CLR(tp->t_state, TS_ERASE); 59885223Sjlemon (void)ttyoutput('/', tp); 59984102Sjlemon } 60084102Sjlemon i = tp->t_column; 60185223Sjlemon ttyecho(c, tp); 60285466Sjlemon if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) { 60385466Sjlemon /* 60485466Sjlemon * Place the cursor over the '^' of the ^D. 60585466Sjlemon */ 60685466Sjlemon i = imin(2, tp->t_column - i); 60785466Sjlemon while (i > 0) { 60885466Sjlemon (void)ttyoutput('\b', tp); 60985466Sjlemon i--; 61085466Sjlemon } 61112693Sphk } 61212693Sphk } 61312693Sphkendcase: 61484102Sjlemon /* 61584102Sjlemon * IXANY means allow any character to restart output. 61684931Sfjoe */ 61712693Sphk if (ISSET(tp->t_state, TS_TTSTOP) && 61812693Sphk !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) 61912693Sphk return (0); 62084931Sfjoerestartoutput: 6211541Srgrimes CLR(tp->t_lflag, FLUSHO); 62284931Sfjoe CLR(tp->t_state, TS_TTSTOP); 6237088Swollmanstartoutput: 62412693Sphk return (ttstart(tp)); 62512693Sphk} 6261541Srgrimes 6271541Srgrimes/* 6281541Srgrimes * Output a single character on a tty, doing output processing 62984931Sfjoe * as needed (expanding tabs, newline processing, etc.). 63084931Sfjoe * Returns < 0 if succeeds, otherwise returns char to resend. 63184931Sfjoe * Must be recursive. 6321541Srgrimes */ 6331541Srgrimesstatic int 6341541Srgrimesttyoutput(int c, struct tty *tp) 6351541Srgrimes{ 6361541Srgrimes tcflag_t oflag; 63772270Sluigi int col, s; 63884931Sfjoe 63972270Sluigi oflag = tp->t_oflag; 64084931Sfjoe if (!ISSET(oflag, OPOST)) { 64171963Sjulian if (ISSET(tp->t_lflag, FLUSHO)) 64271963Sjulian return (-1); 64384931Sfjoe if (putc(c, &tp->t_outq)) 64484931Sfjoe return (c); 64572270Sluigi tk_nout++; 64639389Sfenner tp->t_outcc++; 6471541Srgrimes return (-1); 64884931Sfjoe } 64982893Salfred /* 65082893Salfred * Do tab expansion if OXTABS is set. Special case if we external 65184931Sfjoe * processing, we don't do the tab expansion because we'll probably 65284931Sfjoe * get it wrong. If tab expansion needs to be done, let it happen 65384931Sfjoe * externally. 65484931Sfjoe */ 65584931Sfjoe CLR(c, ~TTY_CHARMASK); 65682893Salfred if (c == '\t' && 65739389Sfenner ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) { 65884931Sfjoe c = 8 - (tp->t_column & 7); 65984931Sfjoe if (!ISSET(tp->t_lflag, FLUSHO)) { 66084931Sfjoe s = spltty(); /* Don't interrupt tabs. */ 66139389Sfenner c -= b_to_q(" ", c, &tp->t_outq); 66239389Sfenner tk_nout += c; 66346568Speter tp->t_outcc += c; 66484931Sfjoe splx(s); 66584931Sfjoe } 66684931Sfjoe tp->t_column += c; 66784931Sfjoe return (c ? -1 : '\t'); 66884931Sfjoe } 66984931Sfjoe if (c == CEOT && ISSET(oflag, ONOEOT)) 67084931Sfjoe return (-1); 67184931Sfjoe 67284931Sfjoe /* 67384931Sfjoe * Newline translation: if ONLCR is set, 67484931Sfjoe * translate newline into "\r\n". 67584931Sfjoe */ 67684931Sfjoe if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) { 67784931Sfjoe tk_nout++; 67884931Sfjoe tp->t_outcc++; 67984931Sfjoe if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq)) 68084931Sfjoe return (c); 68184931Sfjoe } 68284931Sfjoe /* If OCRNL is set, translate "\r" into "\n". */ 68384931Sfjoe else if (c == '\r' && ISSET(tp->t_oflag, OCRNL)) 68484931Sfjoe c = '\n'; 68558313Slile /* If ONOCR is set, don't transmit CRs when on column 0. */ 68645705Seivind else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0) 68745705Seivind return (-1); 68845705Seivind 68945705Seivind tk_nout++; 69045705Seivind tp->t_outcc++; 69184931Sfjoe if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) 69244627Sjulian return (c); 69358313Slile 69458313Slile col = tp->t_column; 69558313Slile switch (CCLASS(c)) { 69658313Slile case BACKSPACE: 69758313Slile if (col > 0) 69858313Slile --col; 69958313Slile break; 70051320Slile case CONTROL: 70151320Slile break; 70251320Slile case NEWLINE: 70351320Slile if (ISSET(tp->t_oflag, ONLCR | ONLRET)) 70458313Slile col = 0; 70558313Slile break; 70658313Slile case RETURN: 70744627Sjulian col = 0; 70858313Slile break; 70944627Sjulian case ORDINARY: 71050512Slile ++col; 71150512Slile break; 71250512Slile case TAB: 71344627Sjulian col = (col + 8) & ~7; 71445705Seivind break; 71558313Slile } 71644627Sjulian tp->t_column = col; 7171541Srgrimes return (-1); 71834961Sphk} 7191541Srgrimes 7201541Srgrimes/* 7211541Srgrimes * Ioctls for all tty devices. Called after line-discipline specific ioctl 72284931Sfjoe * has been called to do discipline-specific functions and/or reject any 7231541Srgrimes * of these ioctl commands. 7241541Srgrimes */ 7251541Srgrimes/* ARGSUSED */ 7261541Srgrimesint 7271541Srgrimesttioctl(struct tty *tp, u_long cmd, void *data, int flag) 7281541Srgrimes{ 7291541Srgrimes struct proc *p; 7301541Srgrimes struct thread *td; 7311541Srgrimes struct pgrp *pgrp; 7321541Srgrimes int s, error; 7331541Srgrimes 73484931Sfjoe td = curthread; /* XXX */ 73584931Sfjoe p = td->td_proc; 7361541Srgrimes 7371541Srgrimes /* If the ioctl involves modification, hang if in the background. */ 7383282Swollman switch (cmd) { 7393282Swollman case TIOCCBRK: 7403282Swollman case TIOCCONS: 74112693Sphk case TIOCDRAIN: 74212693Sphk case TIOCEXCL: 74312693Sphk case TIOCFLUSH: 74412693Sphk#ifdef TIOCHPCL 7453282Swollman case TIOCHPCL: 7463282Swollman#endif 7473282Swollman case TIOCNXCL: 7483282Swollman case TIOCSBRK: 7493282Swollman case TIOCSCTTY: 7503282Swollman case TIOCSDRAINWAIT: 7515101Swollman case TIOCSETA: 75212693Sphk case TIOCSETAF: 75312693Sphk case TIOCSETAW: 75412693Sphk case TIOCSETD: 75512693Sphk case TIOCSPGRP: 7563282Swollman case TIOCSTART: 7573282Swollman case TIOCSTAT: 7583282Swollman case TIOCSTI: 7593282Swollman case TIOCSTOP: 7603282Swollman case TIOCSWINSZ: 76184931Sfjoe#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 7623282Swollman case TIOCLBIC: 76312693Sphk case TIOCLBIS: 76412693Sphk case TIOCLSET: 7653282Swollman case TIOCSETC: 76684931Sfjoe case OTIOCSETD: 76784931Sfjoe case TIOCSETN: 7683282Swollman case TIOCSETP: 76963080Sdwmalone case TIOCSLTC: 77063080Sdwmalone#endif 77163080Sdwmalone sx_slock(&proctree_lock); 77263080Sdwmalone PROC_LOCK(p); 77363080Sdwmalone while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) && 77463080Sdwmalone !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 77563080Sdwmalone !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { 77663080Sdwmalone pgrp = p->p_pgrp; 77763080Sdwmalone PROC_UNLOCK(p); 77863080Sdwmalone if (pgrp->pg_jobc == 0) { 77963080Sdwmalone sx_sunlock(&proctree_lock); 78063080Sdwmalone return (EIO); 78163080Sdwmalone } 78263080Sdwmalone PGRP_LOCK(pgrp); 78384931Sfjoe sx_sunlock(&proctree_lock); 78463080Sdwmalone pgsignal(pgrp, SIGTTOU, 1); 78563080Sdwmalone PGRP_UNLOCK(pgrp); 78684931Sfjoe error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1", 78784931Sfjoe 0); 78863080Sdwmalone if (error) 78963080Sdwmalone return (error); 79063080Sdwmalone sx_slock(&proctree_lock); 79163080Sdwmalone PROC_LOCK(p); 79263080Sdwmalone } 79363080Sdwmalone PROC_UNLOCK(p); 79463080Sdwmalone sx_sunlock(&proctree_lock); 7954069Swollman break; 7968876Srgrimes } 7977088Swollman 7984069Swollman switch (cmd) { /* Process the ioctl. */ 7993282Swollman case FIOASYNC: /* set/clear async i/o */ 8003282Swollman s = spltty(); 80184931Sfjoe if (*(int *)data) 8023282Swollman SET(tp->t_state, TS_ASYNC); 80384931Sfjoe else 8043282Swollman CLR(tp->t_state, TS_ASYNC); 8051541Srgrimes splx(s); 8061541Srgrimes break; 80784931Sfjoe case FIONBIO: /* set/clear non-blocking i/o */ 80884931Sfjoe break; /* XXX: delete. */ 80984931Sfjoe case FIONREAD: /* get # bytes to read */ 81084931Sfjoe s = spltty(); 81184931Sfjoe *(int *)data = ttnread(tp); 81284931Sfjoe splx(s); 81384931Sfjoe break; 81484931Sfjoe 81584931Sfjoe case FIOSETOWN: 81684931Sfjoe /* 81784931Sfjoe * Policy -- Don't allow FIOSETOWN on someone else's 81845705Seivind * controlling tty 81944627Sjulian */ 82051320Slile if (tp->t_session != NULL && !isctty(p, tp)) 82151320Slile return (ENOTTY); 82284931Sfjoe 82351320Slile error = fsetown(*(int *)data, &tp->t_sigio); 82444627Sjulian if (error) 82558313Slile return (error); 82658313Slile break; 82758313Slile case FIOGETOWN: 82858313Slile if (tp->t_session != NULL && !isctty(p, tp)) 82944627Sjulian return (ENOTTY); 83044627Sjulian *(int *)data = fgetown(tp->t_sigio); 83151320Slile break; 83251320Slile 83358313Slile case TIOCEXCL: /* set exclusive use of tty */ 83458313Slile s = spltty(); 83544627Sjulian SET(tp->t_state, TS_XCLUDE); 83645705Seivind splx(s); 83751320Slile break; 83851320Slile case TIOCFLUSH: { /* flush buffers */ 83951320Slile int flags = *(int *)data; 84051320Slile 84151320Slile if (flags == 0) 84251320Slile flags = FREAD | FWRITE; 84344627Sjulian else 84484931Sfjoe flags &= FREAD | FWRITE; 84551320Slile ttyflush(tp, flags); 84644627Sjulian break; 84744627Sjulian } 84844627Sjulian case TIOCCONS: /* become virtual console */ 8491541Srgrimes if (*(int *)data) { 8501541Srgrimes struct nameidata nid; 85184931Sfjoe 8521541Srgrimes if (constty && constty != tp && 8531541Srgrimes ISSET(constty->t_state, TS_CONNECTED)) 85432350Seivind return (EBUSY); 8551541Srgrimes 8561541Srgrimes /* Ensure user can open the real console. */ 8571541Srgrimes NDINIT(&nid, LOOKUP, LOCKLEAF | FOLLOW, UIO_SYSSPACE, 8581541Srgrimes "/dev/console", td); 8591541Srgrimes if ((error = namei(&nid)) != 0) 8601541Srgrimes return (error); 8611541Srgrimes NDFREE(&nid, NDF_ONLY_PNBUF); 8621541Srgrimes error = VOP_ACCESS(nid.ni_vp, VREAD, td->td_ucred, td); 8631541Srgrimes vput(nid.ni_vp); 8641541Srgrimes if (error) 8651541Srgrimes return (error); 8661541Srgrimes 8671541Srgrimes constty = tp; 8681541Srgrimes } else if (tp == constty) 8691541Srgrimes constty = NULL; 8701541Srgrimes break; 8711541Srgrimes case TIOCDRAIN: /* wait till output drained */ 8721541Srgrimes error = ttywait(tp); 8731541Srgrimes if (error) 8741541Srgrimes return (error); 8751541Srgrimes break; 8761541Srgrimes case TIOCGETA: { /* get termios struct */ 8771541Srgrimes struct termios *t = (struct termios *)data; 8781541Srgrimes 8791541Srgrimes bcopy(&tp->t_termios, t, sizeof(struct termios)); 8801541Srgrimes break; 8811541Srgrimes } 8821541Srgrimes case TIOCGETD: /* get line discipline */ 8831541Srgrimes *(int *)data = tp->t_line; 8841541Srgrimes break; 8851541Srgrimes case TIOCGWINSZ: /* get window size */ 8861541Srgrimes *(struct winsize *)data = tp->t_winsize; 8874069Swollman break; 8881541Srgrimes case TIOCGPGRP: /* get pgrp of tty */ 8891541Srgrimes if (!isctty(p, tp)) 8901541Srgrimes return (ENOTTY); 8915101Swollman *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; 8921541Srgrimes break; 8931541Srgrimes#ifdef TIOCHPCL 8941541Srgrimes case TIOCHPCL: /* hang up on last close */ 8954069Swollman s = spltty(); 89612693Sphk SET(tp->t_cflag, HUPCL); 8974069Swollman splx(s); 89812693Sphk break; 8994069Swollman#endif 90012693Sphk case TIOCNXCL: /* reset exclusive use of tty */ 9014069Swollman s = spltty(); 9024069Swollman CLR(tp->t_state, TS_XCLUDE); 90312693Sphk splx(s); 9044069Swollman break; 9057088Swollman case TIOCOUTQ: /* output queue size */ 9064069Swollman *(int *)data = tp->t_outq.c_cc; 90712693Sphk break; 9084069Swollman case TIOCSETA: /* set termios struct */ 9091541Srgrimes case TIOCSETAW: /* drain output, set */ 9101541Srgrimes case TIOCSETAF: { /* drn out, fls in, set */ 9111541Srgrimes struct termios *t = (struct termios *)data; 9121541Srgrimes 9135195Swollman if (t->c_ispeed == 0) 91484931Sfjoe t->c_ispeed = t->c_ospeed; 91584931Sfjoe if (t->c_ispeed == 0) 9165195Swollman t->c_ispeed = tp->t_ospeed; 9175195Swollman if (t->c_ispeed == 0) 91825822Stegge return (EINVAL); 91984931Sfjoe s = spltty(); 92084931Sfjoe if (cmd == TIOCSETAW || cmd == TIOCSETAF) { 9215195Swollman error = ttywait(tp); 9225195Swollman if (error) { 9235195Swollman splx(s); 92469152Sjlemon return (error); 92569152Sjlemon } 92669152Sjlemon if (cmd == TIOCSETAF) 92769152Sjlemon ttyflush(tp, FREAD); 92869152Sjlemon } 92969152Sjlemon if (!ISSET(t->c_cflag, CIGNORE)) { 93069152Sjlemon /* 93169152Sjlemon * Set device hardware. 93269152Sjlemon */ 93369152Sjlemon if (tp->t_param && (error = (*tp->t_param)(tp, t))) { 934 splx(s); 935 return (error); 936 } 937 if (ISSET(t->c_cflag, CLOCAL) && 938 !ISSET(tp->t_cflag, CLOCAL)) { 939 /* 940 * XXX disconnections would be too hard to 941 * get rid of without this kludge. The only 942 * way to get rid of controlling terminals 943 * is to exit from the session leader. 944 */ 945 CLR(tp->t_state, TS_ZOMBIE); 946 947 wakeup(TSA_CARR_ON(tp)); 948 ttwakeup(tp); 949 ttwwakeup(tp); 950 } 951 if ((ISSET(tp->t_state, TS_CARR_ON) || 952 ISSET(t->c_cflag, CLOCAL)) && 953 !ISSET(tp->t_state, TS_ZOMBIE)) 954 SET(tp->t_state, TS_CONNECTED); 955 else 956 CLR(tp->t_state, TS_CONNECTED); 957 tp->t_cflag = t->c_cflag; 958 tp->t_ispeed = t->c_ispeed; 959 if (t->c_ospeed != 0) 960 tp->t_ospeed = t->c_ospeed; 961 ttsetwater(tp); 962 } 963 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) && 964 cmd != TIOCSETAF) { 965 if (ISSET(t->c_lflag, ICANON)) 966 SET(tp->t_lflag, PENDIN); 967 else { 968 /* 969 * XXX we really shouldn't allow toggling 970 * ICANON while we're in a non-termios line 971 * discipline. Now we have to worry about 972 * panicing for a null queue. 973 */ 974 if (tp->t_canq.c_cbreserved > 0 && 975 tp->t_rawq.c_cbreserved > 0) { 976 catq(&tp->t_rawq, &tp->t_canq); 977 /* 978 * XXX the queue limits may be 979 * different, so the old queue 980 * swapping method no longer works. 981 */ 982 catq(&tp->t_canq, &tp->t_rawq); 983 } 984 CLR(tp->t_lflag, PENDIN); 985 } 986 ttwakeup(tp); 987 } 988 tp->t_iflag = t->c_iflag; 989 tp->t_oflag = t->c_oflag; 990 /* 991 * Make the EXTPROC bit read only. 992 */ 993 if (ISSET(tp->t_lflag, EXTPROC)) 994 SET(t->c_lflag, EXTPROC); 995 else 996 CLR(t->c_lflag, EXTPROC); 997 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN); 998 if (t->c_cc[VMIN] != tp->t_cc[VMIN] || 999 t->c_cc[VTIME] != tp->t_cc[VTIME]) 1000 ttwakeup(tp); 1001 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc)); 1002 splx(s); 1003 break; 1004 } 1005 case TIOCSETD: { /* set line discipline */ 1006 int t = *(int *)data; 1007 dev_t device = tp->t_dev; 1008 1009 if ((u_int)t >= nlinesw) 1010 return (ENXIO); 1011 if (t != tp->t_line) { 1012 s = spltty(); 1013 (*linesw[tp->t_line].l_close)(tp, flag); 1014 error = (*linesw[t].l_open)(device, tp); 1015 if (error) { 1016 (void)(*linesw[tp->t_line].l_open)(device, tp); 1017 splx(s); 1018 return (error); 1019 } 1020 tp->t_line = t; 1021 splx(s); 1022 } 1023 break; 1024 } 1025 case TIOCSTART: /* start output, like ^Q */ 1026 s = spltty(); 1027 if (ISSET(tp->t_state, TS_TTSTOP) || 1028 ISSET(tp->t_lflag, FLUSHO)) { 1029 CLR(tp->t_lflag, FLUSHO); 1030 CLR(tp->t_state, TS_TTSTOP); 1031 ttstart(tp); 1032 } 1033 splx(s); 1034 break; 1035 case TIOCSTI: /* simulate terminal input */ 1036 if ((flag & FREAD) == 0 && suser(td)) 1037 return (EPERM); 1038 if (!isctty(p, tp) && suser(td)) 1039 return (EACCES); 1040 s = spltty(); 1041 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp); 1042 splx(s); 1043 break; 1044 case TIOCSTOP: /* stop output, like ^S */ 1045 s = spltty(); 1046 if (!ISSET(tp->t_state, TS_TTSTOP)) { 1047 SET(tp->t_state, TS_TTSTOP); 1048 (*tp->t_stop)(tp, 0); 1049 } 1050 splx(s); 1051 break; 1052 case TIOCSCTTY: /* become controlling tty */ 1053 /* Session ctty vnode pointer set in vnode layer. */ 1054 sx_slock(&proctree_lock); 1055 if (!SESS_LEADER(p) || 1056 ((p->p_session->s_ttyvp || tp->t_session) && 1057 (tp->t_session != p->p_session))) { 1058 sx_sunlock(&proctree_lock); 1059 return (EPERM); 1060 } 1061 tp->t_session = p->p_session; 1062 tp->t_pgrp = p->p_pgrp; 1063 SESS_LOCK(p->p_session); 1064 p->p_session->s_ttyp = tp; 1065 SESS_UNLOCK(p->p_session); 1066 PROC_LOCK(p); 1067 p->p_flag |= P_CONTROLT; 1068 PROC_UNLOCK(p); 1069 sx_sunlock(&proctree_lock); 1070 break; 1071 case TIOCSPGRP: { /* set pgrp of tty */ 1072 sx_slock(&proctree_lock); 1073 pgrp = pgfind(*(int *)data); 1074 if (!isctty(p, tp)) { 1075 if (pgrp != NULL) 1076 PGRP_UNLOCK(pgrp); 1077 sx_sunlock(&proctree_lock); 1078 return (ENOTTY); 1079 } 1080 if (pgrp == NULL) { 1081 sx_sunlock(&proctree_lock); 1082 return (EPERM); 1083 } 1084 PGRP_UNLOCK(pgrp); 1085 if (pgrp->pg_session != p->p_session) { 1086 sx_sunlock(&proctree_lock); 1087 return (EPERM); 1088 } 1089 sx_sunlock(&proctree_lock); 1090 tp->t_pgrp = pgrp; 1091 break; 1092 } 1093 case TIOCSTAT: /* simulate control-T */ 1094 s = spltty(); 1095 ttyinfo(tp); 1096 splx(s); 1097 break; 1098 case TIOCSWINSZ: /* set window size */ 1099 if (bcmp((caddr_t)&tp->t_winsize, data, 1100 sizeof (struct winsize))) { 1101 tp->t_winsize = *(struct winsize *)data; 1102 if (tp->t_pgrp != NULL) { 1103 PGRP_LOCK(tp->t_pgrp); 1104 pgsignal(tp->t_pgrp, SIGWINCH, 1); 1105 PGRP_UNLOCK(tp->t_pgrp); 1106 } 1107 } 1108 break; 1109 case TIOCSDRAINWAIT: 1110 error = suser(td); 1111 if (error) 1112 return (error); 1113 tp->t_timeout = *(int *)data * hz; 1114 wakeup(TSA_OCOMPLETE(tp)); 1115 wakeup(TSA_OLOWAT(tp)); 1116 break; 1117 case TIOCGDRAINWAIT: 1118 *(int *)data = tp->t_timeout / hz; 1119 break; 1120 default: 1121#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1122 return (ttcompat(tp, cmd, data, flag)); 1123#else 1124 return (ENOIOCTL); 1125#endif 1126 } 1127 return (0); 1128} 1129 1130int 1131ttypoll(dev_t dev, int events, struct thread *td) 1132{ 1133 int s; 1134 int revents = 0; 1135 struct tty *tp; 1136 1137 tp = dev->si_tty; 1138 if (tp == NULL) /* XXX used to return ENXIO, but that means true! */ 1139 return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)) 1140 | POLLHUP); 1141 1142 s = spltty(); 1143 if (events & (POLLIN | POLLRDNORM)) { 1144 if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE)) 1145 revents |= events & (POLLIN | POLLRDNORM); 1146 else 1147 selrecord(td, &tp->t_rsel); 1148 } 1149 if (events & (POLLOUT | POLLWRNORM)) { 1150 if ((tp->t_outq.c_cc <= tp->t_olowat && 1151 ISSET(tp->t_state, TS_CONNECTED)) 1152 || ISSET(tp->t_state, TS_ZOMBIE)) 1153 revents |= events & (POLLOUT | POLLWRNORM); 1154 else 1155 selrecord(td, &tp->t_wsel); 1156 } 1157 splx(s); 1158 return (revents); 1159} 1160 1161static struct filterops ttyread_filtops = 1162 { 1, NULL, filt_ttyrdetach, filt_ttyread }; 1163static struct filterops ttywrite_filtops = 1164 { 1, NULL, filt_ttywdetach, filt_ttywrite }; 1165 1166int 1167ttykqfilter(dev_t dev, struct knote *kn) 1168{ 1169 struct tty *tp = dev->si_tty; 1170 struct klist *klist; 1171 int s; 1172 1173 switch (kn->kn_filter) { 1174 case EVFILT_READ: 1175 klist = &tp->t_rsel.si_note; 1176 kn->kn_fop = &ttyread_filtops; 1177 break; 1178 case EVFILT_WRITE: 1179 klist = &tp->t_wsel.si_note; 1180 kn->kn_fop = &ttywrite_filtops; 1181 break; 1182 default: 1183 return (1); 1184 } 1185 1186 kn->kn_hook = (caddr_t)dev; 1187 1188 s = spltty(); 1189 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1190 splx(s); 1191 1192 return (0); 1193} 1194 1195static void 1196filt_ttyrdetach(struct knote *kn) 1197{ 1198 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 1199 int s = spltty(); 1200 1201 SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext); 1202 splx(s); 1203} 1204 1205static int 1206filt_ttyread(struct knote *kn, long hint) 1207{ 1208 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 1209 1210 kn->kn_data = ttnread(tp); 1211 if (ISSET(tp->t_state, TS_ZOMBIE)) { 1212 kn->kn_flags |= EV_EOF; 1213 return (1); 1214 } 1215 return (kn->kn_data > 0); 1216} 1217 1218static void 1219filt_ttywdetach(struct knote *kn) 1220{ 1221 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 1222 int s = spltty(); 1223 1224 SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext); 1225 splx(s); 1226} 1227 1228static int 1229filt_ttywrite(struct knote *kn, long hint) 1230{ 1231 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty; 1232 1233 kn->kn_data = tp->t_outq.c_cc; 1234 if (ISSET(tp->t_state, TS_ZOMBIE)) 1235 return (1); 1236 return (kn->kn_data <= tp->t_olowat && 1237 ISSET(tp->t_state, TS_CONNECTED)); 1238} 1239 1240/* 1241 * Must be called at spltty(). 1242 */ 1243static int 1244ttnread(struct tty *tp) 1245{ 1246 int nread; 1247 1248 if (ISSET(tp->t_lflag, PENDIN)) 1249 ttypend(tp); 1250 nread = tp->t_canq.c_cc; 1251 if (!ISSET(tp->t_lflag, ICANON)) { 1252 nread += tp->t_rawq.c_cc; 1253 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0) 1254 nread = 0; 1255 } 1256 return (nread); 1257} 1258 1259/* 1260 * Wait for output to drain. 1261 */ 1262int 1263ttywait(struct tty *tp) 1264{ 1265 int error, s; 1266 1267 error = 0; 1268 s = spltty(); 1269 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 1270 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) { 1271 (*tp->t_oproc)(tp); 1272 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 1273 ISSET(tp->t_state, TS_CONNECTED)) { 1274 SET(tp->t_state, TS_SO_OCOMPLETE); 1275 error = ttysleep(tp, TSA_OCOMPLETE(tp), 1276 TTOPRI | PCATCH, "ttywai", 1277 tp->t_timeout); 1278 if (error) { 1279 if (error == EWOULDBLOCK) 1280 error = EIO; 1281 break; 1282 } 1283 } else 1284 break; 1285 } 1286 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY))) 1287 error = EIO; 1288 splx(s); 1289 return (error); 1290} 1291 1292/* 1293 * Flush if successfully wait. 1294 */ 1295static int 1296ttywflush(struct tty *tp) 1297{ 1298 int error; 1299 1300 if ((error = ttywait(tp)) == 0) 1301 ttyflush(tp, FREAD); 1302 return (error); 1303} 1304 1305/* 1306 * Flush tty read and/or write queues, notifying anyone waiting. 1307 */ 1308void 1309ttyflush(struct tty *tp, int rw) 1310{ 1311 int s; 1312 1313 s = spltty(); 1314#if 0 1315again: 1316#endif 1317 if (rw & FWRITE) { 1318 FLUSHQ(&tp->t_outq); 1319 CLR(tp->t_state, TS_TTSTOP); 1320 } 1321 (*tp->t_stop)(tp, rw); 1322 if (rw & FREAD) { 1323 FLUSHQ(&tp->t_canq); 1324 FLUSHQ(&tp->t_rawq); 1325 CLR(tp->t_lflag, PENDIN); 1326 tp->t_rocount = 0; 1327 tp->t_rocol = 0; 1328 CLR(tp->t_state, TS_LOCAL); 1329 ttwakeup(tp); 1330 if (ISSET(tp->t_state, TS_TBLOCK)) { 1331 if (rw & FWRITE) 1332 FLUSHQ(&tp->t_outq); 1333 ttyunblock(tp); 1334 1335 /* 1336 * Don't let leave any state that might clobber the 1337 * next line discipline (although we should do more 1338 * to send the START char). Not clearing the state 1339 * may have caused the "putc to a clist with no 1340 * reserved cblocks" panic/printf. 1341 */ 1342 CLR(tp->t_state, TS_TBLOCK); 1343 1344#if 0 /* forget it, sleeping isn't always safe and we don't know when it is */ 1345 if (ISSET(tp->t_iflag, IXOFF)) { 1346 /* 1347 * XXX wait a bit in the hope that the stop 1348 * character (if any) will go out. Waiting 1349 * isn't good since it allows races. This 1350 * will be fixed when the stop character is 1351 * put in a special queue. Don't bother with 1352 * the checks in ttywait() since the timeout 1353 * will save us. 1354 */ 1355 SET(tp->t_state, TS_SO_OCOMPLETE); 1356 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI, 1357 "ttyfls", hz / 10); 1358 /* 1359 * Don't try sending the stop character again. 1360 */ 1361 CLR(tp->t_state, TS_TBLOCK); 1362 goto again; 1363 } 1364#endif 1365 } 1366 } 1367 if (rw & FWRITE) { 1368 FLUSHQ(&tp->t_outq); 1369 ttwwakeup(tp); 1370 } 1371 splx(s); 1372} 1373 1374/* 1375 * Copy in the default termios characters. 1376 */ 1377void 1378termioschars(struct termios *t) 1379{ 1380 1381 bcopy(ttydefchars, t->c_cc, sizeof t->c_cc); 1382} 1383 1384/* 1385 * Old interface. 1386 */ 1387void 1388ttychars(struct tty *tp) 1389{ 1390 1391 termioschars(&tp->t_termios); 1392} 1393 1394/* 1395 * Handle input high water. Send stop character for the IXOFF case. Turn 1396 * on our input flow control bit and propagate the changes to the driver. 1397 * XXX the stop character should be put in a special high priority queue. 1398 */ 1399void 1400ttyblock(struct tty *tp) 1401{ 1402 1403 SET(tp->t_state, TS_TBLOCK); 1404 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE && 1405 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0) 1406 CLR(tp->t_state, TS_TBLOCK); /* try again later */ 1407 ttstart(tp); 1408} 1409 1410/* 1411 * Handle input low water. Send start character for the IXOFF case. Turn 1412 * off our input flow control bit and propagate the changes to the driver. 1413 * XXX the start character should be put in a special high priority queue. 1414 */ 1415static void 1416ttyunblock(struct tty *tp) 1417{ 1418 1419 CLR(tp->t_state, TS_TBLOCK); 1420 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE && 1421 putc(tp->t_cc[VSTART], &tp->t_outq) != 0) 1422 SET(tp->t_state, TS_TBLOCK); /* try again later */ 1423 ttstart(tp); 1424} 1425 1426#ifdef notyet 1427/* Not used by any current (i386) drivers. */ 1428/* 1429 * Restart after an inter-char delay. 1430 */ 1431void 1432ttrstrt(void *tp_arg) 1433{ 1434 struct tty *tp; 1435 int s; 1436 1437 KASSERT(tp_arg != NULL, ("ttrstrt")); 1438 1439 tp = tp_arg; 1440 s = spltty(); 1441 1442 CLR(tp->t_state, TS_TIMEOUT); 1443 ttstart(tp); 1444 1445 splx(s); 1446} 1447#endif 1448 1449int 1450ttstart(struct tty *tp) 1451{ 1452 1453 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */ 1454 (*tp->t_oproc)(tp); 1455 return (0); 1456} 1457 1458/* 1459 * "close" a line discipline 1460 */ 1461int 1462ttylclose(struct tty *tp, int flag) 1463{ 1464 1465 if (flag & FNONBLOCK || ttywflush(tp)) 1466 ttyflush(tp, FREAD | FWRITE); 1467 return (0); 1468} 1469 1470/* 1471 * Handle modem control transition on a tty. 1472 * Flag indicates new state of carrier. 1473 * Returns 0 if the line should be turned off, otherwise 1. 1474 */ 1475int 1476ttymodem(struct tty *tp, int flag) 1477{ 1478 1479 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) { 1480 /* 1481 * MDMBUF: do flow control according to carrier flag 1482 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP 1483 * works if IXON and IXANY are clear. 1484 */ 1485 if (flag) { 1486 CLR(tp->t_state, TS_CAR_OFLOW); 1487 CLR(tp->t_state, TS_TTSTOP); 1488 ttstart(tp); 1489 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) { 1490 SET(tp->t_state, TS_CAR_OFLOW); 1491 SET(tp->t_state, TS_TTSTOP); 1492 (*tp->t_stop)(tp, 0); 1493 } 1494 } else if (flag == 0) { 1495 /* 1496 * Lost carrier. 1497 */ 1498 CLR(tp->t_state, TS_CARR_ON); 1499 if (ISSET(tp->t_state, TS_ISOPEN) && 1500 !ISSET(tp->t_cflag, CLOCAL)) { 1501 SET(tp->t_state, TS_ZOMBIE); 1502 CLR(tp->t_state, TS_CONNECTED); 1503 if (tp->t_session) { 1504 sx_slock(&proctree_lock); 1505 if (tp->t_session->s_leader) { 1506 struct proc *p; 1507 1508 p = tp->t_session->s_leader; 1509 PROC_LOCK(p); 1510 psignal(p, SIGHUP); 1511 PROC_UNLOCK(p); 1512 } 1513 sx_sunlock(&proctree_lock); 1514 } 1515 ttyflush(tp, FREAD | FWRITE); 1516 return (0); 1517 } 1518 } else { 1519 /* 1520 * Carrier now on. 1521 */ 1522 SET(tp->t_state, TS_CARR_ON); 1523 if (!ISSET(tp->t_state, TS_ZOMBIE)) 1524 SET(tp->t_state, TS_CONNECTED); 1525 wakeup(TSA_CARR_ON(tp)); 1526 ttwakeup(tp); 1527 ttwwakeup(tp); 1528 } 1529 return (1); 1530} 1531 1532/* 1533 * Reinput pending characters after state switch 1534 * call at spltty(). 1535 */ 1536static void 1537ttypend(struct tty *tp) 1538{ 1539 struct clist tq; 1540 int c; 1541 1542 CLR(tp->t_lflag, PENDIN); 1543 SET(tp->t_state, TS_TYPEN); 1544 /* 1545 * XXX this assumes too much about clist internals. It may even 1546 * fail if the cblock slush pool is empty. We can't allocate more 1547 * cblocks here because we are called from an interrupt handler 1548 * and clist_alloc_cblocks() can wait. 1549 */ 1550 tq = tp->t_rawq; 1551 bzero(&tp->t_rawq, sizeof tp->t_rawq); 1552 tp->t_rawq.c_cbmax = tq.c_cbmax; 1553 tp->t_rawq.c_cbreserved = tq.c_cbreserved; 1554 while ((c = getc(&tq)) >= 0) 1555 ttyinput(c, tp); 1556 CLR(tp->t_state, TS_TYPEN); 1557} 1558 1559/* 1560 * Process a read call on a tty device. 1561 */ 1562int 1563ttread(struct tty *tp, struct uio *uio, int flag) 1564{ 1565 struct clist *qp; 1566 int c; 1567 tcflag_t lflag; 1568 cc_t *cc = tp->t_cc; 1569 struct proc *p = curproc; 1570 int s, first, error = 0; 1571 int has_stime = 0, last_cc = 0; 1572 long slp = 0; /* XXX this should be renamed `timo'. */ 1573 struct timeval stime; 1574 struct pgrp *pg; 1575 1576loop: 1577 s = spltty(); 1578 lflag = tp->t_lflag; 1579 /* 1580 * take pending input first 1581 */ 1582 if (ISSET(lflag, PENDIN)) { 1583 ttypend(tp); 1584 splx(s); /* reduce latency */ 1585 s = spltty(); 1586 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */ 1587 } 1588 1589 /* 1590 * Hang process if it's in the background. 1591 */ 1592 if (isbackground(p, tp)) { 1593 splx(s); 1594 sx_slock(&proctree_lock); 1595 PROC_LOCK(p); 1596 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) || 1597 SIGISMEMBER(p->p_sigmask, SIGTTIN) || 1598 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) { 1599 PROC_UNLOCK(p); 1600 sx_sunlock(&proctree_lock); 1601 return (EIO); 1602 } 1603 pg = p->p_pgrp; 1604 PROC_UNLOCK(p); 1605 PGRP_LOCK(pg); 1606 sx_sunlock(&proctree_lock); 1607 pgsignal(pg, SIGTTIN, 1); 1608 PGRP_UNLOCK(pg); 1609 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0); 1610 if (error) 1611 return (error); 1612 goto loop; 1613 } 1614 1615 if (ISSET(tp->t_state, TS_ZOMBIE)) { 1616 splx(s); 1617 return (0); /* EOF */ 1618 } 1619 1620 /* 1621 * If canonical, use the canonical queue, 1622 * else use the raw queue. 1623 * 1624 * (should get rid of clists...) 1625 */ 1626 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq; 1627 1628 if (flag & IO_NDELAY) { 1629 if (qp->c_cc > 0) 1630 goto read; 1631 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) { 1632 splx(s); 1633 return (0); 1634 } 1635 splx(s); 1636 return (EWOULDBLOCK); 1637 } 1638 if (!ISSET(lflag, ICANON)) { 1639 int m = cc[VMIN]; 1640 long t = cc[VTIME]; 1641 struct timeval timecopy; 1642 1643 /* 1644 * Check each of the four combinations. 1645 * (m > 0 && t == 0) is the normal read case. 1646 * It should be fairly efficient, so we check that and its 1647 * companion case (m == 0 && t == 0) first. 1648 * For the other two cases, we compute the target sleep time 1649 * into slp. 1650 */ 1651 if (t == 0) { 1652 if (qp->c_cc < m) 1653 goto sleep; 1654 if (qp->c_cc > 0) 1655 goto read; 1656 1657 /* m, t and qp->c_cc are all 0. 0 is enough input. */ 1658 splx(s); 1659 return (0); 1660 } 1661 t *= 100000; /* time in us */ 1662#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \ 1663 ((t1).tv_usec - (t2).tv_usec)) 1664 if (m > 0) { 1665 if (qp->c_cc <= 0) 1666 goto sleep; 1667 if (qp->c_cc >= m) 1668 goto read; 1669 getmicrotime(&timecopy); 1670 if (!has_stime) { 1671 /* first character, start timer */ 1672 has_stime = 1; 1673 stime = timecopy; 1674 slp = t; 1675 } else if (qp->c_cc > last_cc) { 1676 /* got a character, restart timer */ 1677 stime = timecopy; 1678 slp = t; 1679 } else { 1680 /* nothing, check expiration */ 1681 slp = t - diff(timecopy, stime); 1682 if (slp <= 0) 1683 goto read; 1684 } 1685 last_cc = qp->c_cc; 1686 } else { /* m == 0 */ 1687 if (qp->c_cc > 0) 1688 goto read; 1689 getmicrotime(&timecopy); 1690 if (!has_stime) { 1691 has_stime = 1; 1692 stime = timecopy; 1693 slp = t; 1694 } else { 1695 slp = t - diff(timecopy, stime); 1696 if (slp <= 0) { 1697 /* Timed out, but 0 is enough input. */ 1698 splx(s); 1699 return (0); 1700 } 1701 } 1702 } 1703#undef diff 1704 /* 1705 * Rounding down may make us wake up just short 1706 * of the target, so we round up. 1707 * The formula is ceiling(slp * hz/1000000). 1708 * 32-bit arithmetic is enough for hz < 169. 1709 * XXX see tvtohz() for how to avoid overflow if hz 1710 * is large (divide by `tick' and/or arrange to 1711 * use tvtohz() if hz is large). 1712 */ 1713 slp = (long) (((u_long)slp * hz) + 999999) / 1000000; 1714 goto sleep; 1715 } 1716 if (qp->c_cc <= 0) { 1717sleep: 1718 /* 1719 * There is no input, or not enough input and we can block. 1720 */ 1721 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH, 1722 ISSET(tp->t_state, TS_CONNECTED) ? 1723 "ttyin" : "ttyhup", (int)slp); 1724 splx(s); 1725 if (error == EWOULDBLOCK) 1726 error = 0; 1727 else if (error) 1728 return (error); 1729 /* 1730 * XXX what happens if another process eats some input 1731 * while we are asleep (not just here)? It would be 1732 * safest to detect changes and reset our state variables 1733 * (has_stime and last_cc). 1734 */ 1735 slp = 0; 1736 goto loop; 1737 } 1738read: 1739 splx(s); 1740 /* 1741 * Input present, check for input mapping and processing. 1742 */ 1743 first = 1; 1744 if (ISSET(lflag, ICANON | ISIG)) 1745 goto slowcase; 1746 for (;;) { 1747 char ibuf[IBUFSIZ]; 1748 int icc; 1749 1750 icc = imin(uio->uio_resid, IBUFSIZ); 1751 icc = q_to_b(qp, ibuf, icc); 1752 if (icc <= 0) { 1753 if (first) 1754 goto loop; 1755 break; 1756 } 1757 error = uiomove(ibuf, icc, uio); 1758 /* 1759 * XXX if there was an error then we should ungetc() the 1760 * unmoved chars and reduce icc here. 1761 */ 1762 if (error) 1763 break; 1764 if (uio->uio_resid == 0) 1765 break; 1766 first = 0; 1767 } 1768 goto out; 1769slowcase: 1770 for (;;) { 1771 c = getc(qp); 1772 if (c < 0) { 1773 if (first) 1774 goto loop; 1775 break; 1776 } 1777 /* 1778 * delayed suspend (^Y) 1779 */ 1780 if (CCEQ(cc[VDSUSP], c) && 1781 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) { 1782 if (tp->t_pgrp != NULL) { 1783 PGRP_LOCK(tp->t_pgrp); 1784 pgsignal(tp->t_pgrp, SIGTSTP, 1); 1785 PGRP_UNLOCK(tp->t_pgrp); 1786 } 1787 if (first) { 1788 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, 1789 "ttybg3", 0); 1790 if (error) 1791 break; 1792 goto loop; 1793 } 1794 break; 1795 } 1796 /* 1797 * Interpret EOF only in canonical mode. 1798 */ 1799 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) 1800 break; 1801 /* 1802 * Give user character. 1803 */ 1804 error = ureadc(c, uio); 1805 if (error) 1806 /* XXX should ungetc(c, qp). */ 1807 break; 1808 if (uio->uio_resid == 0) 1809 break; 1810 /* 1811 * In canonical mode check for a "break character" 1812 * marking the end of a "line of input". 1813 */ 1814 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag)) 1815 break; 1816 first = 0; 1817 } 1818 1819out: 1820 /* 1821 * Look to unblock input now that (presumably) 1822 * the input queue has gone down. 1823 */ 1824 s = spltty(); 1825 if (ISSET(tp->t_state, TS_TBLOCK) && 1826 tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat) 1827 ttyunblock(tp); 1828 splx(s); 1829 1830 return (error); 1831} 1832 1833/* 1834 * Check the output queue on tp for space for a kernel message (from uprintf 1835 * or tprintf). Allow some space over the normal hiwater mark so we don't 1836 * lose messages due to normal flow control, but don't let the tty run amok. 1837 * Sleeps here are not interruptible, but we return prematurely if new signals 1838 * arrive. 1839 */ 1840int 1841ttycheckoutq(struct tty *tp, int wait) 1842{ 1843 int hiwat, s; 1844 sigset_t oldmask; 1845 1846 hiwat = tp->t_ohiwat; 1847 SIGEMPTYSET(oldmask); 1848 s = spltty(); 1849 if (wait) 1850 oldmask = curproc->p_siglist; 1851 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) 1852 while (tp->t_outq.c_cc > hiwat) { 1853 ttstart(tp); 1854 if (tp->t_outq.c_cc <= hiwat) 1855 break; 1856 if (!(wait && SIGSETEQ(curproc->p_siglist, oldmask))) { 1857 splx(s); 1858 return (0); 1859 } 1860 SET(tp->t_state, TS_SO_OLOWAT); 1861 tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz); 1862 } 1863 splx(s); 1864 return (1); 1865} 1866 1867/* 1868 * Process a write call on a tty device. 1869 */ 1870int 1871ttwrite(struct tty *tp, struct uio *uio, int flag) 1872{ 1873 char *cp = NULL; 1874 int cc, ce; 1875 struct proc *p; 1876 int i, hiwat, cnt, error, s; 1877 char obuf[OBUFSIZ]; 1878 1879 hiwat = tp->t_ohiwat; 1880 cnt = uio->uio_resid; 1881 error = 0; 1882 cc = 0; 1883loop: 1884 s = spltty(); 1885 if (ISSET(tp->t_state, TS_ZOMBIE)) { 1886 splx(s); 1887 if (uio->uio_resid == cnt) 1888 error = EIO; 1889 goto out; 1890 } 1891 if (!ISSET(tp->t_state, TS_CONNECTED)) { 1892 if (flag & IO_NDELAY) { 1893 splx(s); 1894 error = EWOULDBLOCK; 1895 goto out; 1896 } 1897 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH, 1898 "ttydcd", 0); 1899 splx(s); 1900 if (error) 1901 goto out; 1902 goto loop; 1903 } 1904 splx(s); 1905 /* 1906 * Hang the process if it's in the background. 1907 */ 1908 p = curproc; 1909 sx_slock(&proctree_lock); 1910 PROC_LOCK(p); 1911 if (isbackground(p, tp) && 1912 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) && 1913 !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 1914 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { 1915 if (p->p_pgrp->pg_jobc == 0) { 1916 PROC_UNLOCK(p); 1917 sx_sunlock(&proctree_lock); 1918 error = EIO; 1919 goto out; 1920 } 1921 PROC_UNLOCK(p); 1922 PGRP_LOCK(p->p_pgrp); 1923 sx_sunlock(&proctree_lock); 1924 pgsignal(p->p_pgrp, SIGTTOU, 1); 1925 PGRP_UNLOCK(p->p_pgrp); 1926 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0); 1927 if (error) 1928 goto out; 1929 goto loop; 1930 } else { 1931 PROC_UNLOCK(p); 1932 sx_sunlock(&proctree_lock); 1933 } 1934 /* 1935 * Process the user's data in at most OBUFSIZ chunks. Perform any 1936 * output translation. Keep track of high water mark, sleep on 1937 * overflow awaiting device aid in acquiring new space. 1938 */ 1939 while (uio->uio_resid > 0 || cc > 0) { 1940 if (ISSET(tp->t_lflag, FLUSHO)) { 1941 uio->uio_resid = 0; 1942 return (0); 1943 } 1944 if (tp->t_outq.c_cc > hiwat) 1945 goto ovhiwat; 1946 /* 1947 * Grab a hunk of data from the user, unless we have some 1948 * leftover from last time. 1949 */ 1950 if (cc == 0) { 1951 cc = imin(uio->uio_resid, OBUFSIZ); 1952 cp = obuf; 1953 error = uiomove(cp, cc, uio); 1954 if (error) { 1955 cc = 0; 1956 break; 1957 } 1958 } 1959 /* 1960 * If nothing fancy need be done, grab those characters we 1961 * can handle without any of ttyoutput's processing and 1962 * just transfer them to the output q. For those chars 1963 * which require special processing (as indicated by the 1964 * bits in char_type), call ttyoutput. After processing 1965 * a hunk of data, look for FLUSHO so ^O's will take effect 1966 * immediately. 1967 */ 1968 while (cc > 0) { 1969 if (!ISSET(tp->t_oflag, OPOST)) 1970 ce = cc; 1971 else { 1972 ce = cc - scanc((u_int)cc, (u_char *)cp, 1973 char_type, CCLASSMASK); 1974 /* 1975 * If ce is zero, then we're processing 1976 * a special character through ttyoutput. 1977 */ 1978 if (ce == 0) { 1979 tp->t_rocount = 0; 1980 if (ttyoutput(*cp, tp) >= 0) { 1981 /* No Clists, wait a bit. */ 1982 ttstart(tp); 1983 if (flag & IO_NDELAY) { 1984 error = EWOULDBLOCK; 1985 goto out; 1986 } 1987 error = ttysleep(tp, &lbolt, 1988 TTOPRI|PCATCH, 1989 "ttybf1", 0); 1990 if (error) 1991 goto out; 1992 goto loop; 1993 } 1994 cp++; 1995 cc--; 1996 if (ISSET(tp->t_lflag, FLUSHO) || 1997 tp->t_outq.c_cc > hiwat) 1998 goto ovhiwat; 1999 continue; 2000 } 2001 } 2002 /* 2003 * A bunch of normal characters have been found. 2004 * Transfer them en masse to the output queue and 2005 * continue processing at the top of the loop. 2006 * If there are any further characters in this 2007 * <= OBUFSIZ chunk, the first should be a character 2008 * requiring special handling by ttyoutput. 2009 */ 2010 tp->t_rocount = 0; 2011 i = b_to_q(cp, ce, &tp->t_outq); 2012 ce -= i; 2013 tp->t_column += ce; 2014 cp += ce, cc -= ce, tk_nout += ce; 2015 tp->t_outcc += ce; 2016 if (i > 0) { 2017 /* No Clists, wait a bit. */ 2018 ttstart(tp); 2019 if (flag & IO_NDELAY) { 2020 error = EWOULDBLOCK; 2021 goto out; 2022 } 2023 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, 2024 "ttybf2", 0); 2025 if (error) 2026 goto out; 2027 goto loop; 2028 } 2029 if (ISSET(tp->t_lflag, FLUSHO) || 2030 tp->t_outq.c_cc > hiwat) 2031 break; 2032 } 2033 ttstart(tp); 2034 } 2035out: 2036 /* 2037 * If cc is nonzero, we leave the uio structure inconsistent, as the 2038 * offset and iov pointers have moved forward, but it doesn't matter 2039 * (the call will either return short or restart with a new uio). 2040 */ 2041 uio->uio_resid += cc; 2042 return (error); 2043 2044ovhiwat: 2045 ttstart(tp); 2046 s = spltty(); 2047 /* 2048 * This can only occur if FLUSHO is set in t_lflag, 2049 * or if ttstart/oproc is synchronous (or very fast). 2050 */ 2051 if (tp->t_outq.c_cc <= hiwat) { 2052 splx(s); 2053 goto loop; 2054 } 2055 if (flag & IO_NDELAY) { 2056 splx(s); 2057 uio->uio_resid += cc; 2058 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0); 2059 } 2060 SET(tp->t_state, TS_SO_OLOWAT); 2061 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri", 2062 tp->t_timeout); 2063 splx(s); 2064 if (error == EWOULDBLOCK) 2065 error = EIO; 2066 if (error) 2067 goto out; 2068 goto loop; 2069} 2070 2071/* 2072 * Rubout one character from the rawq of tp 2073 * as cleanly as possible. 2074 */ 2075static void 2076ttyrub(int c, struct tty *tp) 2077{ 2078 char *cp; 2079 int savecol; 2080 int tabc, s; 2081 2082 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 2083 return; 2084 CLR(tp->t_lflag, FLUSHO); 2085 if (ISSET(tp->t_lflag, ECHOE)) { 2086 if (tp->t_rocount == 0) { 2087 /* 2088 * Screwed by ttwrite; retype 2089 */ 2090 ttyretype(tp); 2091 return; 2092 } 2093 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 2094 ttyrubo(tp, 2); 2095 else { 2096 CLR(c, ~TTY_CHARMASK); 2097 switch (CCLASS(c)) { 2098 case ORDINARY: 2099 ttyrubo(tp, 1); 2100 break; 2101 case BACKSPACE: 2102 case CONTROL: 2103 case NEWLINE: 2104 case RETURN: 2105 case VTAB: 2106 if (ISSET(tp->t_lflag, ECHOCTL)) 2107 ttyrubo(tp, 2); 2108 break; 2109 case TAB: 2110 if (tp->t_rocount < tp->t_rawq.c_cc) { 2111 ttyretype(tp); 2112 return; 2113 } 2114 s = spltty(); 2115 savecol = tp->t_column; 2116 SET(tp->t_state, TS_CNTTB); 2117 SET(tp->t_lflag, FLUSHO); 2118 tp->t_column = tp->t_rocol; 2119 cp = tp->t_rawq.c_cf; 2120 if (cp) 2121 tabc = *cp; /* XXX FIX NEXTC */ 2122 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc)) 2123 ttyecho(tabc, tp); 2124 CLR(tp->t_lflag, FLUSHO); 2125 CLR(tp->t_state, TS_CNTTB); 2126 splx(s); 2127 2128 /* savecol will now be length of the tab. */ 2129 savecol -= tp->t_column; 2130 tp->t_column += savecol; 2131 if (savecol > 8) 2132 savecol = 8; /* overflow screw */ 2133 while (--savecol >= 0) 2134 (void)ttyoutput('\b', tp); 2135 break; 2136 default: /* XXX */ 2137#define PANICSTR "ttyrub: would panic c = %d, val = %d\n" 2138 (void)printf(PANICSTR, c, CCLASS(c)); 2139#ifdef notdef 2140 panic(PANICSTR, c, CCLASS(c)); 2141#endif 2142 } 2143 } 2144 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 2145 if (!ISSET(tp->t_state, TS_ERASE)) { 2146 SET(tp->t_state, TS_ERASE); 2147 (void)ttyoutput('\\', tp); 2148 } 2149 ttyecho(c, tp); 2150 } else { 2151 ttyecho(tp->t_cc[VERASE], tp); 2152 /* 2153 * This code may be executed not only when an ERASE key 2154 * is pressed, but also when ^U (KILL) or ^W (WERASE) are. 2155 * So, I didn't think it was worthwhile to pass the extra 2156 * information (which would need an extra parameter, 2157 * changing every call) needed to distinguish the ERASE2 2158 * case from the ERASE. 2159 */ 2160 } 2161 --tp->t_rocount; 2162} 2163 2164/* 2165 * Back over cnt characters, erasing them. 2166 */ 2167static void 2168ttyrubo(struct tty *tp, int cnt) 2169{ 2170 2171 while (cnt-- > 0) { 2172 (void)ttyoutput('\b', tp); 2173 (void)ttyoutput(' ', tp); 2174 (void)ttyoutput('\b', tp); 2175 } 2176} 2177 2178/* 2179 * ttyretype -- 2180 * Reprint the rawq line. Note, it is assumed that c_cc has already 2181 * been checked. 2182 */ 2183static void 2184ttyretype(struct tty *tp) 2185{ 2186 char *cp; 2187 int s, c; 2188 2189 /* Echo the reprint character. */ 2190 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 2191 ttyecho(tp->t_cc[VREPRINT], tp); 2192 2193 (void)ttyoutput('\n', tp); 2194 2195 /* 2196 * XXX 2197 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE 2198 * BIT OF FIRST CHAR. 2199 */ 2200 s = spltty(); 2201 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0); 2202 cp != NULL; cp = nextc(&tp->t_canq, cp, &c)) 2203 ttyecho(c, tp); 2204 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0); 2205 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c)) 2206 ttyecho(c, tp); 2207 CLR(tp->t_state, TS_ERASE); 2208 splx(s); 2209 2210 tp->t_rocount = tp->t_rawq.c_cc; 2211 tp->t_rocol = 0; 2212} 2213 2214/* 2215 * Echo a typed character to the terminal. 2216 */ 2217static void 2218ttyecho(int c, struct tty *tp) 2219{ 2220 2221 if (!ISSET(tp->t_state, TS_CNTTB)) 2222 CLR(tp->t_lflag, FLUSHO); 2223 if ((!ISSET(tp->t_lflag, ECHO) && 2224 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) || 2225 ISSET(tp->t_lflag, EXTPROC)) 2226 return; 2227 if (ISSET(tp->t_lflag, ECHOCTL) && 2228 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') || 2229 ISSET(c, TTY_CHARMASK) == 0177)) { 2230 (void)ttyoutput('^', tp); 2231 CLR(c, ~TTY_CHARMASK); 2232 if (c == 0177) 2233 c = '?'; 2234 else 2235 c += 'A' - 1; 2236 } 2237 (void)ttyoutput(c, tp); 2238} 2239 2240/* 2241 * Wake up any readers on a tty. 2242 */ 2243void 2244ttwakeup(struct tty *tp) 2245{ 2246 2247 if (SEL_WAITING(&tp->t_rsel)) 2248 selwakeup(&tp->t_rsel); 2249 if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL) 2250 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL)); 2251 wakeup(TSA_HUP_OR_INPUT(tp)); 2252 KNOTE(&tp->t_rsel.si_note, 0); 2253} 2254 2255/* 2256 * Wake up any writers on a tty. 2257 */ 2258void 2259ttwwakeup(struct tty *tp) 2260{ 2261 2262 if (SEL_WAITING(&tp->t_wsel) && tp->t_outq.c_cc <= tp->t_olowat) 2263 selwakeup(&tp->t_wsel); 2264 if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL) 2265 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL)); 2266 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) == 2267 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) { 2268 CLR(tp->t_state, TS_SO_OCOMPLETE); 2269 wakeup(TSA_OCOMPLETE(tp)); 2270 } 2271 if (ISSET(tp->t_state, TS_SO_OLOWAT) && 2272 tp->t_outq.c_cc <= tp->t_olowat) { 2273 CLR(tp->t_state, TS_SO_OLOWAT); 2274 wakeup(TSA_OLOWAT(tp)); 2275 } 2276 KNOTE(&tp->t_wsel.si_note, 0); 2277} 2278 2279/* 2280 * Look up a code for a specified speed in a conversion table; 2281 * used by drivers to map software speed values to hardware parameters. 2282 */ 2283int 2284ttspeedtab(int speed, struct speedtab *table) 2285{ 2286 2287 for ( ; table->sp_speed != -1; table++) 2288 if (table->sp_speed == speed) 2289 return (table->sp_code); 2290 return (-1); 2291} 2292 2293/* 2294 * Set input and output watermarks and buffer sizes. For input, the 2295 * high watermark is about one second's worth of input above empty, the 2296 * low watermark is slightly below high water, and the buffer size is a 2297 * driver-dependent amount above high water. For output, the watermarks 2298 * are near the ends of the buffer, with about 1 second's worth of input 2299 * between them. All this only applies to the standard line discipline. 2300 */ 2301void 2302ttsetwater(struct tty *tp) 2303{ 2304 int cps, ttmaxhiwat, x; 2305 2306 /* Input. */ 2307 clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512); 2308 switch (tp->t_ispeedwat) { 2309 case (speed_t)-1: 2310 cps = tp->t_ispeed / 10; 2311 break; 2312 case 0: 2313 /* 2314 * This case is for old drivers that don't know about 2315 * t_ispeedwat. Arrange for them to get the old buffer 2316 * sizes and watermarks. 2317 */ 2318 cps = TTYHOG - 2 * 256; 2319 tp->t_ififosize = 2 * 256; 2320 break; 2321 default: 2322 cps = tp->t_ispeedwat / 10; 2323 break; 2324 } 2325 tp->t_ihiwat = cps; 2326 tp->t_ilowat = 7 * cps / 8; 2327 x = cps + tp->t_ififosize; 2328 clist_alloc_cblocks(&tp->t_rawq, x, x); 2329 2330 /* Output. */ 2331 switch (tp->t_ospeedwat) { 2332 case (speed_t)-1: 2333 cps = tp->t_ospeed / 10; 2334 ttmaxhiwat = 2 * TTMAXHIWAT; 2335 break; 2336 case 0: 2337 cps = tp->t_ospeed / 10; 2338 ttmaxhiwat = TTMAXHIWAT; 2339 break; 2340 default: 2341 cps = tp->t_ospeedwat / 10; 2342 ttmaxhiwat = 8 * TTMAXHIWAT; 2343 break; 2344 } 2345#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 2346 tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 2347 x += cps; 2348 x = CLAMP(x, ttmaxhiwat, TTMINHIWAT); /* XXX clamps are too magic */ 2349 tp->t_ohiwat = roundup(x, CBSIZE); /* XXX for compat */ 2350 x = imax(tp->t_ohiwat, TTMAXHIWAT); /* XXX for compat/safety */ 2351 x += OBUFSIZ + 100; 2352 clist_alloc_cblocks(&tp->t_outq, x, x); 2353#undef CLAMP 2354} 2355 2356/* 2357 * Report on state of foreground process group. 2358 */ 2359void 2360ttyinfo(struct tty *tp) 2361{ 2362 struct proc *p, *pick; 2363 struct timeval utime, stime; 2364 const char *stmp; 2365 long ltmp; 2366 int tmp; 2367 struct thread *td; 2368 2369 if (ttycheckoutq(tp,0) == 0) 2370 return; 2371 2372 /* Print load average. */ 2373 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 2374 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100); 2375 2376 if (tp->t_session == NULL) 2377 ttyprintf(tp, "not a controlling terminal\n"); 2378 else if (tp->t_pgrp == NULL) 2379 ttyprintf(tp, "no foreground process group\n"); 2380 else { 2381 PGRP_LOCK(tp->t_pgrp); 2382 if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) { 2383 PGRP_UNLOCK(tp->t_pgrp); 2384 ttyprintf(tp, "empty foreground process group\n"); 2385 } else { 2386 mtx_lock_spin(&sched_lock); 2387 2388 /* Pick interesting process. */ 2389 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist)) 2390 if (proc_compare(pick, p)) 2391 pick = p; 2392 PGRP_UNLOCK(tp->t_pgrp); 2393 2394 td = FIRST_THREAD_IN_PROC(pick); 2395 stmp = pick->p_stat == SRUN ? "running" : /* XXXKSE */ 2396 pick->p_stat == SMTX ? td->td_mtxname : 2397 td->td_wmesg ? td->td_wmesg : "iowait"; 2398 calcru(pick, &utime, &stime, NULL); 2399 ltmp = pick->p_stat == SIDL || pick->p_stat == SWAIT || 2400 pick->p_stat == SZOMB ? 0 : 2401 pgtok(vmspace_resident_count(pick->p_vmspace)); 2402 mtx_unlock_spin(&sched_lock); 2403 2404 ttyprintf(tp, " cmd: %s %d [%s%s] ", pick->p_comm, 2405 pick->p_pid, pick->p_stat == SMTX ? "*" : "", stmp); 2406 2407 /* Print user time. */ 2408 ttyprintf(tp, "%ld.%02ldu ", 2409 utime.tv_sec, utime.tv_usec / 10000); 2410 2411 /* Print system time. */ 2412 ttyprintf(tp, "%ld.%02lds ", 2413 (long)stime.tv_sec, stime.tv_usec / 10000); 2414 2415 /* Print percentage cpu, resident set size. */ 2416 ttyprintf(tp, "%d%% %ldk\n", tmp / 100, ltmp); 2417 2418 } 2419 } 2420 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 2421} 2422 2423/* 2424 * Returns 1 if p2 is "better" than p1 2425 * 2426 * The algorithm for picking the "interesting" process is thus: 2427 * 2428 * 1) Only foreground processes are eligible - implied. 2429 * 2) Runnable processes are favored over anything else. The runner 2430 * with the highest cpu utilization is picked (p_estcpu). Ties are 2431 * broken by picking the highest pid. 2432 * 3) The sleeper with the shortest sleep time is next. With ties, 2433 * we pick out just "short-term" sleepers (P_SINTR == 0). 2434 * 4) Further ties are broken by picking the highest pid. 2435 */ 2436#define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 2437#define TESTAB(a, b) ((a)<<1 | (b)) 2438#define ONLYA 2 2439#define ONLYB 1 2440#define BOTH 3 2441 2442static int 2443proc_compare(struct proc *p1, struct proc *p2) 2444{ 2445 2446 int esta, estb; 2447 struct ksegrp *kg; 2448 mtx_assert(&sched_lock, MA_OWNED); 2449 if (p1 == NULL) 2450 return (1); 2451 2452 /* 2453 * see if at least one of them is runnable 2454 */ 2455 switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 2456 case ONLYA: 2457 return (0); 2458 case ONLYB: 2459 return (1); 2460 case BOTH: 2461 /* 2462 * tie - favor one with highest recent cpu utilization 2463 */ 2464 esta = estb = 0; 2465 FOREACH_KSEGRP_IN_PROC(p1,kg) { 2466 esta += kg->kg_estcpu; 2467 } 2468 FOREACH_KSEGRP_IN_PROC(p2,kg) { 2469 estb += kg->kg_estcpu; 2470 } 2471 if (estb > esta) 2472 return (1); 2473 if (esta > estb) 2474 return (0); 2475 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2476 } 2477 /* 2478 * weed out zombies 2479 */ 2480 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 2481 case ONLYA: 2482 return (1); 2483 case ONLYB: 2484 return (0); 2485 case BOTH: 2486 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2487 } 2488 2489#if 0 /* XXXKSE */ 2490 /* 2491 * pick the one with the smallest sleep time 2492 */ 2493 if (p2->p_slptime > p1->p_slptime) 2494 return (0); 2495 if (p1->p_slptime > p2->p_slptime) 2496 return (1); 2497 /* 2498 * favor one sleeping in a non-interruptible sleep 2499 */ 2500 if (p1->p_sflag & PS_SINTR && (p2->p_sflag & PS_SINTR) == 0) 2501 return (1); 2502 if (p2->p_sflag & PS_SINTR && (p1->p_sflag & PS_SINTR) == 0) 2503 return (0); 2504#endif 2505 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 2506} 2507 2508/* 2509 * Output char to tty; console putchar style. 2510 */ 2511int 2512tputchar(int c, struct tty *tp) 2513{ 2514 int s; 2515 2516 s = spltty(); 2517 if (!ISSET(tp->t_state, TS_CONNECTED)) { 2518 splx(s); 2519 return (-1); 2520 } 2521 if (c == '\n') 2522 (void)ttyoutput('\r', tp); 2523 (void)ttyoutput(c, tp); 2524 ttstart(tp); 2525 splx(s); 2526 return (0); 2527} 2528 2529/* 2530 * Sleep on chan, returning ERESTART if tty changed while we napped and 2531 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep. If 2532 * the tty is revoked, restarting a pending call will redo validation done 2533 * at the start of the call. 2534 */ 2535int 2536ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo) 2537{ 2538 int error; 2539 int gen; 2540 2541 gen = tp->t_gen; 2542 error = tsleep(chan, pri, wmesg, timo); 2543 if (error) 2544 return (error); 2545 return (tp->t_gen == gen ? 0 : ERESTART); 2546} 2547 2548/* 2549 * Allocate a tty struct. Clists in the struct will be allocated by 2550 * ttyopen(). 2551 */ 2552struct tty * 2553ttymalloc(struct tty *tp) 2554{ 2555 2556 if (tp) 2557 return(tp); 2558 tp = malloc(sizeof *tp, M_TTYS, M_WAITOK | M_ZERO); 2559 ttyregister(tp); 2560 return (tp); 2561} 2562 2563#if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */ 2564/* 2565 * Free a tty struct. Clists in the struct should have been freed by 2566 * ttyclose(). 2567 */ 2568void 2569ttyfree(struct tty *tp) 2570{ 2571 free(tp, M_TTYS); 2572} 2573#endif /* 0 */ 2574 2575void 2576ttyregister(struct tty *tp) 2577{ 2578 tp->t_timeout = -1; 2579 SLIST_INSERT_HEAD(&tty_list, tp, t_list); 2580} 2581 2582static int 2583sysctl_kern_ttys(SYSCTL_HANDLER_ARGS) 2584{ 2585 struct tty *tp; 2586 struct xtty xt; 2587 int error; 2588 2589 SLIST_FOREACH(tp, &tty_list, t_list) { 2590 bzero(&xt, sizeof xt); 2591 xt.xt_size = sizeof xt; 2592#define XT_COPY(field) xt.xt_##field = tp->t_##field 2593 xt.xt_rawcc = tp->t_rawq.c_cc; 2594 xt.xt_cancc = tp->t_canq.c_cc; 2595 xt.xt_outcc = tp->t_outq.c_cc; 2596 XT_COPY(line); 2597 if (tp->t_dev) 2598 xt.xt_dev = dev2udev(tp->t_dev); 2599 XT_COPY(state); 2600 XT_COPY(flags); 2601 XT_COPY(timeout); 2602 if (tp->t_pgrp) 2603 xt.xt_pgid = tp->t_pgrp->pg_id; 2604 if (tp->t_session) 2605 xt.xt_sid = tp->t_session->s_sid; 2606 XT_COPY(termios); 2607 XT_COPY(winsize); 2608 XT_COPY(column); 2609 XT_COPY(rocount); 2610 XT_COPY(rocol); 2611 XT_COPY(ififosize); 2612 XT_COPY(ihiwat); 2613 XT_COPY(ilowat); 2614 XT_COPY(ispeedwat); 2615 XT_COPY(ohiwat); 2616 XT_COPY(olowat); 2617 XT_COPY(ospeedwat); 2618#undef XT_COPY 2619 error = SYSCTL_OUT(req, &xt, sizeof xt); 2620 if (error) 2621 return (error); 2622 } 2623 return (0); 2624} 2625 2626SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD, 2627 0, 0, sysctl_kern_ttys, "S,xtty", "All ttys"); 2628SYSCTL_LONG(_kern, OID_AUTO, tty_nin, CTLFLAG_RD, 2629 &tk_nin, 0, "Total TTY in characters"); 2630SYSCTL_LONG(_kern, OID_AUTO, tty_nout, CTLFLAG_RD, 2631 &tk_nout, 0, "Total TTY out characters"); 2632 2633void 2634nottystop(struct tty *tp, int rw) 2635{ 2636 2637 return; 2638} 2639 2640int 2641ttyread(dev_t dev, struct uio *uio, int flag) 2642{ 2643 struct tty *tp; 2644 2645 tp = dev->si_tty; 2646 if (tp == NULL) 2647 return (ENODEV); 2648 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 2649} 2650 2651int 2652ttywrite(dev_t dev, struct uio *uio, int flag) 2653{ 2654 struct tty *tp; 2655 2656 tp = dev->si_tty; 2657 if (tp == NULL) 2658 return (ENODEV); 2659 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 2660} 2661