Tue Oct 2 23:10:35 2012 UTC ()
Don't call ureadc() with a spinlock held because ureadc() may fault when
writing to userspace.


(mlelstv)
diff -r1.254 -r1.255 src/sys/kern/tty.c

cvs diff -r1.254 -r1.255 src/sys/kern/tty.c (switch to unified diff)

--- src/sys/kern/tty.c 2012/09/30 11:49:44 1.254
+++ src/sys/kern/tty.c 2012/10/02 23:10:34 1.255
@@ -1,2956 +1,2958 @@ @@ -1,2956 +1,2958 @@
1/* $NetBSD: tty.c,v 1.254 2012/09/30 11:49:44 mlelstv Exp $ */ 1/* $NetBSD: tty.c,v 1.255 2012/10/02 23:10:34 mlelstv Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/*- 29/*-
30 * Copyright (c) 1982, 1986, 1990, 1991, 1993 30 * Copyright (c) 1982, 1986, 1990, 1991, 1993
31 * The Regents of the University of California. All rights reserved. 31 * The Regents of the University of California. All rights reserved.
32 * (c) UNIX System Laboratories, Inc. 32 * (c) UNIX System Laboratories, Inc.
33 * All or some portions of this file are derived from material licensed 33 * All or some portions of this file are derived from material licensed
34 * to the University of California by American Telephone and Telegraph 34 * to the University of California by American Telephone and Telegraph
35 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 35 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
36 * the permission of UNIX System Laboratories, Inc. 36 * the permission of UNIX System Laboratories, Inc.
37 * 37 *
38 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions 39 * modification, are permitted provided that the following conditions
40 * are met: 40 * are met:
41 * 1. Redistributions of source code must retain the above copyright 41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer. 42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright 43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the 44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution. 45 * documentation and/or other materials provided with the distribution.
46 * 3. Neither the name of the University nor the names of its contributors 46 * 3. Neither the name of the University nor the names of its contributors
47 * may be used to endorse or promote products derived from this software 47 * may be used to endorse or promote products derived from this software
48 * without specific prior written permission. 48 * without specific prior written permission.
49 * 49 *
50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * SUCH DAMAGE. 60 * SUCH DAMAGE.
61 * 61 *
62 * @(#)tty.c 8.13 (Berkeley) 1/9/95 62 * @(#)tty.c 8.13 (Berkeley) 1/9/95
63 */ 63 */
64 64
65#include <sys/cdefs.h> 65#include <sys/cdefs.h>
66__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.254 2012/09/30 11:49:44 mlelstv Exp $"); 66__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.255 2012/10/02 23:10:34 mlelstv Exp $");
67 67
68#include <sys/param.h> 68#include <sys/param.h>
69#include <sys/systm.h> 69#include <sys/systm.h>
70#include <sys/ioctl.h> 70#include <sys/ioctl.h>
71#include <sys/proc.h> 71#include <sys/proc.h>
72#define TTYDEFCHARS 72#define TTYDEFCHARS
73#include <sys/tty.h> 73#include <sys/tty.h>
74#undef TTYDEFCHARS 74#undef TTYDEFCHARS
75#include <sys/file.h> 75#include <sys/file.h>
76#include <sys/conf.h> 76#include <sys/conf.h>
77#include <sys/cpu.h> 77#include <sys/cpu.h>
78#include <sys/dkstat.h> 78#include <sys/dkstat.h>
79#include <sys/uio.h> 79#include <sys/uio.h>
80#include <sys/kernel.h> 80#include <sys/kernel.h>
81#include <sys/vnode.h> 81#include <sys/vnode.h>
82#include <sys/syslog.h> 82#include <sys/syslog.h>
83#include <sys/kmem.h> 83#include <sys/kmem.h>
84#include <sys/signalvar.h> 84#include <sys/signalvar.h>
85#include <sys/resourcevar.h> 85#include <sys/resourcevar.h>
86#include <sys/poll.h> 86#include <sys/poll.h>
87#include <sys/kprintf.h> 87#include <sys/kprintf.h>
88#include <sys/namei.h> 88#include <sys/namei.h>
89#include <sys/sysctl.h> 89#include <sys/sysctl.h>
90#include <sys/kauth.h> 90#include <sys/kauth.h>
91#include <sys/intr.h> 91#include <sys/intr.h>
92#include <sys/ioctl_compat.h> 92#include <sys/ioctl_compat.h>
93#include <sys/module.h> 93#include <sys/module.h>
94#include <sys/bitops.h> 94#include <sys/bitops.h>
95 95
96static int ttnread(struct tty *); 96static int ttnread(struct tty *);
97static void ttyblock(struct tty *); 97static void ttyblock(struct tty *);
98static void ttyecho(int, struct tty *); 98static void ttyecho(int, struct tty *);
99static void ttyrubo(struct tty *, int); 99static void ttyrubo(struct tty *, int);
100static void ttyprintf_nolock(struct tty *, const char *fmt, ...) 100static void ttyprintf_nolock(struct tty *, const char *fmt, ...)
101 __attribute__((__format__(__printf__,2,3))); 101 __attribute__((__format__(__printf__,2,3)));
102static int proc_compare_wrapper(struct proc *, struct proc *); 102static int proc_compare_wrapper(struct proc *, struct proc *);
103static void ttysigintr(void *); 103static void ttysigintr(void *);
104 104
105/* Symbolic sleep message strings. */ 105/* Symbolic sleep message strings. */
106const char ttclos[] = "ttycls"; 106const char ttclos[] = "ttycls";
107const char ttopen[] = "ttyopn"; 107const char ttopen[] = "ttyopn";
108const char ttybg[] = "ttybg"; 108const char ttybg[] = "ttybg";
109const char ttyin[] = "ttyin"; 109const char ttyin[] = "ttyin";
110const char ttyout[] = "ttyout"; 110const char ttyout[] = "ttyout";
111 111
112/* 112/*
113 * Used to determine whether we still have a connection. This is true in 113 * Used to determine whether we still have a connection. This is true in
114 * one of 3 cases: 114 * one of 3 cases:
115 * 1) We have carrier. 115 * 1) We have carrier.
116 * 2) It's a locally attached terminal, and we are therefore ignoring carrier. 116 * 2) It's a locally attached terminal, and we are therefore ignoring carrier.
117 * 3) We're using a flow control mechanism that overloads the carrier signal. 117 * 3) We're using a flow control mechanism that overloads the carrier signal.
118 */ 118 */
119#define CONNECTED(tp) (ISSET(tp->t_state, TS_CARR_ON) || \ 119#define CONNECTED(tp) (ISSET(tp->t_state, TS_CARR_ON) || \
120 ISSET(tp->t_cflag, CLOCAL | MDMBUF)) 120 ISSET(tp->t_cflag, CLOCAL | MDMBUF))
121 121
122/* 122/*
123 * Table with character classes and parity. The 8th bit indicates parity, 123 * Table with character classes and parity. The 8th bit indicates parity,
124 * the 7th bit indicates the character is an alphameric or underscore (for 124 * the 7th bit indicates the character is an alphameric or underscore (for
125 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits 125 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
126 * are 0 then the character needs no special processing on output; classes 126 * are 0 then the character needs no special processing on output; classes
127 * other than 0 might be translated or (not currently) require delays. 127 * other than 0 might be translated or (not currently) require delays.
128 */ 128 */
129#define E 0x00 /* Even parity. */ 129#define E 0x00 /* Even parity. */
130#define O 0x80 /* Odd parity. */ 130#define O 0x80 /* Odd parity. */
131#define PARITY(c) (char_type[c] & O) 131#define PARITY(c) (char_type[c] & O)
132 132
133#define ALPHA 0x40 /* Alpha or underscore. */ 133#define ALPHA 0x40 /* Alpha or underscore. */
134#define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA) 134#define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
135 135
136#define CCLASSMASK 0x3f 136#define CCLASSMASK 0x3f
137#define CCLASS(c) (char_type[c] & CCLASSMASK) 137#define CCLASS(c) (char_type[c] & CCLASSMASK)
138 138
139#define BS BACKSPACE 139#define BS BACKSPACE
140#define CC CONTROL 140#define CC CONTROL
141#define CR RETURN 141#define CR RETURN
142#define NA ORDINARY | ALPHA 142#define NA ORDINARY | ALPHA
143#define NL NEWLINE 143#define NL NEWLINE
144#define NO ORDINARY 144#define NO ORDINARY
145#define TB TAB 145#define TB TAB
146#define VT VTAB 146#define VT VTAB
147 147
148unsigned char const char_type[] = { 148unsigned char const char_type[] = {
149 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */ 149 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
150 O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */ 150 O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
151 O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */ 151 O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
152 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */ 152 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
153 O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */ 153 O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
154 E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */ 154 E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
155 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */ 155 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
156 O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */ 156 O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
157 O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */ 157 O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
158 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */ 158 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
159 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */ 159 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
160 O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */ 160 O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
161 E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */ 161 E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
162 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */ 162 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
163 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */ 163 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
164 E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */ 164 E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
165 /* 165 /*
166 * Meta chars; should be settable per character set; 166 * Meta chars; should be settable per character set;
167 * for now, treat them all as normal characters. 167 * for now, treat them all as normal characters.
168 */ 168 */
169 NA, NA, NA, NA, NA, NA, NA, NA, 169 NA, NA, NA, NA, NA, NA, NA, NA,
170 NA, NA, NA, NA, NA, NA, NA, NA, 170 NA, NA, NA, NA, NA, NA, NA, NA,
171 NA, NA, NA, NA, NA, NA, NA, NA, 171 NA, NA, NA, NA, NA, NA, NA, NA,
172 NA, NA, NA, NA, NA, NA, NA, NA, 172 NA, NA, NA, NA, NA, NA, NA, NA,
173 NA, NA, NA, NA, NA, NA, NA, NA, 173 NA, NA, NA, NA, NA, NA, NA, NA,
174 NA, NA, NA, NA, NA, NA, NA, NA, 174 NA, NA, NA, NA, NA, NA, NA, NA,
175 NA, NA, NA, NA, NA, NA, NA, NA, 175 NA, NA, NA, NA, NA, NA, NA, NA,
176 NA, NA, NA, NA, NA, NA, NA, NA, 176 NA, NA, NA, NA, NA, NA, NA, NA,
177 NA, NA, NA, NA, NA, NA, NA, NA, 177 NA, NA, NA, NA, NA, NA, NA, NA,
178 NA, NA, NA, NA, NA, NA, NA, NA, 178 NA, NA, NA, NA, NA, NA, NA, NA,
179 NA, NA, NA, NA, NA, NA, NA, NA, 179 NA, NA, NA, NA, NA, NA, NA, NA,
180 NA, NA, NA, NA, NA, NA, NA, NA, 180 NA, NA, NA, NA, NA, NA, NA, NA,
181 NA, NA, NA, NA, NA, NA, NA, NA, 181 NA, NA, NA, NA, NA, NA, NA, NA,
182 NA, NA, NA, NA, NA, NA, NA, NA, 182 NA, NA, NA, NA, NA, NA, NA, NA,
183 NA, NA, NA, NA, NA, NA, NA, NA, 183 NA, NA, NA, NA, NA, NA, NA, NA,
184 NA, NA, NA, NA, NA, NA, NA, NA, 184 NA, NA, NA, NA, NA, NA, NA, NA,
185}; 185};
186#undef BS 186#undef BS
187#undef CC 187#undef CC
188#undef CR 188#undef CR
189#undef NA 189#undef NA
190#undef NL 190#undef NL
191#undef NO 191#undef NO
192#undef TB 192#undef TB
193#undef VT 193#undef VT
194 194
195static struct ttylist_head tty_sigqueue = TAILQ_HEAD_INITIALIZER(tty_sigqueue); 195static struct ttylist_head tty_sigqueue = TAILQ_HEAD_INITIALIZER(tty_sigqueue);
196static void *tty_sigsih; 196static void *tty_sigsih;
197 197
198struct ttylist_head ttylist = TAILQ_HEAD_INITIALIZER(ttylist); 198struct ttylist_head ttylist = TAILQ_HEAD_INITIALIZER(ttylist);
199int tty_count; 199int tty_count;
200kmutex_t tty_lock; 200kmutex_t tty_lock;
201krwlock_t ttcompat_lock; 201krwlock_t ttcompat_lock;
202int (*ttcompatvec)(struct tty *, u_long, void *, int, struct lwp *); 202int (*ttcompatvec)(struct tty *, u_long, void *, int, struct lwp *);
203 203
204uint64_t tk_cancc; 204uint64_t tk_cancc;
205uint64_t tk_nin; 205uint64_t tk_nin;
206uint64_t tk_nout; 206uint64_t tk_nout;
207uint64_t tk_rawcc; 207uint64_t tk_rawcc;
208 208
209static kauth_listener_t tty_listener; 209static kauth_listener_t tty_listener;
210 210
211#define TTY_MINQSIZE 0x00400 211#define TTY_MINQSIZE 0x00400
212#define TTY_MAXQSIZE 0x10000 212#define TTY_MAXQSIZE 0x10000
213int tty_qsize = TTY_MINQSIZE; 213int tty_qsize = TTY_MINQSIZE;
214 214
215static int 215static int
216tty_get_qsize(int *qsize, int newsize) 216tty_get_qsize(int *qsize, int newsize)
217{ 217{
218 newsize = 1 << ilog2(newsize); /* Make it a power of two */  218 newsize = 1 << ilog2(newsize); /* Make it a power of two */
219 219
220 if (newsize < TTY_MINQSIZE || newsize > TTY_MAXQSIZE) 220 if (newsize < TTY_MINQSIZE || newsize > TTY_MAXQSIZE)
221 return EINVAL; 221 return EINVAL;
222 222
223 *qsize = newsize; 223 *qsize = newsize;
224 return 0; 224 return 0;
225} 225}
226 226
227static int 227static int
228tty_set_qsize(struct tty *tp, int newsize) 228tty_set_qsize(struct tty *tp, int newsize)
229{ 229{
230 struct clist rawq, canq, outq; 230 struct clist rawq, canq, outq;
231 struct clist orawq, ocanq, ooutq; 231 struct clist orawq, ocanq, ooutq;
232 232
233 clalloc(&rawq, newsize, 1); 233 clalloc(&rawq, newsize, 1);
234 clalloc(&canq, newsize, 1); 234 clalloc(&canq, newsize, 1);
235 clalloc(&outq, newsize, 0); 235 clalloc(&outq, newsize, 0);
236 236
237 mutex_spin_enter(&tty_lock); 237 mutex_spin_enter(&tty_lock);
238 238
239 if (tp->t_outq.c_cc != 0) { 239 if (tp->t_outq.c_cc != 0) {
240 mutex_spin_exit(&tty_lock); 240 mutex_spin_exit(&tty_lock);
241 clfree(&rawq); 241 clfree(&rawq);
242 clfree(&canq); 242 clfree(&canq);
243 clfree(&outq); 243 clfree(&outq);
244 return EBUSY; 244 return EBUSY;
245 } 245 }
246 246
247 orawq = tp->t_rawq; 247 orawq = tp->t_rawq;
248 ocanq = tp->t_canq; 248 ocanq = tp->t_canq;
249 ooutq = tp->t_outq; 249 ooutq = tp->t_outq;
250 250
251 tp->t_qsize = newsize; 251 tp->t_qsize = newsize;
252 tp->t_rawq = rawq; 252 tp->t_rawq = rawq;
253 tp->t_canq = canq; 253 tp->t_canq = canq;
254 tp->t_outq = outq; 254 tp->t_outq = outq;
255 255
256 ttsetwater(tp); 256 ttsetwater(tp);
257 257
258 mutex_spin_exit(&tty_lock); 258 mutex_spin_exit(&tty_lock);
259 259
260 clfree(&orawq); 260 clfree(&orawq);
261 clfree(&ocanq); 261 clfree(&ocanq);
262 clfree(&ooutq); 262 clfree(&ooutq);
263 263
264 return 0; 264 return 0;
265} 265}
266 266
267static int 267static int
268sysctl_kern_tty_qsize(SYSCTLFN_ARGS) 268sysctl_kern_tty_qsize(SYSCTLFN_ARGS)
269{ 269{
270 int newsize; 270 int newsize;
271 int error; 271 int error;
272 struct sysctlnode node; 272 struct sysctlnode node;
273 node = *rnode; 273 node = *rnode;
274 node.sysctl_data = &newsize; 274 node.sysctl_data = &newsize;
275 275
276 newsize = tty_qsize; 276 newsize = tty_qsize;
277 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 277 error = sysctl_lookup(SYSCTLFN_CALL(&node));
278 if (error || newp == NULL) 278 if (error || newp == NULL)
279 return error; 279 return error;
280 280
281 281
282 return tty_get_qsize(&tty_qsize, newsize); 282 return tty_get_qsize(&tty_qsize, newsize);
283} 283}
284 284
285static void 285static void
286sysctl_kern_tty_setup(void) 286sysctl_kern_tty_setup(void)
287{ 287{
288 const struct sysctlnode *rnode, *cnode; 288 const struct sysctlnode *rnode, *cnode;
289 struct sysctllog *kern_tkstat_sysctllog, *kern_tty_sysctllog; 289 struct sysctllog *kern_tkstat_sysctllog, *kern_tty_sysctllog;
290 290
291 kern_tkstat_sysctllog = NULL; 291 kern_tkstat_sysctllog = NULL;
292 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL, 292 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL,
293 CTLFLAG_PERMANENT, 293 CTLFLAG_PERMANENT,
294 CTLTYPE_NODE, "kern", NULL, 294 CTLTYPE_NODE, "kern", NULL,
295 NULL, 0, NULL, 0, 295 NULL, 0, NULL, 0,
296 CTL_KERN, CTL_EOL); 296 CTL_KERN, CTL_EOL);
297 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL, 297 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL,
298 CTLFLAG_PERMANENT, 298 CTLFLAG_PERMANENT,
299 CTLTYPE_NODE, "tkstat", 299 CTLTYPE_NODE, "tkstat",
300 SYSCTL_DESCR("Number of characters sent and and " 300 SYSCTL_DESCR("Number of characters sent and and "
301 "received on ttys"), 301 "received on ttys"),
302 NULL, 0, NULL, 0, 302 NULL, 0, NULL, 0,
303 CTL_KERN, KERN_TKSTAT, CTL_EOL); 303 CTL_KERN, KERN_TKSTAT, CTL_EOL);
304 304
305 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL, 305 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL,
306 CTLFLAG_PERMANENT, 306 CTLFLAG_PERMANENT,
307 CTLTYPE_QUAD, "nin", 307 CTLTYPE_QUAD, "nin",
308 SYSCTL_DESCR("Total number of tty input characters"), 308 SYSCTL_DESCR("Total number of tty input characters"),
309 NULL, 0, &tk_nin, 0, 309 NULL, 0, &tk_nin, 0,
310 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_NIN, CTL_EOL); 310 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_NIN, CTL_EOL);
311 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL, 311 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL,
312 CTLFLAG_PERMANENT, 312 CTLFLAG_PERMANENT,
313 CTLTYPE_QUAD, "nout", 313 CTLTYPE_QUAD, "nout",
314 SYSCTL_DESCR("Total number of tty output characters"), 314 SYSCTL_DESCR("Total number of tty output characters"),
315 NULL, 0, &tk_nout, 0, 315 NULL, 0, &tk_nout, 0,
316 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_NOUT, CTL_EOL); 316 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_NOUT, CTL_EOL);
317 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL, 317 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL,
318 CTLFLAG_PERMANENT, 318 CTLFLAG_PERMANENT,
319 CTLTYPE_QUAD, "cancc", 319 CTLTYPE_QUAD, "cancc",
320 SYSCTL_DESCR("Number of canonical tty input characters"), 320 SYSCTL_DESCR("Number of canonical tty input characters"),
321 NULL, 0, &tk_cancc, 0, 321 NULL, 0, &tk_cancc, 0,
322 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_CANCC, CTL_EOL); 322 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_CANCC, CTL_EOL);
323 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL, 323 sysctl_createv(&kern_tkstat_sysctllog, 0, NULL, NULL,
324 CTLFLAG_PERMANENT, 324 CTLFLAG_PERMANENT,
325 CTLTYPE_QUAD, "rawcc", 325 CTLTYPE_QUAD, "rawcc",
326 SYSCTL_DESCR("Number of raw tty input characters"), 326 SYSCTL_DESCR("Number of raw tty input characters"),
327 NULL, 0, &tk_rawcc, 0, 327 NULL, 0, &tk_rawcc, 0,
328 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_RAWCC, CTL_EOL); 328 CTL_KERN, KERN_TKSTAT, KERN_TKSTAT_RAWCC, CTL_EOL);
329 329
330 kern_tty_sysctllog = NULL; 330 kern_tty_sysctllog = NULL;
331 sysctl_createv(&kern_tty_sysctllog, 0, NULL, &rnode, 331 sysctl_createv(&kern_tty_sysctllog, 0, NULL, &rnode,
332 CTLFLAG_PERMANENT, 332 CTLFLAG_PERMANENT,
333 CTLTYPE_NODE, "tty", NULL, 333 CTLTYPE_NODE, "tty", NULL,
334 NULL, 0, NULL, 0, 334 NULL, 0, NULL, 0,
335 CTL_KERN, CTL_CREATE, CTL_EOL); 335 CTL_KERN, CTL_CREATE, CTL_EOL);
336 sysctl_createv(&kern_tty_sysctllog, 0, &rnode, &cnode, 336 sysctl_createv(&kern_tty_sysctllog, 0, &rnode, &cnode,
337 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 337 CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
338 CTLTYPE_INT, "qsize", 338 CTLTYPE_INT, "qsize",
339 SYSCTL_DESCR("TTY input and output queue size"), 339 SYSCTL_DESCR("TTY input and output queue size"),
340 sysctl_kern_tty_qsize, 0, &tty_qsize, 0, 340 sysctl_kern_tty_qsize, 0, &tty_qsize, 0,
341 CTL_CREATE, CTL_EOL); 341 CTL_CREATE, CTL_EOL);
342} 342}
343 343
344int 344int
345ttyopen(struct tty *tp, int dialout, int nonblock) 345ttyopen(struct tty *tp, int dialout, int nonblock)
346{ 346{
347 int error; 347 int error;
348 348
349 error = 0; 349 error = 0;
350 350
351 mutex_spin_enter(&tty_lock); 351 mutex_spin_enter(&tty_lock);
352 352
353 if (dialout) { 353 if (dialout) {
354 /* 354 /*
355 * If the device is already open for non-dialout, fail. 355 * If the device is already open for non-dialout, fail.
356 * Otherwise, set TS_DIALOUT to block any pending non-dialout 356 * Otherwise, set TS_DIALOUT to block any pending non-dialout
357 * opens. 357 * opens.
358 */ 358 */
359 if (ISSET(tp->t_state, TS_ISOPEN) && 359 if (ISSET(tp->t_state, TS_ISOPEN) &&
360 !ISSET(tp->t_state, TS_DIALOUT)) { 360 !ISSET(tp->t_state, TS_DIALOUT)) {
361 error = EBUSY; 361 error = EBUSY;
362 goto out; 362 goto out;
363 } 363 }
364 SET(tp->t_state, TS_DIALOUT); 364 SET(tp->t_state, TS_DIALOUT);
365 } else { 365 } else {
366 if (!nonblock) { 366 if (!nonblock) {
367 /* 367 /*
368 * Wait for carrier. Also wait for any dialout 368 * Wait for carrier. Also wait for any dialout
369 * processes to close the tty first. 369 * processes to close the tty first.
370 */ 370 */
371 while (ISSET(tp->t_state, TS_DIALOUT) || 371 while (ISSET(tp->t_state, TS_DIALOUT) ||
372 !CONNECTED(tp)) { 372 !CONNECTED(tp)) {
373 tp->t_wopen++; 373 tp->t_wopen++;
374 error = ttysleep(tp, &tp->t_rawcv, true, 0); 374 error = ttysleep(tp, &tp->t_rawcv, true, 0);
375 tp->t_wopen--; 375 tp->t_wopen--;
376 if (error) 376 if (error)
377 goto out; 377 goto out;
378 } 378 }
379 } else { 379 } else {
380 /* 380 /*
381 * Don't allow a non-blocking non-dialout open if the 381 * Don't allow a non-blocking non-dialout open if the
382 * device is already open for dialout. 382 * device is already open for dialout.
383 */ 383 */
384 if (ISSET(tp->t_state, TS_DIALOUT)) { 384 if (ISSET(tp->t_state, TS_DIALOUT)) {
385 error = EBUSY; 385 error = EBUSY;
386 goto out; 386 goto out;
387 } 387 }
388 } 388 }
389 } 389 }
390 390
391out: 391out:
392 mutex_spin_exit(&tty_lock); 392 mutex_spin_exit(&tty_lock);
393 return (error); 393 return (error);
394} 394}
395 395
396/* 396/*
397 * Initial open of tty, or (re)entry to standard tty line discipline. 397 * Initial open of tty, or (re)entry to standard tty line discipline.
398 */ 398 */
399int 399int
400ttylopen(dev_t device, struct tty *tp) 400ttylopen(dev_t device, struct tty *tp)
401{ 401{
402 402
403 mutex_spin_enter(&tty_lock); 403 mutex_spin_enter(&tty_lock);
404 tp->t_dev = device; 404 tp->t_dev = device;
405 if (!ISSET(tp->t_state, TS_ISOPEN)) { 405 if (!ISSET(tp->t_state, TS_ISOPEN)) {
406 SET(tp->t_state, TS_ISOPEN); 406 SET(tp->t_state, TS_ISOPEN);
407 memset(&tp->t_winsize, 0, sizeof(tp->t_winsize)); 407 memset(&tp->t_winsize, 0, sizeof(tp->t_winsize));
408 tp->t_flags = 0; 408 tp->t_flags = 0;
409 } 409 }
410 mutex_spin_exit(&tty_lock); 410 mutex_spin_exit(&tty_lock);
411 if (tp->t_qsize != tty_qsize) 411 if (tp->t_qsize != tty_qsize)
412 tty_set_qsize(tp, tty_qsize); 412 tty_set_qsize(tp, tty_qsize);
413 return (0); 413 return (0);
414} 414}
415 415
416/* 416/*
417 * Handle close() on a tty line: flush and set to initial state, 417 * Handle close() on a tty line: flush and set to initial state,
418 * bumping generation number so that pending read/write calls 418 * bumping generation number so that pending read/write calls
419 * can detect recycling of the tty. 419 * can detect recycling of the tty.
420 */ 420 */
421int 421int
422ttyclose(struct tty *tp) 422ttyclose(struct tty *tp)
423{ 423{
424 extern struct tty *constty; /* Temporary virtual console. */ 424 extern struct tty *constty; /* Temporary virtual console. */
425 struct session *sess; 425 struct session *sess;
426 426
427 mutex_spin_enter(&tty_lock); 427 mutex_spin_enter(&tty_lock);
428 428
429 if (constty == tp) 429 if (constty == tp)
430 constty = NULL; 430 constty = NULL;
431 431
432 ttyflush(tp, FREAD | FWRITE); 432 ttyflush(tp, FREAD | FWRITE);
433 433
434 tp->t_gen++; 434 tp->t_gen++;
435 tp->t_pgrp = NULL; 435 tp->t_pgrp = NULL;
436 tp->t_state = 0; 436 tp->t_state = 0;
437 sess = tp->t_session; 437 sess = tp->t_session;
438 tp->t_session = NULL; 438 tp->t_session = NULL;
439 439
440 mutex_spin_exit(&tty_lock); 440 mutex_spin_exit(&tty_lock);
441 441
442 if (sess != NULL) { 442 if (sess != NULL) {
443 mutex_enter(proc_lock); 443 mutex_enter(proc_lock);
444 /* Releases proc_lock. */ 444 /* Releases proc_lock. */
445 proc_sessrele(sess); 445 proc_sessrele(sess);
446 } 446 }
447 return (0); 447 return (0);
448} 448}
449 449
450#define FLUSHQ(q) { \ 450#define FLUSHQ(q) { \
451 if ((q)->c_cc) \ 451 if ((q)->c_cc) \
452 ndflush(q, (q)->c_cc); \ 452 ndflush(q, (q)->c_cc); \
453} 453}
454 454
455/* 455/*
456 * This macro is used in canonical mode input processing, where a read 456 * This macro is used in canonical mode input processing, where a read
457 * request shall not return unless a 'line delimiter' ('\n') or 'break' 457 * request shall not return unless a 'line delimiter' ('\n') or 'break'
458 * (EOF, EOL, EOL2) character (or a signal) has been received. As EOL2 458 * (EOF, EOL, EOL2) character (or a signal) has been received. As EOL2
459 * is an extension to the POSIX.1 defined set of special characters, 459 * is an extension to the POSIX.1 defined set of special characters,
460 * recognize it only if IEXTEN is set in the set of local flags. 460 * recognize it only if IEXTEN is set in the set of local flags.
461 */ 461 */
462#define TTBREAKC(c, lflg) \ 462#define TTBREAKC(c, lflg) \
463 ((c) == '\n' || (((c) == cc[VEOF] || (c) == cc[VEOL] || \ 463 ((c) == '\n' || (((c) == cc[VEOF] || (c) == cc[VEOL] || \
464 ((c) == cc[VEOL2] && ISSET(lflg, IEXTEN))) && (c) != _POSIX_VDISABLE)) 464 ((c) == cc[VEOL2] && ISSET(lflg, IEXTEN))) && (c) != _POSIX_VDISABLE))
465 465
466 466
467 467
468/* 468/*
469 * ttyinput() helper. 469 * ttyinput() helper.
470 * Call with the tty lock held. 470 * Call with the tty lock held.
471 */ 471 */
472/* XXX static */ int 472/* XXX static */ int
473ttyinput_wlock(int c, struct tty *tp) 473ttyinput_wlock(int c, struct tty *tp)
474{ 474{
475 int iflag, lflag, i, error; 475 int iflag, lflag, i, error;
476 u_char *cc; 476 u_char *cc;
477 477
478 KASSERT(mutex_owned(&tty_lock)); 478 KASSERT(mutex_owned(&tty_lock));
479 479
480 /* 480 /*
481 * If input is pending take it first. 481 * If input is pending take it first.
482 */ 482 */
483 lflag = tp->t_lflag; 483 lflag = tp->t_lflag;
484 if (ISSET(lflag, PENDIN)) 484 if (ISSET(lflag, PENDIN))
485 ttypend(tp); 485 ttypend(tp);
486 /* 486 /*
487 * Gather stats. 487 * Gather stats.
488 */ 488 */
489 if (ISSET(lflag, ICANON)) { 489 if (ISSET(lflag, ICANON)) {
490 ++tk_cancc; 490 ++tk_cancc;
491 ++tp->t_cancc; 491 ++tp->t_cancc;
492 } else { 492 } else {
493 ++tk_rawcc; 493 ++tk_rawcc;
494 ++tp->t_rawcc; 494 ++tp->t_rawcc;
495 } 495 }
496 ++tk_nin; 496 ++tk_nin;
497 497
498 cc = tp->t_cc; 498 cc = tp->t_cc;
499 499
500 /* 500 /*
501 * Handle exceptional conditions (break, parity, framing). 501 * Handle exceptional conditions (break, parity, framing).
502 */ 502 */
503 iflag = tp->t_iflag; 503 iflag = tp->t_iflag;
504 if ((error = (ISSET(c, TTY_ERRORMASK))) != 0) { 504 if ((error = (ISSET(c, TTY_ERRORMASK))) != 0) {
505 CLR(c, TTY_ERRORMASK); 505 CLR(c, TTY_ERRORMASK);
506 if (ISSET(error, TTY_FE) && c == 0) { /* Break. */ 506 if (ISSET(error, TTY_FE) && c == 0) { /* Break. */
507 if (ISSET(iflag, IGNBRK)) 507 if (ISSET(iflag, IGNBRK))
508 return (0); 508 return (0);
509 else if (ISSET(iflag, BRKINT)) { 509 else if (ISSET(iflag, BRKINT)) {
510 ttyflush(tp, FREAD | FWRITE); 510 ttyflush(tp, FREAD | FWRITE);
511 ttysig(tp, TTYSIG_PG1, SIGINT); 511 ttysig(tp, TTYSIG_PG1, SIGINT);
512 return (0); 512 return (0);
513 } else if (ISSET(iflag, PARMRK)) 513 } else if (ISSET(iflag, PARMRK))
514 goto parmrk; 514 goto parmrk;
515 } else if ((ISSET(error, TTY_PE) && ISSET(iflag, INPCK)) || 515 } else if ((ISSET(error, TTY_PE) && ISSET(iflag, INPCK)) ||
516 ISSET(error, TTY_FE)) { 516 ISSET(error, TTY_FE)) {
517 if (ISSET(iflag, IGNPAR)) 517 if (ISSET(iflag, IGNPAR))
518 return (0); 518 return (0);
519 else if (ISSET(iflag, PARMRK)) { 519 else if (ISSET(iflag, PARMRK)) {
520 parmrk: (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 520 parmrk: (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
521 (void)putc(0 | TTY_QUOTE, &tp->t_rawq); 521 (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
522 (void)putc(c | TTY_QUOTE, &tp->t_rawq); 522 (void)putc(c | TTY_QUOTE, &tp->t_rawq);
523 return (0); 523 return (0);
524 } else 524 } else
525 c = 0; 525 c = 0;
526 } 526 }
527 } else if (c == 0377 && 527 } else if (c == 0377 &&
528 ISSET(iflag, ISTRIP|IGNPAR|INPCK|PARMRK) == (INPCK|PARMRK)) { 528 ISSET(iflag, ISTRIP|IGNPAR|INPCK|PARMRK) == (INPCK|PARMRK)) {
529 /* "Escape" a valid character of '\377'. */ 529 /* "Escape" a valid character of '\377'. */
530 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 530 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
531 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); 531 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
532 goto endcase; 532 goto endcase;
533 } 533 }
534 534
535 /* 535 /*
536 * In tandem mode, check high water mark. 536 * In tandem mode, check high water mark.
537 */ 537 */
538 if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW)) 538 if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW))
539 ttyblock(tp); 539 ttyblock(tp);
540 if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP)) 540 if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
541 CLR(c, 0x80); 541 CLR(c, 0x80);
542 if (!ISSET(lflag, EXTPROC)) { 542 if (!ISSET(lflag, EXTPROC)) {
543 /* 543 /*
544 * Check for literal nexting very first 544 * Check for literal nexting very first
545 */ 545 */
546 if (ISSET(tp->t_state, TS_LNCH)) { 546 if (ISSET(tp->t_state, TS_LNCH)) {
547 SET(c, TTY_QUOTE); 547 SET(c, TTY_QUOTE);
548 CLR(tp->t_state, TS_LNCH); 548 CLR(tp->t_state, TS_LNCH);
549 } 549 }
550 /* 550 /*
551 * Scan for special characters. This code 551 * Scan for special characters. This code
552 * is really just a big case statement with 552 * is really just a big case statement with
553 * non-constant cases. The bottom of the 553 * non-constant cases. The bottom of the
554 * case statement is labeled ``endcase'', so goto 554 * case statement is labeled ``endcase'', so goto
555 * it after a case match, or similar. 555 * it after a case match, or similar.
556 */ 556 */
557 557
558 /* 558 /*
559 * Control chars which aren't controlled 559 * Control chars which aren't controlled
560 * by ICANON, ISIG, or IXON. 560 * by ICANON, ISIG, or IXON.
561 */ 561 */
562 if (ISSET(lflag, IEXTEN)) { 562 if (ISSET(lflag, IEXTEN)) {
563 if (CCEQ(cc[VLNEXT], c)) { 563 if (CCEQ(cc[VLNEXT], c)) {
564 if (ISSET(lflag, ECHO)) { 564 if (ISSET(lflag, ECHO)) {
565 if (ISSET(lflag, ECHOE)) { 565 if (ISSET(lflag, ECHOE)) {
566 (void)ttyoutput('^', tp); 566 (void)ttyoutput('^', tp);
567 (void)ttyoutput('\b', tp); 567 (void)ttyoutput('\b', tp);
568 } else 568 } else
569 ttyecho(c, tp); 569 ttyecho(c, tp);
570 } 570 }
571 SET(tp->t_state, TS_LNCH); 571 SET(tp->t_state, TS_LNCH);
572 goto endcase; 572 goto endcase;
573 } 573 }
574 if (CCEQ(cc[VDISCARD], c)) { 574 if (CCEQ(cc[VDISCARD], c)) {
575 if (ISSET(lflag, FLUSHO)) 575 if (ISSET(lflag, FLUSHO))
576 CLR(tp->t_lflag, FLUSHO); 576 CLR(tp->t_lflag, FLUSHO);
577 else { 577 else {
578 ttyflush(tp, FWRITE); 578 ttyflush(tp, FWRITE);
579 ttyecho(c, tp); 579 ttyecho(c, tp);
580 if (tp->t_rawq.c_cc + tp->t_canq.c_cc) 580 if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
581 ttyretype(tp); 581 ttyretype(tp);
582 SET(tp->t_lflag, FLUSHO); 582 SET(tp->t_lflag, FLUSHO);
583 } 583 }
584 goto startoutput; 584 goto startoutput;
585 } 585 }
586 } 586 }
587 /* 587 /*
588 * Signals. 588 * Signals.
589 */ 589 */
590 if (ISSET(lflag, ISIG)) { 590 if (ISSET(lflag, ISIG)) {
591 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) { 591 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
592 if (!ISSET(lflag, NOFLSH)) 592 if (!ISSET(lflag, NOFLSH))
593 ttyflush(tp, FREAD | FWRITE); 593 ttyflush(tp, FREAD | FWRITE);
594 ttyecho(c, tp); 594 ttyecho(c, tp);
595 ttysig(tp, TTYSIG_PG1, CCEQ(cc[VINTR], c) ? 595 ttysig(tp, TTYSIG_PG1, CCEQ(cc[VINTR], c) ?
596 SIGINT : SIGQUIT); 596 SIGINT : SIGQUIT);
597 goto endcase; 597 goto endcase;
598 } 598 }
599 if (CCEQ(cc[VSUSP], c)) { 599 if (CCEQ(cc[VSUSP], c)) {
600 if (!ISSET(lflag, NOFLSH)) 600 if (!ISSET(lflag, NOFLSH))
601 ttyflush(tp, FREAD); 601 ttyflush(tp, FREAD);
602 ttyecho(c, tp); 602 ttyecho(c, tp);
603 ttysig(tp, TTYSIG_PG1, SIGTSTP); 603 ttysig(tp, TTYSIG_PG1, SIGTSTP);
604 goto endcase; 604 goto endcase;
605 } 605 }
606 } 606 }
607 /* 607 /*
608 * Handle start/stop characters. 608 * Handle start/stop characters.
609 */ 609 */
610 if (ISSET(iflag, IXON)) { 610 if (ISSET(iflag, IXON)) {
611 if (CCEQ(cc[VSTOP], c)) { 611 if (CCEQ(cc[VSTOP], c)) {
612 if (!ISSET(tp->t_state, TS_TTSTOP)) { 612 if (!ISSET(tp->t_state, TS_TTSTOP)) {
613 SET(tp->t_state, TS_TTSTOP); 613 SET(tp->t_state, TS_TTSTOP);
614 cdev_stop(tp, 0); 614 cdev_stop(tp, 0);
615 return (0); 615 return (0);
616 } 616 }
617 if (!CCEQ(cc[VSTART], c)) 617 if (!CCEQ(cc[VSTART], c))
618 return (0); 618 return (0);
619 /* 619 /*
620 * if VSTART == VSTOP then toggle 620 * if VSTART == VSTOP then toggle
621 */ 621 */
622 goto endcase; 622 goto endcase;
623 } 623 }
624 if (CCEQ(cc[VSTART], c)) 624 if (CCEQ(cc[VSTART], c))
625 goto restartoutput; 625 goto restartoutput;
626 } 626 }
627 /* 627 /*
628 * IGNCR, ICRNL, & INLCR 628 * IGNCR, ICRNL, & INLCR
629 */ 629 */
630 if (c == '\r') { 630 if (c == '\r') {
631 if (ISSET(iflag, IGNCR)) 631 if (ISSET(iflag, IGNCR))
632 goto endcase; 632 goto endcase;
633 else if (ISSET(iflag, ICRNL)) 633 else if (ISSET(iflag, ICRNL))
634 c = '\n'; 634 c = '\n';
635 } else if (c == '\n' && ISSET(iflag, INLCR)) 635 } else if (c == '\n' && ISSET(iflag, INLCR))
636 c = '\r'; 636 c = '\r';
637 } 637 }
638 if (!ISSET(lflag, EXTPROC) && ISSET(lflag, ICANON)) { 638 if (!ISSET(lflag, EXTPROC) && ISSET(lflag, ICANON)) {
639 /* 639 /*
640 * From here on down canonical mode character 640 * From here on down canonical mode character
641 * processing takes place. 641 * processing takes place.
642 */ 642 */
643 /* 643 /*
644 * erase (^H / ^?) 644 * erase (^H / ^?)
645 */ 645 */
646 if (CCEQ(cc[VERASE], c)) { 646 if (CCEQ(cc[VERASE], c)) {
647 if (tp->t_rawq.c_cc) 647 if (tp->t_rawq.c_cc)
648 ttyrub(unputc(&tp->t_rawq), tp); 648 ttyrub(unputc(&tp->t_rawq), tp);
649 goto endcase; 649 goto endcase;
650 } 650 }
651 /* 651 /*
652 * kill (^U) 652 * kill (^U)
653 */ 653 */
654 if (CCEQ(cc[VKILL], c)) { 654 if (CCEQ(cc[VKILL], c)) {
655 if (ISSET(lflag, ECHOKE) && 655 if (ISSET(lflag, ECHOKE) &&
656 tp->t_rawq.c_cc == tp->t_rocount && 656 tp->t_rawq.c_cc == tp->t_rocount &&
657 !ISSET(lflag, ECHOPRT)) 657 !ISSET(lflag, ECHOPRT))
658 while (tp->t_rawq.c_cc) 658 while (tp->t_rawq.c_cc)
659 ttyrub(unputc(&tp->t_rawq), tp); 659 ttyrub(unputc(&tp->t_rawq), tp);
660 else { 660 else {
661 ttyecho(c, tp); 661 ttyecho(c, tp);
662 if (ISSET(lflag, ECHOK) || 662 if (ISSET(lflag, ECHOK) ||
663 ISSET(lflag, ECHOKE)) 663 ISSET(lflag, ECHOKE))
664 ttyecho('\n', tp); 664 ttyecho('\n', tp);
665 FLUSHQ(&tp->t_rawq); 665 FLUSHQ(&tp->t_rawq);
666 tp->t_rocount = 0; 666 tp->t_rocount = 0;
667 } 667 }
668 CLR(tp->t_state, TS_LOCAL); 668 CLR(tp->t_state, TS_LOCAL);
669 goto endcase; 669 goto endcase;
670 } 670 }
671 /* 671 /*
672 * Extensions to the POSIX.1 GTI set of functions. 672 * Extensions to the POSIX.1 GTI set of functions.
673 */ 673 */
674 if (ISSET(lflag, IEXTEN)) { 674 if (ISSET(lflag, IEXTEN)) {
675 /* 675 /*
676 * word erase (^W) 676 * word erase (^W)
677 */ 677 */
678 if (CCEQ(cc[VWERASE], c)) { 678 if (CCEQ(cc[VWERASE], c)) {
679 int alt = ISSET(lflag, ALTWERASE); 679 int alt = ISSET(lflag, ALTWERASE);
680 int ctype; 680 int ctype;
681 681
682 /* 682 /*
683 * erase whitespace 683 * erase whitespace
684 */ 684 */
685 while ((c = unputc(&tp->t_rawq)) == ' ' || 685 while ((c = unputc(&tp->t_rawq)) == ' ' ||
686 c == '\t') 686 c == '\t')
687 ttyrub(c, tp); 687 ttyrub(c, tp);
688 if (c == -1) 688 if (c == -1)
689 goto endcase; 689 goto endcase;
690 /* 690 /*
691 * erase last char of word and remember the 691 * erase last char of word and remember the
692 * next chars type (for ALTWERASE) 692 * next chars type (for ALTWERASE)
693 */ 693 */
694 ttyrub(c, tp); 694 ttyrub(c, tp);
695 c = unputc(&tp->t_rawq); 695 c = unputc(&tp->t_rawq);
696 if (c == -1) 696 if (c == -1)
697 goto endcase; 697 goto endcase;
698 if (c == ' ' || c == '\t') { 698 if (c == ' ' || c == '\t') {
699 (void)putc(c, &tp->t_rawq); 699 (void)putc(c, &tp->t_rawq);
700 goto endcase; 700 goto endcase;
701 } 701 }
702 ctype = ISALPHA(c); 702 ctype = ISALPHA(c);
703 /* 703 /*
704 * erase rest of word 704 * erase rest of word
705 */ 705 */
706 do { 706 do {
707 ttyrub(c, tp); 707 ttyrub(c, tp);
708 c = unputc(&tp->t_rawq); 708 c = unputc(&tp->t_rawq);
709 if (c == -1) 709 if (c == -1)
710 goto endcase; 710 goto endcase;
711 } while (c != ' ' && c != '\t' && 711 } while (c != ' ' && c != '\t' &&
712 (alt == 0 || ISALPHA(c) == ctype)); 712 (alt == 0 || ISALPHA(c) == ctype));
713 (void)putc(c, &tp->t_rawq); 713 (void)putc(c, &tp->t_rawq);
714 goto endcase; 714 goto endcase;
715 } 715 }
716 /* 716 /*
717 * reprint line (^R) 717 * reprint line (^R)
718 */ 718 */
719 if (CCEQ(cc[VREPRINT], c)) { 719 if (CCEQ(cc[VREPRINT], c)) {
720 ttyretype(tp); 720 ttyretype(tp);
721 goto endcase; 721 goto endcase;
722 } 722 }
723 /* 723 /*
724 * ^T - kernel info and generate SIGINFO 724 * ^T - kernel info and generate SIGINFO
725 */ 725 */
726 if (CCEQ(cc[VSTATUS], c)) { 726 if (CCEQ(cc[VSTATUS], c)) {
727 ttysig(tp, TTYSIG_PG1, SIGINFO); 727 ttysig(tp, TTYSIG_PG1, SIGINFO);
728 goto endcase; 728 goto endcase;
729 } 729 }
730 } 730 }
731 } 731 }
732 /* 732 /*
733 * Check for input buffer overflow 733 * Check for input buffer overflow
734 */ 734 */
735 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) { 735 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
736 if (ISSET(iflag, IMAXBEL)) { 736 if (ISSET(iflag, IMAXBEL)) {
737 if (tp->t_outq.c_cc < tp->t_hiwat) 737 if (tp->t_outq.c_cc < tp->t_hiwat)
738 (void)ttyoutput(CTRL('g'), tp); 738 (void)ttyoutput(CTRL('g'), tp);
739 } else 739 } else
740 ttyflush(tp, FREAD | FWRITE); 740 ttyflush(tp, FREAD | FWRITE);
741 goto endcase; 741 goto endcase;
742 } 742 }
743 /* 743 /*
744 * Put data char in q for user and 744 * Put data char in q for user and
745 * wakeup on seeing a line delimiter. 745 * wakeup on seeing a line delimiter.
746 */ 746 */
747 if (putc(c, &tp->t_rawq) >= 0) { 747 if (putc(c, &tp->t_rawq) >= 0) {
748 if (!ISSET(lflag, ICANON)) { 748 if (!ISSET(lflag, ICANON)) {
749 ttwakeup(tp); 749 ttwakeup(tp);
750 ttyecho(c, tp); 750 ttyecho(c, tp);
751 goto endcase; 751 goto endcase;
752 } 752 }
753 if (TTBREAKC(c, lflag)) { 753 if (TTBREAKC(c, lflag)) {
754 tp->t_rocount = 0; 754 tp->t_rocount = 0;
755 catq(&tp->t_rawq, &tp->t_canq); 755 catq(&tp->t_rawq, &tp->t_canq);
756 ttwakeup(tp); 756 ttwakeup(tp);
757 } else if (tp->t_rocount++ == 0) 757 } else if (tp->t_rocount++ == 0)
758 tp->t_rocol = tp->t_column; 758 tp->t_rocol = tp->t_column;
759 if (ISSET(tp->t_state, TS_ERASE)) { 759 if (ISSET(tp->t_state, TS_ERASE)) {
760 /* 760 /*
761 * end of prterase \.../ 761 * end of prterase \.../
762 */ 762 */
763 CLR(tp->t_state, TS_ERASE); 763 CLR(tp->t_state, TS_ERASE);
764 (void)ttyoutput('/', tp); 764 (void)ttyoutput('/', tp);
765 } 765 }
766 i = tp->t_column; 766 i = tp->t_column;
767 ttyecho(c, tp); 767 ttyecho(c, tp);
768 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) { 768 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
769 /* 769 /*
770 * Place the cursor over the '^' of the ^D. 770 * Place the cursor over the '^' of the ^D.
771 */ 771 */
772 i = min(2, tp->t_column - i); 772 i = min(2, tp->t_column - i);
773 while (i > 0) { 773 while (i > 0) {
774 (void)ttyoutput('\b', tp); 774 (void)ttyoutput('\b', tp);
775 i--; 775 i--;
776 } 776 }
777 } 777 }
778 } 778 }
779 endcase: 779 endcase:
780 /* 780 /*
781 * IXANY means allow any character to restart output. 781 * IXANY means allow any character to restart output.
782 */ 782 */
783 if (ISSET(tp->t_state, TS_TTSTOP) && 783 if (ISSET(tp->t_state, TS_TTSTOP) &&
784 !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) { 784 !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) {
785 return (0); 785 return (0);
786 } 786 }
787 restartoutput: 787 restartoutput:
788 CLR(tp->t_lflag, FLUSHO); 788 CLR(tp->t_lflag, FLUSHO);
789 CLR(tp->t_state, TS_TTSTOP); 789 CLR(tp->t_state, TS_TTSTOP);
790 startoutput: 790 startoutput:
791 return (ttstart(tp)); 791 return (ttstart(tp));
792} 792}
793 793
794/* 794/*
795 * Process input of a single character received on a tty. 795 * Process input of a single character received on a tty.
796 * 796 *
797 * XXX - this is a hack, all drivers must changed to acquire the 797 * XXX - this is a hack, all drivers must changed to acquire the
798 * lock before calling linesw->l_rint() 798 * lock before calling linesw->l_rint()
799 */ 799 */
800int 800int
801ttyinput(int c, struct tty *tp) 801ttyinput(int c, struct tty *tp)
802{ 802{
803 int error; 803 int error;
804 804
805 /* 805 /*
806 * Unless the receiver is enabled, drop incoming data. 806 * Unless the receiver is enabled, drop incoming data.
807 */ 807 */
808 if (!ISSET(tp->t_cflag, CREAD)) 808 if (!ISSET(tp->t_cflag, CREAD))
809 return (0); 809 return (0);
810 810
811 mutex_spin_enter(&tty_lock); 811 mutex_spin_enter(&tty_lock);
812 error = ttyinput_wlock(c, tp); 812 error = ttyinput_wlock(c, tp);
813 mutex_spin_exit(&tty_lock); 813 mutex_spin_exit(&tty_lock);
814 814
815 return (error); 815 return (error);
816} 816}
817 817
818/* 818/*
819 * Output a single character on a tty, doing output processing 819 * Output a single character on a tty, doing output processing
820 * as needed (expanding tabs, newline processing, etc.). 820 * as needed (expanding tabs, newline processing, etc.).
821 * Returns < 0 if succeeds, otherwise returns char to resend. 821 * Returns < 0 if succeeds, otherwise returns char to resend.
822 * Must be recursive. 822 * Must be recursive.
823 * 823 *
824 * Call with tty lock held. 824 * Call with tty lock held.
825 */ 825 */
826int 826int
827ttyoutput(int c, struct tty *tp) 827ttyoutput(int c, struct tty *tp)
828{ 828{
829 long oflag; 829 long oflag;
830 int col, notout; 830 int col, notout;
831 831
832 KASSERT(mutex_owned(&tty_lock)); 832 KASSERT(mutex_owned(&tty_lock));
833 833
834 oflag = tp->t_oflag; 834 oflag = tp->t_oflag;
835 if (!ISSET(oflag, OPOST)) { 835 if (!ISSET(oflag, OPOST)) {
836 tk_nout++; 836 tk_nout++;
837 tp->t_outcc++; 837 tp->t_outcc++;
838 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) 838 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
839 return (c); 839 return (c);
840 return (-1); 840 return (-1);
841 } 841 }
842 /* 842 /*
843 * Do tab expansion if OXTABS is set. Special case if we do external 843 * Do tab expansion if OXTABS is set. Special case if we do external
844 * processing, we don't do the tab expansion because we'll probably 844 * processing, we don't do the tab expansion because we'll probably
845 * get it wrong. If tab expansion needs to be done, let it happen 845 * get it wrong. If tab expansion needs to be done, let it happen
846 * externally. 846 * externally.
847 */ 847 */
848 CLR(c, ~TTY_CHARMASK); 848 CLR(c, ~TTY_CHARMASK);
849 if (c == '\t' && 849 if (c == '\t' &&
850 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) { 850 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
851 c = 8 - (tp->t_column & 7); 851 c = 8 - (tp->t_column & 7);
852 if (ISSET(tp->t_lflag, FLUSHO)) { 852 if (ISSET(tp->t_lflag, FLUSHO)) {
853 notout = 0; 853 notout = 0;
854 } else { 854 } else {
855 notout = b_to_q(" ", c, &tp->t_outq); 855 notout = b_to_q(" ", c, &tp->t_outq);
856 c -= notout; 856 c -= notout;
857 tk_nout += c; 857 tk_nout += c;
858 tp->t_outcc += c; 858 tp->t_outcc += c;
859 } 859 }
860 tp->t_column += c; 860 tp->t_column += c;
861 return (notout ? '\t' : -1); 861 return (notout ? '\t' : -1);
862 } 862 }
863 if (c == CEOT && ISSET(oflag, ONOEOT)) 863 if (c == CEOT && ISSET(oflag, ONOEOT))
864 return (-1); 864 return (-1);
865 865
866 /* 866 /*
867 * Newline translation: if ONLCR is set, 867 * Newline translation: if ONLCR is set,
868 * translate newline into "\r\n". 868 * translate newline into "\r\n".
869 */ 869 */
870 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) { 870 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
871 tk_nout++; 871 tk_nout++;
872 tp->t_outcc++; 872 tp->t_outcc++;
873 if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq)) 873 if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
874 return (c); 874 return (c);
875 } 875 }
876 /* If OCRNL is set, translate "\r" into "\n". */ 876 /* If OCRNL is set, translate "\r" into "\n". */
877 else if (c == '\r' && ISSET(tp->t_oflag, OCRNL)) 877 else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
878 c = '\n'; 878 c = '\n';
879 /* If ONOCR is set, don't transmit CRs when on column 0. */ 879 /* If ONOCR is set, don't transmit CRs when on column 0. */
880 else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0) 880 else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0)
881 return (-1); 881 return (-1);
882 882
883 tk_nout++; 883 tk_nout++;
884 tp->t_outcc++; 884 tp->t_outcc++;
885 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) 885 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
886 return (c); 886 return (c);
887 887
888 col = tp->t_column; 888 col = tp->t_column;
889 switch (CCLASS(c)) { 889 switch (CCLASS(c)) {
890 case BACKSPACE: 890 case BACKSPACE:
891 if (col > 0) 891 if (col > 0)
892 --col; 892 --col;
893 break; 893 break;
894 case CONTROL: 894 case CONTROL:
895 break; 895 break;
896 case NEWLINE: 896 case NEWLINE:
897 if (ISSET(tp->t_oflag, ONLCR | ONLRET)) 897 if (ISSET(tp->t_oflag, ONLCR | ONLRET))
898 col = 0; 898 col = 0;
899 break; 899 break;
900 case RETURN: 900 case RETURN:
901 col = 0; 901 col = 0;
902 break; 902 break;
903 case ORDINARY: 903 case ORDINARY:
904 ++col; 904 ++col;
905 break; 905 break;
906 case TAB: 906 case TAB:
907 col = (col + 8) & ~7; 907 col = (col + 8) & ~7;
908 break; 908 break;
909 } 909 }
910 tp->t_column = col; 910 tp->t_column = col;
911 return (-1); 911 return (-1);
912} 912}
913 913
914/* 914/*
915 * Ioctls for all tty devices. Called after line-discipline specific ioctl 915 * Ioctls for all tty devices. Called after line-discipline specific ioctl
916 * has been called to do discipline-specific functions and/or reject any 916 * has been called to do discipline-specific functions and/or reject any
917 * of these ioctl commands. 917 * of these ioctl commands.
918 */ 918 */
919/* ARGSUSED */ 919/* ARGSUSED */
920int 920int
921ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l) 921ttioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l)
922{ 922{
923 extern struct tty *constty; /* Temporary virtual console. */ 923 extern struct tty *constty; /* Temporary virtual console. */
924 struct proc *p = l ? l->l_proc : NULL; 924 struct proc *p = l ? l->l_proc : NULL;
925 struct linesw *lp; 925 struct linesw *lp;
926 int s, error; 926 int s, error;
927 struct pathbuf *pb; 927 struct pathbuf *pb;
928 struct nameidata nd; 928 struct nameidata nd;
929 char infobuf[200]; 929 char infobuf[200];
930 930
931 /* If the ioctl involves modification, hang if in the background. */ 931 /* If the ioctl involves modification, hang if in the background. */
932 switch (cmd) { 932 switch (cmd) {
933 case TIOCFLUSH: 933 case TIOCFLUSH:
934 case TIOCDRAIN: 934 case TIOCDRAIN:
935 case TIOCSBRK: 935 case TIOCSBRK:
936 case TIOCCBRK: 936 case TIOCCBRK:
937 case TIOCSTART: 937 case TIOCSTART:
938 case TIOCSETA: 938 case TIOCSETA:
939 case TIOCSETD: 939 case TIOCSETD:
940 case TIOCSLINED: 940 case TIOCSLINED:
941 case TIOCSETAF: 941 case TIOCSETAF:
942 case TIOCSETAW: 942 case TIOCSETAW:
943#ifdef notdef 943#ifdef notdef
944 case TIOCSPGRP: 944 case TIOCSPGRP:
945 case FIOSETOWN: 945 case FIOSETOWN:
946#endif 946#endif
947 case TIOCSTAT: 947 case TIOCSTAT:
948 case TIOCSTI: 948 case TIOCSTI:
949 case TIOCSWINSZ: 949 case TIOCSWINSZ:
950 case TIOCSQSIZE: 950 case TIOCSQSIZE:
951 case TIOCLBIC: 951 case TIOCLBIC:
952 case TIOCLBIS: 952 case TIOCLBIS:
953 case TIOCLSET: 953 case TIOCLSET:
954 case TIOCSETC: 954 case TIOCSETC:
955 case OTIOCSETD: 955 case OTIOCSETD:
956 case TIOCSETN: 956 case TIOCSETN:
957 case TIOCSETP: 957 case TIOCSETP:
958 case TIOCSLTC: 958 case TIOCSLTC:
959 mutex_spin_enter(&tty_lock); 959 mutex_spin_enter(&tty_lock);
960 while (isbackground(curproc, tp) && 960 while (isbackground(curproc, tp) &&
961 p->p_pgrp->pg_jobc && (p->p_lflag & PL_PPWAIT) == 0 && 961 p->p_pgrp->pg_jobc && (p->p_lflag & PL_PPWAIT) == 0 &&
962 !sigismasked(l, SIGTTOU)) { 962 !sigismasked(l, SIGTTOU)) {
963 mutex_spin_exit(&tty_lock); 963 mutex_spin_exit(&tty_lock);
964 964
965 mutex_enter(proc_lock); 965 mutex_enter(proc_lock);
966 pgsignal(p->p_pgrp, SIGTTOU, 1); 966 pgsignal(p->p_pgrp, SIGTTOU, 1);
967 mutex_exit(proc_lock); 967 mutex_exit(proc_lock);
968  968
969 mutex_spin_enter(&tty_lock); 969 mutex_spin_enter(&tty_lock);
970 error = ttypause(tp, hz); 970 error = ttypause(tp, hz);
971 if (error) { 971 if (error) {
972 mutex_spin_exit(&tty_lock); 972 mutex_spin_exit(&tty_lock);
973 return (error); 973 return (error);
974 } 974 }
975 } 975 }
976 mutex_spin_exit(&tty_lock); 976 mutex_spin_exit(&tty_lock);
977 break; 977 break;
978 } 978 }
979 979
980 switch (cmd) { /* Process the ioctl. */ 980 switch (cmd) { /* Process the ioctl. */
981 case FIOASYNC: /* set/clear async i/o */ 981 case FIOASYNC: /* set/clear async i/o */
982 mutex_spin_enter(&tty_lock); 982 mutex_spin_enter(&tty_lock);
983 if (*(int *)data) 983 if (*(int *)data)
984 SET(tp->t_state, TS_ASYNC); 984 SET(tp->t_state, TS_ASYNC);
985 else 985 else
986 CLR(tp->t_state, TS_ASYNC); 986 CLR(tp->t_state, TS_ASYNC);
987 mutex_spin_exit(&tty_lock); 987 mutex_spin_exit(&tty_lock);
988 break; 988 break;
989 case FIONBIO: /* set/clear non-blocking i/o */ 989 case FIONBIO: /* set/clear non-blocking i/o */
990 break; /* XXX: delete. */ 990 break; /* XXX: delete. */
991 case FIONREAD: /* get # bytes to read */ 991 case FIONREAD: /* get # bytes to read */
992 mutex_spin_enter(&tty_lock); 992 mutex_spin_enter(&tty_lock);
993 *(int *)data = ttnread(tp); 993 *(int *)data = ttnread(tp);
994 mutex_spin_exit(&tty_lock); 994 mutex_spin_exit(&tty_lock);
995 break; 995 break;
996 case FIONWRITE: /* get # bytes to written & unsent */ 996 case FIONWRITE: /* get # bytes to written & unsent */
997 mutex_spin_enter(&tty_lock); 997 mutex_spin_enter(&tty_lock);
998 *(int *)data = tp->t_outq.c_cc; 998 *(int *)data = tp->t_outq.c_cc;
999 mutex_spin_exit(&tty_lock); 999 mutex_spin_exit(&tty_lock);
1000 break; 1000 break;
1001 case FIONSPACE: /* get # bytes to written & unsent */ 1001 case FIONSPACE: /* get # bytes to written & unsent */
1002 mutex_spin_enter(&tty_lock); 1002 mutex_spin_enter(&tty_lock);
1003 *(int *)data = tp->t_outq.c_cn - tp->t_outq.c_cc; 1003 *(int *)data = tp->t_outq.c_cn - tp->t_outq.c_cc;
1004 mutex_spin_exit(&tty_lock); 1004 mutex_spin_exit(&tty_lock);
1005 break; 1005 break;
1006 case TIOCEXCL: /* set exclusive use of tty */ 1006 case TIOCEXCL: /* set exclusive use of tty */
1007 mutex_spin_enter(&tty_lock); 1007 mutex_spin_enter(&tty_lock);
1008 SET(tp->t_state, TS_XCLUDE); 1008 SET(tp->t_state, TS_XCLUDE);
1009 mutex_spin_exit(&tty_lock); 1009 mutex_spin_exit(&tty_lock);
1010 break; 1010 break;
1011 case TIOCFLUSH: { /* flush buffers */ 1011 case TIOCFLUSH: { /* flush buffers */
1012 int flags = *(int *)data; 1012 int flags = *(int *)data;
1013 1013
1014 if (flags == 0) 1014 if (flags == 0)
1015 flags = FREAD | FWRITE; 1015 flags = FREAD | FWRITE;
1016 else 1016 else
1017 flags &= FREAD | FWRITE; 1017 flags &= FREAD | FWRITE;
1018 mutex_spin_enter(&tty_lock); 1018 mutex_spin_enter(&tty_lock);
1019 ttyflush(tp, flags); 1019 ttyflush(tp, flags);
1020 mutex_spin_exit(&tty_lock); 1020 mutex_spin_exit(&tty_lock);
1021 break; 1021 break;
1022 } 1022 }
1023 case TIOCCONS: /* become virtual console */ 1023 case TIOCCONS: /* become virtual console */
1024 if (*(int *)data) { 1024 if (*(int *)data) {
1025 if (constty && constty != tp && 1025 if (constty && constty != tp &&
1026 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) == 1026 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
1027 (TS_CARR_ON | TS_ISOPEN)) 1027 (TS_CARR_ON | TS_ISOPEN))
1028 return EBUSY; 1028 return EBUSY;
1029 1029
1030 pb = pathbuf_create("/dev/console"); 1030 pb = pathbuf_create("/dev/console");
1031 if (pb == NULL) { 1031 if (pb == NULL) {
1032 return ENOMEM; 1032 return ENOMEM;
1033 } 1033 }
1034 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pb); 1034 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, pb);
1035 if ((error = namei(&nd)) != 0) { 1035 if ((error = namei(&nd)) != 0) {
1036 pathbuf_destroy(pb); 1036 pathbuf_destroy(pb);
1037 return error; 1037 return error;
1038 } 1038 }
1039 error = VOP_ACCESS(nd.ni_vp, VREAD, l->l_cred); 1039 error = VOP_ACCESS(nd.ni_vp, VREAD, l->l_cred);
1040 vput(nd.ni_vp); 1040 vput(nd.ni_vp);
1041 pathbuf_destroy(pb); 1041 pathbuf_destroy(pb);
1042 if (error) 1042 if (error)
1043 return error; 1043 return error;
1044 1044
1045 constty = tp; 1045 constty = tp;
1046 } else if (tp == constty) 1046 } else if (tp == constty)
1047 constty = NULL; 1047 constty = NULL;
1048 break; 1048 break;
1049 case TIOCDRAIN: /* wait till output drained */ 1049 case TIOCDRAIN: /* wait till output drained */
1050 if ((error = ttywait(tp)) != 0) 1050 if ((error = ttywait(tp)) != 0)
1051 return (error); 1051 return (error);
1052 break; 1052 break;
1053 case TIOCGETA: { /* get termios struct */ 1053 case TIOCGETA: { /* get termios struct */
1054 struct termios *t = (struct termios *)data; 1054 struct termios *t = (struct termios *)data;
1055 1055
1056 memcpy(t, &tp->t_termios, sizeof(struct termios)); 1056 memcpy(t, &tp->t_termios, sizeof(struct termios));
1057 break; 1057 break;
1058 } 1058 }
1059 case TIOCGETD: /* get line discipline (old) */ 1059 case TIOCGETD: /* get line discipline (old) */
1060 *(int *)data = tp->t_linesw->l_no; 1060 *(int *)data = tp->t_linesw->l_no;
1061 break; 1061 break;
1062 case TIOCGLINED: /* get line discipline (new) */ 1062 case TIOCGLINED: /* get line discipline (new) */
1063 (void)strncpy((char *)data, tp->t_linesw->l_name, 1063 (void)strncpy((char *)data, tp->t_linesw->l_name,
1064 TTLINEDNAMELEN - 1); 1064 TTLINEDNAMELEN - 1);
1065 break; 1065 break;
1066 case TIOCGWINSZ: /* get window size */ 1066 case TIOCGWINSZ: /* get window size */
1067 *(struct winsize *)data = tp->t_winsize; 1067 *(struct winsize *)data = tp->t_winsize;
1068 break; 1068 break;
1069 case TIOCGQSIZE: 1069 case TIOCGQSIZE:
1070 *(int *)data = tp->t_qsize; 1070 *(int *)data = tp->t_qsize;
1071 break; 1071 break;
1072 case FIOGETOWN: 1072 case FIOGETOWN:
1073 mutex_enter(proc_lock); 1073 mutex_enter(proc_lock);
1074 if (tp->t_session != NULL && !isctty(p, tp)) { 1074 if (tp->t_session != NULL && !isctty(p, tp)) {
1075 mutex_exit(proc_lock); 1075 mutex_exit(proc_lock);
1076 return (ENOTTY); 1076 return (ENOTTY);
1077 } 1077 }
1078 *(int *)data = tp->t_pgrp ? -tp->t_pgrp->pg_id : 0; 1078 *(int *)data = tp->t_pgrp ? -tp->t_pgrp->pg_id : 0;
1079 mutex_exit(proc_lock); 1079 mutex_exit(proc_lock);
1080 break; 1080 break;
1081 case TIOCGPGRP: /* get pgrp of tty */ 1081 case TIOCGPGRP: /* get pgrp of tty */
1082 mutex_enter(proc_lock); 1082 mutex_enter(proc_lock);
1083 if (!isctty(p, tp)) { 1083 if (!isctty(p, tp)) {
1084 mutex_exit(proc_lock); 1084 mutex_exit(proc_lock);
1085 return (ENOTTY); 1085 return (ENOTTY);
1086 } 1086 }
1087 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID; 1087 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PGID;
1088 mutex_exit(proc_lock); 1088 mutex_exit(proc_lock);
1089 break; 1089 break;
1090 case TIOCGSID: /* get sid of tty */ 1090 case TIOCGSID: /* get sid of tty */
1091 mutex_enter(proc_lock); 1091 mutex_enter(proc_lock);
1092 if (!isctty(p, tp)) { 1092 if (!isctty(p, tp)) {
1093 mutex_exit(proc_lock); 1093 mutex_exit(proc_lock);
1094 return (ENOTTY); 1094 return (ENOTTY);
1095 } 1095 }
1096 *(int *)data = tp->t_session->s_sid; 1096 *(int *)data = tp->t_session->s_sid;
1097 mutex_exit(proc_lock); 1097 mutex_exit(proc_lock);
1098 break; 1098 break;
1099#ifdef TIOCHPCL 1099#ifdef TIOCHPCL
1100 case TIOCHPCL: /* hang up on last close */ 1100 case TIOCHPCL: /* hang up on last close */
1101 mutex_spin_enter(&tty_lock); 1101 mutex_spin_enter(&tty_lock);
1102 SET(tp->t_cflag, HUPCL); 1102 SET(tp->t_cflag, HUPCL);
1103 mutex_spin_exit(&tty_lock); 1103 mutex_spin_exit(&tty_lock);
1104 break; 1104 break;
1105#endif 1105#endif
1106 case TIOCNXCL: /* reset exclusive use of tty */ 1106 case TIOCNXCL: /* reset exclusive use of tty */
1107 mutex_spin_enter(&tty_lock); 1107 mutex_spin_enter(&tty_lock);
1108 CLR(tp->t_state, TS_XCLUDE); 1108 CLR(tp->t_state, TS_XCLUDE);
1109 mutex_spin_exit(&tty_lock); 1109 mutex_spin_exit(&tty_lock);
1110 break; 1110 break;
1111 case TIOCOUTQ: /* output queue size */ 1111 case TIOCOUTQ: /* output queue size */
1112 *(int *)data = tp->t_outq.c_cc; 1112 *(int *)data = tp->t_outq.c_cc;
1113 break; 1113 break;
1114 case TIOCSETA: /* set termios struct */ 1114 case TIOCSETA: /* set termios struct */
1115 case TIOCSETAW: /* drain output, set */ 1115 case TIOCSETAW: /* drain output, set */
1116 case TIOCSETAF: { /* drn out, fls in, set */ 1116 case TIOCSETAF: { /* drn out, fls in, set */
1117 struct termios *t = (struct termios *)data; 1117 struct termios *t = (struct termios *)data;
1118 1118
1119 if (cmd == TIOCSETAW || cmd == TIOCSETAF) { 1119 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
1120 if ((error = ttywait(tp)) != 0) 1120 if ((error = ttywait(tp)) != 0)
1121 return (error); 1121 return (error);
1122 1122
1123 if (cmd == TIOCSETAF) { 1123 if (cmd == TIOCSETAF) {
1124 mutex_spin_enter(&tty_lock); 1124 mutex_spin_enter(&tty_lock);
1125 ttyflush(tp, FREAD); 1125 ttyflush(tp, FREAD);
1126 mutex_spin_exit(&tty_lock); 1126 mutex_spin_exit(&tty_lock);
1127 } 1127 }
1128 } 1128 }
1129 1129
1130 s = spltty(); 1130 s = spltty();
1131 /* 1131 /*
1132 * XXXSMP - some drivers call back on us from t_param(), so 1132 * XXXSMP - some drivers call back on us from t_param(), so
1133 * don't take the tty spin lock here. 1133 * don't take the tty spin lock here.
1134 * require t_param() to unlock upon callback? 1134 * require t_param() to unlock upon callback?
1135 */ 1135 */
1136 /* wanted here: mutex_spin_enter(&tty_lock); */ 1136 /* wanted here: mutex_spin_enter(&tty_lock); */
1137 if (!ISSET(t->c_cflag, CIGNORE)) { 1137 if (!ISSET(t->c_cflag, CIGNORE)) {
1138 /* 1138 /*
1139 * Set device hardware. 1139 * Set device hardware.
1140 */ 1140 */
1141 if (tp->t_param && (error = (*tp->t_param)(tp, t))) { 1141 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1142 /* wanted here: mutex_spin_exit(&tty_lock); */ 1142 /* wanted here: mutex_spin_exit(&tty_lock); */
1143 splx(s); 1143 splx(s);
1144 return (error); 1144 return (error);
1145 } else { 1145 } else {
1146 tp->t_cflag = t->c_cflag; 1146 tp->t_cflag = t->c_cflag;
1147 tp->t_ispeed = t->c_ispeed; 1147 tp->t_ispeed = t->c_ispeed;
1148 tp->t_ospeed = t->c_ospeed; 1148 tp->t_ospeed = t->c_ospeed;
1149 if (t->c_ospeed == 0) 1149 if (t->c_ospeed == 0)
1150 ttysig(tp, TTYSIG_LEADER, SIGHUP); 1150 ttysig(tp, TTYSIG_LEADER, SIGHUP);
1151 } 1151 }
1152 ttsetwater(tp); 1152 ttsetwater(tp);
1153 } 1153 }
1154 1154
1155 /* delayed lock acquiring */ 1155 /* delayed lock acquiring */
1156 mutex_spin_enter(&tty_lock); 1156 mutex_spin_enter(&tty_lock);
1157 if (cmd != TIOCSETAF) { 1157 if (cmd != TIOCSETAF) {
1158 if (ISSET(t->c_lflag, ICANON) != 1158 if (ISSET(t->c_lflag, ICANON) !=
1159 ISSET(tp->t_lflag, ICANON)) { 1159 ISSET(tp->t_lflag, ICANON)) {
1160 if (ISSET(t->c_lflag, ICANON)) { 1160 if (ISSET(t->c_lflag, ICANON)) {
1161 SET(tp->t_lflag, PENDIN); 1161 SET(tp->t_lflag, PENDIN);
1162 ttwakeup(tp); 1162 ttwakeup(tp);
1163 } else { 1163 } else {
1164 struct clist tq; 1164 struct clist tq;
1165 1165
1166 catq(&tp->t_rawq, &tp->t_canq); 1166 catq(&tp->t_rawq, &tp->t_canq);
1167 tq = tp->t_rawq; 1167 tq = tp->t_rawq;
1168 tp->t_rawq = tp->t_canq; 1168 tp->t_rawq = tp->t_canq;
1169 tp->t_canq = tq; 1169 tp->t_canq = tq;
1170 CLR(tp->t_lflag, PENDIN); 1170 CLR(tp->t_lflag, PENDIN);
1171 } 1171 }
1172 } 1172 }
1173 } 1173 }
1174 tp->t_iflag = t->c_iflag; 1174 tp->t_iflag = t->c_iflag;
1175 tp->t_oflag = t->c_oflag; 1175 tp->t_oflag = t->c_oflag;
1176 /* 1176 /*
1177 * Make the EXTPROC bit read only. 1177 * Make the EXTPROC bit read only.
1178 */ 1178 */
1179 if (ISSET(tp->t_lflag, EXTPROC)) 1179 if (ISSET(tp->t_lflag, EXTPROC))
1180 SET(t->c_lflag, EXTPROC); 1180 SET(t->c_lflag, EXTPROC);
1181 else 1181 else
1182 CLR(t->c_lflag, EXTPROC); 1182 CLR(t->c_lflag, EXTPROC);
1183 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN); 1183 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1184 memcpy(tp->t_cc, t->c_cc, sizeof(t->c_cc)); 1184 memcpy(tp->t_cc, t->c_cc, sizeof(t->c_cc));
1185 mutex_spin_exit(&tty_lock); 1185 mutex_spin_exit(&tty_lock);
1186 splx(s); 1186 splx(s);
1187 break; 1187 break;
1188 } 1188 }
1189 case TIOCSETD: /* set line discipline (old) */ 1189 case TIOCSETD: /* set line discipline (old) */
1190 lp = ttyldisc_lookup_bynum(*(int *)data); 1190 lp = ttyldisc_lookup_bynum(*(int *)data);
1191 goto setldisc; 1191 goto setldisc;
1192 1192
1193 case TIOCSLINED: { /* set line discipline (new) */ 1193 case TIOCSLINED: { /* set line discipline (new) */
1194 char *name = (char *)data; 1194 char *name = (char *)data;
1195 dev_t device; 1195 dev_t device;
1196 1196
1197 /* Null terminate to prevent buffer overflow */ 1197 /* Null terminate to prevent buffer overflow */
1198 name[TTLINEDNAMELEN - 1] = '\0'; 1198 name[TTLINEDNAMELEN - 1] = '\0';
1199 lp = ttyldisc_lookup(name); 1199 lp = ttyldisc_lookup(name);
1200 setldisc: 1200 setldisc:
1201 if (lp == NULL) 1201 if (lp == NULL)
1202 return (ENXIO); 1202 return (ENXIO);
1203 1203
1204 if (lp != tp->t_linesw) { 1204 if (lp != tp->t_linesw) {
1205 device = tp->t_dev; 1205 device = tp->t_dev;
1206 s = spltty(); 1206 s = spltty();
1207 (*tp->t_linesw->l_close)(tp, flag); 1207 (*tp->t_linesw->l_close)(tp, flag);
1208 error = (*lp->l_open)(device, tp); 1208 error = (*lp->l_open)(device, tp);
1209 if (error) { 1209 if (error) {
1210 (void)(*tp->t_linesw->l_open)(device, tp); 1210 (void)(*tp->t_linesw->l_open)(device, tp);
1211 splx(s); 1211 splx(s);
1212 ttyldisc_release(lp); 1212 ttyldisc_release(lp);
1213 return (error); 1213 return (error);
1214 } 1214 }
1215 ttyldisc_release(tp->t_linesw); 1215 ttyldisc_release(tp->t_linesw);
1216 tp->t_linesw = lp; 1216 tp->t_linesw = lp;
1217 splx(s); 1217 splx(s);
1218 } else { 1218 } else {
1219 /* Drop extra reference. */ 1219 /* Drop extra reference. */
1220 ttyldisc_release(lp); 1220 ttyldisc_release(lp);
1221 } 1221 }
1222 break; 1222 break;
1223 } 1223 }
1224 case TIOCSTART: /* start output, like ^Q */ 1224 case TIOCSTART: /* start output, like ^Q */
1225 mutex_spin_enter(&tty_lock); 1225 mutex_spin_enter(&tty_lock);
1226 if (ISSET(tp->t_state, TS_TTSTOP) || 1226 if (ISSET(tp->t_state, TS_TTSTOP) ||
1227 ISSET(tp->t_lflag, FLUSHO)) { 1227 ISSET(tp->t_lflag, FLUSHO)) {
1228 CLR(tp->t_lflag, FLUSHO); 1228 CLR(tp->t_lflag, FLUSHO);
1229 CLR(tp->t_state, TS_TTSTOP); 1229 CLR(tp->t_state, TS_TTSTOP);
1230 ttstart(tp); 1230 ttstart(tp);
1231 } 1231 }
1232 mutex_spin_exit(&tty_lock); 1232 mutex_spin_exit(&tty_lock);
1233 break; 1233 break;
1234 case TIOCSTI: /* simulate terminal input */ 1234 case TIOCSTI: /* simulate terminal input */
1235 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_STI, 1235 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_STI,
1236 tp) != 0) { 1236 tp) != 0) {
1237 if (!ISSET(flag, FREAD)) 1237 if (!ISSET(flag, FREAD))
1238 return (EPERM); 1238 return (EPERM);
1239 if (!isctty(p, tp)) 1239 if (!isctty(p, tp))
1240 return (EACCES); 1240 return (EACCES);
1241 } 1241 }
1242 (*tp->t_linesw->l_rint)(*(u_char *)data, tp); 1242 (*tp->t_linesw->l_rint)(*(u_char *)data, tp);
1243 break; 1243 break;
1244 case TIOCSTOP: /* stop output, like ^S */ 1244 case TIOCSTOP: /* stop output, like ^S */
1245 { 1245 {
1246 mutex_spin_enter(&tty_lock); 1246 mutex_spin_enter(&tty_lock);
1247 if (!ISSET(tp->t_state, TS_TTSTOP)) { 1247 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1248 SET(tp->t_state, TS_TTSTOP); 1248 SET(tp->t_state, TS_TTSTOP);
1249 cdev_stop(tp, 0); 1249 cdev_stop(tp, 0);
1250 } 1250 }
1251 mutex_spin_exit(&tty_lock); 1251 mutex_spin_exit(&tty_lock);
1252 break; 1252 break;
1253 } 1253 }
1254 case TIOCSCTTY: /* become controlling tty */ 1254 case TIOCSCTTY: /* become controlling tty */
1255 mutex_enter(proc_lock); 1255 mutex_enter(proc_lock);
1256 mutex_spin_enter(&tty_lock); 1256 mutex_spin_enter(&tty_lock);
1257 1257
1258 /* Session ctty vnode pointer set in vnode layer. */ 1258 /* Session ctty vnode pointer set in vnode layer. */
1259 if (!SESS_LEADER(p) || 1259 if (!SESS_LEADER(p) ||
1260 ((p->p_session->s_ttyvp || tp->t_session) && 1260 ((p->p_session->s_ttyvp || tp->t_session) &&
1261 (tp->t_session != p->p_session))) { 1261 (tp->t_session != p->p_session))) {
1262 mutex_spin_exit(&tty_lock); 1262 mutex_spin_exit(&tty_lock);
1263 mutex_exit(proc_lock); 1263 mutex_exit(proc_lock);
1264 return (EPERM); 1264 return (EPERM);
1265 } 1265 }
1266 1266
1267 /* 1267 /*
1268 * `p_session' acquires a reference. 1268 * `p_session' acquires a reference.
1269 * But note that if `t_session' is set at this point, 1269 * But note that if `t_session' is set at this point,
1270 * it must equal `p_session', in which case the session 1270 * it must equal `p_session', in which case the session
1271 * already has the correct reference count. 1271 * already has the correct reference count.
1272 */ 1272 */
1273 if (tp->t_session == NULL) { 1273 if (tp->t_session == NULL) {
1274 proc_sesshold(p->p_session); 1274 proc_sesshold(p->p_session);
1275 } 1275 }
1276 tp->t_session = p->p_session; 1276 tp->t_session = p->p_session;
1277 tp->t_pgrp = p->p_pgrp; 1277 tp->t_pgrp = p->p_pgrp;
1278 p->p_session->s_ttyp = tp; 1278 p->p_session->s_ttyp = tp;
1279 p->p_lflag |= PL_CONTROLT; 1279 p->p_lflag |= PL_CONTROLT;
1280 mutex_spin_exit(&tty_lock); 1280 mutex_spin_exit(&tty_lock);
1281 mutex_exit(proc_lock); 1281 mutex_exit(proc_lock);
1282 break; 1282 break;
1283 case FIOSETOWN: { /* set pgrp of tty */ 1283 case FIOSETOWN: { /* set pgrp of tty */
1284 pid_t pgid = *(pid_t *)data; 1284 pid_t pgid = *(pid_t *)data;
1285 struct pgrp *pgrp; 1285 struct pgrp *pgrp;
1286 1286
1287 mutex_enter(proc_lock);  1287 mutex_enter(proc_lock);
1288 if (tp->t_session != NULL && !isctty(p, tp)) { 1288 if (tp->t_session != NULL && !isctty(p, tp)) {
1289 mutex_exit(proc_lock); 1289 mutex_exit(proc_lock);
1290 return (ENOTTY); 1290 return (ENOTTY);
1291 } 1291 }
1292 1292
1293 if (pgid < 0) { 1293 if (pgid < 0) {
1294 pgrp = pgrp_find(-pgid); 1294 pgrp = pgrp_find(-pgid);
1295 if (pgrp == NULL) { 1295 if (pgrp == NULL) {
1296 mutex_exit(proc_lock); 1296 mutex_exit(proc_lock);
1297 return (EINVAL); 1297 return (EINVAL);
1298 } 1298 }
1299 } else { 1299 } else {
1300 struct proc *p1; 1300 struct proc *p1;
1301 p1 = proc_find(pgid); 1301 p1 = proc_find(pgid);
1302 if (!p1) { 1302 if (!p1) {
1303 mutex_exit(proc_lock); 1303 mutex_exit(proc_lock);
1304 return (ESRCH); 1304 return (ESRCH);
1305 } 1305 }
1306 pgrp = p1->p_pgrp; 1306 pgrp = p1->p_pgrp;
1307 } 1307 }
1308 1308
1309 if (pgrp->pg_session != p->p_session) { 1309 if (pgrp->pg_session != p->p_session) {
1310 mutex_exit(proc_lock); 1310 mutex_exit(proc_lock);
1311 return (EPERM); 1311 return (EPERM);
1312 } 1312 }
1313 mutex_spin_enter(&tty_lock); 1313 mutex_spin_enter(&tty_lock);
1314 tp->t_pgrp = pgrp; 1314 tp->t_pgrp = pgrp;
1315 mutex_spin_exit(&tty_lock); 1315 mutex_spin_exit(&tty_lock);
1316 mutex_exit(proc_lock); 1316 mutex_exit(proc_lock);
1317 break; 1317 break;
1318 } 1318 }
1319 case TIOCSPGRP: { /* set pgrp of tty */ 1319 case TIOCSPGRP: { /* set pgrp of tty */
1320 struct pgrp *pgrp; 1320 struct pgrp *pgrp;
1321 pid_t pgid = *(pid_t *)data; 1321 pid_t pgid = *(pid_t *)data;
1322 1322
1323 if (pgid == NO_PGID) 1323 if (pgid == NO_PGID)
1324 return EINVAL; 1324 return EINVAL;
1325 1325
1326 mutex_enter(proc_lock);  1326 mutex_enter(proc_lock);
1327 if (!isctty(p, tp)) { 1327 if (!isctty(p, tp)) {
1328 mutex_exit(proc_lock); 1328 mutex_exit(proc_lock);
1329 return (ENOTTY); 1329 return (ENOTTY);
1330 } 1330 }
1331 pgrp = pgrp_find(pgid); 1331 pgrp = pgrp_find(pgid);
1332 if (pgrp == NULL || pgrp->pg_session != p->p_session) { 1332 if (pgrp == NULL || pgrp->pg_session != p->p_session) {
1333 mutex_exit(proc_lock); 1333 mutex_exit(proc_lock);
1334 return (EPERM); 1334 return (EPERM);
1335 } 1335 }
1336 mutex_spin_enter(&tty_lock); 1336 mutex_spin_enter(&tty_lock);
1337 tp->t_pgrp = pgrp; 1337 tp->t_pgrp = pgrp;
1338 mutex_spin_exit(&tty_lock); 1338 mutex_spin_exit(&tty_lock);
1339 mutex_exit(proc_lock); 1339 mutex_exit(proc_lock);
1340 break; 1340 break;
1341 } 1341 }
1342 case TIOCSTAT: /* get load avg stats */ 1342 case TIOCSTAT: /* get load avg stats */
1343 mutex_enter(proc_lock); 1343 mutex_enter(proc_lock);
1344 ttygetinfo(tp, 0, infobuf, sizeof(infobuf)); 1344 ttygetinfo(tp, 0, infobuf, sizeof(infobuf));
1345 mutex_exit(proc_lock); 1345 mutex_exit(proc_lock);
1346 1346
1347 mutex_spin_enter(&tty_lock); 1347 mutex_spin_enter(&tty_lock);
1348 ttyputinfo(tp, infobuf); 1348 ttyputinfo(tp, infobuf);
1349 mutex_spin_exit(&tty_lock); 1349 mutex_spin_exit(&tty_lock);
1350 break; 1350 break;
1351 case TIOCSWINSZ: /* set window size */ 1351 case TIOCSWINSZ: /* set window size */
1352 mutex_spin_enter(&tty_lock); 1352 mutex_spin_enter(&tty_lock);
1353 if (memcmp((void *)&tp->t_winsize, data, 1353 if (memcmp((void *)&tp->t_winsize, data,
1354 sizeof(struct winsize))) { 1354 sizeof(struct winsize))) {
1355 tp->t_winsize = *(struct winsize *)data; 1355 tp->t_winsize = *(struct winsize *)data;
1356 ttysig(tp, TTYSIG_PG1, SIGWINCH); 1356 ttysig(tp, TTYSIG_PG1, SIGWINCH);
1357 } 1357 }
1358 mutex_spin_exit(&tty_lock); 1358 mutex_spin_exit(&tty_lock);
1359 break; 1359 break;
1360 case TIOCSQSIZE: 1360 case TIOCSQSIZE:
1361 if ((error = tty_get_qsize(&s, *(int *)data)) == 0 && 1361 if ((error = tty_get_qsize(&s, *(int *)data)) == 0 &&
1362 s != tp->t_qsize) 1362 s != tp->t_qsize)
1363 error = tty_set_qsize(tp, s); 1363 error = tty_set_qsize(tp, s);
1364 return error; 1364 return error;
1365 default: 1365 default:
1366 /* We may have to load the compat module for this. */ 1366 /* We may have to load the compat module for this. */
1367 for (;;) { 1367 for (;;) {
1368 rw_enter(&ttcompat_lock, RW_READER); 1368 rw_enter(&ttcompat_lock, RW_READER);
1369 if (ttcompatvec != NULL) { 1369 if (ttcompatvec != NULL) {
1370 break; 1370 break;
1371 } 1371 }
1372 rw_exit(&ttcompat_lock); 1372 rw_exit(&ttcompat_lock);
1373 (void)module_autoload("compat", MODULE_CLASS_ANY); 1373 (void)module_autoload("compat", MODULE_CLASS_ANY);
1374 if (ttcompatvec == NULL) { 1374 if (ttcompatvec == NULL) {
1375 return EPASSTHROUGH; 1375 return EPASSTHROUGH;
1376 } 1376 }
1377 } 1377 }
1378 error = (*ttcompatvec)(tp, cmd, data, flag, l); 1378 error = (*ttcompatvec)(tp, cmd, data, flag, l);
1379 rw_exit(&ttcompat_lock); 1379 rw_exit(&ttcompat_lock);
1380 return error; 1380 return error;
1381 } 1381 }
1382 return (0); 1382 return (0);
1383} 1383}
1384 1384
1385int 1385int
1386ttpoll(struct tty *tp, int events, struct lwp *l) 1386ttpoll(struct tty *tp, int events, struct lwp *l)
1387{ 1387{
1388 int revents; 1388 int revents;
1389 1389
1390 revents = 0; 1390 revents = 0;
1391 mutex_spin_enter(&tty_lock); 1391 mutex_spin_enter(&tty_lock);
1392 if (events & (POLLIN | POLLRDNORM)) 1392 if (events & (POLLIN | POLLRDNORM))
1393 if (ttnread(tp) > 0) 1393 if (ttnread(tp) > 0)
1394 revents |= events & (POLLIN | POLLRDNORM); 1394 revents |= events & (POLLIN | POLLRDNORM);
1395 1395
1396 if (events & (POLLOUT | POLLWRNORM)) 1396 if (events & (POLLOUT | POLLWRNORM))
1397 if (tp->t_outq.c_cc <= tp->t_lowat) 1397 if (tp->t_outq.c_cc <= tp->t_lowat)
1398 revents |= events & (POLLOUT | POLLWRNORM); 1398 revents |= events & (POLLOUT | POLLWRNORM);
1399 1399
1400 if (events & POLLHUP) 1400 if (events & POLLHUP)
1401 if (!CONNECTED(tp)) 1401 if (!CONNECTED(tp))
1402 revents |= POLLHUP; 1402 revents |= POLLHUP;
1403 1403
1404 if (revents == 0) { 1404 if (revents == 0) {
1405 if (events & (POLLIN | POLLHUP | POLLRDNORM)) 1405 if (events & (POLLIN | POLLHUP | POLLRDNORM))
1406 selrecord(l, &tp->t_rsel); 1406 selrecord(l, &tp->t_rsel);
1407 1407
1408 if (events & (POLLOUT | POLLWRNORM)) 1408 if (events & (POLLOUT | POLLWRNORM))
1409 selrecord(l, &tp->t_wsel); 1409 selrecord(l, &tp->t_wsel);
1410 } 1410 }
1411 1411
1412 mutex_spin_exit(&tty_lock); 1412 mutex_spin_exit(&tty_lock);
1413 1413
1414 return (revents); 1414 return (revents);
1415} 1415}
1416 1416
1417static void 1417static void
1418filt_ttyrdetach(struct knote *kn) 1418filt_ttyrdetach(struct knote *kn)
1419{ 1419{
1420 struct tty *tp; 1420 struct tty *tp;
1421 1421
1422 tp = kn->kn_hook; 1422 tp = kn->kn_hook;
1423 mutex_spin_enter(&tty_lock); 1423 mutex_spin_enter(&tty_lock);
1424 SLIST_REMOVE(&tp->t_rsel.sel_klist, kn, knote, kn_selnext); 1424 SLIST_REMOVE(&tp->t_rsel.sel_klist, kn, knote, kn_selnext);
1425 mutex_spin_exit(&tty_lock); 1425 mutex_spin_exit(&tty_lock);
1426} 1426}
1427 1427
1428static int 1428static int
1429filt_ttyread(struct knote *kn, long hint) 1429filt_ttyread(struct knote *kn, long hint)
1430{ 1430{
1431 struct tty *tp; 1431 struct tty *tp;
1432 1432
1433 tp = kn->kn_hook; 1433 tp = kn->kn_hook;
1434 if ((hint & NOTE_SUBMIT) == 0) 1434 if ((hint & NOTE_SUBMIT) == 0)
1435 mutex_spin_enter(&tty_lock); 1435 mutex_spin_enter(&tty_lock);
1436 kn->kn_data = ttnread(tp); 1436 kn->kn_data = ttnread(tp);
1437 if ((hint & NOTE_SUBMIT) == 0) 1437 if ((hint & NOTE_SUBMIT) == 0)
1438 mutex_spin_exit(&tty_lock); 1438 mutex_spin_exit(&tty_lock);
1439 return (kn->kn_data > 0); 1439 return (kn->kn_data > 0);
1440} 1440}
1441 1441
1442static void 1442static void
1443filt_ttywdetach(struct knote *kn) 1443filt_ttywdetach(struct knote *kn)
1444{ 1444{
1445 struct tty *tp; 1445 struct tty *tp;
1446 1446
1447 tp = kn->kn_hook; 1447 tp = kn->kn_hook;
1448 mutex_spin_enter(&tty_lock); 1448 mutex_spin_enter(&tty_lock);
1449 SLIST_REMOVE(&tp->t_wsel.sel_klist, kn, knote, kn_selnext); 1449 SLIST_REMOVE(&tp->t_wsel.sel_klist, kn, knote, kn_selnext);
1450 mutex_spin_exit(&tty_lock); 1450 mutex_spin_exit(&tty_lock);
1451} 1451}
1452 1452
1453static int 1453static int
1454filt_ttywrite(struct knote *kn, long hint) 1454filt_ttywrite(struct knote *kn, long hint)
1455{ 1455{
1456 struct tty *tp; 1456 struct tty *tp;
1457 int canwrite; 1457 int canwrite;
1458 1458
1459 tp = kn->kn_hook; 1459 tp = kn->kn_hook;
1460 if ((hint & NOTE_SUBMIT) == 0) 1460 if ((hint & NOTE_SUBMIT) == 0)
1461 mutex_spin_enter(&tty_lock); 1461 mutex_spin_enter(&tty_lock);
1462 kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc; 1462 kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc;
1463 canwrite = (tp->t_outq.c_cc <= tp->t_lowat) && CONNECTED(tp); 1463 canwrite = (tp->t_outq.c_cc <= tp->t_lowat) && CONNECTED(tp);
1464 if ((hint & NOTE_SUBMIT) == 0) 1464 if ((hint & NOTE_SUBMIT) == 0)
1465 mutex_spin_exit(&tty_lock); 1465 mutex_spin_exit(&tty_lock);
1466 return (canwrite); 1466 return (canwrite);
1467} 1467}
1468 1468
1469static const struct filterops ttyread_filtops = 1469static const struct filterops ttyread_filtops =
1470 { 1, NULL, filt_ttyrdetach, filt_ttyread }; 1470 { 1, NULL, filt_ttyrdetach, filt_ttyread };
1471static const struct filterops ttywrite_filtops = 1471static const struct filterops ttywrite_filtops =
1472 { 1, NULL, filt_ttywdetach, filt_ttywrite }; 1472 { 1, NULL, filt_ttywdetach, filt_ttywrite };
1473 1473
1474int 1474int
1475ttykqfilter(dev_t dev, struct knote *kn) 1475ttykqfilter(dev_t dev, struct knote *kn)
1476{ 1476{
1477 struct tty *tp; 1477 struct tty *tp;
1478 struct klist *klist; 1478 struct klist *klist;
1479 1479
1480 if ((tp = cdev_tty(dev)) == NULL) 1480 if ((tp = cdev_tty(dev)) == NULL)
1481 return (ENXIO); 1481 return (ENXIO);
1482 1482
1483 switch (kn->kn_filter) { 1483 switch (kn->kn_filter) {
1484 case EVFILT_READ: 1484 case EVFILT_READ:
1485 klist = &tp->t_rsel.sel_klist; 1485 klist = &tp->t_rsel.sel_klist;
1486 kn->kn_fop = &ttyread_filtops; 1486 kn->kn_fop = &ttyread_filtops;
1487 break; 1487 break;
1488 case EVFILT_WRITE: 1488 case EVFILT_WRITE:
1489 klist = &tp->t_wsel.sel_klist; 1489 klist = &tp->t_wsel.sel_klist;
1490 kn->kn_fop = &ttywrite_filtops; 1490 kn->kn_fop = &ttywrite_filtops;
1491 break; 1491 break;
1492 default: 1492 default:
1493 return EINVAL; 1493 return EINVAL;
1494 } 1494 }
1495 1495
1496 kn->kn_hook = tp; 1496 kn->kn_hook = tp;
1497 1497
1498 mutex_spin_enter(&tty_lock); 1498 mutex_spin_enter(&tty_lock);
1499 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1499 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1500 mutex_spin_exit(&tty_lock); 1500 mutex_spin_exit(&tty_lock);
1501 1501
1502 return (0); 1502 return (0);
1503} 1503}
1504 1504
1505/* 1505/*
1506 * Find the number of chars ready to be read from this tty. 1506 * Find the number of chars ready to be read from this tty.
1507 * Call with the tty lock held. 1507 * Call with the tty lock held.
1508 */ 1508 */
1509static int 1509static int
1510ttnread(struct tty *tp) 1510ttnread(struct tty *tp)
1511{ 1511{
1512 int nread; 1512 int nread;
1513 1513
1514 KASSERT(mutex_owned(&tty_lock)); 1514 KASSERT(mutex_owned(&tty_lock));
1515 1515
1516 if (ISSET(tp->t_lflag, PENDIN)) 1516 if (ISSET(tp->t_lflag, PENDIN))
1517 ttypend(tp); 1517 ttypend(tp);
1518 nread = tp->t_canq.c_cc; 1518 nread = tp->t_canq.c_cc;
1519 if (!ISSET(tp->t_lflag, ICANON)) { 1519 if (!ISSET(tp->t_lflag, ICANON)) {
1520 nread += tp->t_rawq.c_cc; 1520 nread += tp->t_rawq.c_cc;
1521 if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME]) 1521 if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
1522 nread = 0; 1522 nread = 0;
1523 } 1523 }
1524 return (nread); 1524 return (nread);
1525} 1525}
1526 1526
1527/* 1527/*
1528 * Wait for output to drain. 1528 * Wait for output to drain.
1529 */ 1529 */
1530int 1530int
1531ttywait(struct tty *tp) 1531ttywait(struct tty *tp)
1532{ 1532{
1533 int error; 1533 int error;
1534 1534
1535 error = 0; 1535 error = 0;
1536 1536
1537 mutex_spin_enter(&tty_lock); 1537 mutex_spin_enter(&tty_lock);
1538 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && 1538 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1539 CONNECTED(tp) && tp->t_oproc) { 1539 CONNECTED(tp) && tp->t_oproc) {
1540 (*tp->t_oproc)(tp); 1540 (*tp->t_oproc)(tp);
1541 error = ttysleep(tp, &tp->t_outcv, true, 0); 1541 error = ttysleep(tp, &tp->t_outcv, true, 0);
1542 if (error) 1542 if (error)
1543 break; 1543 break;
1544 } 1544 }
1545 mutex_spin_exit(&tty_lock); 1545 mutex_spin_exit(&tty_lock);
1546 1546
1547 return (error); 1547 return (error);
1548} 1548}
1549 1549
1550/* 1550/*
1551 * Flush if successfully wait. 1551 * Flush if successfully wait.
1552 */ 1552 */
1553int 1553int
1554ttywflush(struct tty *tp) 1554ttywflush(struct tty *tp)
1555{ 1555{
1556 int error; 1556 int error;
1557 1557
1558 if ((error = ttywait(tp)) == 0) { 1558 if ((error = ttywait(tp)) == 0) {
1559 mutex_spin_enter(&tty_lock); 1559 mutex_spin_enter(&tty_lock);
1560 ttyflush(tp, FREAD); 1560 ttyflush(tp, FREAD);
1561 mutex_spin_exit(&tty_lock); 1561 mutex_spin_exit(&tty_lock);
1562 } 1562 }
1563 return (error); 1563 return (error);
1564} 1564}
1565 1565
1566/* 1566/*
1567 * Flush tty read and/or write queues, notifying anyone waiting. 1567 * Flush tty read and/or write queues, notifying anyone waiting.
1568 * Call with the tty lock held. 1568 * Call with the tty lock held.
1569 */ 1569 */
1570void 1570void
1571ttyflush(struct tty *tp, int rw) 1571ttyflush(struct tty *tp, int rw)
1572{ 1572{
1573 1573
1574 KASSERT(mutex_owned(&tty_lock)); 1574 KASSERT(mutex_owned(&tty_lock));
1575 1575
1576 if (rw & FREAD) { 1576 if (rw & FREAD) {
1577 FLUSHQ(&tp->t_canq); 1577 FLUSHQ(&tp->t_canq);
1578 FLUSHQ(&tp->t_rawq); 1578 FLUSHQ(&tp->t_rawq);
1579 tp->t_rocount = 0; 1579 tp->t_rocount = 0;
1580 tp->t_rocol = 0; 1580 tp->t_rocol = 0;
1581 CLR(tp->t_state, TS_LOCAL); 1581 CLR(tp->t_state, TS_LOCAL);
1582 ttwakeup(tp); 1582 ttwakeup(tp);
1583 } 1583 }
1584 if (rw & FWRITE) { 1584 if (rw & FWRITE) {
1585 CLR(tp->t_state, TS_TTSTOP); 1585 CLR(tp->t_state, TS_TTSTOP);
1586 cdev_stop(tp, rw); 1586 cdev_stop(tp, rw);
1587 FLUSHQ(&tp->t_outq); 1587 FLUSHQ(&tp->t_outq);
1588 cv_broadcast(&tp->t_outcv); 1588 cv_broadcast(&tp->t_outcv);
1589 selnotify(&tp->t_wsel, 0, NOTE_SUBMIT); 1589 selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
1590 } 1590 }
1591} 1591}
1592 1592
1593/* 1593/*
1594 * Copy in the default termios characters. 1594 * Copy in the default termios characters.
1595 */ 1595 */
1596void 1596void
1597ttychars(struct tty *tp) 1597ttychars(struct tty *tp)
1598{ 1598{
1599 1599
1600 memcpy(tp->t_cc, ttydefchars, sizeof(ttydefchars)); 1600 memcpy(tp->t_cc, ttydefchars, sizeof(ttydefchars));
1601} 1601}
1602 1602
1603/* 1603/*
1604 * Send stop character on input overflow. 1604 * Send stop character on input overflow.
1605 * Call with the tty lock held. 1605 * Call with the tty lock held.
1606 */ 1606 */
1607static void 1607static void
1608ttyblock(struct tty *tp) 1608ttyblock(struct tty *tp)
1609{ 1609{
1610 int total; 1610 int total;
1611 1611
1612 KASSERT(mutex_owned(&tty_lock)); 1612 KASSERT(mutex_owned(&tty_lock));
1613 1613
1614 total = tp->t_rawq.c_cc + tp->t_canq.c_cc; 1614 total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
1615 if (tp->t_rawq.c_cc > TTYHOG) { 1615 if (tp->t_rawq.c_cc > TTYHOG) {
1616 ttyflush(tp, FREAD | FWRITE); 1616 ttyflush(tp, FREAD | FWRITE);
1617 CLR(tp->t_state, TS_TBLOCK); 1617 CLR(tp->t_state, TS_TBLOCK);
1618 } 1618 }
1619 /* 1619 /*
1620 * Block further input iff: current input > threshold 1620 * Block further input iff: current input > threshold
1621 * AND input is available to user program. 1621 * AND input is available to user program.
1622 */ 1622 */
1623 if (total >= TTYHOG / 2 && 1623 if (total >= TTYHOG / 2 &&
1624 !ISSET(tp->t_state, TS_TBLOCK) && 1624 !ISSET(tp->t_state, TS_TBLOCK) &&
1625 (!ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0)) { 1625 (!ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0)) {
1626 if (ISSET(tp->t_iflag, IXOFF) && 1626 if (ISSET(tp->t_iflag, IXOFF) &&
1627 tp->t_cc[VSTOP] != _POSIX_VDISABLE && 1627 tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1628 putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) { 1628 putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
1629 SET(tp->t_state, TS_TBLOCK); 1629 SET(tp->t_state, TS_TBLOCK);
1630 ttstart(tp); 1630 ttstart(tp);
1631 } 1631 }
1632 /* Try to block remote output via hardware flow control. */ 1632 /* Try to block remote output via hardware flow control. */
1633 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow && 1633 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1634 (*tp->t_hwiflow)(tp, 1) != 0) 1634 (*tp->t_hwiflow)(tp, 1) != 0)
1635 SET(tp->t_state, TS_TBLOCK); 1635 SET(tp->t_state, TS_TBLOCK);
1636 } 1636 }
1637} 1637}
1638 1638
1639/* 1639/*
1640 * Delayed line discipline output 1640 * Delayed line discipline output
1641 */ 1641 */
1642void 1642void
1643ttrstrt(void *tp_arg) 1643ttrstrt(void *tp_arg)
1644{ 1644{
1645 struct tty *tp; 1645 struct tty *tp;
1646 1646
1647#ifdef DIAGNOSTIC 1647#ifdef DIAGNOSTIC
1648 if (tp_arg == NULL) 1648 if (tp_arg == NULL)
1649 panic("ttrstrt"); 1649 panic("ttrstrt");
1650#endif 1650#endif
1651 tp = tp_arg; 1651 tp = tp_arg;
1652 mutex_spin_enter(&tty_lock); 1652 mutex_spin_enter(&tty_lock);
1653 1653
1654 CLR(tp->t_state, TS_TIMEOUT); 1654 CLR(tp->t_state, TS_TIMEOUT);
1655 ttstart(tp); /* XXX - Shouldn't this be tp->l_start(tp)? */ 1655 ttstart(tp); /* XXX - Shouldn't this be tp->l_start(tp)? */
1656 1656
1657 mutex_spin_exit(&tty_lock); 1657 mutex_spin_exit(&tty_lock);
1658} 1658}
1659 1659
1660/* 1660/*
1661 * start a line discipline 1661 * start a line discipline
1662 * Always call with tty lock held? 1662 * Always call with tty lock held?
1663 */ 1663 */
1664int 1664int
1665ttstart(struct tty *tp) 1665ttstart(struct tty *tp)
1666{ 1666{
1667 1667
1668 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */ 1668 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1669 (*tp->t_oproc)(tp); 1669 (*tp->t_oproc)(tp);
1670 return (0); 1670 return (0);
1671} 1671}
1672 1672
1673/* 1673/*
1674 * "close" a line discipline 1674 * "close" a line discipline
1675 */ 1675 */
1676int 1676int
1677ttylclose(struct tty *tp, int flag) 1677ttylclose(struct tty *tp, int flag)
1678{ 1678{
1679 1679
1680 if (flag & FNONBLOCK) { 1680 if (flag & FNONBLOCK) {
1681 mutex_spin_enter(&tty_lock); 1681 mutex_spin_enter(&tty_lock);
1682 ttyflush(tp, FREAD | FWRITE); 1682 ttyflush(tp, FREAD | FWRITE);
1683 mutex_spin_exit(&tty_lock); 1683 mutex_spin_exit(&tty_lock);
1684 } else 1684 } else
1685 ttywflush(tp); 1685 ttywflush(tp);
1686 return (0); 1686 return (0);
1687} 1687}
1688 1688
1689/* 1689/*
1690 * Handle modem control transition on a tty. 1690 * Handle modem control transition on a tty.
1691 * Flag indicates new state of carrier. 1691 * Flag indicates new state of carrier.
1692 * Returns 0 if the line should be turned off, otherwise 1. 1692 * Returns 0 if the line should be turned off, otherwise 1.
1693 */ 1693 */
1694int 1694int
1695ttymodem(struct tty *tp, int flag) 1695ttymodem(struct tty *tp, int flag)
1696{ 1696{
1697 1697
1698 mutex_spin_enter(&tty_lock); 1698 mutex_spin_enter(&tty_lock);
1699 if (flag == 0) { 1699 if (flag == 0) {
1700 if (ISSET(tp->t_state, TS_CARR_ON)) { 1700 if (ISSET(tp->t_state, TS_CARR_ON)) {
1701 /* 1701 /*
1702 * Lost carrier. 1702 * Lost carrier.
1703 */ 1703 */
1704 CLR(tp->t_state, TS_CARR_ON); 1704 CLR(tp->t_state, TS_CARR_ON);
1705 if (ISSET(tp->t_state, TS_ISOPEN) && !CONNECTED(tp)) { 1705 if (ISSET(tp->t_state, TS_ISOPEN) && !CONNECTED(tp)) {
1706 ttysig(tp, TTYSIG_LEADER, SIGHUP); 1706 ttysig(tp, TTYSIG_LEADER, SIGHUP);
1707 ttyflush(tp, FREAD | FWRITE); 1707 ttyflush(tp, FREAD | FWRITE);
1708 mutex_spin_exit(&tty_lock); 1708 mutex_spin_exit(&tty_lock);
1709 return (0); 1709 return (0);
1710 } 1710 }
1711 } 1711 }
1712 } else { 1712 } else {
1713 if (!ISSET(tp->t_state, TS_CARR_ON)) { 1713 if (!ISSET(tp->t_state, TS_CARR_ON)) {
1714 /* 1714 /*
1715 * Carrier now on. 1715 * Carrier now on.
1716 */ 1716 */
1717 SET(tp->t_state, TS_CARR_ON); 1717 SET(tp->t_state, TS_CARR_ON);
1718 ttwakeup(tp); 1718 ttwakeup(tp);
1719 } 1719 }
1720 } 1720 }
1721 mutex_spin_exit(&tty_lock); 1721 mutex_spin_exit(&tty_lock);
1722 1722
1723 return (1); 1723 return (1);
1724} 1724}
1725 1725
1726/* 1726/*
1727 * Default modem control routine (for other line disciplines). 1727 * Default modem control routine (for other line disciplines).
1728 * Return argument flag, to turn off device on carrier drop. 1728 * Return argument flag, to turn off device on carrier drop.
1729 */ 1729 */
1730int 1730int
1731nullmodem(struct tty *tp, int flag) 1731nullmodem(struct tty *tp, int flag)
1732{ 1732{
1733 1733
1734 mutex_spin_enter(&tty_lock); 1734 mutex_spin_enter(&tty_lock);
1735 if (flag) 1735 if (flag)
1736 SET(tp->t_state, TS_CARR_ON); 1736 SET(tp->t_state, TS_CARR_ON);
1737 else { 1737 else {
1738 CLR(tp->t_state, TS_CARR_ON); 1738 CLR(tp->t_state, TS_CARR_ON);
1739 if (!CONNECTED(tp)) { 1739 if (!CONNECTED(tp)) {
1740 ttysig(tp, TTYSIG_LEADER, SIGHUP); 1740 ttysig(tp, TTYSIG_LEADER, SIGHUP);
1741 mutex_spin_exit(&tty_lock); 1741 mutex_spin_exit(&tty_lock);
1742 return (0); 1742 return (0);
1743 } 1743 }
1744 } 1744 }
1745 mutex_spin_exit(&tty_lock); 1745 mutex_spin_exit(&tty_lock);
1746 1746
1747 return (1); 1747 return (1);
1748} 1748}
1749 1749
1750/* 1750/*
1751 * Reinput pending characters after state switch. 1751 * Reinput pending characters after state switch.
1752 */ 1752 */
1753void 1753void
1754ttypend(struct tty *tp) 1754ttypend(struct tty *tp)
1755{ 1755{
1756 struct clist tq; 1756 struct clist tq;
1757 int c; 1757 int c;
1758 1758
1759 KASSERT(mutex_owned(&tty_lock)); 1759 KASSERT(mutex_owned(&tty_lock));
1760 1760
1761 CLR(tp->t_lflag, PENDIN); 1761 CLR(tp->t_lflag, PENDIN);
1762 SET(tp->t_state, TS_TYPEN); 1762 SET(tp->t_state, TS_TYPEN);
1763 tq = tp->t_rawq; 1763 tq = tp->t_rawq;
1764 tp->t_rawq.c_cc = 0; 1764 tp->t_rawq.c_cc = 0;
1765 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0; 1765 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
1766 while ((c = getc(&tq)) >= 0) 1766 while ((c = getc(&tq)) >= 0)
1767 ttyinput_wlock(c, tp); 1767 ttyinput_wlock(c, tp);
1768 CLR(tp->t_state, TS_TYPEN); 1768 CLR(tp->t_state, TS_TYPEN);
1769} 1769}
1770 1770
1771/* 1771/*
1772 * Process a read call on a tty device. 1772 * Process a read call on a tty device.
1773 */ 1773 */
1774int 1774int
1775ttread(struct tty *tp, struct uio *uio, int flag) 1775ttread(struct tty *tp, struct uio *uio, int flag)
1776{ 1776{
1777 struct clist *qp; 1777 struct clist *qp;
1778 u_char *cc; 1778 u_char *cc;
1779 struct proc *p; 1779 struct proc *p;
1780 int c, first, error, has_stime, last_cc; 1780 int c, first, error, has_stime, last_cc;
1781 long lflag, slp; 1781 long lflag, slp;
1782 struct timeval now, stime; 1782 struct timeval now, stime;
1783 1783
1784 if (uio->uio_resid == 0) 1784 if (uio->uio_resid == 0)
1785 return 0; 1785 return 0;
1786 1786
1787 stime.tv_usec = 0; /* XXX gcc */ 1787 stime.tv_usec = 0; /* XXX gcc */
1788 stime.tv_sec = 0; /* XXX gcc */ 1788 stime.tv_sec = 0; /* XXX gcc */
1789 1789
1790 cc = tp->t_cc; 1790 cc = tp->t_cc;
1791 p = curproc; 1791 p = curproc;
1792 error = 0; 1792 error = 0;
1793 has_stime = 0; 1793 has_stime = 0;
1794 last_cc = 0; 1794 last_cc = 0;
1795 slp = 0; 1795 slp = 0;
1796 1796
1797 loop: 1797 loop:
1798 mutex_spin_enter(&tty_lock); 1798 mutex_spin_enter(&tty_lock);
1799 lflag = tp->t_lflag; 1799 lflag = tp->t_lflag;
1800 /* 1800 /*
1801 * take pending input first 1801 * take pending input first
1802 */ 1802 */
1803 if (ISSET(lflag, PENDIN)) 1803 if (ISSET(lflag, PENDIN))
1804 ttypend(tp); 1804 ttypend(tp);
1805 1805
1806 /* 1806 /*
1807 * Hang process if it's in the background. 1807 * Hang process if it's in the background.
1808 */ 1808 */
1809 if (isbackground(p, tp)) { 1809 if (isbackground(p, tp)) {
1810 if (sigismasked(curlwp, SIGTTIN) || 1810 if (sigismasked(curlwp, SIGTTIN) ||
1811 p->p_lflag & PL_PPWAIT || p->p_pgrp->pg_jobc == 0) { 1811 p->p_lflag & PL_PPWAIT || p->p_pgrp->pg_jobc == 0) {
1812 mutex_spin_exit(&tty_lock); 1812 mutex_spin_exit(&tty_lock);
1813 return (EIO); 1813 return (EIO);
1814 } 1814 }
1815 mutex_spin_exit(&tty_lock); 1815 mutex_spin_exit(&tty_lock);
1816 1816
1817 mutex_enter(proc_lock); 1817 mutex_enter(proc_lock);
1818 pgsignal(p->p_pgrp, SIGTTIN, 1); 1818 pgsignal(p->p_pgrp, SIGTTIN, 1);
1819 mutex_exit(proc_lock); 1819 mutex_exit(proc_lock);
1820 1820
1821 mutex_spin_enter(&tty_lock); 1821 mutex_spin_enter(&tty_lock);
1822 error = ttypause(tp, hz); 1822 error = ttypause(tp, hz);
1823 mutex_spin_exit(&tty_lock); 1823 mutex_spin_exit(&tty_lock);
1824 if (error) 1824 if (error)
1825 return (error); 1825 return (error);
1826 goto loop; 1826 goto loop;
1827 } 1827 }
1828 1828
1829 if (!ISSET(lflag, ICANON)) { 1829 if (!ISSET(lflag, ICANON)) {
1830 int m = cc[VMIN]; 1830 int m = cc[VMIN];
1831 long t = cc[VTIME]; 1831 long t = cc[VTIME];
1832 1832
1833 qp = &tp->t_rawq; 1833 qp = &tp->t_rawq;
1834 /* 1834 /*
1835 * Check each of the four combinations. 1835 * Check each of the four combinations.
1836 * (m > 0 && t == 0) is the normal read case. 1836 * (m > 0 && t == 0) is the normal read case.
1837 * It should be fairly efficient, so we check that and its 1837 * It should be fairly efficient, so we check that and its
1838 * companion case (m == 0 && t == 0) first. 1838 * companion case (m == 0 && t == 0) first.
1839 * For the other two cases, we compute the target sleep time 1839 * For the other two cases, we compute the target sleep time
1840 * into slp. 1840 * into slp.
1841 */ 1841 */
1842 if (t == 0) { 1842 if (t == 0) {
1843 if (qp->c_cc < m) 1843 if (qp->c_cc < m)
1844 goto sleep; 1844 goto sleep;
1845 goto read; 1845 goto read;
1846 } 1846 }
1847 t *= hz; /* time in deca-ticks */ 1847 t *= hz; /* time in deca-ticks */
1848/* 1848/*
1849 * Time difference in deca-ticks, split division to avoid numeric overflow. 1849 * Time difference in deca-ticks, split division to avoid numeric overflow.
1850 * Ok for hz < ~200kHz 1850 * Ok for hz < ~200kHz
1851 */ 1851 */
1852#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 10 * hz + \ 1852#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 10 * hz + \
1853 ((t1).tv_usec - (t2).tv_usec) / 100 * hz / 1000) 1853 ((t1).tv_usec - (t2).tv_usec) / 100 * hz / 1000)
1854 if (m > 0) { 1854 if (m > 0) {
1855 if (qp->c_cc <= 0) 1855 if (qp->c_cc <= 0)
1856 goto sleep; 1856 goto sleep;
1857 if (qp->c_cc >= m) 1857 if (qp->c_cc >= m)
1858 goto read; 1858 goto read;
1859 if (!has_stime) { 1859 if (!has_stime) {
1860 /* first character, start timer */ 1860 /* first character, start timer */
1861 has_stime = 1; 1861 has_stime = 1;
1862 getmicrotime(&stime); 1862 getmicrotime(&stime);
1863 slp = t; 1863 slp = t;
1864 } else if (qp->c_cc > last_cc) { 1864 } else if (qp->c_cc > last_cc) {
1865 /* got a character, restart timer */ 1865 /* got a character, restart timer */
1866 getmicrotime(&stime); 1866 getmicrotime(&stime);
1867 slp = t; 1867 slp = t;
1868 } else { 1868 } else {
1869 /* nothing, check expiration */ 1869 /* nothing, check expiration */
1870 getmicrotime(&now); 1870 getmicrotime(&now);
1871 slp = t - diff(now, stime); 1871 slp = t - diff(now, stime);
1872 } 1872 }
1873 } else { /* m == 0 */ 1873 } else { /* m == 0 */
1874 if (qp->c_cc > 0) 1874 if (qp->c_cc > 0)
1875 goto read; 1875 goto read;
1876 if (!has_stime) { 1876 if (!has_stime) {
1877 has_stime = 1; 1877 has_stime = 1;
1878 getmicrotime(&stime); 1878 getmicrotime(&stime);
1879 slp = t; 1879 slp = t;
1880 } else { 1880 } else {
1881 getmicrotime(&now); 1881 getmicrotime(&now);
1882 slp = t - diff(now, stime); 1882 slp = t - diff(now, stime);
1883 } 1883 }
1884 } 1884 }
1885 last_cc = qp->c_cc; 1885 last_cc = qp->c_cc;
1886#undef diff 1886#undef diff
1887 if (slp > 0) { 1887 if (slp > 0) {
1888 /* 1888 /*
1889 * Convert deca-ticks back to ticks. 1889 * Convert deca-ticks back to ticks.
1890 * Rounding down may make us wake up just short 1890 * Rounding down may make us wake up just short
1891 * of the target, so we round up. 1891 * of the target, so we round up.
1892 * Maybe we should do 'slp/10 + 1' because the 1892 * Maybe we should do 'slp/10 + 1' because the
1893 * first tick maybe almost immediate. 1893 * first tick maybe almost immediate.
1894 * However it is more useful for a program that sets 1894 * However it is more useful for a program that sets
1895 * VTIME=10 to wakeup every second not every 1.01 1895 * VTIME=10 to wakeup every second not every 1.01
1896 * seconds (if hz=100). 1896 * seconds (if hz=100).
1897 */ 1897 */
1898 slp = (slp + 9)/ 10; 1898 slp = (slp + 9)/ 10;
1899 goto sleep; 1899 goto sleep;
1900 } 1900 }
1901 } else if ((qp = &tp->t_canq)->c_cc <= 0) { 1901 } else if ((qp = &tp->t_canq)->c_cc <= 0) {
1902 int carrier; 1902 int carrier;
1903 1903
1904 sleep: 1904 sleep:
1905 /* 1905 /*
1906 * If there is no input, sleep on rawq 1906 * If there is no input, sleep on rawq
1907 * awaiting hardware receipt and notification. 1907 * awaiting hardware receipt and notification.
1908 * If we have data, we don't need to check for carrier. 1908 * If we have data, we don't need to check for carrier.
1909 */ 1909 */
1910 carrier = CONNECTED(tp); 1910 carrier = CONNECTED(tp);
1911 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) { 1911 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1912 mutex_spin_exit(&tty_lock); 1912 mutex_spin_exit(&tty_lock);
1913 return (0); /* EOF */ 1913 return (0); /* EOF */
1914 } 1914 }
1915 if (!has_stime || slp <= 0) { 1915 if (!has_stime || slp <= 0) {
1916 if (flag & IO_NDELAY) { 1916 if (flag & IO_NDELAY) {
1917 mutex_spin_exit(&tty_lock); 1917 mutex_spin_exit(&tty_lock);
1918 return (EWOULDBLOCK); 1918 return (EWOULDBLOCK);
1919 } 1919 }
1920 } 1920 }
1921 error = ttysleep(tp, &tp->t_rawcv, true, slp); 1921 error = ttysleep(tp, &tp->t_rawcv, true, slp);
1922 mutex_spin_exit(&tty_lock); 1922 mutex_spin_exit(&tty_lock);
1923 /* VMIN == 0: any quantity read satisfies */ 1923 /* VMIN == 0: any quantity read satisfies */
1924 if (cc[VMIN] == 0 && error == EWOULDBLOCK) 1924 if (cc[VMIN] == 0 && error == EWOULDBLOCK)
1925 return (0); 1925 return (0);
1926 if (error && error != EWOULDBLOCK) 1926 if (error && error != EWOULDBLOCK)
1927 return (error); 1927 return (error);
1928 goto loop; 1928 goto loop;
1929 } 1929 }
1930 read: 1930 read:
1931 1931
1932 /* 1932 /*
1933 * Input present, check for input mapping and processing. 1933 * Input present, check for input mapping and processing.
1934 */ 1934 */
1935 first = 1; 1935 first = 1;
1936 while ((c = getc(qp)) >= 0) { 1936 while ((c = getc(qp)) >= 0) {
1937 /* 1937 /*
1938 * delayed suspend (^Y) 1938 * delayed suspend (^Y)
1939 */ 1939 */
1940 if (CCEQ(cc[VDSUSP], c) && 1940 if (CCEQ(cc[VDSUSP], c) &&
1941 ISSET(lflag, IEXTEN|ISIG) == (IEXTEN|ISIG)) { 1941 ISSET(lflag, IEXTEN|ISIG) == (IEXTEN|ISIG)) {
1942 ttysig(tp, TTYSIG_PG1, SIGTSTP); 1942 ttysig(tp, TTYSIG_PG1, SIGTSTP);
1943 if (first) { 1943 if (first) {
1944 error = ttypause(tp, hz); 1944 error = ttypause(tp, hz);
1945 if (error) 1945 if (error)
1946 break; 1946 break;
1947 mutex_spin_exit(&tty_lock); 1947 mutex_spin_exit(&tty_lock);
1948 goto loop; 1948 goto loop;
1949 } 1949 }
1950 break; 1950 break;
1951 } 1951 }
1952 /* 1952 /*
1953 * Interpret EOF only in canonical mode. 1953 * Interpret EOF only in canonical mode.
1954 */ 1954 */
1955 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) 1955 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1956 break; 1956 break;
1957 /* 1957 /*
1958 * Give user character. 1958 * Give user character.
1959 */ 1959 */
 1960 mutex_spin_exit(&tty_lock);
1960 error = ureadc(c, uio); 1961 error = ureadc(c, uio);
 1962 mutex_spin_enter(&tty_lock);
1961 if (error) 1963 if (error)
1962 break; 1964 break;
1963 if (uio->uio_resid == 0) 1965 if (uio->uio_resid == 0)
1964 break; 1966 break;
1965 /* 1967 /*
1966 * In canonical mode check for a "break character" 1968 * In canonical mode check for a "break character"
1967 * marking the end of a "line of input". 1969 * marking the end of a "line of input".
1968 */ 1970 */
1969 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag)) 1971 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1970 break; 1972 break;
1971 first = 0; 1973 first = 0;
1972 } 1974 }
1973 1975
1974 /* 1976 /*
1975 * Look to unblock output now that (presumably) 1977 * Look to unblock output now that (presumably)
1976 * the input queue has gone down. 1978 * the input queue has gone down.
1977 */ 1979 */
1978 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG / 5) { 1980 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG / 5) {
1979 if (ISSET(tp->t_iflag, IXOFF) && 1981 if (ISSET(tp->t_iflag, IXOFF) &&
1980 cc[VSTART] != _POSIX_VDISABLE && 1982 cc[VSTART] != _POSIX_VDISABLE &&
1981 putc(cc[VSTART], &tp->t_outq) == 0) { 1983 putc(cc[VSTART], &tp->t_outq) == 0) {
1982 CLR(tp->t_state, TS_TBLOCK); 1984 CLR(tp->t_state, TS_TBLOCK);
1983 ttstart(tp); 1985 ttstart(tp);
1984 } 1986 }
1985 /* Try to unblock remote output via hardware flow control. */ 1987 /* Try to unblock remote output via hardware flow control. */
1986 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow && 1988 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1987 (*tp->t_hwiflow)(tp, 0) != 0) 1989 (*tp->t_hwiflow)(tp, 0) != 0)
1988 CLR(tp->t_state, TS_TBLOCK); 1990 CLR(tp->t_state, TS_TBLOCK);
1989 } 1991 }
1990 mutex_spin_exit(&tty_lock); 1992 mutex_spin_exit(&tty_lock);
1991 1993
1992 return (error); 1994 return (error);
1993} 1995}
1994 1996
1995/* 1997/*
1996 * Check the output queue on tp for space for a kernel message (from uprintf 1998 * Check the output queue on tp for space for a kernel message (from uprintf
1997 * or tprintf). Allow some space over the normal hiwater mark so we don't 1999 * or tprintf). Allow some space over the normal hiwater mark so we don't
1998 * lose messages due to normal flow control, but don't let the tty run amok. 2000 * lose messages due to normal flow control, but don't let the tty run amok.
1999 * Sleeps here are not interruptible, but we return prematurely if new signals 2001 * Sleeps here are not interruptible, but we return prematurely if new signals
2000 * arrive. 2002 * arrive.
2001 * Call with tty lock held. 2003 * Call with tty lock held.
2002 */ 2004 */
2003static int 2005static int
2004ttycheckoutq_wlock(struct tty *tp, int wait) 2006ttycheckoutq_wlock(struct tty *tp, int wait)
2005{ 2007{
2006 int hiwat, error; 2008 int hiwat, error;
2007 2009
2008 KASSERT(mutex_owned(&tty_lock)); 2010 KASSERT(mutex_owned(&tty_lock));
2009 2011
2010 hiwat = tp->t_hiwat; 2012 hiwat = tp->t_hiwat;
2011 if (tp->t_outq.c_cc > hiwat + 200) 2013 if (tp->t_outq.c_cc > hiwat + 200)
2012 while (tp->t_outq.c_cc > hiwat) { 2014 while (tp->t_outq.c_cc > hiwat) {
2013 ttstart(tp); 2015 ttstart(tp);
2014 if (wait == 0) 2016 if (wait == 0)
2015 return (0); 2017 return (0);
2016 error = ttysleep(tp, &tp->t_outcv, true, hz); 2018 error = ttysleep(tp, &tp->t_outcv, true, hz);
2017 if (error == EINTR) 2019 if (error == EINTR)
2018 wait = 0; 2020 wait = 0;
2019 } 2021 }
2020 2022
2021 return (1); 2023 return (1);
2022} 2024}
2023 2025
2024int 2026int
2025ttycheckoutq(struct tty *tp, int wait) 2027ttycheckoutq(struct tty *tp, int wait)
2026{ 2028{
2027 int r; 2029 int r;
2028 2030
2029 mutex_spin_enter(&tty_lock); 2031 mutex_spin_enter(&tty_lock);
2030 r = ttycheckoutq_wlock(tp, wait); 2032 r = ttycheckoutq_wlock(tp, wait);
2031 mutex_spin_exit(&tty_lock); 2033 mutex_spin_exit(&tty_lock);
2032 2034
2033 return (r); 2035 return (r);
2034} 2036}
2035 2037
2036/* 2038/*
2037 * Process a write call on a tty device. 2039 * Process a write call on a tty device.
2038 */ 2040 */
2039int 2041int
2040ttwrite(struct tty *tp, struct uio *uio, int flag) 2042ttwrite(struct tty *tp, struct uio *uio, int flag)
2041{ 2043{
2042 u_char *cp; 2044 u_char *cp;
2043 struct proc *p; 2045 struct proc *p;
2044 int cc, ce, i, hiwat, error; 2046 int cc, ce, i, hiwat, error;
2045 u_char obuf[OBUFSIZ]; 2047 u_char obuf[OBUFSIZ];
2046 2048
2047 cp = NULL; 2049 cp = NULL;
2048 hiwat = tp->t_hiwat; 2050 hiwat = tp->t_hiwat;
2049 error = 0; 2051 error = 0;
2050 cc = 0; 2052 cc = 0;
2051 loop: 2053 loop:
2052 mutex_spin_enter(&tty_lock); 2054 mutex_spin_enter(&tty_lock);
2053 if (!CONNECTED(tp)) { 2055 if (!CONNECTED(tp)) {
2054 if (ISSET(tp->t_state, TS_ISOPEN)) { 2056 if (ISSET(tp->t_state, TS_ISOPEN)) {
2055 mutex_spin_exit(&tty_lock); 2057 mutex_spin_exit(&tty_lock);
2056 return (EIO); 2058 return (EIO);
2057 } else if (flag & IO_NDELAY) { 2059 } else if (flag & IO_NDELAY) {
2058 mutex_spin_exit(&tty_lock); 2060 mutex_spin_exit(&tty_lock);
2059 error = EWOULDBLOCK; 2061 error = EWOULDBLOCK;
2060 goto out; 2062 goto out;
2061 } else { 2063 } else {
2062 /* Sleep awaiting carrier. */ 2064 /* Sleep awaiting carrier. */
2063 error = ttysleep(tp, &tp->t_rawcv, true, 0); 2065 error = ttysleep(tp, &tp->t_rawcv, true, 0);
2064 mutex_spin_exit(&tty_lock); 2066 mutex_spin_exit(&tty_lock);
2065 if (error) 2067 if (error)
2066 goto out; 2068 goto out;
2067 goto loop; 2069 goto loop;
2068 } 2070 }
2069 } 2071 }
2070 2072
2071 /* 2073 /*
2072 * Hang the process if it's in the background. 2074 * Hang the process if it's in the background.
2073 */ 2075 */
2074 p = curproc; 2076 p = curproc;
2075 if (isbackground(p, tp) && 2077 if (isbackground(p, tp) &&
2076 ISSET(tp->t_lflag, TOSTOP) && (p->p_lflag & PL_PPWAIT) == 0 && 2078 ISSET(tp->t_lflag, TOSTOP) && (p->p_lflag & PL_PPWAIT) == 0 &&
2077 !sigismasked(curlwp, SIGTTOU)) { 2079 !sigismasked(curlwp, SIGTTOU)) {
2078 if (p->p_pgrp->pg_jobc == 0) { 2080 if (p->p_pgrp->pg_jobc == 0) {
2079 error = EIO; 2081 error = EIO;
2080 mutex_spin_exit(&tty_lock); 2082 mutex_spin_exit(&tty_lock);
2081 goto out; 2083 goto out;
2082 } 2084 }
2083 mutex_spin_exit(&tty_lock); 2085 mutex_spin_exit(&tty_lock);
2084 2086
2085 mutex_enter(proc_lock); 2087 mutex_enter(proc_lock);
2086 pgsignal(p->p_pgrp, SIGTTOU, 1); 2088 pgsignal(p->p_pgrp, SIGTTOU, 1);
2087 mutex_exit(proc_lock); 2089 mutex_exit(proc_lock);
2088 2090
2089 mutex_spin_enter(&tty_lock); 2091 mutex_spin_enter(&tty_lock);
2090 error = ttypause(tp, hz); 2092 error = ttypause(tp, hz);
2091 mutex_spin_exit(&tty_lock); 2093 mutex_spin_exit(&tty_lock);
2092 if (error) 2094 if (error)
2093 goto out; 2095 goto out;
2094 goto loop; 2096 goto loop;
2095 } 2097 }
2096 mutex_spin_exit(&tty_lock); 2098 mutex_spin_exit(&tty_lock);
2097 2099
2098 /* 2100 /*
2099 * Process the user's data in at most OBUFSIZ chunks. Perform any 2101 * Process the user's data in at most OBUFSIZ chunks. Perform any
2100 * output translation. Keep track of high water mark, sleep on 2102 * output translation. Keep track of high water mark, sleep on
2101 * overflow awaiting device aid in acquiring new space. 2103 * overflow awaiting device aid in acquiring new space.
2102 */ 2104 */
2103 while (uio->uio_resid > 0 || cc > 0) { 2105 while (uio->uio_resid > 0 || cc > 0) {
2104 if (ISSET(tp->t_lflag, FLUSHO)) { 2106 if (ISSET(tp->t_lflag, FLUSHO)) {
2105 uio->uio_resid = 0; 2107 uio->uio_resid = 0;
2106 return (0); 2108 return (0);
2107 } 2109 }
2108 if (tp->t_outq.c_cc > hiwat) 2110 if (tp->t_outq.c_cc > hiwat)
2109 goto ovhiwat; 2111 goto ovhiwat;
2110 /* 2112 /*
2111 * Grab a hunk of data from the user, unless we have some 2113 * Grab a hunk of data from the user, unless we have some
2112 * leftover from last time. 2114 * leftover from last time.
2113 */ 2115 */
2114 if (cc == 0) { 2116 if (cc == 0) {
2115 cc = min(uio->uio_resid, OBUFSIZ); 2117 cc = min(uio->uio_resid, OBUFSIZ);
2116 cp = obuf; 2118 cp = obuf;
2117 error = uiomove(cp, cc, uio); 2119 error = uiomove(cp, cc, uio);
2118 if (error) { 2120 if (error) {
2119 cc = 0; 2121 cc = 0;
2120 goto out; 2122 goto out;
2121 } 2123 }
2122 } 2124 }
2123 /* 2125 /*
2124 * If nothing fancy need be done, grab those characters we 2126 * If nothing fancy need be done, grab those characters we
2125 * can handle without any of ttyoutput's processing and 2127 * can handle without any of ttyoutput's processing and
2126 * just transfer them to the output q. For those chars 2128 * just transfer them to the output q. For those chars
2127 * which require special processing (as indicated by the 2129 * which require special processing (as indicated by the
2128 * bits in char_type), call ttyoutput. After processing 2130 * bits in char_type), call ttyoutput. After processing
2129 * a hunk of data, look for FLUSHO so ^O's will take effect 2131 * a hunk of data, look for FLUSHO so ^O's will take effect
2130 * immediately. 2132 * immediately.
2131 */ 2133 */
2132 mutex_spin_enter(&tty_lock); 2134 mutex_spin_enter(&tty_lock);
2133 while (cc > 0) { 2135 while (cc > 0) {
2134 if (!ISSET(tp->t_oflag, OPOST)) 2136 if (!ISSET(tp->t_oflag, OPOST))
2135 ce = cc; 2137 ce = cc;
2136 else { 2138 else {
2137 ce = cc - scanc((u_int)cc, cp, char_type, 2139 ce = cc - scanc((u_int)cc, cp, char_type,
2138 CCLASSMASK); 2140 CCLASSMASK);
2139 /* 2141 /*
2140 * If ce is zero, then we're processing 2142 * If ce is zero, then we're processing
2141 * a special character through ttyoutput. 2143 * a special character through ttyoutput.
2142 */ 2144 */
2143 if (ce == 0) { 2145 if (ce == 0) {
2144 tp->t_rocount = 0; 2146 tp->t_rocount = 0;
2145 if (ttyoutput(*cp, tp) >= 0) { 2147 if (ttyoutput(*cp, tp) >= 0) {
2146 /* out of space */ 2148 /* out of space */
2147 mutex_spin_exit(&tty_lock); 2149 mutex_spin_exit(&tty_lock);
2148 goto overfull; 2150 goto overfull;
2149 } 2151 }
2150 cp++; 2152 cp++;
2151 cc--; 2153 cc--;
2152 if (ISSET(tp->t_lflag, FLUSHO) || 2154 if (ISSET(tp->t_lflag, FLUSHO) ||
2153 tp->t_outq.c_cc > hiwat) { 2155 tp->t_outq.c_cc > hiwat) {
2154 mutex_spin_exit(&tty_lock); 2156 mutex_spin_exit(&tty_lock);
2155 goto ovhiwat; 2157 goto ovhiwat;
2156 } 2158 }
2157 continue; 2159 continue;
2158 } 2160 }
2159 } 2161 }
2160 /* 2162 /*
2161 * A bunch of normal characters have been found. 2163 * A bunch of normal characters have been found.
2162 * Transfer them en masse to the output queue and 2164 * Transfer them en masse to the output queue and
2163 * continue processing at the top of the loop. 2165 * continue processing at the top of the loop.
2164 * If there are any further characters in this 2166 * If there are any further characters in this
2165 * <= OBUFSIZ chunk, the first should be a character 2167 * <= OBUFSIZ chunk, the first should be a character
2166 * requiring special handling by ttyoutput. 2168 * requiring special handling by ttyoutput.
2167 */ 2169 */
2168 tp->t_rocount = 0; 2170 tp->t_rocount = 0;
2169 i = b_to_q(cp, ce, &tp->t_outq); 2171 i = b_to_q(cp, ce, &tp->t_outq);
2170 ce -= i; 2172 ce -= i;
2171 tp->t_column += ce; 2173 tp->t_column += ce;
2172 cp += ce, cc -= ce, tk_nout += ce; 2174 cp += ce, cc -= ce, tk_nout += ce;
2173 tp->t_outcc += ce; 2175 tp->t_outcc += ce;
2174 if (i > 0) { 2176 if (i > 0) {
2175 /* out of space */ 2177 /* out of space */
2176 mutex_spin_exit(&tty_lock); 2178 mutex_spin_exit(&tty_lock);
2177 goto overfull; 2179 goto overfull;
2178 } 2180 }
2179 if (ISSET(tp->t_lflag, FLUSHO) || 2181 if (ISSET(tp->t_lflag, FLUSHO) ||
2180 tp->t_outq.c_cc > hiwat) 2182 tp->t_outq.c_cc > hiwat)
2181 break; 2183 break;
2182 } 2184 }
2183 ttstart(tp); 2185 ttstart(tp);
2184 mutex_spin_exit(&tty_lock); 2186 mutex_spin_exit(&tty_lock);
2185 } 2187 }
2186 2188
2187 out: 2189 out:
2188 /* 2190 /*
2189 * If cc is nonzero, we leave the uio structure inconsistent, as the 2191 * If cc is nonzero, we leave the uio structure inconsistent, as the
2190 * offset and iov pointers have moved forward, but it doesn't matter 2192 * offset and iov pointers have moved forward, but it doesn't matter
2191 * (the call will either return short or restart with a new uio). 2193 * (the call will either return short or restart with a new uio).
2192 */ 2194 */
2193 uio->uio_resid += cc; 2195 uio->uio_resid += cc;
2194 return (error); 2196 return (error);
2195 2197
2196 overfull: 2198 overfull:
2197 /* 2199 /*
2198 * Since we are using ring buffers, if we can't insert any more into 2200 * Since we are using ring buffers, if we can't insert any more into
2199 * the output queue, we can assume the ring is full and that someone 2201 * the output queue, we can assume the ring is full and that someone
2200 * forgot to set the high water mark correctly. We set it and then 2202 * forgot to set the high water mark correctly. We set it and then
2201 * proceed as normal. 2203 * proceed as normal.
2202 */ 2204 */
2203 hiwat = tp->t_outq.c_cc - 1; 2205 hiwat = tp->t_outq.c_cc - 1;
2204 2206
2205 ovhiwat: 2207 ovhiwat:
2206 mutex_spin_enter(&tty_lock); 2208 mutex_spin_enter(&tty_lock);
2207 ttstart(tp); 2209 ttstart(tp);
2208 /* 2210 /*
2209 * This can only occur if FLUSHO is set in t_lflag, 2211 * This can only occur if FLUSHO is set in t_lflag,
2210 * or if ttstart/oproc is synchronous (or very fast). 2212 * or if ttstart/oproc is synchronous (or very fast).
2211 */ 2213 */
2212 if (tp->t_outq.c_cc <= hiwat) { 2214 if (tp->t_outq.c_cc <= hiwat) {
2213 mutex_spin_exit(&tty_lock); 2215 mutex_spin_exit(&tty_lock);
2214 goto loop; 2216 goto loop;
2215 } 2217 }
2216 if (flag & IO_NDELAY) { 2218 if (flag & IO_NDELAY) {
2217 mutex_spin_exit(&tty_lock); 2219 mutex_spin_exit(&tty_lock);
2218 error = EWOULDBLOCK; 2220 error = EWOULDBLOCK;
2219 goto out; 2221 goto out;
2220 } 2222 }
2221 error = ttysleep(tp, &tp->t_outcv, true, 0); 2223 error = ttysleep(tp, &tp->t_outcv, true, 0);
2222 mutex_spin_exit(&tty_lock); 2224 mutex_spin_exit(&tty_lock);
2223 if (error) 2225 if (error)
2224 goto out; 2226 goto out;
2225 goto loop; 2227 goto loop;
2226} 2228}
2227 2229
2228/* 2230/*
2229 * Try to pull more output from the producer. Return non-zero if 2231 * Try to pull more output from the producer. Return non-zero if
2230 * there is output ready to be sent. 2232 * there is output ready to be sent.
2231 */ 2233 */
2232bool 2234bool
2233ttypull(struct tty *tp) 2235ttypull(struct tty *tp)
2234{ 2236{
2235 2237
2236 /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */ 2238 /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
2237 2239
2238 if (tp->t_outq.c_cc <= tp->t_lowat) { 2240 if (tp->t_outq.c_cc <= tp->t_lowat) {
2239 cv_broadcast(&tp->t_outcv); 2241 cv_broadcast(&tp->t_outcv);
2240 selnotify(&tp->t_wsel, 0, NOTE_SUBMIT); 2242 selnotify(&tp->t_wsel, 0, NOTE_SUBMIT);
2241 } 2243 }
2242 return tp->t_outq.c_cc != 0; 2244 return tp->t_outq.c_cc != 0;
2243} 2245}
2244 2246
2245/* 2247/*
2246 * Rubout one character from the rawq of tp 2248 * Rubout one character from the rawq of tp
2247 * as cleanly as possible. 2249 * as cleanly as possible.
2248 * Called with tty lock held. 2250 * Called with tty lock held.
2249 */ 2251 */
2250void 2252void
2251ttyrub(int c, struct tty *tp) 2253ttyrub(int c, struct tty *tp)
2252{ 2254{
2253 u_char *cp; 2255 u_char *cp;
2254 int savecol, tabc; 2256 int savecol, tabc;
2255 2257
2256 KASSERT(mutex_owned(&tty_lock)); 2258 KASSERT(mutex_owned(&tty_lock));
2257 2259
2258 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) 2260 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2259 return; 2261 return;
2260 CLR(tp->t_lflag, FLUSHO); 2262 CLR(tp->t_lflag, FLUSHO);
2261 if (ISSET(tp->t_lflag, ECHOE)) { 2263 if (ISSET(tp->t_lflag, ECHOE)) {
2262 if (tp->t_rocount == 0) { 2264 if (tp->t_rocount == 0) {
2263 /* 2265 /*
2264 * Screwed by ttwrite; retype 2266 * Screwed by ttwrite; retype
2265 */ 2267 */
2266 ttyretype(tp); 2268 ttyretype(tp);
2267 return; 2269 return;
2268 } 2270 }
2269 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) 2271 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
2270 ttyrubo(tp, 2); 2272 ttyrubo(tp, 2);
2271 else { 2273 else {
2272 CLR(c, ~TTY_CHARMASK); 2274 CLR(c, ~TTY_CHARMASK);
2273 switch (CCLASS(c)) { 2275 switch (CCLASS(c)) {
2274 case ORDINARY: 2276 case ORDINARY:
2275 ttyrubo(tp, 1); 2277 ttyrubo(tp, 1);
2276 break; 2278 break;
2277 case BACKSPACE: 2279 case BACKSPACE:
2278 case CONTROL: 2280 case CONTROL:
2279 case NEWLINE: 2281 case NEWLINE:
2280 case RETURN: 2282 case RETURN:
2281 case VTAB: 2283 case VTAB:
2282 if (ISSET(tp->t_lflag, ECHOCTL)) 2284 if (ISSET(tp->t_lflag, ECHOCTL))
2283 ttyrubo(tp, 2); 2285 ttyrubo(tp, 2);
2284 break; 2286 break;
2285 case TAB: 2287 case TAB:
2286 if (tp->t_rocount < tp->t_rawq.c_cc) { 2288 if (tp->t_rocount < tp->t_rawq.c_cc) {
2287 ttyretype(tp); 2289 ttyretype(tp);
2288 return; 2290 return;
2289 } 2291 }
2290 savecol = tp->t_column; 2292 savecol = tp->t_column;
2291 SET(tp->t_state, TS_CNTTB); 2293 SET(tp->t_state, TS_CNTTB);
2292 SET(tp->t_lflag, FLUSHO); 2294 SET(tp->t_lflag, FLUSHO);
2293 tp->t_column = tp->t_rocol; 2295 tp->t_column = tp->t_rocol;
2294 for (cp = firstc(&tp->t_rawq, &tabc); cp; 2296 for (cp = firstc(&tp->t_rawq, &tabc); cp;
2295 cp = nextc(&tp->t_rawq, cp, &tabc)) 2297 cp = nextc(&tp->t_rawq, cp, &tabc))
2296 ttyecho(tabc, tp); 2298 ttyecho(tabc, tp);
2297 CLR(tp->t_lflag, FLUSHO); 2299 CLR(tp->t_lflag, FLUSHO);
2298 CLR(tp->t_state, TS_CNTTB); 2300 CLR(tp->t_state, TS_CNTTB);
2299 2301
2300 /* savecol will now be length of the tab. */ 2302 /* savecol will now be length of the tab. */
2301 savecol -= tp->t_column; 2303 savecol -= tp->t_column;
2302 tp->t_column += savecol; 2304 tp->t_column += savecol;
2303 if (savecol > 8) 2305 if (savecol > 8)
2304 savecol = 8; /* overflow screw */ 2306 savecol = 8; /* overflow screw */
2305 while (--savecol >= 0) 2307 while (--savecol >= 0)
2306 (void)ttyoutput('\b', tp); 2308 (void)ttyoutput('\b', tp);
2307 break; 2309 break;
2308 default: /* XXX */ 2310 default: /* XXX */
2309 (void)printf("ttyrub: would panic c = %d, " 2311 (void)printf("ttyrub: would panic c = %d, "
2310 "val = %d\n", c, CCLASS(c)); 2312 "val = %d\n", c, CCLASS(c));
2311 } 2313 }
2312 } 2314 }
2313 } else if (ISSET(tp->t_lflag, ECHOPRT)) { 2315 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2314 if (!ISSET(tp->t_state, TS_ERASE)) { 2316 if (!ISSET(tp->t_state, TS_ERASE)) {
2315 SET(tp->t_state, TS_ERASE); 2317 SET(tp->t_state, TS_ERASE);
2316 (void)ttyoutput('\\', tp); 2318 (void)ttyoutput('\\', tp);
2317 } 2319 }
2318 ttyecho(c, tp); 2320 ttyecho(c, tp);
2319 } else 2321 } else
2320 ttyecho(tp->t_cc[VERASE], tp); 2322 ttyecho(tp->t_cc[VERASE], tp);
2321 --tp->t_rocount; 2323 --tp->t_rocount;
2322} 2324}
2323 2325
2324/* 2326/*
2325 * Back over cnt characters, erasing them. 2327 * Back over cnt characters, erasing them.
2326 * Called with tty lock held. 2328 * Called with tty lock held.
2327 */ 2329 */
2328static void 2330static void
2329ttyrubo(struct tty *tp, int cnt) 2331ttyrubo(struct tty *tp, int cnt)
2330{ 2332{
2331 2333
2332 KASSERT(mutex_owned(&tty_lock)); 2334 KASSERT(mutex_owned(&tty_lock));
2333 2335
2334 while (cnt-- > 0) { 2336 while (cnt-- > 0) {
2335 (void)ttyoutput('\b', tp); 2337 (void)ttyoutput('\b', tp);
2336 (void)ttyoutput(' ', tp); 2338 (void)ttyoutput(' ', tp);
2337 (void)ttyoutput('\b', tp); 2339 (void)ttyoutput('\b', tp);
2338 } 2340 }
2339} 2341}
2340 2342
2341/* 2343/*
2342 * ttyretype -- 2344 * ttyretype --
2343 * Reprint the rawq line. Note, it is assumed that c_cc has already 2345 * Reprint the rawq line. Note, it is assumed that c_cc has already
2344 * been checked. 2346 * been checked.
2345 * 2347 *
2346 * Called with tty lock held. 2348 * Called with tty lock held.
2347 */ 2349 */
2348void 2350void
2349ttyretype(struct tty *tp) 2351ttyretype(struct tty *tp)
2350{ 2352{
2351 u_char *cp; 2353 u_char *cp;
2352 int c; 2354 int c;
2353 2355
2354 KASSERT(mutex_owned(&tty_lock)); 2356 KASSERT(mutex_owned(&tty_lock));
2355 2357
2356 /* Echo the reprint character. */ 2358 /* Echo the reprint character. */
2357 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) 2359 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2358 ttyecho(tp->t_cc[VREPRINT], tp); 2360 ttyecho(tp->t_cc[VREPRINT], tp);
2359 2361
2360 (void)ttyoutput('\n', tp); 2362 (void)ttyoutput('\n', tp);
2361 2363
2362 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c)) 2364 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
2363 ttyecho(c, tp); 2365 ttyecho(c, tp);
2364 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c)) 2366 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
2365 ttyecho(c, tp); 2367 ttyecho(c, tp);
2366 CLR(tp->t_state, TS_ERASE); 2368 CLR(tp->t_state, TS_ERASE);
2367 2369
2368 tp->t_rocount = tp->t_rawq.c_cc; 2370 tp->t_rocount = tp->t_rawq.c_cc;
2369 tp->t_rocol = 0; 2371 tp->t_rocol = 0;
2370} 2372}
2371 2373
2372/* 2374/*
2373 * Echo a typed character to the terminal. 2375 * Echo a typed character to the terminal.
2374 * Called with tty lock held. 2376 * Called with tty lock held.
2375 */ 2377 */
2376static void 2378static void
2377ttyecho(int c, struct tty *tp) 2379ttyecho(int c, struct tty *tp)
2378{ 2380{
2379 2381
2380 KASSERT(mutex_owned(&tty_lock)); 2382 KASSERT(mutex_owned(&tty_lock));
2381 2383
2382 if (!ISSET(tp->t_state, TS_CNTTB)) 2384 if (!ISSET(tp->t_state, TS_CNTTB))
2383 CLR(tp->t_lflag, FLUSHO); 2385 CLR(tp->t_lflag, FLUSHO);
2384 if ((!ISSET(tp->t_lflag, ECHO) && 2386 if ((!ISSET(tp->t_lflag, ECHO) &&
2385 (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) || 2387 (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
2386 ISSET(tp->t_lflag, EXTPROC)) 2388 ISSET(tp->t_lflag, EXTPROC))
2387 return; 2389 return;
2388 if (((ISSET(tp->t_lflag, ECHOCTL) && 2390 if (((ISSET(tp->t_lflag, ECHOCTL) &&
2389 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) || 2391 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
2390 ISSET(c, TTY_CHARMASK) == 0177)) { 2392 ISSET(c, TTY_CHARMASK) == 0177)) {
2391 (void)ttyoutput('^', tp); 2393 (void)ttyoutput('^', tp);
2392 CLR(c, ~TTY_CHARMASK); 2394 CLR(c, ~TTY_CHARMASK);
2393 if (c == 0177) 2395 if (c == 0177)
2394 c = '?'; 2396 c = '?';
2395 else 2397 else
2396 c += 'A' - 1; 2398 c += 'A' - 1;
2397 } 2399 }
2398 (void)ttyoutput(c, tp); 2400 (void)ttyoutput(c, tp);
2399} 2401}
2400 2402
2401/* 2403/*
2402 * Wake up any readers on a tty. 2404 * Wake up any readers on a tty.
2403 * Called with tty lock held. 2405 * Called with tty lock held.
2404 */ 2406 */
2405void 2407void
2406ttwakeup(struct tty *tp) 2408ttwakeup(struct tty *tp)
2407{ 2409{
2408 2410
2409 KASSERT(mutex_owned(&tty_lock)); 2411 KASSERT(mutex_owned(&tty_lock));
2410 2412
2411 selnotify(&tp->t_rsel, 0, NOTE_SUBMIT); 2413 selnotify(&tp->t_rsel, 0, NOTE_SUBMIT);
2412 if (ISSET(tp->t_state, TS_ASYNC)) 2414 if (ISSET(tp->t_state, TS_ASYNC))
2413 ttysig(tp, TTYSIG_PG2, SIGIO); 2415 ttysig(tp, TTYSIG_PG2, SIGIO);
2414 cv_broadcast(&tp->t_rawcv); 2416 cv_broadcast(&tp->t_rawcv);
2415} 2417}
2416 2418
2417/* 2419/*
2418 * Look up a code for a specified speed in a conversion table; 2420 * Look up a code for a specified speed in a conversion table;
2419 * used by drivers to map software speed values to hardware parameters. 2421 * used by drivers to map software speed values to hardware parameters.
2420 */ 2422 */
2421int 2423int
2422ttspeedtab(int speed, const struct speedtab *table) 2424ttspeedtab(int speed, const struct speedtab *table)
2423{ 2425{
2424 2426
2425 for (; table->sp_speed != -1; table++) 2427 for (; table->sp_speed != -1; table++)
2426 if (table->sp_speed == speed) 2428 if (table->sp_speed == speed)
2427 return (table->sp_code); 2429 return (table->sp_code);
2428 return (-1); 2430 return (-1);
2429} 2431}
2430 2432
2431/* 2433/*
2432 * Set tty hi and low water marks. 2434 * Set tty hi and low water marks.
2433 * 2435 *
2434 * Try to arrange the dynamics so there's about one second 2436 * Try to arrange the dynamics so there's about one second
2435 * from hi to low water. 2437 * from hi to low water.
2436 */ 2438 */
2437void 2439void
2438ttsetwater(struct tty *tp) 2440ttsetwater(struct tty *tp)
2439{ 2441{
2440 int cps, x; 2442 int cps, x;
2441 2443
2442 /* XXX not yet KASSERT(mutex_owned(&tty_lock)); */ 2444 /* XXX not yet KASSERT(mutex_owned(&tty_lock)); */
2443 2445
2444#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x)) 2446#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2445 2447
2446 cps = tp->t_ospeed / 10; 2448 cps = tp->t_ospeed / 10;
2447 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT); 2449 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2448 x += cps; 2450 x += cps;
2449 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT); 2451 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
2450 tp->t_hiwat = roundup(x, TTROUND); 2452 tp->t_hiwat = roundup(x, TTROUND);
2451#undef CLAMP 2453#undef CLAMP
2452} 2454}
2453 2455
2454/* 2456/*
2455 * Prepare report on state of foreground process group. 2457 * Prepare report on state of foreground process group.
2456 * Call with proc_lock held. 2458 * Call with proc_lock held.
2457 */ 2459 */
2458void 2460void
2459ttygetinfo(struct tty *tp, int fromsig, char *buf, size_t bufsz) 2461ttygetinfo(struct tty *tp, int fromsig, char *buf, size_t bufsz)
2460{ 2462{
2461 struct lwp *l; 2463 struct lwp *l;
2462 struct proc *p, *pick = NULL; 2464 struct proc *p, *pick = NULL;
2463 struct timeval utime, stime; 2465 struct timeval utime, stime;
2464 int tmp; 2466 int tmp;
2465 fixpt_t pctcpu = 0; 2467 fixpt_t pctcpu = 0;
2466 const char *msg; 2468 const char *msg;
2467 char lmsg[100]; 2469 char lmsg[100];
2468 long rss; 2470 long rss;
2469 2471
2470 KASSERT(mutex_owned(proc_lock)); 2472 KASSERT(mutex_owned(proc_lock));
2471 2473
2472 *buf = '\0'; 2474 *buf = '\0';
2473 2475
2474 if (tp->t_session == NULL) 2476 if (tp->t_session == NULL)
2475 msg = "not a controlling terminal\n"; 2477 msg = "not a controlling terminal\n";
2476 else if (tp->t_pgrp == NULL) 2478 else if (tp->t_pgrp == NULL)
2477 msg = "no foreground process group\n"; 2479 msg = "no foreground process group\n";
2478 else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL) 2480 else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL)
2479 msg = "empty foreground process group\n"; 2481 msg = "empty foreground process group\n";
2480 else { 2482 else {
2481 /* Pick interesting process. */ 2483 /* Pick interesting process. */
2482 for (; p != NULL; p = LIST_NEXT(p, p_pglist)) { 2484 for (; p != NULL; p = LIST_NEXT(p, p_pglist)) {
2483 struct proc *oldpick; 2485 struct proc *oldpick;
2484 2486
2485 if (pick == NULL) { 2487 if (pick == NULL) {
2486 pick = p; 2488 pick = p;
2487 continue; 2489 continue;
2488 } 2490 }
2489 if (pick->p_lock < p->p_lock) { 2491 if (pick->p_lock < p->p_lock) {
2490 mutex_enter(pick->p_lock); 2492 mutex_enter(pick->p_lock);
2491 mutex_enter(p->p_lock); 2493 mutex_enter(p->p_lock);
2492 } else if (pick->p_lock > p->p_lock) { 2494 } else if (pick->p_lock > p->p_lock) {
2493 mutex_enter(p->p_lock); 2495 mutex_enter(p->p_lock);
2494 mutex_enter(pick->p_lock); 2496 mutex_enter(pick->p_lock);
2495 } else 2497 } else
2496 mutex_enter(p->p_lock); 2498 mutex_enter(p->p_lock);
2497 oldpick = pick; 2499 oldpick = pick;
2498 if (proc_compare_wrapper(pick, p)) 2500 if (proc_compare_wrapper(pick, p))
2499 pick = p; 2501 pick = p;
2500 mutex_exit(p->p_lock); 2502 mutex_exit(p->p_lock);
2501 if (p->p_lock != oldpick->p_lock) 2503 if (p->p_lock != oldpick->p_lock)
2502 mutex_exit(oldpick->p_lock); 2504 mutex_exit(oldpick->p_lock);
2503 } 2505 }
2504 if (fromsig && 2506 if (fromsig &&
2505 (SIGACTION_PS(pick->p_sigacts, SIGINFO).sa_flags & 2507 (SIGACTION_PS(pick->p_sigacts, SIGINFO).sa_flags &
2506 SA_NOKERNINFO)) 2508 SA_NOKERNINFO))
2507 return; 2509 return;
2508 msg = NULL; 2510 msg = NULL;
2509 } 2511 }
2510 2512
2511 /* Print load average. */ 2513 /* Print load average. */
2512 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; 2514 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2513 snprintf(lmsg, sizeof(lmsg), "load: %d.%02d ", tmp / 100, tmp % 100); 2515 snprintf(lmsg, sizeof(lmsg), "load: %d.%02d ", tmp / 100, tmp % 100);
2514 strlcat(buf, lmsg, bufsz); 2516 strlcat(buf, lmsg, bufsz);
2515 2517
2516 if (pick == NULL) { 2518 if (pick == NULL) {
2517 strlcat(buf, msg, bufsz); 2519 strlcat(buf, msg, bufsz);
2518 return; 2520 return;
2519 } 2521 }
2520 2522
2521 snprintf(lmsg, sizeof(lmsg), " cmd: %s %d [", pick->p_comm, 2523 snprintf(lmsg, sizeof(lmsg), " cmd: %s %d [", pick->p_comm,
2522 pick->p_pid); 2524 pick->p_pid);
2523 strlcat(buf, lmsg, bufsz); 2525 strlcat(buf, lmsg, bufsz);
2524 2526
2525 mutex_enter(pick->p_lock); 2527 mutex_enter(pick->p_lock);
2526 LIST_FOREACH(l, &pick->p_lwps, l_sibling) { 2528 LIST_FOREACH(l, &pick->p_lwps, l_sibling) {
2527 const char *lp; 2529 const char *lp;
2528 lwp_lock(l); 2530 lwp_lock(l);
2529#ifdef LWP_PC 2531#ifdef LWP_PC
2530#define FMT_RUN "%#"PRIxVADDR 2532#define FMT_RUN "%#"PRIxVADDR
2531#define VAL_RUNNING (vaddr_t)LWP_PC(l) 2533#define VAL_RUNNING (vaddr_t)LWP_PC(l)
2532#define VAL_RUNABLE (vaddr_t)LWP_PC(l) 2534#define VAL_RUNABLE (vaddr_t)LWP_PC(l)
2533#else 2535#else
2534#define FMT_RUN "%s" 2536#define FMT_RUN "%s"
2535#define VAL_RUNNING "running" 2537#define VAL_RUNNING "running"
2536#define VAL_RUNABLE "runnable" 2538#define VAL_RUNABLE "runnable"
2537#endif 2539#endif
2538 switch (l->l_stat) { 2540 switch (l->l_stat) {
2539 case LSONPROC: 2541 case LSONPROC:
2540 snprintf(lmsg, sizeof(lmsg), FMT_RUN"/%d", VAL_RUNNING, 2542 snprintf(lmsg, sizeof(lmsg), FMT_RUN"/%d", VAL_RUNNING,
2541 cpu_index(l->l_cpu)); 2543 cpu_index(l->l_cpu));
2542 lp = lmsg; 2544 lp = lmsg;
2543 break; 2545 break;
2544 case LSRUN: 2546 case LSRUN:
2545 snprintf(lmsg, sizeof(lmsg), FMT_RUN, VAL_RUNABLE); 2547 snprintf(lmsg, sizeof(lmsg), FMT_RUN, VAL_RUNABLE);
2546 lp = lmsg; 2548 lp = lmsg;
2547 break; 2549 break;
2548 default: 2550 default:
2549 lp = l->l_wchan ? l->l_wmesg : "iowait"; 2551 lp = l->l_wchan ? l->l_wmesg : "iowait";
2550 break; 2552 break;
2551 }  2553 }
2552 strlcat(buf, lp, bufsz); 2554 strlcat(buf, lp, bufsz);
2553 strlcat(buf, LIST_NEXT(l, l_sibling) != NULL ? " " : "] ", 2555 strlcat(buf, LIST_NEXT(l, l_sibling) != NULL ? " " : "] ",
2554 bufsz); 2556 bufsz);
2555 pctcpu += l->l_pctcpu; 2557 pctcpu += l->l_pctcpu;
2556 lwp_unlock(l); 2558 lwp_unlock(l);
2557 } 2559 }
2558 pctcpu += pick->p_pctcpu; 2560 pctcpu += pick->p_pctcpu;
2559 calcru(pick, &utime, &stime, NULL, NULL); 2561 calcru(pick, &utime, &stime, NULL, NULL);
2560 mutex_exit(pick->p_lock); 2562 mutex_exit(pick->p_lock);
2561 2563
2562 /* Round up and print user+system time, %CPU and RSS. */ 2564 /* Round up and print user+system time, %CPU and RSS. */
2563 utime.tv_usec += 5000; 2565 utime.tv_usec += 5000;
2564 if (utime.tv_usec >= 1000000) { 2566 if (utime.tv_usec >= 1000000) {
2565 utime.tv_sec += 1; 2567 utime.tv_sec += 1;
2566 utime.tv_usec -= 1000000; 2568 utime.tv_usec -= 1000000;
2567 } 2569 }
2568 stime.tv_usec += 5000; 2570 stime.tv_usec += 5000;
2569 if (stime.tv_usec >= 1000000) { 2571 if (stime.tv_usec >= 1000000) {
2570 stime.tv_sec += 1; 2572 stime.tv_sec += 1;
2571 stime.tv_usec -= 1000000; 2573 stime.tv_usec -= 1000000;
2572 } 2574 }
2573#define pgtok(a) (((u_long) ((a) * PAGE_SIZE) / 1024)) 2575#define pgtok(a) (((u_long) ((a) * PAGE_SIZE) / 1024))
2574 tmp = (pctcpu * 10000 + FSCALE / 2) >> FSHIFT; 2576 tmp = (pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
2575 if (pick->p_stat == SIDL || P_ZOMBIE(pick)) 2577 if (pick->p_stat == SIDL || P_ZOMBIE(pick))
2576 rss = 0; 2578 rss = 0;
2577 else 2579 else
2578 rss = pgtok(vm_resident_count(pick->p_vmspace)); 2580 rss = pgtok(vm_resident_count(pick->p_vmspace));
2579 2581
2580 snprintf(lmsg, sizeof(lmsg), "%ld.%02ldu %ld.%02lds %d%% %ldk", 2582 snprintf(lmsg, sizeof(lmsg), "%ld.%02ldu %ld.%02lds %d%% %ldk",
2581 (long)utime.tv_sec, (long)utime.tv_usec / 10000, 2583 (long)utime.tv_sec, (long)utime.tv_usec / 10000,
2582 (long)stime.tv_sec, (long)stime.tv_usec / 10000, 2584 (long)stime.tv_sec, (long)stime.tv_usec / 10000,
2583 tmp / 100, rss); 2585 tmp / 100, rss);
2584 strlcat(buf, lmsg, bufsz); 2586 strlcat(buf, lmsg, bufsz);
2585} 2587}
2586 2588
2587/* 2589/*
2588 * Print report on state of foreground process group. 2590 * Print report on state of foreground process group.
2589 * Call with tty_lock held. 2591 * Call with tty_lock held.
2590 */ 2592 */
2591void 2593void
2592ttyputinfo(struct tty *tp, char *buf) 2594ttyputinfo(struct tty *tp, char *buf)
2593{ 2595{
2594 2596
2595 KASSERT(mutex_owned(&tty_lock)); 2597 KASSERT(mutex_owned(&tty_lock));
2596 2598
2597 if (ttycheckoutq_wlock(tp, 0) == 0) 2599 if (ttycheckoutq_wlock(tp, 0) == 0)
2598 return; 2600 return;
2599 ttyprintf_nolock(tp, "%s\n", buf); 2601 ttyprintf_nolock(tp, "%s\n", buf);
2600 tp->t_rocount = 0; /* so pending input will be retyped if BS */ 2602 tp->t_rocount = 0; /* so pending input will be retyped if BS */
2601} 2603}
2602 2604
2603/* 2605/*
2604 * Returns 1 if p2 has a better chance being the active foreground process 2606 * Returns 1 if p2 has a better chance being the active foreground process
2605 * in a terminal instead of p1. 2607 * in a terminal instead of p1.
2606 */ 2608 */
2607static int 2609static int
2608proc_compare_wrapper(struct proc *p1, struct proc *p2) 2610proc_compare_wrapper(struct proc *p1, struct proc *p2)
2609{ 2611{
2610 lwp_t *l1, *l2; 2612 lwp_t *l1, *l2;
2611 2613
2612 KASSERT(mutex_owned(p1->p_lock)); 2614 KASSERT(mutex_owned(p1->p_lock));
2613 KASSERT(mutex_owned(p2->p_lock)); 2615 KASSERT(mutex_owned(p2->p_lock));
2614 2616
2615 if ((l1 = LIST_FIRST(&p1->p_lwps)) == NULL) 2617 if ((l1 = LIST_FIRST(&p1->p_lwps)) == NULL)
2616 return 1; 2618 return 1;
2617 2619
2618 if ((l2 = LIST_FIRST(&p2->p_lwps)) == NULL) 2620 if ((l2 = LIST_FIRST(&p2->p_lwps)) == NULL)
2619 return 0; 2621 return 0;
2620 2622
2621 return proc_compare(p1, l1, p2, l2); 2623 return proc_compare(p1, l1, p2, l2);
2622} 2624}
2623 2625
2624/* 2626/*
2625 * Output char to tty; console putchar style. 2627 * Output char to tty; console putchar style.
2626 * Can be called with tty lock held through kprintf() machinery.. 2628 * Can be called with tty lock held through kprintf() machinery..
2627 */ 2629 */
2628int 2630int
2629tputchar(int c, int flags, struct tty *tp) 2631tputchar(int c, int flags, struct tty *tp)
2630{ 2632{
2631 int r = 0; 2633 int r = 0;
2632 2634
2633 if ((flags & NOLOCK) == 0) 2635 if ((flags & NOLOCK) == 0)
2634 mutex_spin_enter(&tty_lock); 2636 mutex_spin_enter(&tty_lock);
2635 if (!CONNECTED(tp)) { 2637 if (!CONNECTED(tp)) {
2636 r = -1; 2638 r = -1;
2637 goto out; 2639 goto out;
2638 } 2640 }
2639 if (c == '\n') 2641 if (c == '\n')
2640 (void)ttyoutput('\r', tp); 2642 (void)ttyoutput('\r', tp);
2641 (void)ttyoutput(c, tp); 2643 (void)ttyoutput(c, tp);
2642 ttstart(tp); 2644 ttstart(tp);
2643out: 2645out:
2644 if ((flags & NOLOCK) == 0) 2646 if ((flags & NOLOCK) == 0)
2645 mutex_spin_exit(&tty_lock); 2647 mutex_spin_exit(&tty_lock);
2646 return (r); 2648 return (r);
2647} 2649}
2648 2650
2649/* 2651/*
2650 * Sleep on chan, returning ERESTART if tty changed while we napped and 2652 * Sleep on chan, returning ERESTART if tty changed while we napped and
2651 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by 2653 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by
2652 * cv_timedwait(_sig). 2654 * cv_timedwait(_sig).
2653 * If the tty is revoked, restarting a pending call will redo validation done 2655 * If the tty is revoked, restarting a pending call will redo validation done
2654 * at the start of the call. 2656 * at the start of the call.
2655 * 2657 *
2656 * Must be called with the tty lock held. 2658 * Must be called with the tty lock held.
2657 */ 2659 */
2658int 2660int
2659ttysleep(struct tty *tp, kcondvar_t *cv, bool catch, int timo) 2661ttysleep(struct tty *tp, kcondvar_t *cv, bool catch, int timo)
2660{ 2662{
2661 int error; 2663 int error;
2662 short gen; 2664 short gen;
2663 2665
2664 KASSERT(mutex_owned(&tty_lock)); 2666 KASSERT(mutex_owned(&tty_lock));
2665 2667
2666 gen = tp->t_gen; 2668 gen = tp->t_gen;
2667 if (cv == NULL) 2669 if (cv == NULL)
2668 error = kpause("ttypause", catch, timo, &tty_lock); 2670 error = kpause("ttypause", catch, timo, &tty_lock);
2669 else if (catch) 2671 else if (catch)
2670 error = cv_timedwait_sig(cv, &tty_lock, timo); 2672 error = cv_timedwait_sig(cv, &tty_lock, timo);
2671 else 2673 else
2672 error = cv_timedwait(cv, &tty_lock, timo); 2674 error = cv_timedwait(cv, &tty_lock, timo);
2673 if (error != 0) 2675 if (error != 0)
2674 return (error); 2676 return (error);
2675 return (tp->t_gen == gen ? 0 : ERESTART); 2677 return (tp->t_gen == gen ? 0 : ERESTART);
2676} 2678}
2677 2679
2678int 2680int
2679ttypause(struct tty *tp, int timo) 2681ttypause(struct tty *tp, int timo)
2680{ 2682{
2681 int error; 2683 int error;
2682 2684
2683 error = ttysleep(tp, NULL, true, timo); 2685 error = ttysleep(tp, NULL, true, timo);
2684 if (error == EWOULDBLOCK) 2686 if (error == EWOULDBLOCK)
2685 error = 0; 2687 error = 0;
2686 return error; 2688 return error;
2687} 2689}
2688 2690
2689/* 2691/*
2690 * Attach a tty to the tty list. 2692 * Attach a tty to the tty list.
2691 * 2693 *
2692 * This should be called ONLY once per real tty (including pty's). 2694 * This should be called ONLY once per real tty (including pty's).
2693 * eg, on the sparc, the keyboard and mouse have struct tty's that are 2695 * eg, on the sparc, the keyboard and mouse have struct tty's that are
2694 * distinctly NOT usable as tty's, and thus should not be attached to 2696 * distinctly NOT usable as tty's, and thus should not be attached to
2695 * the ttylist. This is why this call is not done from tty_alloc(). 2697 * the ttylist. This is why this call is not done from tty_alloc().
2696 * 2698 *
2697 * Device drivers should attach tty's at a similar time that they are 2699 * Device drivers should attach tty's at a similar time that they are
2698 * allocated, or, for the case of statically allocated struct tty's 2700 * allocated, or, for the case of statically allocated struct tty's
2699 * either in the attach or (first) open routine. 2701 * either in the attach or (first) open routine.
2700 */ 2702 */
2701void 2703void
2702tty_attach(struct tty *tp) 2704tty_attach(struct tty *tp)
2703{ 2705{
2704 2706
2705 mutex_spin_enter(&tty_lock); 2707 mutex_spin_enter(&tty_lock);
2706 TAILQ_INSERT_TAIL(&ttylist, tp, tty_link); 2708 TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
2707 ++tty_count; 2709 ++tty_count;
2708 mutex_spin_exit(&tty_lock); 2710 mutex_spin_exit(&tty_lock);
2709} 2711}
2710 2712
2711/* 2713/*
2712 * Remove a tty from the tty list. 2714 * Remove a tty from the tty list.
2713 */ 2715 */
2714void 2716void
2715tty_detach(struct tty *tp) 2717tty_detach(struct tty *tp)
2716{ 2718{
2717 2719
2718 mutex_spin_enter(&tty_lock); 2720 mutex_spin_enter(&tty_lock);
2719 --tty_count; 2721 --tty_count;
2720#ifdef DIAGNOSTIC 2722#ifdef DIAGNOSTIC
2721 if (tty_count < 0) 2723 if (tty_count < 0)
2722 panic("tty_detach: tty_count < 0"); 2724 panic("tty_detach: tty_count < 0");
2723#endif 2725#endif
2724 TAILQ_REMOVE(&ttylist, tp, tty_link); 2726 TAILQ_REMOVE(&ttylist, tp, tty_link);
2725 mutex_spin_exit(&tty_lock); 2727 mutex_spin_exit(&tty_lock);
2726} 2728}
2727 2729
2728/* 2730/*
2729 * Allocate a tty structure and its associated buffers. 2731 * Allocate a tty structure and its associated buffers.
2730 */ 2732 */
2731struct tty * 2733struct tty *
2732tty_alloc(void) 2734tty_alloc(void)
2733{ 2735{
2734 struct tty *tp; 2736 struct tty *tp;
2735 int i; 2737 int i;
2736 2738
2737 tp = kmem_zalloc(sizeof(*tp), KM_SLEEP); 2739 tp = kmem_zalloc(sizeof(*tp), KM_SLEEP);
2738 callout_init(&tp->t_rstrt_ch, 0); 2740 callout_init(&tp->t_rstrt_ch, 0);
2739 callout_setfunc(&tp->t_rstrt_ch, ttrstrt, tp); 2741 callout_setfunc(&tp->t_rstrt_ch, ttrstrt, tp);
2740 tp->t_qsize = tty_qsize; 2742 tp->t_qsize = tty_qsize;
2741 clalloc(&tp->t_rawq, tp->t_qsize, 1); 2743 clalloc(&tp->t_rawq, tp->t_qsize, 1);
2742 cv_init(&tp->t_rawcv, "ttyraw"); 2744 cv_init(&tp->t_rawcv, "ttyraw");
2743 cv_init(&tp->t_rawcvf, "ttyrawf"); 2745 cv_init(&tp->t_rawcvf, "ttyrawf");
2744 clalloc(&tp->t_canq, tp->t_qsize, 1); 2746 clalloc(&tp->t_canq, tp->t_qsize, 1);
2745 cv_init(&tp->t_cancv, "ttycan"); 2747 cv_init(&tp->t_cancv, "ttycan");
2746 cv_init(&tp->t_cancvf, "ttycanf"); 2748 cv_init(&tp->t_cancvf, "ttycanf");
2747 /* output queue doesn't need quoting */ 2749 /* output queue doesn't need quoting */
2748 clalloc(&tp->t_outq, tp->t_qsize, 0); 2750 clalloc(&tp->t_outq, tp->t_qsize, 0);
2749 cv_init(&tp->t_outcv, "ttyout"); 2751 cv_init(&tp->t_outcv, "ttyout");
2750 cv_init(&tp->t_outcvf, "ttyoutf"); 2752 cv_init(&tp->t_outcvf, "ttyoutf");
2751 /* Set default line discipline. */ 2753 /* Set default line discipline. */
2752 tp->t_linesw = ttyldisc_default(); 2754 tp->t_linesw = ttyldisc_default();
2753 tp->t_dev = NODEV; 2755 tp->t_dev = NODEV;
2754 selinit(&tp->t_rsel); 2756 selinit(&tp->t_rsel);
2755 selinit(&tp->t_wsel); 2757 selinit(&tp->t_wsel);
2756 for (i = 0; i < TTYSIG_COUNT; i++) { 2758 for (i = 0; i < TTYSIG_COUNT; i++) {
2757 sigemptyset(&tp->t_sigs[i]); 2759 sigemptyset(&tp->t_sigs[i]);
2758 } 2760 }
2759 2761
2760 return tp; 2762 return tp;
2761} 2763}
2762 2764
2763/* 2765/*
2764 * Free a tty structure and its buffers. 2766 * Free a tty structure and its buffers.
2765 * 2767 *
2766 * Be sure to call tty_detach() for any tty that has been 2768 * Be sure to call tty_detach() for any tty that has been
2767 * tty_attach()ed. 2769 * tty_attach()ed.
2768 */ 2770 */
2769void 2771void
2770tty_free(struct tty *tp) 2772tty_free(struct tty *tp)
2771{ 2773{
2772 int i; 2774 int i;
2773 2775
2774 mutex_enter(proc_lock); 2776 mutex_enter(proc_lock);
2775 mutex_enter(&tty_lock); 2777 mutex_enter(&tty_lock);
2776 for (i = 0; i < TTYSIG_COUNT; i++)  2778 for (i = 0; i < TTYSIG_COUNT; i++)
2777 sigemptyset(&tp->t_sigs[i]); 2779 sigemptyset(&tp->t_sigs[i]);
2778 if (tp->t_sigcount != 0) 2780 if (tp->t_sigcount != 0)
2779 TAILQ_REMOVE(&tty_sigqueue, tp, t_sigqueue); 2781 TAILQ_REMOVE(&tty_sigqueue, tp, t_sigqueue);
2780 mutex_exit(&tty_lock); 2782 mutex_exit(&tty_lock);
2781 mutex_exit(proc_lock); 2783 mutex_exit(proc_lock);
2782 2784
2783 callout_halt(&tp->t_rstrt_ch, NULL); 2785 callout_halt(&tp->t_rstrt_ch, NULL);
2784 callout_destroy(&tp->t_rstrt_ch); 2786 callout_destroy(&tp->t_rstrt_ch);
2785 ttyldisc_release(tp->t_linesw); 2787 ttyldisc_release(tp->t_linesw);
2786 clfree(&tp->t_rawq); 2788 clfree(&tp->t_rawq);
2787 clfree(&tp->t_canq); 2789 clfree(&tp->t_canq);
2788 clfree(&tp->t_outq); 2790 clfree(&tp->t_outq);
2789 cv_destroy(&tp->t_rawcv); 2791 cv_destroy(&tp->t_rawcv);
2790 cv_destroy(&tp->t_rawcvf); 2792 cv_destroy(&tp->t_rawcvf);
2791 cv_destroy(&tp->t_cancv); 2793 cv_destroy(&tp->t_cancv);
2792 cv_destroy(&tp->t_cancvf); 2794 cv_destroy(&tp->t_cancvf);
2793 cv_destroy(&tp->t_outcv); 2795 cv_destroy(&tp->t_outcv);
2794 cv_destroy(&tp->t_outcvf); 2796 cv_destroy(&tp->t_outcvf);
2795 seldestroy(&tp->t_rsel); 2797 seldestroy(&tp->t_rsel);
2796 seldestroy(&tp->t_wsel); 2798 seldestroy(&tp->t_wsel);
2797 kmem_free(tp, sizeof(*tp)); 2799 kmem_free(tp, sizeof(*tp));
2798} 2800}
2799 2801
2800/* 2802/*
2801 * ttyprintf_nolock: send a message to a specific tty, without locking. 2803 * ttyprintf_nolock: send a message to a specific tty, without locking.
2802 * 2804 *
2803 * => should be used only by tty driver or anything that knows the 2805 * => should be used only by tty driver or anything that knows the
2804 * underlying tty will not be revoked(2)'d away. [otherwise, 2806 * underlying tty will not be revoked(2)'d away. [otherwise,
2805 * use tprintf] 2807 * use tprintf]
2806 */ 2808 */
2807static void 2809static void
2808ttyprintf_nolock(struct tty *tp, const char *fmt, ...) 2810ttyprintf_nolock(struct tty *tp, const char *fmt, ...)
2809{ 2811{
2810 va_list ap; 2812 va_list ap;
2811 2813
2812 /* No mutex needed; going to process TTY. */ 2814 /* No mutex needed; going to process TTY. */
2813 va_start(ap, fmt); 2815 va_start(ap, fmt);
2814 kprintf(fmt, TOTTY|NOLOCK, tp, NULL, ap); 2816 kprintf(fmt, TOTTY|NOLOCK, tp, NULL, ap);
2815 va_end(ap); 2817 va_end(ap);
2816} 2818}
2817 2819
2818static int 2820static int
2819tty_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 2821tty_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
2820 void *arg0, void *arg1, void *arg2, void *arg3) 2822 void *arg0, void *arg1, void *arg2, void *arg3)
2821{ 2823{
2822 struct tty *tty; 2824 struct tty *tty;
2823 int result; 2825 int result;
2824 2826
2825 result = KAUTH_RESULT_DEFER; 2827 result = KAUTH_RESULT_DEFER;
2826 2828
2827 if (action != KAUTH_DEVICE_TTY_OPEN) 2829 if (action != KAUTH_DEVICE_TTY_OPEN)
2828 return result; 2830 return result;
2829 2831
2830 tty = arg0; 2832 tty = arg0;
2831 2833
2832 /* If it's not opened, we allow. */ 2834 /* If it's not opened, we allow. */
2833 if ((tty->t_state & TS_ISOPEN) == 0) 2835 if ((tty->t_state & TS_ISOPEN) == 0)
2834 result = KAUTH_RESULT_ALLOW; 2836 result = KAUTH_RESULT_ALLOW;
2835 else { 2837 else {
2836 /* 2838 /*
2837 * If it's opened, we can only allow if it's not exclusively 2839 * If it's opened, we can only allow if it's not exclusively
2838 * opened; otherwise, that's a privileged operation and we 2840 * opened; otherwise, that's a privileged operation and we
2839 * let the secmodel handle it. 2841 * let the secmodel handle it.
2840 */ 2842 */
2841 if ((tty->t_state & TS_XCLUDE) == 0) 2843 if ((tty->t_state & TS_XCLUDE) == 0)
2842 result = KAUTH_RESULT_ALLOW; 2844 result = KAUTH_RESULT_ALLOW;
2843 } 2845 }
2844 2846
2845 return result; 2847 return result;
2846} 2848}
2847 2849
2848/* 2850/*
2849 * Initialize the tty subsystem. 2851 * Initialize the tty subsystem.
2850 */ 2852 */
2851void 2853void
2852tty_init(void) 2854tty_init(void)
2853{ 2855{
2854 2856
2855 mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_VM); 2857 mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_VM);
2856 rw_init(&ttcompat_lock); 2858 rw_init(&ttcompat_lock);
2857 tty_sigsih = softint_establish(SOFTINT_CLOCK, ttysigintr, NULL); 2859 tty_sigsih = softint_establish(SOFTINT_CLOCK, ttysigintr, NULL);
2858 KASSERT(tty_sigsih != NULL); 2860 KASSERT(tty_sigsih != NULL);
2859 2861
2860 tty_listener = kauth_listen_scope(KAUTH_SCOPE_DEVICE, 2862 tty_listener = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
2861 tty_listener_cb, NULL); 2863 tty_listener_cb, NULL);
2862 2864
2863 sysctl_kern_tty_setup(); 2865 sysctl_kern_tty_setup();
2864} 2866}
2865 2867
2866/* 2868/*
2867 * Send a signal from a tty to its process group or session leader. 2869 * Send a signal from a tty to its process group or session leader.
2868 * Handoff to the target is deferred to a soft interrupt. 2870 * Handoff to the target is deferred to a soft interrupt.
2869 */ 2871 */
2870void 2872void
2871ttysig(struct tty *tp, enum ttysigtype st, int sig) 2873ttysig(struct tty *tp, enum ttysigtype st, int sig)
2872{ 2874{
2873 sigset_t *sp; 2875 sigset_t *sp;
2874 2876
2875 /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */ 2877 /* XXXSMP not yet KASSERT(mutex_owned(&tty_lock)); */
2876 2878
2877 sp = &tp->t_sigs[st]; 2879 sp = &tp->t_sigs[st];
2878 if (sigismember(sp, sig)) 2880 if (sigismember(sp, sig))
2879 return; 2881 return;
2880 sigaddset(sp, sig); 2882 sigaddset(sp, sig);
2881 if (tp->t_sigcount++ == 0) 2883 if (tp->t_sigcount++ == 0)
2882 TAILQ_INSERT_TAIL(&tty_sigqueue, tp, t_sigqueue); 2884 TAILQ_INSERT_TAIL(&tty_sigqueue, tp, t_sigqueue);
2883 softint_schedule(tty_sigsih); 2885 softint_schedule(tty_sigsih);
2884} 2886}
2885 2887
2886/* 2888/*
2887 * Deliver deferred signals from ttys. Note that the process groups 2889 * Deliver deferred signals from ttys. Note that the process groups
2888 * and sessions associated with the ttys may have changed from when 2890 * and sessions associated with the ttys may have changed from when
2889 * the signal was originally sent, but in practice it should not matter. 2891 * the signal was originally sent, but in practice it should not matter.
2890 * For signals produced as a result of a syscall, the soft interrupt 2892 * For signals produced as a result of a syscall, the soft interrupt
2891 * will fire before the syscall returns to the user. 2893 * will fire before the syscall returns to the user.
2892 */ 2894 */
2893static void 2895static void
2894ttysigintr(void *cookie) 2896ttysigintr(void *cookie)
2895{ 2897{
2896 struct tty *tp; 2898 struct tty *tp;
2897 enum ttysigtype st; 2899 enum ttysigtype st;
2898 struct pgrp *pgrp; 2900 struct pgrp *pgrp;
2899 struct session *sess; 2901 struct session *sess;
2900 int sig, lflag; 2902 int sig, lflag;
2901 char infobuf[200]; 2903 char infobuf[200];
2902 2904
2903 mutex_enter(proc_lock); 2905 mutex_enter(proc_lock);
2904 mutex_spin_enter(&tty_lock); 2906 mutex_spin_enter(&tty_lock);
2905 while ((tp = TAILQ_FIRST(&tty_sigqueue)) != NULL) { 2907 while ((tp = TAILQ_FIRST(&tty_sigqueue)) != NULL) {
2906 KASSERT(tp->t_sigcount > 0); 2908 KASSERT(tp->t_sigcount > 0);
2907 for (st = 0; st < TTYSIG_COUNT; st++) { 2909 for (st = 0; st < TTYSIG_COUNT; st++) {
2908 if ((sig = firstsig(&tp->t_sigs[st])) != 0) 2910 if ((sig = firstsig(&tp->t_sigs[st])) != 0)
2909 break; 2911 break;
2910 } 2912 }
2911 KASSERT(st < TTYSIG_COUNT); 2913 KASSERT(st < TTYSIG_COUNT);
2912 sigdelset(&tp->t_sigs[st], sig); 2914 sigdelset(&tp->t_sigs[st], sig);
2913 if (--tp->t_sigcount == 0) 2915 if (--tp->t_sigcount == 0)
2914 TAILQ_REMOVE(&tty_sigqueue, tp, t_sigqueue); 2916 TAILQ_REMOVE(&tty_sigqueue, tp, t_sigqueue);
2915 pgrp = tp->t_pgrp; 2917 pgrp = tp->t_pgrp;
2916 sess = tp->t_session; 2918 sess = tp->t_session;
2917 lflag = tp->t_lflag; 2919 lflag = tp->t_lflag;
2918 if (sig == SIGINFO) { 2920 if (sig == SIGINFO) {
2919 if (ISSET(tp->t_state, TS_SIGINFO)) { 2921 if (ISSET(tp->t_state, TS_SIGINFO)) {
2920 /* Via ioctl: ignore tty option. */ 2922 /* Via ioctl: ignore tty option. */
2921 tp->t_state &= ~TS_SIGINFO; 2923 tp->t_state &= ~TS_SIGINFO;
2922 lflag |= ISIG; 2924 lflag |= ISIG;
2923 } 2925 }
2924 if (!ISSET(lflag, NOKERNINFO)) { 2926 if (!ISSET(lflag, NOKERNINFO)) {
2925 mutex_spin_exit(&tty_lock); 2927 mutex_spin_exit(&tty_lock);
2926 ttygetinfo(tp, 1, infobuf, sizeof(infobuf)); 2928 ttygetinfo(tp, 1, infobuf, sizeof(infobuf));
2927 mutex_spin_enter(&tty_lock); 2929 mutex_spin_enter(&tty_lock);
2928 ttyputinfo(tp, infobuf); 2930 ttyputinfo(tp, infobuf);
2929 } 2931 }
2930 if (!ISSET(lflag, ISIG)) 2932 if (!ISSET(lflag, ISIG))
2931 continue; 2933 continue;
2932 } 2934 }
2933 mutex_spin_exit(&tty_lock); 2935 mutex_spin_exit(&tty_lock);
2934 KASSERT(sig != 0); 2936 KASSERT(sig != 0);
2935 switch (st) { 2937 switch (st) {
2936 case TTYSIG_PG1: 2938 case TTYSIG_PG1:
2937 if (pgrp != NULL) 2939 if (pgrp != NULL)
2938 pgsignal(pgrp, sig, 1); 2940 pgsignal(pgrp, sig, 1);
2939 break; 2941 break;
2940 case TTYSIG_PG2: 2942 case TTYSIG_PG2:
2941 if (pgrp != NULL) 2943 if (pgrp != NULL)
2942 pgsignal(pgrp, sig, sess != NULL); 2944 pgsignal(pgrp, sig, sess != NULL);
2943 break; 2945 break;
2944 case TTYSIG_LEADER: 2946 case TTYSIG_LEADER:
2945 if (sess != NULL && sess->s_leader != NULL) 2947 if (sess != NULL && sess->s_leader != NULL)
2946 psignal(sess->s_leader, sig); 2948 psignal(sess->s_leader, sig);
2947 break; 2949 break;
2948 default: 2950 default:
2949 /* NOTREACHED */ 2951 /* NOTREACHED */
2950 break; 2952 break;
2951 } 2953 }
2952 mutex_spin_enter(&tty_lock); 2954 mutex_spin_enter(&tty_lock);
2953 } 2955 }
2954 mutex_spin_exit(&tty_lock); 2956 mutex_spin_exit(&tty_lock);
2955 mutex_exit(proc_lock); 2957 mutex_exit(proc_lock);
2956} 2958}