xref: /openbsd/sys/kern/tty.c (revision b9ae17a0)
1 /*	$OpenBSD: tty.c,v 1.178 2024/12/30 02:46:00 guenther Exp $	*/
2 /*	$NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $	*/
3 
4 /*-
5  * Copyright (c) 1982, 1986, 1990, 1991, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  * (c) UNIX System Laboratories, Inc.
8  * All or some portions of this file are derived from material licensed
9  * to the University of California by American Telephone and Telegraph
10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11  * the permission of UNIX System Laboratories, Inc.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *	@(#)tty.c	8.8 (Berkeley) 1/21/94
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/ioctl.h>
43 #include <sys/proc.h>
44 #define	TTYDEFCHARS
45 #include <sys/tty.h>
46 #undef	TTYDEFCHARS
47 #include <sys/fcntl.h>
48 #include <sys/conf.h>
49 #include <sys/uio.h>
50 #include <sys/kernel.h>
51 #include <sys/vnode.h>
52 #include <sys/lock.h>
53 #include <sys/malloc.h>
54 #include <sys/msgbuf.h>
55 #include <sys/signalvar.h>
56 #include <sys/resourcevar.h>
57 #include <sys/sysctl.h>
58 #include <sys/pool.h>
59 #include <sys/unistd.h>
60 #include <sys/pledge.h>
61 
62 #include <sys/namei.h>
63 
64 #include <uvm/uvm_extern.h>
65 
66 #include <dev/cons.h>
67 
68 #include "pty.h"
69 
70 static int ttnread(struct tty *);
71 static void ttyblock(struct tty *);
72 void ttyunblock(struct tty *);
73 static void ttyecho(int, struct tty *);
74 static void ttyrubo(struct tty *, int);
75 int	filt_ttyread(struct knote *kn, long hint);
76 void 	filt_ttyrdetach(struct knote *kn);
77 int	filt_ttywrite(struct knote *kn, long hint);
78 void 	filt_ttywdetach(struct knote *kn);
79 int	filt_ttyexcept(struct knote *kn, long hint);
80 void	ttystats_init(struct itty **, int *, size_t *);
81 int	ttywait_nsec(struct tty *, uint64_t);
82 int	ttysleep_nsec(struct tty *, void *, int, char *, uint64_t);
83 
84 /* Symbolic sleep message strings. */
85 char ttclos[]	= "ttycls";
86 char ttopen[]	= "ttyopn";
87 char ttybg[]	= "ttybg";
88 char ttyin[]	= "ttyin";
89 char ttyout[]	= "ttyout";
90 
91 /*
92  * Table with character classes and parity. The 8th bit indicates parity,
93  * the 7th bit indicates the character is an alphameric or underscore (for
94  * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
95  * are 0 then the character needs no special processing on output; classes
96  * other than 0 might be translated or (not currently) require delays.
97  */
98 #define	E	0x00	/* Even parity. */
99 #define	O	0x80	/* Odd parity. */
100 #define	PARITY(c)	(char_type[c] & O)
101 
102 #define	ALPHA	0x40	/* Alpha or underscore. */
103 #define	ISALPHA(c)	(char_type[(c) & TTY_CHARMASK] & ALPHA)
104 
105 #define	CCLASSMASK	0x3f
106 #define	CCLASS(c)	(char_type[c] & CCLASSMASK)
107 
108 #define	BS	BACKSPACE
109 #define	CC	CONTROL
110 #define	CR	RETURN
111 #define	NA	ORDINARY | ALPHA
112 #define	NL	NEWLINE
113 #define	NO	ORDINARY
114 #define	TB	TAB
115 #define	VT	VTAB
116 
117 u_char const char_type[] = {
118 	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC,	/* nul - bel */
119 	O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
120 	O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
121 	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
122 	O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
123 	E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
124 	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
125 	O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
126 	O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
127 	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
128 	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
129 	O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
130 	E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
131 	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
132 	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
133 	E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
134 	/*
135 	 * Meta chars; should be settable per character set;
136 	 * for now, treat them all as normal characters.
137 	 */
138 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
139 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
140 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
141 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
142 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
143 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
144 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
145 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
146 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
147 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
148 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
149 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
150 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
151 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
152 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
153 	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
154 };
155 #undef	BS
156 #undef	CC
157 #undef	CR
158 #undef	NA
159 #undef	NL
160 #undef	NO
161 #undef	TB
162 #undef	VT
163 
164 #define	islower(c)	((c) >= 'a' && (c) <= 'z')
165 #define	isupper(c)	((c) >= 'A' && (c) <= 'Z')
166 
167 #define	tolower(c)	((c) - 'A' + 'a')
168 #define	toupper(c)	((c) - 'a' + 'A')
169 
170 struct ttylist_head ttylist;	/* TAILQ_HEAD */
171 int tty_count;
172 struct rwlock ttylist_lock = RWLOCK_INITIALIZER("ttylist");
173 
174 int64_t tk_cancc, tk_nin, tk_nout, tk_rawcc;
175 
176 /*
177  * Initial open of tty, or (re)entry to standard tty line discipline.
178  */
179 int
ttyopen(dev_t device,struct tty * tp,struct proc * p)180 ttyopen(dev_t device, struct tty *tp, struct proc *p)
181 {
182 	int s;
183 
184 	s = spltty();
185 	tp->t_dev = device;
186 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
187 		SET(tp->t_state, TS_ISOPEN);
188 		memset(&tp->t_winsize, 0, sizeof(tp->t_winsize));
189 		tp->t_column = 0;
190 	}
191 	CLR(tp->t_state, TS_WOPEN);
192 	splx(s);
193 	return (0);
194 }
195 
196 /*
197  * Handle close() on a tty line: flush and set to initial state,
198  * bumping generation number so that pending read/write calls
199  * can detect recycling of the tty.
200  */
201 int
ttyclose(struct tty * tp)202 ttyclose(struct tty *tp)
203 {
204 	if (constty == tp)
205 		constty = NULL;
206 
207 	ttyflush(tp, FREAD | FWRITE);
208 
209 	tp->t_gen++;
210 	tp->t_pgrp = NULL;
211 	if (tp->t_session)
212 		SESSRELE(tp->t_session);
213 	tp->t_session = NULL;
214 	tp->t_state = 0;
215 	return (0);
216 }
217 
218 #define	FLUSHQ(q) {							\
219 	if ((q)->c_cc)							\
220 		ndflush(q, (q)->c_cc);					\
221 }
222 
223 /* Is 'c' a line delimiter ("break" character)? */
224 #define	TTBREAKC(c, lflag)						\
225 	((c) == '\n' || (((c) == cc[VEOF] || (c) == cc[VEOL] ||		\
226 	((c) == cc[VEOL2] && (lflag & IEXTEN))) && (c) != _POSIX_VDISABLE))
227 
228 
229 /*
230  * Process input of a single character received on a tty.  Returns 0 normally,
231  * 1 if a costly operation was reached.
232  */
233 int
ttyinput(int c,struct tty * tp)234 ttyinput(int c, struct tty *tp)
235 {
236 	int iflag, lflag;
237 	u_char *cc;
238 	int i, error, ret = 0;
239 	int s;
240 
241 	enqueue_randomness(tp->t_dev << 8 | c);
242 	/*
243 	 * If receiver is not enabled, drop it.
244 	 */
245 	if (!ISSET(tp->t_cflag, CREAD))
246 		return (0);
247 
248 	/*
249 	 * If input is pending take it first.
250 	 */
251 	lflag = tp->t_lflag;
252 	s = spltty();
253 	if (ISSET(lflag, PENDIN))
254 		ttypend(tp);
255 	splx(s);
256 	/*
257 	 * Gather stats.
258 	 */
259 	if (ISSET(lflag, ICANON)) {
260 		++tk_cancc;
261 		++tp->t_cancc;
262 	} else {
263 		++tk_rawcc;
264 		++tp->t_rawcc;
265 	}
266 	++tk_nin;
267 
268 	/* Handle exceptional conditions (break, parity, framing). */
269 	cc = tp->t_cc;
270 	iflag = tp->t_iflag;
271 	if ((error = (ISSET(c, TTY_ERRORMASK))) != 0) {
272 		CLR(c, TTY_ERRORMASK);
273 		if (ISSET(error, TTY_FE) && !c) {	/* Break. */
274 			if (ISSET(iflag, IGNBRK))
275 				return (0);
276 			ttyflush(tp, FREAD | FWRITE);
277 			if (ISSET(iflag, BRKINT)) {
278 			    pgsignal(tp->t_pgrp, SIGINT, 1);
279 			    goto endcase;
280 			}
281 			else if (ISSET(iflag, PARMRK))
282 				goto parmrk;
283 		} else if ((ISSET(error, TTY_PE) && ISSET(iflag, INPCK)) ||
284 		    ISSET(error, TTY_FE)) {
285 			if (ISSET(iflag, IGNPAR))
286 				goto endcase;
287 			else if (ISSET(iflag, PARMRK)) {
288 parmrk:				(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
289 				if (ISSET(iflag, ISTRIP) || c != 0377)
290 					(void)putc(0 | TTY_QUOTE, &tp->t_rawq);
291 				(void)putc(c | TTY_QUOTE, &tp->t_rawq);
292 				goto endcase;
293 			} else
294 				c = 0;
295 		}
296 	}
297 	if (c == 0377 && !ISSET(iflag, ISTRIP) && ISSET(iflag, PARMRK))
298 		goto parmrk;
299 
300 	/*
301 	 * In tandem mode, check high water mark.
302 	 */
303 	if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW))
304 		ttyblock(tp);
305 	if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
306 		CLR(c, 0x80);
307 	if (!ISSET(lflag, EXTPROC)) {
308 		/*
309 		 * Check for literal nexting very first
310 		 */
311 		if (ISSET(tp->t_state, TS_LNCH)) {
312 			SET(c, TTY_QUOTE);
313 			CLR(tp->t_state, TS_LNCH);
314 		}
315 		/*
316 		 * Scan for special characters.  This code
317 		 * is really just a big case statement with
318 		 * non-constant cases.  The bottom of the
319 		 * case statement is labeled ``endcase'', so goto
320 		 * it after a case match, or similar.
321 		 */
322 
323 		/*
324 		 * Control chars which aren't controlled
325 		 * by ICANON, ISIG, or IXON.
326 		 */
327 		if (ISSET(lflag, IEXTEN)) {
328 			if (CCEQ(cc[VLNEXT], c)) {
329 				if (ISSET(lflag, ECHO)) {
330 					if (ISSET(lflag, ECHOE)) {
331 						(void)ttyoutput('^', tp);
332 						(void)ttyoutput('\b', tp);
333 					} else
334 						ttyecho(c, tp);
335 				}
336 				SET(tp->t_state, TS_LNCH);
337 				goto endcase;
338 			}
339 			if (CCEQ(cc[VDISCARD], c)) {
340 				if (ISSET(lflag, FLUSHO))
341 					CLR(tp->t_lflag, FLUSHO);
342 				else {
343 					ttyflush(tp, FWRITE);
344 					ttyecho(c, tp);
345 					if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
346 						ret = ttyretype(tp);
347 					SET(tp->t_lflag, FLUSHO);
348 				}
349 				goto startoutput;
350 			}
351 		}
352 		/*
353 		 * Signals.
354 		 */
355 		if (ISSET(lflag, ISIG)) {
356 			if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
357 				if (!ISSET(lflag, NOFLSH))
358 					ttyflush(tp, FREAD | FWRITE);
359 				ttyecho(c, tp);
360 				pgsignal(tp->t_pgrp,
361 				    CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
362 				goto endcase;
363 			}
364 			if (CCEQ(cc[VSUSP], c)) {
365 				if (!ISSET(lflag, NOFLSH))
366 					ttyflush(tp, FREAD);
367 				ttyecho(c, tp);
368 				pgsignal(tp->t_pgrp, SIGTSTP, 1);
369 				goto endcase;
370 			}
371 		}
372 		/*
373 		 * Handle start/stop characters.
374 		 */
375 		if (ISSET(iflag, IXON)) {
376 			if (CCEQ(cc[VSTOP], c)) {
377 				if (!ISSET(tp->t_state, TS_TTSTOP)) {
378 					SET(tp->t_state, TS_TTSTOP);
379 					(*cdevsw[major(tp->t_dev)].d_stop)(tp,
380 					   0);
381 					return (0);
382 				}
383 				if (!CCEQ(cc[VSTART], c))
384 					return (0);
385 				/*
386 				 * if VSTART == VSTOP then toggle
387 				 */
388 				goto endcase;
389 			}
390 			if (CCEQ(cc[VSTART], c))
391 				goto restartoutput;
392 		}
393 		/*
394 		 * IGNCR, ICRNL, & INLCR
395 		 */
396 		if (c == '\r') {
397 			if (ISSET(iflag, IGNCR))
398 				goto endcase;
399 			else if (ISSET(iflag, ICRNL))
400 				c = '\n';
401 		} else if (c == '\n' && ISSET(iflag, INLCR))
402 			c = '\r';
403 	}
404 	if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
405 		/*
406 		 * From here on down canonical mode character
407 		 * processing takes place.
408 		 */
409 		/*
410 		 * upper case or specials with IUCLC and XCASE
411 		 */
412 		if (ISSET(lflag, XCASE) && ISSET(iflag, IUCLC)) {
413 			if (ISSET(tp->t_state, TS_BKSL)) {
414 				CLR(tp->t_state, TS_BKSL);
415 				switch (c) {
416 				case '\'':
417 					c = '`';
418 					break;
419 				case '!':
420 					c = '|';
421 					break;
422 				case '^':
423 					c = '~';
424 					break;
425 				case '(':
426 					c = '{';
427 					break;
428 				case ')':
429 					c = '}';
430 					break;
431 				}
432 			}
433 			else if (c == '\\') {
434 				SET(tp->t_state, TS_BKSL);
435 				goto endcase;
436 			}
437 			else if (isupper(c))
438 				c = tolower(c);
439 		}
440 		else if (ISSET(iflag, IUCLC) && isupper(c))
441 			c = tolower(c);
442 		/*
443 		 * erase (^H / ^?)
444 		 */
445 		if (CCEQ(cc[VERASE], c)) {
446 			if (tp->t_rawq.c_cc)
447 				ret = ttyrub(unputc(&tp->t_rawq), tp);
448 			goto endcase;
449 		}
450 		/*
451 		 * kill (^U)
452 		 */
453 		if (CCEQ(cc[VKILL], c)) {
454 			if (ISSET(lflag, ECHOKE) &&
455 			    tp->t_rawq.c_cc == tp->t_rocount &&
456 			    !ISSET(lflag, ECHOPRT)) {
457 				while (tp->t_rawq.c_cc)
458 					if (ttyrub(unputc(&tp->t_rawq), tp))
459 						ret = 1;
460 			} else {
461 				ttyecho(c, tp);
462 				if (ISSET(lflag, ECHOK) ||
463 				    ISSET(lflag, ECHOKE))
464 					ttyecho('\n', tp);
465 				FLUSHQ(&tp->t_rawq);
466 				tp->t_rocount = 0;
467 			}
468 			CLR(tp->t_state, TS_LOCAL);
469 			goto endcase;
470 		}
471 		/*
472 		 * word erase (^W)
473 		 */
474 		if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
475 			int alt = ISSET(lflag, ALTWERASE);
476 			int ctype;
477 
478 			/*
479 			 * erase whitespace
480 			 */
481 			while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
482 				if (ttyrub(c, tp))
483 					ret = 1;
484 			if (c == -1)
485 				goto endcase;
486 			/*
487 			 * erase last char of word and remember the
488 			 * next chars type (for ALTWERASE)
489 			 */
490 			if (ttyrub(c, tp))
491 				ret = 1;
492 			c = unputc(&tp->t_rawq);
493 			if (c == -1)
494 				goto endcase;
495 			if (c == ' ' || c == '\t') {
496 				(void)putc(c, &tp->t_rawq);
497 				goto endcase;
498 			}
499 			ctype = ISALPHA(c);
500 			/*
501 			 * erase rest of word
502 			 */
503 			do {
504 				if (ttyrub(c, tp))
505 					ret = 1;
506 				c = unputc(&tp->t_rawq);
507 				if (c == -1)
508 					goto endcase;
509 			} while (c != ' ' && c != '\t' &&
510 			    (alt == 0 || ISALPHA(c) == ctype));
511 			(void)putc(c, &tp->t_rawq);
512 			goto endcase;
513 		}
514 		/*
515 		 * reprint line (^R)
516 		 */
517 		if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
518 			ret = ttyretype(tp);
519 			goto endcase;
520 		}
521 		/*
522 		 * ^T - kernel info and generate SIGINFO
523 		 */
524 		if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
525 			if (ISSET(lflag, ISIG))
526 				pgsignal(tp->t_pgrp, SIGINFO, 1);
527 			if (!ISSET(lflag, NOKERNINFO))
528 				ttyinfo(tp);
529 			goto endcase;
530 		}
531 	}
532 	/*
533 	 * Check for input buffer overflow
534 	 */
535 	if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG(tp)) {
536 		if (ISSET(iflag, IMAXBEL)) {
537 			if (tp->t_outq.c_cc < tp->t_hiwat)
538 				(void)ttyoutput(CTRL('g'), tp);
539 		} else
540 			ttyflush(tp, FREAD | FWRITE);
541 		goto endcase;
542 	}
543 	/*
544 	 * Put data char in q for user and
545 	 * wakeup on seeing a line delimiter.
546 	 */
547 	if (putc(c, &tp->t_rawq) >= 0) {
548 		if (!ISSET(lflag, ICANON)) {
549 			ttwakeup(tp);
550 			ttyecho(c, tp);
551 			goto endcase;
552 		}
553 		if (TTBREAKC(c, lflag)) {
554 			tp->t_rocount = 0;
555 			catq(&tp->t_rawq, &tp->t_canq);
556 			ttwakeup(tp);
557 		} else if (tp->t_rocount++ == 0)
558 			tp->t_rocol = tp->t_column;
559 		if (ISSET(tp->t_state, TS_ERASE)) {
560 			/*
561 			 * end of prterase \.../
562 			 */
563 			CLR(tp->t_state, TS_ERASE);
564 			(void)ttyoutput('/', tp);
565 		}
566 		i = tp->t_column;
567 		ttyecho(c, tp);
568 		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
569 			/*
570 			 * Place the cursor over the '^' of the ^D.
571 			 */
572 			i = min(2, tp->t_column - i);
573 			while (i > 0) {
574 				(void)ttyoutput('\b', tp);
575 				i--;
576 			}
577 		}
578 	}
579 endcase:
580 	/*
581 	 * IXANY means allow any character to restart output.
582 	 */
583 	if (ISSET(tp->t_state, TS_TTSTOP) &&
584 	    !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
585 		return (ret);
586 restartoutput:
587 	CLR(tp->t_lflag, FLUSHO);
588 	CLR(tp->t_state, TS_TTSTOP);
589 startoutput:
590 	ttstart(tp);
591 	return (ret);
592 }
593 
594 /*
595  * Output a single character on a tty, doing output processing
596  * as needed (expanding tabs, newline processing, etc.).
597  * Returns < 0 if succeeds, otherwise returns char to resend.
598  * Must be recursive.
599  */
600 int
ttyoutput(int c,struct tty * tp)601 ttyoutput(int c, struct tty *tp)
602 {
603 	long oflag;
604 	int col, notout, s, c2;
605 
606 	oflag = tp->t_oflag;
607 	if (!ISSET(oflag, OPOST)) {
608 		tk_nout++;
609 		tp->t_outcc++;
610 		if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
611 			return (c);
612 		return (-1);
613 	}
614 	/*
615 	 * Do tab expansion if OXTABS is set.  Special case if we external
616 	 * processing, we don't do the tab expansion because we'll probably
617 	 * get it wrong.  If tab expansion needs to be done, let it happen
618 	 * externally.
619 	 */
620 	CLR(c, ~TTY_CHARMASK);
621 	if (c == '\t' &&
622 	    ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
623 		c = 8 - (tp->t_column & 7);
624 		if (ISSET(tp->t_lflag, FLUSHO)) {
625 			notout = 0;
626 		} else {
627 			s = spltty();		/* Don't interrupt tabs. */
628 			notout = b_to_q("        ", c, &tp->t_outq);
629 			c -= notout;
630 			tk_nout += c;
631 			tp->t_outcc += c;
632 			splx(s);
633 		}
634 		tp->t_column += c;
635 		return (notout ? '\t' : -1);
636 	}
637 	if (c == CEOT && ISSET(oflag, ONOEOT))
638 		return (-1);
639 
640 	/*
641 	 * Newline translation: if ONLCR is set,
642 	 * translate newline into "\r\n".  If OCRNL
643 	 * is set, translate '\r' into '\n'.
644 	 */
645 	if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
646 		tk_nout++;
647 		tp->t_outcc++;
648 		if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
649 			return (c);
650 		tp->t_column = 0;
651 	}
652 	else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
653 		c = '\n';
654 
655 	if (ISSET(tp->t_oflag, OLCUC) && islower(c))
656 		c = toupper(c);
657 	else if (ISSET(tp->t_oflag, OLCUC) && ISSET(tp->t_lflag, XCASE)) {
658 		c2 = c;
659 		switch (c) {
660 		case '`':
661 			c2 = '\'';
662 			break;
663 		case '|':
664 			c2 = '!';
665 			break;
666 		case '~':
667 			c2 = '^';
668 			break;
669 		case '{':
670 			c2 = '(';
671 			break;
672 		case '}':
673 			c2 = ')';
674 			break;
675 		}
676 		if (c == '\\' || isupper(c) || c != c2) {
677 			tk_nout++;
678 			tp->t_outcc++;
679 			if (putc('\\', &tp->t_outq))
680 				return (c);
681 			c = c2;
682 		}
683 	}
684 	if (ISSET(tp->t_oflag, ONOCR) && c == '\r' && tp->t_column == 0)
685 		return (-1);
686 
687 	tk_nout++;
688 	tp->t_outcc++;
689 	if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
690 		return (c);
691 
692 	col = tp->t_column;
693 	switch (CCLASS(c)) {
694 	case BACKSPACE:
695 		if (col > 0)
696 			--col;
697 		break;
698 	case CONTROL:
699 		break;
700 	case NEWLINE:
701 		if (ISSET(tp->t_oflag, ONLRET) || ISSET(tp->t_oflag, OCRNL))
702 			col = 0;
703 		break;
704 	case RETURN:
705 		col = 0;
706 		break;
707 	case ORDINARY:
708 		++col;
709 		break;
710 	case TAB:
711 		col = (col + 8) & ~7;
712 		break;
713 	}
714 	tp->t_column = col;
715 	return (-1);
716 }
717 
718 /*
719  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
720  * has been called to do discipline-specific functions and/or reject any
721  * of these ioctl commands.
722  */
723 int
ttioctl(struct tty * tp,u_long cmd,caddr_t data,int flag,struct proc * p)724 ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
725 {
726 	extern int nlinesw;
727 	struct process *pr = p->p_p;
728 	int s, error;
729 
730 	/* If the ioctl involves modification, hang if in the background. */
731 	switch (cmd) {
732 	case  FIOSETOWN:
733 	case  TIOCFLUSH:
734 	case  TIOCDRAIN:
735 	case  TIOCSBRK:
736 	case  TIOCCBRK:
737 	case  TIOCSETA:
738 	case  TIOCSETD:
739 	case  TIOCSETAF:
740 	case  TIOCSETAW:
741 	case  TIOCSPGRP:
742 	case  TIOCSTAT:
743 	case  TIOCSWINSZ:
744 		while (isbackground(pr, tp) &&
745 		    (pr->ps_flags & PS_PPWAIT) == 0 &&
746 		    !sigismasked(p, SIGTTOU)) {
747 			if (pr->ps_pgrp->pg_jobc == 0)
748 				return (EIO);
749 			pgsignal(pr->ps_pgrp, SIGTTOU, 1);
750 			error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
751 			    ttybg);
752 			if (error)
753 				return (error);
754 		}
755 		break;
756 	}
757 
758 	switch (cmd) {			/* Process the ioctl. */
759 	case FIOASYNC:			/* set/clear async i/o */
760 		s = spltty();
761 		if (*(int *)data)
762 			SET(tp->t_state, TS_ASYNC);
763 		else
764 			CLR(tp->t_state, TS_ASYNC);
765 		splx(s);
766 		break;
767 	case FIONREAD:			/* get # bytes to read */
768 		s = spltty();
769 		*(int *)data = ttnread(tp);
770 		splx(s);
771 		break;
772 	case TIOCEXCL:			/* set exclusive use of tty */
773 		s = spltty();
774 		SET(tp->t_state, TS_XCLUDE);
775 		splx(s);
776 		break;
777 	case TIOCFLUSH: {		/* flush buffers */
778 		int flags = *(int *)data;
779 
780 		if (flags == 0)
781 			flags = FREAD | FWRITE;
782 		else
783 			flags &= FREAD | FWRITE;
784 		ttyflush(tp, flags);
785 		break;
786 	}
787 	case TIOCCONS: {		/* become virtual console */
788 		if (*(int *)data) {
789 			struct nameidata nid;
790 
791 			if (constty != NULL && constty != tp &&
792 			    ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
793 			    (TS_CARR_ON | TS_ISOPEN))
794 				return (EBUSY);
795 
796 			/* ensure user can open the real console */
797 			NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
798 			nid.ni_pledge = PLEDGE_RPATH | PLEDGE_WPATH;
799 			nid.ni_unveil = UNVEIL_READ | UNVEIL_WRITE;
800 			error = namei(&nid);
801 			if (error)
802 				return (error);
803 			vn_lock(nid.ni_vp, LK_EXCLUSIVE | LK_RETRY);
804 			error = VOP_ACCESS(nid.ni_vp, VREAD, p->p_ucred, p);
805 			VOP_UNLOCK(nid.ni_vp);
806 			vrele(nid.ni_vp);
807 			if (error)
808 				return (error);
809 
810 			constty = tp;
811 		} else if (tp == constty)
812 			constty = NULL;
813 		break;
814 	}
815 	case TIOCDRAIN:			/* wait till output drained */
816 		if ((error = ttywait(tp)) != 0)
817 			return (error);
818 		break;
819 	case TIOCGETA: {		/* get termios struct */
820 		struct termios *t = (struct termios *)data;
821 
822 		memcpy(t, &tp->t_termios, sizeof(struct termios));
823 		break;
824 	}
825 	case TIOCGETD:			/* get line discipline */
826 		*(int *)data = tp->t_line;
827 		break;
828 	case TIOCGWINSZ:		/* get window size */
829 		*(struct winsize *)data = tp->t_winsize;
830 		break;
831 	case TIOCGTSTAMP:
832 		s = spltty();
833 		*(struct timeval *)data = tp->t_tv;
834 		splx(s);
835 		break;
836 	case FIOGETOWN:			/* get pgrp of tty */
837 		if (!isctty(pr, tp) && suser(p))
838 			return (ENOTTY);
839 		*(int *)data = tp->t_pgrp ? -tp->t_pgrp->pg_id : 0;
840 		break;
841 	case TIOCGPGRP:			/* get pgrp of tty */
842 		if (!isctty(pr, tp) && suser(p))
843 			return (ENOTTY);
844 		*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
845 		break;
846 	case TIOCGSID:			/* get sid of tty */
847 		if (!isctty(pr, tp))
848 			return (ENOTTY);
849 		*(int *)data = tp->t_session->s_leader->ps_pid;
850 		break;
851 	case TIOCNXCL:			/* reset exclusive use of tty */
852 		s = spltty();
853 		CLR(tp->t_state, TS_XCLUDE);
854 		splx(s);
855 		break;
856 	case TIOCOUTQ:			/* output queue size */
857 		*(int *)data = tp->t_outq.c_cc;
858 		break;
859 	case TIOCSETA:			/* set termios struct */
860 	case TIOCSETAW:			/* drain output, set */
861 	case TIOCSETAF: {		/* drn out, fls in, set */
862 		struct termios *t = (struct termios *)data;
863 
864 		s = spltty();
865 		if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
866 			if ((error = ttywait(tp)) != 0) {
867 				splx(s);
868 				return (error);
869 			}
870 			if (cmd == TIOCSETAF)
871 				ttyflush(tp, FREAD);
872 		}
873 		if (!ISSET(t->c_cflag, CIGNORE)) {
874 			/*
875 			 * Some minor validation is necessary.
876 			 */
877 			if (t->c_ispeed < 0 || t->c_ospeed < 0) {
878 				splx(s);
879 				return (EINVAL);
880 			}
881 			/*
882 			 * Set device hardware.
883 			 */
884 			if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
885 				splx(s);
886 				return (error);
887 			} else {
888 				if (!ISSET(tp->t_state, TS_CARR_ON) &&
889 				    ISSET(tp->t_cflag, CLOCAL) &&
890 				    !ISSET(t->c_cflag, CLOCAL)) {
891 					CLR(tp->t_state, TS_ISOPEN);
892 					SET(tp->t_state, TS_WOPEN);
893 					ttwakeup(tp);
894 				}
895 				tp->t_cflag = t->c_cflag;
896 				tp->t_ispeed = t->c_ispeed;
897 				tp->t_ospeed = t->c_ospeed;
898 				if (t->c_ospeed == 0 && tp->t_session &&
899 				    tp->t_session->s_leader)
900 					prsignal(tp->t_session->s_leader,
901 					    SIGHUP);
902 			}
903 			ttsetwater(tp);
904 		}
905 		if (cmd != TIOCSETAF) {
906 			if (ISSET(t->c_lflag, ICANON) !=
907 			    ISSET(tp->t_lflag, ICANON)) {
908 				if (ISSET(t->c_lflag, ICANON)) {
909 					SET(tp->t_lflag, PENDIN);
910 					ttwakeup(tp);
911 				} else {
912 					struct clist tq;
913 
914 					catq(&tp->t_rawq, &tp->t_canq);
915 					tq = tp->t_rawq;
916 					tp->t_rawq = tp->t_canq;
917 					tp->t_canq = tq;
918 					CLR(tp->t_lflag, PENDIN);
919 				}
920 			}
921 		}
922 		tp->t_iflag = t->c_iflag;
923 		tp->t_oflag = t->c_oflag;
924 		/*
925 		 * Make the EXTPROC bit read only.
926 		 */
927 		if (ISSET(tp->t_lflag, EXTPROC))
928 			SET(t->c_lflag, EXTPROC);
929 		else
930 			CLR(t->c_lflag, EXTPROC);
931 		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
932 		memcpy(tp->t_cc, t->c_cc, sizeof(t->c_cc));
933 		splx(s);
934 		break;
935 	}
936 	case TIOCSETD: {		/* set line discipline */
937 		int t = *(int *)data;
938 		dev_t device = tp->t_dev;
939 
940 		if ((u_int)t >= nlinesw)
941 			return (ENXIO);
942 		if (t != tp->t_line) {
943 			s = spltty();
944 			(*linesw[tp->t_line].l_close)(tp, flag, p);
945 			error = (*linesw[t].l_open)(device, tp, p);
946 			if (error) {
947 				(*linesw[tp->t_line].l_open)(device, tp, p);
948 				splx(s);
949 				return (error);
950 			}
951 			tp->t_line = t;
952 			splx(s);
953 		}
954 		break;
955 	}
956 	case TIOCSTART:			/* start output, like ^Q */
957 		s = spltty();
958 		if (ISSET(tp->t_state, TS_TTSTOP) ||
959 		    ISSET(tp->t_lflag, FLUSHO)) {
960 			CLR(tp->t_lflag, FLUSHO);
961 			CLR(tp->t_state, TS_TTSTOP);
962 			ttstart(tp);
963 		}
964 		splx(s);
965 		break;
966 	case TIOCSTOP:			/* stop output, like ^S */
967 		s = spltty();
968 		if (!ISSET(tp->t_state, TS_TTSTOP)) {
969 			SET(tp->t_state, TS_TTSTOP);
970 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
971 		}
972 		splx(s);
973 		break;
974 	case TIOCSCTTY:			/* become controlling tty */
975 		/* Session ctty vnode pointer set in vnode layer. */
976 		if (!SESS_LEADER(pr) ||
977 		    ((pr->ps_session->s_ttyvp || tp->t_session) &&
978 		     (tp->t_session != pr->ps_session)))
979 			return (EPERM);
980 		if (tp->t_session)
981 			SESSRELE(tp->t_session);
982 		SESSHOLD(pr->ps_session);
983 		tp->t_session = pr->ps_session;
984 		tp->t_pgrp = pr->ps_pgrp;
985 		pr->ps_session->s_ttyp = tp;
986 		atomic_setbits_int(&pr->ps_flags, PS_CONTROLT);
987 		break;
988 	case FIOSETOWN: {		/* set pgrp of tty */
989 		struct pgrp *pgrp;
990 		struct process *pr1;
991 		pid_t pgid = *(int *)data;
992 
993 		if (!isctty(pr, tp))
994 			return (ENOTTY);
995 		if (pgid < 0) {
996 			pgrp = pgfind(-pgid);
997 		} else {
998 			pr1 = prfind(pgid);
999 			if (pr1 == NULL)
1000 				return (ESRCH);
1001 			pgrp = pr1->ps_pgrp;
1002 		}
1003 		if (pgrp == NULL)
1004 			return (EINVAL);
1005 		else if (pgrp->pg_session != pr->ps_session)
1006 			return (EPERM);
1007 		tp->t_pgrp = pgrp;
1008 		break;
1009 	}
1010 	case TIOCSPGRP: {		/* set pgrp of tty */
1011 		struct pgrp *pgrp = pgfind(*(int *)data);
1012 
1013 		if (!isctty(pr, tp))
1014 			return (ENOTTY);
1015 		else if (pgrp == NULL)
1016 			return (EINVAL);
1017 		else if (pgrp->pg_session != pr->ps_session)
1018 			return (EPERM);
1019 		tp->t_pgrp = pgrp;
1020 		break;
1021 	}
1022 	case TIOCSTAT:			/* get load avg stats */
1023 		ttyinfo(tp);
1024 		break;
1025 	case TIOCSWINSZ:		/* set window size */
1026 		if (bcmp((caddr_t)&tp->t_winsize, data,
1027 		    sizeof (struct winsize))) {
1028 			tp->t_winsize = *(struct winsize *)data;
1029 			pgsignal(tp->t_pgrp, SIGWINCH, 1);
1030 		}
1031 		break;
1032 	case TIOCSTSTAMP: {
1033 		struct tstamps *ts = (struct tstamps *)data;
1034 
1035 		s = spltty();
1036 		CLR(tp->t_flags, TS_TSTAMPDCDSET);
1037 		CLR(tp->t_flags, TS_TSTAMPCTSSET);
1038 		CLR(tp->t_flags, TS_TSTAMPDCDCLR);
1039 		CLR(tp->t_flags, TS_TSTAMPCTSCLR);
1040 		if (ISSET(ts->ts_set, TIOCM_CAR))
1041 			SET(tp->t_flags, TS_TSTAMPDCDSET);
1042 		if (ISSET(ts->ts_set, TIOCM_CTS))
1043 			SET(tp->t_flags, TS_TSTAMPCTSSET);
1044 		if (ISSET(ts->ts_clr, TIOCM_CAR))
1045 			SET(tp->t_flags, TS_TSTAMPDCDCLR);
1046 		if (ISSET(ts->ts_clr, TIOCM_CTS))
1047 			SET(tp->t_flags, TS_TSTAMPCTSCLR);
1048 		splx(s);
1049 		break;
1050 	}
1051 	default:
1052 		return (-1);
1053 	}
1054 	return (0);
1055 }
1056 
1057 const struct filterops ttyread_filtops = {
1058 	.f_flags	= FILTEROP_ISFD,
1059 	.f_attach	= NULL,
1060 	.f_detach	= filt_ttyrdetach,
1061 	.f_event	= filt_ttyread,
1062 };
1063 
1064 const struct filterops ttywrite_filtops = {
1065 	.f_flags	= FILTEROP_ISFD,
1066 	.f_attach	= NULL,
1067 	.f_detach	= filt_ttywdetach,
1068 	.f_event	= filt_ttywrite,
1069 };
1070 
1071 const struct filterops ttyexcept_filtops = {
1072 	.f_flags	= FILTEROP_ISFD,
1073 	.f_attach	= NULL,
1074 	.f_detach	= filt_ttyrdetach,
1075 	.f_event	= filt_ttyexcept,
1076 };
1077 
1078 int
ttkqfilter(dev_t dev,struct knote * kn)1079 ttkqfilter(dev_t dev, struct knote *kn)
1080 {
1081 	struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
1082 	struct klist *klist;
1083 	int s;
1084 
1085 	switch (kn->kn_filter) {
1086 	case EVFILT_READ:
1087 		klist = &tp->t_rsel.si_note;
1088 		kn->kn_fop = &ttyread_filtops;
1089 		break;
1090 	case EVFILT_WRITE:
1091 		klist = &tp->t_wsel.si_note;
1092 		kn->kn_fop = &ttywrite_filtops;
1093 		break;
1094 	case EVFILT_EXCEPT:
1095 		if (kn->kn_flags & __EV_SELECT) {
1096 			/* Prevent triggering exceptfds. */
1097 			return (EPERM);
1098 		}
1099 		if ((kn->kn_flags & __EV_POLL) == 0) {
1100 			/* Disallow usage through kevent(2). */
1101 			return (EINVAL);
1102 		}
1103 		klist = &tp->t_rsel.si_note;
1104 		kn->kn_fop = &ttyexcept_filtops;
1105 		break;
1106 	default:
1107 		return (EINVAL);
1108 	}
1109 
1110 	kn->kn_hook = tp;
1111 
1112 	s = spltty();
1113 	klist_insert_locked(klist, kn);
1114 	splx(s);
1115 
1116 	return (0);
1117 }
1118 
1119 void
filt_ttyrdetach(struct knote * kn)1120 filt_ttyrdetach(struct knote *kn)
1121 {
1122 	struct tty *tp = kn->kn_hook;
1123 	int s;
1124 
1125 	s = spltty();
1126 	klist_remove_locked(&tp->t_rsel.si_note, kn);
1127 	splx(s);
1128 }
1129 
1130 int
filt_ttyread(struct knote * kn,long hint)1131 filt_ttyread(struct knote *kn, long hint)
1132 {
1133 	struct tty *tp = kn->kn_hook;
1134 	int active, s;
1135 
1136 	s = spltty();
1137 	kn->kn_data = ttnread(tp);
1138 	active = (kn->kn_data > 0);
1139 	if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
1140 		kn->kn_flags |= EV_EOF;
1141 		if (kn->kn_flags & __EV_POLL)
1142 			kn->kn_flags |= __EV_HUP;
1143 		active = 1;
1144 	} else {
1145 		kn->kn_flags &= ~(EV_EOF | __EV_HUP);
1146 	}
1147 	splx(s);
1148 	return (active);
1149 }
1150 
1151 void
filt_ttywdetach(struct knote * kn)1152 filt_ttywdetach(struct knote *kn)
1153 {
1154 	struct tty *tp = kn->kn_hook;
1155 	int s;
1156 
1157 	s = spltty();
1158 	klist_remove_locked(&tp->t_wsel.si_note, kn);
1159 	splx(s);
1160 }
1161 
1162 int
filt_ttywrite(struct knote * kn,long hint)1163 filt_ttywrite(struct knote *kn, long hint)
1164 {
1165 	struct tty *tp = kn->kn_hook;
1166 	int active, s;
1167 
1168 	s = spltty();
1169 	kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc;
1170 	active = (tp->t_outq.c_cc <= tp->t_lowat);
1171 
1172 	/* Write-side HUP condition is only for poll(2) and select(2). */
1173 	if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) {
1174 		if (!ISSET(tp->t_cflag, CLOCAL) &&
1175 		    !ISSET(tp->t_state, TS_CARR_ON)) {
1176 			kn->kn_flags |= __EV_HUP;
1177 			active = 1;
1178 		} else {
1179 			kn->kn_flags &= ~__EV_HUP;
1180 		}
1181 	}
1182 	splx(s);
1183 	return (active);
1184 }
1185 
1186 int
filt_ttyexcept(struct knote * kn,long hint)1187 filt_ttyexcept(struct knote *kn, long hint)
1188 {
1189 	struct tty *tp = kn->kn_hook;
1190 	int active = 0;
1191 	int s;
1192 
1193 	s = spltty();
1194 	if (kn->kn_flags & __EV_POLL) {
1195 		if (!ISSET(tp->t_cflag, CLOCAL) &&
1196 		    !ISSET(tp->t_state, TS_CARR_ON)) {
1197 			kn->kn_flags |= __EV_HUP;
1198 			active = 1;
1199 		} else {
1200 			kn->kn_flags &= ~__EV_HUP;
1201 		}
1202 	}
1203 	splx(s);
1204 	return (active);
1205 }
1206 
1207 static int
ttnread(struct tty * tp)1208 ttnread(struct tty *tp)
1209 {
1210 	int nread;
1211 
1212 	splassert(IPL_TTY);
1213 
1214 	if (ISSET(tp->t_lflag, PENDIN))
1215 		ttypend(tp);
1216 	nread = tp->t_canq.c_cc;
1217 	if (!ISSET(tp->t_lflag, ICANON)) {
1218 		nread += tp->t_rawq.c_cc;
1219 		if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
1220 			nread = 0;
1221 	}
1222 	return (nread);
1223 }
1224 
1225 /*
1226  * Wait for output to drain, or if this times out, flush it.
1227  */
1228 int
ttywait_nsec(struct tty * tp,uint64_t nsecs)1229 ttywait_nsec(struct tty *tp, uint64_t nsecs)
1230 {
1231 	int error, s;
1232 
1233 	error = 0;
1234 	s = spltty();
1235 	while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1236 	    (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL)) &&
1237 	    tp->t_oproc) {
1238 		(*tp->t_oproc)(tp);
1239 		if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1240 		    (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
1241 		    && tp->t_oproc) {
1242 			SET(tp->t_state, TS_ASLEEP);
1243 			error = ttysleep_nsec(tp, &tp->t_outq, TTOPRI | PCATCH,
1244 			    ttyout, nsecs);
1245 			if (error == EWOULDBLOCK)
1246 				ttyflush(tp, FWRITE);
1247 			if (error)
1248 				break;
1249 		} else
1250 			break;
1251 	}
1252 	splx(s);
1253 	return (error);
1254 }
1255 
1256 int
ttywait(struct tty * tp)1257 ttywait(struct tty *tp)
1258 {
1259 	return (ttywait_nsec(tp, INFSLP));
1260 }
1261 
1262 /*
1263  * Flush if successfully wait.
1264  */
1265 int
ttywflush(struct tty * tp)1266 ttywflush(struct tty *tp)
1267 {
1268 	int error;
1269 
1270 	error = ttywait_nsec(tp, SEC_TO_NSEC(5));
1271 	if (error == 0 || error == EWOULDBLOCK)
1272 		ttyflush(tp, FREAD);
1273 	return (error);
1274 }
1275 
1276 /*
1277  * Flush tty read and/or write queues, notifying anyone waiting.
1278  */
1279 void
ttyflush(struct tty * tp,int rw)1280 ttyflush(struct tty *tp, int rw)
1281 {
1282 	int s;
1283 
1284 	s = spltty();
1285 	if (rw & FREAD) {
1286 		FLUSHQ(&tp->t_canq);
1287 		FLUSHQ(&tp->t_rawq);
1288 		tp->t_rocount = 0;
1289 		tp->t_rocol = 0;
1290 		CLR(tp->t_state, TS_LOCAL);
1291 		ttyunblock(tp);
1292 		ttwakeup(tp);
1293 	}
1294 	if (rw & FWRITE) {
1295 		CLR(tp->t_state, TS_TTSTOP);
1296 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1297 		FLUSHQ(&tp->t_outq);
1298 		wakeup((caddr_t)&tp->t_outq);
1299 		selwakeup(&tp->t_wsel);
1300 	}
1301 	splx(s);
1302 }
1303 
1304 /*
1305  * Copy in the default termios characters.
1306  */
1307 void
ttychars(struct tty * tp)1308 ttychars(struct tty *tp)
1309 {
1310 
1311 	memcpy(tp->t_cc, ttydefchars, sizeof(ttydefchars));
1312 }
1313 
1314 /*
1315  * Send stop character on input overflow.
1316  */
1317 static void
ttyblock(struct tty * tp)1318 ttyblock(struct tty *tp)
1319 {
1320 	int total;
1321 
1322 	total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
1323 	if (tp->t_rawq.c_cc > TTYHOG(tp)) {
1324 		ttyflush(tp, FREAD | FWRITE);
1325 		CLR(tp->t_state, TS_TBLOCK);
1326 	}
1327 	/*
1328 	 * Block further input iff: current input > threshold
1329 	 * AND input is available to user program.
1330 	 */
1331 	if ((total >= TTYHOG(tp) / 2 &&
1332 	     !ISSET(tp->t_state, TS_TBLOCK) &&
1333 	     !ISSET(tp->t_lflag, ICANON)) || tp->t_canq.c_cc > 0) {
1334 		if (ISSET(tp->t_iflag, IXOFF) &&
1335 		    tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1336 		    putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
1337 			SET(tp->t_state, TS_TBLOCK);
1338 			ttstart(tp);
1339 		}
1340 		/* Try to block remote output via hardware flow control. */
1341 		if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1342 		    (*tp->t_hwiflow)(tp, 1) != 0)
1343 			SET(tp->t_state, TS_TBLOCK);
1344 	}
1345 }
1346 
1347 void
ttrstrt(void * arg)1348 ttrstrt(void *arg)
1349 {
1350 	struct tty *tp = (struct tty *)arg;
1351 	int s;
1352 
1353 #ifdef DIAGNOSTIC
1354 	if (tp == NULL)
1355 		panic("ttrstrt");
1356 #endif
1357 	s = spltty();
1358 	CLR(tp->t_state, TS_TIMEOUT);
1359 	ttstart(tp);
1360 	splx(s);
1361 }
1362 
1363 int
ttstart(struct tty * tp)1364 ttstart(struct tty *tp)
1365 {
1366 
1367 	if (tp->t_oproc != NULL)	/* XXX: Kludge for pty. */
1368 		(*tp->t_oproc)(tp);
1369 	return (0);
1370 }
1371 
1372 /*
1373  * "close" a line discipline
1374  */
1375 int
ttylclose(struct tty * tp,int flag,struct proc * p)1376 ttylclose(struct tty *tp, int flag, struct proc *p)
1377 {
1378 
1379 	if (flag & FNONBLOCK)
1380 		ttyflush(tp, FREAD | FWRITE);
1381 	else
1382 		ttywflush(tp);
1383 	return (0);
1384 }
1385 
1386 /*
1387  * Handle modem control transition on a tty.
1388  * Flag indicates new state of carrier.
1389  * Returns 0 if the line should be turned off, otherwise 1.
1390  */
1391 int
ttymodem(struct tty * tp,int flag)1392 ttymodem(struct tty *tp, int flag)
1393 {
1394 
1395 	if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
1396 		/*
1397 		 * MDMBUF: do flow control according to carrier flag
1398 		 */
1399 		if (flag) {
1400 			CLR(tp->t_state, TS_TTSTOP);
1401 			ttstart(tp);
1402 		} else if (!ISSET(tp->t_state, TS_TTSTOP)) {
1403 			SET(tp->t_state, TS_TTSTOP);
1404 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
1405 		}
1406 	} else if (flag == 0) {
1407 		/*
1408 		 * Lost carrier.
1409 		 */
1410 		CLR(tp->t_state, TS_CARR_ON);
1411 		if (ISSET(tp->t_state, TS_ISOPEN) &&
1412 		    !ISSET(tp->t_cflag, CLOCAL)) {
1413 			if (tp->t_session && tp->t_session->s_leader)
1414 				prsignal(tp->t_session->s_leader, SIGHUP);
1415 			ttyflush(tp, FREAD | FWRITE);
1416 			return (0);
1417 		}
1418 	} else {
1419 		/*
1420 		 * Carrier now on.
1421 		 */
1422 		SET(tp->t_state, TS_CARR_ON);
1423 		ttwakeup(tp);
1424 	}
1425 	return (1);
1426 }
1427 
1428 /*
1429  * Default modem control routine (for other line disciplines).
1430  * Return argument flag, to turn off device on carrier drop.
1431  */
1432 int
nullmodem(struct tty * tp,int flag)1433 nullmodem(struct tty *tp, int flag)
1434 {
1435 
1436 	if (flag)
1437 		SET(tp->t_state, TS_CARR_ON);
1438 	else {
1439 		CLR(tp->t_state, TS_CARR_ON);
1440 		if (ISSET(tp->t_state, TS_ISOPEN) &&
1441 		    !ISSET(tp->t_cflag, CLOCAL)) {
1442 			if (tp->t_session && tp->t_session->s_leader)
1443 				prsignal(tp->t_session->s_leader, SIGHUP);
1444 			ttyflush(tp, FREAD | FWRITE);
1445 			return (0);
1446 		}
1447 	}
1448 	return (1);
1449 }
1450 
1451 /*
1452  * Reinput pending characters after state switch
1453  * call at spltty().
1454  */
1455 void
ttypend(struct tty * tp)1456 ttypend(struct tty *tp)
1457 {
1458 	struct clist tq;
1459 	int c;
1460 
1461 	splassert(IPL_TTY);
1462 
1463 	CLR(tp->t_lflag, PENDIN);
1464 	SET(tp->t_state, TS_TYPEN);
1465 	tq = tp->t_rawq;
1466 	tp->t_rawq.c_cc = 0;
1467 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = NULL;
1468 	while ((c = getc(&tq)) >= 0)
1469 		ttyinput(c, tp);
1470 	CLR(tp->t_state, TS_TYPEN);
1471 }
1472 
1473 void ttvtimeout(void *);
1474 
1475 void
ttvtimeout(void * arg)1476 ttvtimeout(void *arg)
1477 {
1478 	struct tty *tp = (struct tty *)arg;
1479 
1480 	wakeup(&tp->t_rawq);
1481 }
1482 
1483 /*
1484  * Process a read call on a tty device.
1485  */
1486 int
ttread(struct tty * tp,struct uio * uio,int flag)1487 ttread(struct tty *tp, struct uio *uio, int flag)
1488 {
1489 	struct timeout *stime = NULL;
1490 	struct proc *p = curproc;
1491 	struct process *pr = p->p_p;
1492 	int s, first, error = 0;
1493 	u_char *cc = tp->t_cc;
1494 	struct clist *qp;
1495 	int last_cc = 0;
1496 	long lflag;
1497 	int c;
1498 
1499 loop:	lflag = tp->t_lflag;
1500 	s = spltty();
1501 	/*
1502 	 * take pending input first
1503 	 */
1504 	if (ISSET(lflag, PENDIN))
1505 		ttypend(tp);
1506 	splx(s);
1507 
1508 	/*
1509 	 * Hang process if it's in the background.
1510 	 */
1511 	if (isbackground(pr, tp)) {
1512 		if (sigismasked(p, SIGTTIN) ||
1513 		    pr->ps_flags & PS_PPWAIT || pr->ps_pgrp->pg_jobc == 0) {
1514 			error = EIO;
1515 			goto out;
1516 		}
1517 		pgsignal(pr->ps_pgrp, SIGTTIN, 1);
1518 		error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg);
1519 		if (error)
1520 			goto out;
1521 		goto loop;
1522 	}
1523 
1524 	s = spltty();
1525 	if (!ISSET(lflag, ICANON)) {
1526 		int min = cc[VMIN];
1527 		int time = cc[VTIME] * 100;	/* tenths of a second (ms) */
1528 
1529 		qp = &tp->t_rawq;
1530 		/*
1531 		 * Check each of the four combinations.
1532 		 * (min > 0 && time == 0) is the normal read case.
1533 		 * It should be fairly efficient, so we check that and its
1534 		 * companion case (min == 0 && time == 0) first.
1535 		 */
1536 		if (time == 0) {
1537 			if (qp->c_cc < min)
1538 				goto sleep;
1539 			goto read;
1540 		}
1541 		if (min > 0) {
1542 			if (qp->c_cc <= 0)
1543 				goto sleep;
1544 			if (qp->c_cc >= min)
1545 				goto read;
1546 			if (stime == NULL) {
1547 alloc_timer:
1548 				stime = malloc(sizeof(*stime), M_TEMP, M_WAITOK);
1549 				timeout_set(stime, ttvtimeout, tp);
1550 				timeout_add_msec(stime, time);
1551 			} else if (qp->c_cc > last_cc) {
1552 				/* got a character, restart timer */
1553 				timeout_add_msec(stime, time);
1554 			}
1555 		} else {	/* min == 0 */
1556 			if (qp->c_cc > 0)
1557 				goto read;
1558 			if (stime == NULL) {
1559 				goto alloc_timer;
1560 			}
1561 		}
1562 		last_cc = qp->c_cc;
1563 		if (stime && !timeout_triggered(stime)) {
1564 			goto sleep;
1565 		}
1566 	} else if ((qp = &tp->t_canq)->c_cc <= 0) {
1567 		int carrier;
1568 
1569 sleep:
1570 		/*
1571 		 * If there is no input, sleep on rawq
1572 		 * awaiting hardware receipt and notification.
1573 		 * If we have data, we don't need to check for carrier.
1574 		 */
1575 		carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1576 		    ISSET(tp->t_cflag, CLOCAL);
1577 		if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1578 			splx(s);
1579 			error = 0;
1580 			goto out;
1581 		}
1582 		if (flag & IO_NDELAY) {
1583 			splx(s);
1584 			error = EWOULDBLOCK;
1585 			goto out;
1586 		}
1587 		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
1588 		    carrier ? ttyin : ttopen);
1589 		splx(s);
1590 		if (stime && timeout_triggered(stime))
1591 			error = EWOULDBLOCK;
1592 		if (cc[VMIN] == 0 && error == EWOULDBLOCK) {
1593 			error = 0;
1594 			goto out;
1595 		}
1596 		if (error && error != EWOULDBLOCK)
1597 			goto out;
1598 		error = 0;
1599 		goto loop;
1600 	}
1601 read:
1602 	splx(s);
1603 
1604 	/*
1605 	 * Input present, check for input mapping and processing.
1606 	 */
1607 	first = 1;
1608 	while ((c = getc(qp)) >= 0) {
1609 		/*
1610 		 * delayed suspend (^Y)
1611 		 */
1612 		if (CCEQ(cc[VDSUSP], c) &&
1613 		    ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1614 			pgsignal(tp->t_pgrp, SIGTSTP, 1);
1615 			if (first) {
1616 				error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1617 				    ttybg);
1618 				if (error)
1619 					break;
1620 				goto loop;
1621 			}
1622 			break;
1623 		}
1624 		/*
1625 		 * Interpret EOF only in canonical mode.
1626 		 */
1627 		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1628 			break;
1629 		/*
1630 		 * Give user character.
1631 		 */
1632 		error = ureadc(c, uio);
1633 		if (error)
1634 			break;
1635 		if (uio->uio_resid == 0)
1636 			break;
1637 		/*
1638 		 * In canonical mode check for a "break character"
1639 		 * marking the end of a "line of input".
1640 		 */
1641 		if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1642 			break;
1643 		first = 0;
1644 	}
1645 	/*
1646 	 * Look to unblock output now that (presumably)
1647 	 * the input queue has gone down.
1648 	 */
1649 	s = spltty();
1650 	if (tp->t_rawq.c_cc < TTYHOG(tp)/5)
1651 		ttyunblock(tp);
1652 	splx(s);
1653 
1654 out:
1655 	if (stime) {
1656 		timeout_del(stime);
1657 		free(stime, M_TEMP, sizeof(*stime));
1658 	}
1659 	return (error);
1660 }
1661 
1662 /* Call at spltty */
1663 void
ttyunblock(struct tty * tp)1664 ttyunblock(struct tty *tp)
1665 {
1666 	u_char *cc = tp->t_cc;
1667 
1668 	splassert(IPL_TTY);
1669 
1670 	if (ISSET(tp->t_state, TS_TBLOCK)) {
1671 		if (ISSET(tp->t_iflag, IXOFF) &&
1672 		    cc[VSTART] != _POSIX_VDISABLE &&
1673 		    putc(cc[VSTART], &tp->t_outq) == 0) {
1674 			CLR(tp->t_state, TS_TBLOCK);
1675 			ttstart(tp);
1676 		}
1677 		/* Try to unblock remote output via hardware flow control. */
1678 		if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1679 		    (*tp->t_hwiflow)(tp, 0) != 0)
1680 			CLR(tp->t_state, TS_TBLOCK);
1681 	}
1682 }
1683 
1684 /*
1685  * Check the output queue on tp for space for a kernel message (from uprintf
1686  * or tprintf).  Allow some space over the normal hiwater mark so we don't
1687  * lose messages due to normal flow control, but don't let the tty run amok.
1688  * Sleeps here are not interruptible, but we return prematurely if new signals
1689  * arrive.
1690  */
1691 int
ttycheckoutq(struct tty * tp,int wait)1692 ttycheckoutq(struct tty *tp, int wait)
1693 {
1694 	int hiwat, s, oldsig;
1695 
1696 	hiwat = tp->t_hiwat;
1697 	s = spltty();
1698 	oldsig = wait ? SIGPENDING(curproc) : 0;
1699 	if (tp->t_outq.c_cc > hiwat + TTHIWATMINSPACE)
1700 		while (tp->t_outq.c_cc > hiwat) {
1701 			ttstart(tp);
1702 			if (wait == 0 || SIGPENDING(curproc) != oldsig) {
1703 				splx(s);
1704 				return (0);
1705 			}
1706 			SET(tp->t_state, TS_ASLEEP);
1707 			tsleep_nsec(&tp->t_outq, PZERO - 1, "ttckoutq",
1708 			    SEC_TO_NSEC(1));
1709 		}
1710 	splx(s);
1711 	return (1);
1712 }
1713 
1714 /*
1715  * Process a write call on a tty device.
1716  */
1717 int
ttwrite(struct tty * tp,struct uio * uio,int flag)1718 ttwrite(struct tty *tp, struct uio *uio, int flag)
1719 {
1720 	u_char *cp = NULL;
1721 	int cc, ce, obufcc = 0;
1722 	struct proc *p;
1723 	struct process *pr;
1724 	int hiwat, error, s;
1725 	size_t cnt;
1726 	u_char obuf[OBUFSIZ];
1727 
1728 	hiwat = tp->t_hiwat;
1729 	cnt = uio->uio_resid;
1730 	error = 0;
1731 	cc = 0;
1732 loop:
1733 	s = spltty();
1734 	if (!ISSET(tp->t_state, TS_CARR_ON) &&
1735 	    !ISSET(tp->t_cflag, CLOCAL)) {
1736 		if (ISSET(tp->t_state, TS_ISOPEN)) {
1737 			splx(s);
1738 			error = EIO;
1739 			goto done;
1740 		} else if (flag & IO_NDELAY) {
1741 			splx(s);
1742 			error = EWOULDBLOCK;
1743 			goto out;
1744 		} else {
1745 			/* Sleep awaiting carrier. */
1746 			error = ttysleep(tp,
1747 			    &tp->t_rawq, TTIPRI | PCATCH, ttopen);
1748 			splx(s);
1749 			if (error)
1750 				goto out;
1751 			goto loop;
1752 		}
1753 	}
1754 	splx(s);
1755 	/*
1756 	 * Hang the process if it's in the background.
1757 	 */
1758 	p = curproc;
1759 	pr = p->p_p;
1760 	if (isbackground(pr, tp) &&
1761 	    ISSET(tp->t_lflag, TOSTOP) && (pr->ps_flags & PS_PPWAIT) == 0 &&
1762 	    !sigismasked(p, SIGTTOU)) {
1763 		if (pr->ps_pgrp->pg_jobc == 0) {
1764 			error = EIO;
1765 			goto out;
1766 		}
1767 		pgsignal(pr->ps_pgrp, SIGTTOU, 1);
1768 		error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg);
1769 		if (error)
1770 			goto out;
1771 		goto loop;
1772 	}
1773 	/*
1774 	 * Process the user's data in at most OBUFSIZ chunks.  Perform any
1775 	 * output translation.  Keep track of high water mark, sleep on
1776 	 * overflow awaiting device aid in acquiring new space.
1777 	 */
1778 	while (uio->uio_resid > 0 || cc > 0) {
1779 		if (ISSET(tp->t_lflag, FLUSHO)) {
1780 			uio->uio_resid = 0;
1781 			goto done;
1782 		}
1783 		if (tp->t_outq.c_cc > hiwat)
1784 			goto ovhiwat;
1785 		/*
1786 		 * Grab a hunk of data from the user, unless we have some
1787 		 * leftover from last time.
1788 		 */
1789 		if (cc == 0) {
1790 			cc = MIN(uio->uio_resid, OBUFSIZ);
1791 			cp = obuf;
1792 			error = uiomove(cp, cc, uio);
1793 			if (error) {
1794 				cc = 0;
1795 				break;
1796 			}
1797 			if (cc > obufcc)
1798 				obufcc = cc;
1799 
1800 			/* duplicate /dev/console output into console buffer */
1801 			if (consbufp && cn_tab &&
1802 			    cn_tab->cn_dev == tp->t_dev && tp->t_gen == 0) {
1803 				int i;
1804 				for (i = 0; i < cc; i++) {
1805 					char c = cp[i];
1806 					if (c != '\0' && c != '\r' && c != 0177)
1807 						msgbuf_putchar(consbufp, c);
1808 				}
1809 			}
1810 		}
1811 		/*
1812 		 * If nothing fancy need be done, grab those characters we
1813 		 * can handle without any of ttyoutput's processing and
1814 		 * just transfer them to the output q.  For those chars
1815 		 * which require special processing (as indicated by the
1816 		 * bits in char_type), call ttyoutput.  After processing
1817 		 * a hunk of data, look for FLUSHO so ^O's will take effect
1818 		 * immediately.
1819 		 */
1820 		while (cc > 0) {
1821 			int i;
1822 			if (!ISSET(tp->t_oflag, OPOST))
1823 				ce = cc;
1824 			else {
1825 				ce = cc - scanc((u_int)cc, cp, char_type,
1826 				    CCLASSMASK);
1827 				/*
1828 				 * If ce is zero, then we're processing
1829 				 * a special character through ttyoutput.
1830 				 */
1831 				if (ce == 0) {
1832 					tp->t_rocount = 0;
1833 					if (ttyoutput(*cp, tp) >= 0) {
1834 						/* out of space */
1835 						goto ovhiwat;
1836 					}
1837 					cp++;
1838 					cc--;
1839 					if (ISSET(tp->t_lflag, FLUSHO) ||
1840 					    tp->t_outq.c_cc > hiwat)
1841 						goto ovhiwat;
1842 					continue;
1843 				}
1844 			}
1845 			/*
1846 			 * A bunch of normal characters have been found.
1847 			 * Transfer them en masse to the output queue and
1848 			 * continue processing at the top of the loop.
1849 			 * If there are any further characters in this
1850 			 * <= OBUFSIZ chunk, the first should be a character
1851 			 * requiring special handling by ttyoutput.
1852 			 */
1853 			tp->t_rocount = 0;
1854 			i = b_to_q(cp, ce, &tp->t_outq);
1855 			ce -= i;
1856 			tp->t_column += ce;
1857 			cp += ce, cc -= ce, tk_nout += ce;
1858 			tp->t_outcc += ce;
1859 			if (i > 0) {
1860 				/* out of space */
1861 				goto ovhiwat;
1862 			}
1863 			if (ISSET(tp->t_lflag, FLUSHO) ||
1864 			    tp->t_outq.c_cc > hiwat)
1865 				break;
1866 		}
1867 		ttstart(tp);
1868 	}
1869 out:
1870 	/*
1871 	 * If cc is nonzero, we leave the uio structure inconsistent, as the
1872 	 * offset and iov pointers have moved forward, but it doesn't matter
1873 	 * (the call will either return short or restart with a new uio).
1874 	 */
1875 	uio->uio_resid += cc;
1876 done:
1877 	if (obufcc)
1878 		explicit_bzero(obuf, obufcc);
1879 	return (error);
1880 
1881 ovhiwat:
1882 	ttstart(tp);
1883 	s = spltty();
1884 	/*
1885 	 * This can only occur if FLUSHO is set in t_lflag,
1886 	 * or if ttstart/oproc is synchronous (or very fast).
1887 	 */
1888 	if (tp->t_outq.c_cc <= hiwat) {
1889 		splx(s);
1890 		goto loop;
1891 	}
1892 	if (flag & IO_NDELAY) {
1893 		splx(s);
1894 		uio->uio_resid += cc;
1895 		if (obufcc)
1896 			explicit_bzero(obuf, obufcc);
1897 		return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1898 	}
1899 	SET(tp->t_state, TS_ASLEEP);
1900 	error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout);
1901 	splx(s);
1902 	if (error)
1903 		goto out;
1904 	goto loop;
1905 }
1906 
1907 /*
1908  * Rubout one character from the rawq of tp
1909  * as cleanly as possible.
1910  */
1911 int
ttyrub(int c,struct tty * tp)1912 ttyrub(int c, struct tty *tp)
1913 {
1914 	u_char *cp;
1915 	int savecol;
1916 	int tabc, s, cc;
1917 
1918 	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1919 		return 0;
1920 	CLR(tp->t_lflag, FLUSHO);
1921 	if (ISSET(tp->t_lflag, ECHOE)) {
1922 		if (tp->t_rocount == 0) {
1923 			/*
1924 			 * Screwed by ttwrite; retype
1925 			 */
1926 			return ttyretype(tp);
1927 		}
1928 		if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1929 			ttyrubo(tp, 2);
1930 		else {
1931 			CLR(c, ~TTY_CHARMASK);
1932 			switch (CCLASS(c)) {
1933 			case ORDINARY:
1934 				ttyrubo(tp, 1);
1935 				break;
1936 			case BACKSPACE:
1937 			case CONTROL:
1938 			case NEWLINE:
1939 			case RETURN:
1940 			case VTAB:
1941 				if (ISSET(tp->t_lflag, ECHOCTL))
1942 					ttyrubo(tp, 2);
1943 				break;
1944 			case TAB:
1945 				if (tp->t_rocount < tp->t_rawq.c_cc)
1946 					return ttyretype(tp);
1947 				s = spltty();
1948 				savecol = tp->t_column;
1949 				SET(tp->t_state, TS_CNTTB);
1950 				SET(tp->t_lflag, FLUSHO);
1951 				tp->t_column = tp->t_rocol;
1952 				for (cp = firstc(&tp->t_rawq, &tabc, &cc); cp;
1953 				    cp = nextc(&tp->t_rawq, cp, &tabc, &cc))
1954 					ttyecho(tabc, tp);
1955 				CLR(tp->t_lflag, FLUSHO);
1956 				CLR(tp->t_state, TS_CNTTB);
1957 				splx(s);
1958 
1959 				/* savecol will now be length of the tab. */
1960 				savecol -= tp->t_column;
1961 				tp->t_column += savecol;
1962 				if (savecol > 8)
1963 					savecol = 8;	/* overflow screw */
1964 				while (--savecol >= 0)
1965 					(void)ttyoutput('\b', tp);
1966 				break;
1967 			default:			/* XXX */
1968 #define	PANICSTR	"ttyrub: would panic c = %d, val = %d"
1969 				(void)printf(PANICSTR "\n", c, CCLASS(c));
1970 #ifdef notdef
1971 				panic(PANICSTR, c, CCLASS(c));
1972 #endif
1973 			}
1974 		}
1975 	} else if (ISSET(tp->t_lflag, ECHOPRT)) {
1976 		if (!ISSET(tp->t_state, TS_ERASE)) {
1977 			SET(tp->t_state, TS_ERASE);
1978 			(void)ttyoutput('\\', tp);
1979 		}
1980 		ttyecho(c, tp);
1981 	} else
1982 		ttyecho(tp->t_cc[VERASE], tp);
1983 	--tp->t_rocount;
1984 	return 0;
1985 }
1986 
1987 /*
1988  * Back over cnt characters, erasing them.
1989  */
1990 static void
ttyrubo(struct tty * tp,int cnt)1991 ttyrubo(struct tty *tp, int cnt)
1992 {
1993 
1994 	while (cnt-- > 0) {
1995 		(void)ttyoutput('\b', tp);
1996 		(void)ttyoutput(' ', tp);
1997 		(void)ttyoutput('\b', tp);
1998 	}
1999 }
2000 
2001 /*
2002  * ttyretype --
2003  *	Reprint the rawq line.  Note, it is assumed that c_cc has already
2004  *	been checked.
2005  */
2006 int
ttyretype(struct tty * tp)2007 ttyretype(struct tty *tp)
2008 {
2009 	u_char *cp;
2010 	int s, c, cc;
2011 
2012 	/* Echo the reprint character. */
2013 	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2014 		ttyecho(tp->t_cc[VREPRINT], tp);
2015 
2016 	(void)ttyoutput('\n', tp);
2017 
2018 	s = spltty();
2019 	for (cp = firstc(&tp->t_canq, &c, &cc); cp;
2020 	    cp = nextc(&tp->t_canq, cp, &c, &cc))
2021 		ttyecho(c, tp);
2022 	for (cp = firstc(&tp->t_rawq, &c, &cc); cp;
2023 	    cp = nextc(&tp->t_rawq, cp, &c, &cc))
2024 		ttyecho(c, tp);
2025 	CLR(tp->t_state, TS_ERASE);
2026 	splx(s);
2027 
2028 	tp->t_rocount = tp->t_rawq.c_cc;
2029 	tp->t_rocol = 0;
2030 	return (1);
2031 }
2032 
2033 /*
2034  * Echo a typed character to the terminal.
2035  */
2036 static void
ttyecho(int c,struct tty * tp)2037 ttyecho(int c, struct tty *tp)
2038 {
2039 
2040 	if (!ISSET(tp->t_state, TS_CNTTB))
2041 		CLR(tp->t_lflag, FLUSHO);
2042 	if ((!ISSET(tp->t_lflag, ECHO) &&
2043 	    (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
2044 	    ISSET(tp->t_lflag, EXTPROC))
2045 		return;
2046 	if (((ISSET(tp->t_lflag, ECHOCTL) &&
2047 	     (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
2048 	    ISSET(c, TTY_CHARMASK) == 0177)) {
2049 		(void)ttyoutput('^', tp);
2050 		CLR(c, ~TTY_CHARMASK);
2051 		if (c == 0177)
2052 			c = '?';
2053 		else
2054 			c += 'A' - 1;
2055 	}
2056 	(void)ttyoutput(c, tp);
2057 }
2058 
2059 /*
2060  * Wakeup any writers if necessary.
2061  */
2062 void
ttwakeupwr(struct tty * tp)2063 ttwakeupwr(struct tty *tp)
2064 {
2065 
2066 	if (tp->t_outq.c_cc <= tp->t_lowat) {
2067 		if (ISSET(tp->t_state, TS_ASLEEP)) {
2068 			CLR(tp->t_state, TS_ASLEEP);
2069 			wakeup(&tp->t_outq);
2070 		}
2071 		selwakeup(&tp->t_wsel);
2072 	}
2073 }
2074 
2075 /*
2076  * Wake up any readers on a tty.
2077  */
2078 void
ttwakeup(struct tty * tp)2079 ttwakeup(struct tty *tp)
2080 {
2081 
2082 	selwakeup(&tp->t_rsel);
2083 	if (ISSET(tp->t_state, TS_ASYNC))
2084 		pgsignal(tp->t_pgrp, SIGIO, 1);
2085 	wakeup((caddr_t)&tp->t_rawq);
2086 }
2087 
2088 /*
2089  * Look up a code for a specified speed in a conversion table;
2090  * used by drivers to map software speed values to hardware parameters.
2091  */
2092 int
ttspeedtab(int speed,const struct speedtab * table)2093 ttspeedtab(int speed, const struct speedtab *table)
2094 {
2095 
2096 	for ( ; table->sp_speed != -1; table++)
2097 		if (table->sp_speed == speed)
2098 			return (table->sp_code);
2099 	return (-1);
2100 }
2101 
2102 /*
2103  * Set tty hi and low water marks.
2104  *
2105  * Try to arrange the dynamics so there's about one second
2106  * from hi to low water.
2107  */
2108 void
ttsetwater(struct tty * tp)2109 ttsetwater(struct tty *tp)
2110 {
2111 	int cps, x;
2112 
2113 #define CLAMP(x, h, l)	((x) > h ? h : ((x) < l) ? l : (x))
2114 
2115 	cps = tp->t_ospeed / 10;
2116 	tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2117 	x += cps;
2118 	tp->t_hiwat = CLAMP(x, tp->t_outq.c_cn - TTHIWATMINSPACE, TTMINHIWAT);
2119 #undef	CLAMP
2120 }
2121 
2122 /*
2123  * Get the total estcpu for a process, summing across threads.
2124  * Returns true if at least one thread is runnable/running.
2125  */
2126 static int
process_sum(struct process * pr,fixpt_t * estcpup)2127 process_sum(struct process *pr, fixpt_t *estcpup)
2128 {
2129 	struct proc *p;
2130 	fixpt_t estcpu;
2131 	int ret;
2132 
2133 	ret = 0;
2134 	estcpu = 0;
2135 	TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
2136 		if (p->p_stat == SRUN || p->p_stat == SONPROC)
2137 			ret = 1;
2138 		estcpu += p->p_pctcpu;
2139 	}
2140 
2141 	*estcpup = estcpu;
2142 	return (ret);
2143 }
2144 
2145 /*
2146  * Report on state of foreground process group.
2147  */
2148 void
ttyinfo(struct tty * tp)2149 ttyinfo(struct tty *tp)
2150 {
2151 	struct process *pr, *pickpr;
2152 	struct proc *p, *pick;
2153 	struct tusage tu;
2154 	struct timespec utime, stime;
2155 	int tmp;
2156 
2157 	if (ttycheckoutq(tp,0) == 0)
2158 		return;
2159 
2160 	/* Print load average. */
2161 	tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2162 	ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2163 
2164 	if (tp->t_session == NULL)
2165 		ttyprintf(tp, "not a controlling terminal\n");
2166 	else if (tp->t_pgrp == NULL)
2167 		ttyprintf(tp, "no foreground process group\n");
2168 	else if ((pr = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL)
2169 empty:		ttyprintf(tp, "empty foreground process group\n");
2170 	else {
2171 		const char *state;
2172 		fixpt_t pctcpu, pctcpu2;
2173 		int run, run2;
2174 		int calc_pctcpu;
2175 		long rss = 0;
2176 
2177 		/*
2178 		 * Pick the most active process:
2179 		 *  - prefer at least one running/runnable thread
2180 		 *  - prefer higher total pctcpu
2181 		 *  - prefer non-zombie
2182 		 * Otherwise take the most recently added to this process group
2183 		 */
2184 		pickpr = pr;
2185 		run = process_sum(pickpr, &pctcpu);
2186 		while ((pr = LIST_NEXT(pr, ps_pglist)) != NULL) {
2187 			run2 = process_sum(pr, &pctcpu2);
2188 			if (run) {
2189 				/*
2190 				 * pick is running; is p running w/same or
2191 				 * more cpu?
2192 				 */
2193 				if (run2 && pctcpu2 >= pctcpu)
2194 					goto update_pickpr;
2195 				continue;
2196 			}
2197 			/* pick isn't running; is p running *or* w/more cpu? */
2198 			if (run2 || pctcpu2 > pctcpu)
2199 				goto update_pickpr;
2200 
2201 			/* if p has less cpu or is zombie, then it's worse */
2202 			if (pctcpu2 < pctcpu || (pr->ps_flags & PS_ZOMBIE))
2203 				continue;
2204 update_pickpr:
2205 			pickpr = pr;
2206 			run = run2;
2207 			pctcpu = pctcpu2;
2208 		}
2209 
2210 		/* Calculate percentage cpu, resident set size. */
2211 		calc_pctcpu = (pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
2212 		if ((pickpr->ps_flags & (PS_EMBRYO | PS_ZOMBIE)) == 0 &&
2213 		    pickpr->ps_vmspace != NULL)
2214 			rss = vm_resident_count(pickpr->ps_vmspace);
2215 
2216 		tuagg_get_process(&tu, pickpr);
2217 		calctsru(&tu, &utime, &stime, NULL);
2218 
2219 		/* Round up and print user time. */
2220 		utime.tv_nsec += 5000000;
2221 		if (utime.tv_nsec >= 1000000000) {
2222 			utime.tv_sec += 1;
2223 			utime.tv_nsec -= 1000000000;
2224 		}
2225 
2226 		/* Round up and print system time. */
2227 		stime.tv_nsec += 5000000;
2228 		if (stime.tv_nsec >= 1000000000) {
2229 			stime.tv_sec += 1;
2230 			stime.tv_nsec -= 1000000000;
2231 		}
2232 
2233 		/*
2234 		 * Find the most active thread:
2235 		 *  - prefer runnable
2236 		 *  - prefer higher pctcpu
2237 		 *  - prefer living
2238 		 * Otherwise take the newest thread
2239 		 */
2240 		pick = p = TAILQ_FIRST(&pickpr->ps_threads);
2241 		if (p == NULL)
2242 			goto empty;
2243 		run = p->p_stat == SRUN || p->p_stat == SONPROC;
2244 		pctcpu = p->p_pctcpu;
2245 		while ((p = TAILQ_NEXT(p, p_thr_link)) != NULL) {
2246 			run2 = p->p_stat == SRUN || p->p_stat == SONPROC;
2247 			pctcpu2 = p->p_pctcpu;
2248 			if (run) {
2249 				/*
2250 				 * pick is running; is p running w/same or
2251 				 * more cpu?
2252 				 */
2253 				if (run2 && pctcpu2 >= pctcpu)
2254 					goto update_pick;
2255 				continue;
2256 			}
2257 			/* pick isn't running; is p running *or* w/more cpu? */
2258 			if (run2 || pctcpu2 > pctcpu)
2259 				goto update_pick;
2260 
2261 			/* if p has less cpu or is exiting, then it's worse */
2262 			if (pctcpu2 < pctcpu || p->p_flag & P_WEXIT)
2263 				continue;
2264 update_pick:
2265 			pick = p;
2266 			run = run2;
2267 			pctcpu = p->p_pctcpu;
2268 		}
2269 		state = pick->p_stat == SONPROC ? "running" :
2270 		        pick->p_stat == SRUN ? "runnable" :
2271 		        pick->p_wmesg ? pick->p_wmesg : "iowait";
2272 
2273 		ttyprintf(tp,
2274 		    " cmd: %s %d [%s] %lld.%02ldu %lld.%02lds %d%% %ldk\n",
2275 		    pickpr->ps_comm, pickpr->ps_pid, state,
2276 		    (long long)utime.tv_sec, utime.tv_nsec / 10000000,
2277 		    (long long)stime.tv_sec, stime.tv_nsec / 10000000,
2278 		    calc_pctcpu / 100, rss);
2279 	}
2280 	tp->t_rocount = 0;	/* so pending input will be retyped if BS */
2281 }
2282 
2283 /*
2284  * Output char to tty; console putchar style.
2285  */
2286 int
tputchar(int c,struct tty * tp)2287 tputchar(int c, struct tty *tp)
2288 {
2289 	int s;
2290 
2291 	s = spltty();
2292 	if (ISSET(tp->t_state, TS_ISOPEN) == 0 ||
2293 	    !(ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))) {
2294 		splx(s);
2295 		return (-1);
2296 	}
2297 	if (c == '\n')
2298 		(void)ttyoutput('\r', tp);
2299 	(void)ttyoutput(c, tp);
2300 	ttstart(tp);
2301 	splx(s);
2302 	return (0);
2303 }
2304 
2305 /*
2306  * Sleep on chan, returning ERESTART if tty changed while we napped and
2307  * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep.  If
2308  * the tty is revoked, restarting a pending call will redo validation done
2309  * at the start of the call.
2310  */
2311 int
ttysleep(struct tty * tp,void * chan,int pri,char * wmesg)2312 ttysleep(struct tty *tp, void *chan, int pri, char *wmesg)
2313 {
2314 	return (ttysleep_nsec(tp, chan, pri, wmesg, INFSLP));
2315 }
2316 
2317 int
ttysleep_nsec(struct tty * tp,void * chan,int pri,char * wmesg,uint64_t nsecs)2318 ttysleep_nsec(struct tty *tp, void *chan, int pri, char *wmesg, uint64_t nsecs)
2319 {
2320 	int error;
2321 	short gen;
2322 
2323 	gen = tp->t_gen;
2324 	if ((error = tsleep_nsec(chan, pri, wmesg, nsecs)) != 0)
2325 		return (error);
2326 	return (tp->t_gen == gen ? 0 : ERESTART);
2327 }
2328 
2329 /*
2330  * Initialise the global tty list.
2331  */
2332 void
tty_init(void)2333 tty_init(void)
2334 {
2335 
2336 	TAILQ_INIT(&ttylist);
2337 	tty_count = 0;
2338 }
2339 
2340 /*
2341  * Allocate a tty structure and its associated buffers, and attach it to the
2342  * tty list.
2343  */
2344 struct tty *
ttymalloc(int baud)2345 ttymalloc(int baud)
2346 {
2347 	struct tty *tp;
2348 
2349 	tp = malloc(sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO);
2350 
2351 	if (baud == 0)
2352 		baud = 115200;
2353 
2354 	if (baud <= 9600)
2355 		tp->t_qlen = 1024;
2356 	else if (baud <= 115200)
2357 		tp->t_qlen = 4096;
2358 	else
2359 		tp->t_qlen = 8192;
2360 	clalloc(&tp->t_rawq, tp->t_qlen, 1);
2361 	clalloc(&tp->t_canq, tp->t_qlen, 1);
2362 	/* output queue doesn't need quoting */
2363 	clalloc(&tp->t_outq, tp->t_qlen, 0);
2364 
2365 	rw_enter_write(&ttylist_lock);
2366 	TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
2367 	++tty_count;
2368 	rw_exit_write(&ttylist_lock);
2369 
2370 	timeout_set(&tp->t_rstrt_to, ttrstrt, tp);
2371 
2372 	return(tp);
2373 }
2374 
2375 
2376 /*
2377  * Free a tty structure and its buffers, after removing it from the tty list.
2378  */
2379 void
ttyfree(struct tty * tp)2380 ttyfree(struct tty *tp)
2381 {
2382 	int s;
2383 
2384 	rw_enter_write(&ttylist_lock);
2385 	--tty_count;
2386 #ifdef DIAGNOSTIC
2387 	if (tty_count < 0)
2388 		panic("ttyfree: tty_count < 0");
2389 #endif
2390 	TAILQ_REMOVE(&ttylist, tp, tty_link);
2391 	rw_exit_write(&ttylist_lock);
2392 
2393 	s = spltty();
2394 	klist_invalidate(&tp->t_rsel.si_note);
2395 	klist_invalidate(&tp->t_wsel.si_note);
2396 	splx(s);
2397 
2398 	clfree(&tp->t_rawq);
2399 	clfree(&tp->t_canq);
2400 	clfree(&tp->t_outq);
2401 	free(tp, M_TTYS, sizeof(*tp));
2402 }
2403 
2404 void
ttystats_init(struct itty ** ttystats,int * ttycp,size_t * ttystatssiz)2405 ttystats_init(struct itty **ttystats, int *ttycp, size_t *ttystatssiz)
2406 {
2407 	int ntty = 0, ttyc;
2408 	struct itty *itp;
2409 	struct tty *tp;
2410 
2411 	ttyc = tty_count;
2412 	*ttystatssiz = ttyc * sizeof(struct itty);
2413 	*ttystats = mallocarray(ttyc, sizeof(struct itty),
2414 	    M_SYSCTL, M_WAITOK|M_ZERO);
2415 
2416 	rw_enter_write(&ttylist_lock);
2417 	for (tp = TAILQ_FIRST(&ttylist), itp = *ttystats; tp && ntty++ < ttyc;
2418 	    tp = TAILQ_NEXT(tp, tty_link), itp++) {
2419 		itp->t_dev = tp->t_dev;
2420 		itp->t_rawq_c_cc = tp->t_rawq.c_cc;
2421 		itp->t_canq_c_cc = tp->t_canq.c_cc;
2422 		itp->t_outq_c_cc = tp->t_outq.c_cc;
2423 		itp->t_hiwat = tp->t_hiwat;
2424 		itp->t_lowat = tp->t_lowat;
2425 		if (ISSET(tp->t_oflag, OPOST))
2426 			itp->t_column = tp->t_column;
2427 		itp->t_state = tp->t_state;
2428 		itp->t_session = tp->t_session;
2429 		if (tp->t_pgrp)
2430 			itp->t_pgrp_pg_id = tp->t_pgrp->pg_id;
2431 		else
2432 			itp->t_pgrp_pg_id = 0;
2433 		itp->t_line = tp->t_line;
2434 	}
2435 	rw_exit_write(&ttylist_lock);
2436 	*ttycp = ntty;
2437 }
2438 
2439 /*
2440  * Return tty-related information.
2441  */
2442 int
sysctl_tty(int * name,u_int namelen,void * oldp,size_t * oldlenp,void * newp,size_t newlen)2443 sysctl_tty(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
2444     size_t newlen)
2445 {
2446 	int err;
2447 
2448 	if (namelen != 1)
2449 		return (ENOTDIR);
2450 
2451 	switch (name[0]) {
2452 	case KERN_TTY_TKNIN:
2453 		return (sysctl_rdquad(oldp, oldlenp, newp, tk_nin));
2454 	case KERN_TTY_TKNOUT:
2455 		return (sysctl_rdquad(oldp, oldlenp, newp, tk_nout));
2456 	case KERN_TTY_TKRAWCC:
2457 		return (sysctl_rdquad(oldp, oldlenp, newp, tk_rawcc));
2458 	case KERN_TTY_TKCANCC:
2459 		return (sysctl_rdquad(oldp, oldlenp, newp, tk_cancc));
2460 	case KERN_TTY_INFO:
2461 	    {
2462 		struct itty *ttystats;
2463 		size_t ttystatssiz;
2464 		int ttyc;
2465 
2466 		ttystats_init(&ttystats, &ttyc, &ttystatssiz);
2467 		err = sysctl_rdstruct(oldp, oldlenp, newp, ttystats,
2468 		    ttyc * sizeof(struct itty));
2469 		free(ttystats, M_SYSCTL, ttystatssiz);
2470 		return (err);
2471 	    }
2472 	default:
2473 #if NPTY > 0
2474 		return (sysctl_pty(name, namelen, oldp, oldlenp, newp, newlen));
2475 #else
2476 		return (EOPNOTSUPP);
2477 #endif
2478 	}
2479 	/* NOTREACHED */
2480 }
2481 
2482 void
ttytstamp(struct tty * tp,int octs,int ncts,int odcd,int ndcd)2483 ttytstamp(struct tty *tp, int octs, int ncts, int odcd, int ndcd)
2484 {
2485 	int doit = 0;
2486 
2487 	if (ncts ^ octs)
2488 		doit |= ncts ? ISSET(tp->t_flags, TS_TSTAMPCTSSET) :
2489 		    ISSET(tp->t_flags, TS_TSTAMPCTSCLR);
2490 	if (ndcd ^ odcd)
2491 		doit |= ndcd ? ISSET(tp->t_flags, TS_TSTAMPDCDSET) :
2492 		    ISSET(tp->t_flags, TS_TSTAMPDCDCLR);
2493 
2494 	if (doit)
2495 		microtime(&tp->t_tv);
2496 }
2497