FreeBSD/Linux Kernel Cross Reference
sys/kern/tty.c
1 /* $OpenBSD: tty.c,v 1.176 2022/08/14 01:58:28 jsg 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
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
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
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
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
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 FIONBIO: /* set/clear non-blocking i/o */
768 break; /* XXX: delete. */
769 case FIONREAD: /* get # bytes to read */
770 s = spltty();
771 *(int *)data = ttnread(tp);
772 splx(s);
773 break;
774 case TIOCEXCL: /* set exclusive use of tty */
775 s = spltty();
776 SET(tp->t_state, TS_XCLUDE);
777 splx(s);
778 break;
779 case TIOCFLUSH: { /* flush buffers */
780 int flags = *(int *)data;
781
782 if (flags == 0)
783 flags = FREAD | FWRITE;
784 else
785 flags &= FREAD | FWRITE;
786 ttyflush(tp, flags);
787 break;
788 }
789 case TIOCCONS: { /* become virtual console */
790 if (*(int *)data) {
791 struct nameidata nid;
792
793 if (constty != NULL && constty != tp &&
794 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
795 (TS_CARR_ON | TS_ISOPEN))
796 return (EBUSY);
797
798 /* ensure user can open the real console */
799 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
800 nid.ni_pledge = PLEDGE_RPATH | PLEDGE_WPATH;
801 nid.ni_unveil = UNVEIL_READ | UNVEIL_WRITE;
802 error = namei(&nid);
803 if (error)
804 return (error);
805 vn_lock(nid.ni_vp, LK_EXCLUSIVE | LK_RETRY);
806 error = VOP_ACCESS(nid.ni_vp, VREAD, p->p_ucred, p);
807 VOP_UNLOCK(nid.ni_vp);
808 vrele(nid.ni_vp);
809 if (error)
810 return (error);
811
812 constty = tp;
813 } else if (tp == constty)
814 constty = NULL;
815 break;
816 }
817 case TIOCDRAIN: /* wait till output drained */
818 if ((error = ttywait(tp)) != 0)
819 return (error);
820 break;
821 case TIOCGETA: { /* get termios struct */
822 struct termios *t = (struct termios *)data;
823
824 memcpy(t, &tp->t_termios, sizeof(struct termios));
825 break;
826 }
827 case TIOCGETD: /* get line discipline */
828 *(int *)data = tp->t_line;
829 break;
830 case TIOCGWINSZ: /* get window size */
831 *(struct winsize *)data = tp->t_winsize;
832 break;
833 case TIOCGTSTAMP:
834 s = spltty();
835 *(struct timeval *)data = tp->t_tv;
836 splx(s);
837 break;
838 case FIOGETOWN: /* get pgrp of tty */
839 if (!isctty(pr, tp) && suser(p))
840 return (ENOTTY);
841 *(int *)data = tp->t_pgrp ? -tp->t_pgrp->pg_id : 0;
842 break;
843 case TIOCGPGRP: /* get pgrp of tty */
844 if (!isctty(pr, tp) && suser(p))
845 return (ENOTTY);
846 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
847 break;
848 case TIOCGSID: /* get sid of tty */
849 if (!isctty(pr, tp))
850 return (ENOTTY);
851 *(int *)data = tp->t_session->s_leader->ps_pid;
852 break;
853 case TIOCNXCL: /* reset exclusive use of tty */
854 s = spltty();
855 CLR(tp->t_state, TS_XCLUDE);
856 splx(s);
857 break;
858 case TIOCOUTQ: /* output queue size */
859 *(int *)data = tp->t_outq.c_cc;
860 break;
861 case TIOCSETA: /* set termios struct */
862 case TIOCSETAW: /* drain output, set */
863 case TIOCSETAF: { /* drn out, fls in, set */
864 struct termios *t = (struct termios *)data;
865
866 s = spltty();
867 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
868 if ((error = ttywait(tp)) != 0) {
869 splx(s);
870 return (error);
871 }
872 if (cmd == TIOCSETAF)
873 ttyflush(tp, FREAD);
874 }
875 if (!ISSET(t->c_cflag, CIGNORE)) {
876 /*
877 * Some minor validation is necessary.
878 */
879 if (t->c_ispeed < 0 || t->c_ospeed < 0) {
880 splx(s);
881 return (EINVAL);
882 }
883 /*
884 * Set device hardware.
885 */
886 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
887 splx(s);
888 return (error);
889 } else {
890 if (!ISSET(tp->t_state, TS_CARR_ON) &&
891 ISSET(tp->t_cflag, CLOCAL) &&
892 !ISSET(t->c_cflag, CLOCAL)) {
893 CLR(tp->t_state, TS_ISOPEN);
894 SET(tp->t_state, TS_WOPEN);
895 ttwakeup(tp);
896 }
897 tp->t_cflag = t->c_cflag;
898 tp->t_ispeed = t->c_ispeed;
899 tp->t_ospeed = t->c_ospeed;
900 if (t->c_ospeed == 0 && tp->t_session &&
901 tp->t_session->s_leader)
902 prsignal(tp->t_session->s_leader,
903 SIGHUP);
904 }
905 ttsetwater(tp);
906 }
907 if (cmd != TIOCSETAF) {
908 if (ISSET(t->c_lflag, ICANON) !=
909 ISSET(tp->t_lflag, ICANON)) {
910 if (ISSET(t->c_lflag, ICANON)) {
911 SET(tp->t_lflag, PENDIN);
912 ttwakeup(tp);
913 } else {
914 struct clist tq;
915
916 catq(&tp->t_rawq, &tp->t_canq);
917 tq = tp->t_rawq;
918 tp->t_rawq = tp->t_canq;
919 tp->t_canq = tq;
920 CLR(tp->t_lflag, PENDIN);
921 }
922 }
923 }
924 tp->t_iflag = t->c_iflag;
925 tp->t_oflag = t->c_oflag;
926 /*
927 * Make the EXTPROC bit read only.
928 */
929 if (ISSET(tp->t_lflag, EXTPROC))
930 SET(t->c_lflag, EXTPROC);
931 else
932 CLR(t->c_lflag, EXTPROC);
933 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
934 memcpy(tp->t_cc, t->c_cc, sizeof(t->c_cc));
935 splx(s);
936 break;
937 }
938 case TIOCSETD: { /* set line discipline */
939 int t = *(int *)data;
940 dev_t device = tp->t_dev;
941
942 if ((u_int)t >= nlinesw)
943 return (ENXIO);
944 if (t != tp->t_line) {
945 s = spltty();
946 (*linesw[tp->t_line].l_close)(tp, flag, p);
947 error = (*linesw[t].l_open)(device, tp, p);
948 if (error) {
949 (*linesw[tp->t_line].l_open)(device, tp, p);
950 splx(s);
951 return (error);
952 }
953 tp->t_line = t;
954 splx(s);
955 }
956 break;
957 }
958 case TIOCSTART: /* start output, like ^Q */
959 s = spltty();
960 if (ISSET(tp->t_state, TS_TTSTOP) ||
961 ISSET(tp->t_lflag, FLUSHO)) {
962 CLR(tp->t_lflag, FLUSHO);
963 CLR(tp->t_state, TS_TTSTOP);
964 ttstart(tp);
965 }
966 splx(s);
967 break;
968 case TIOCSTOP: /* stop output, like ^S */
969 s = spltty();
970 if (!ISSET(tp->t_state, TS_TTSTOP)) {
971 SET(tp->t_state, TS_TTSTOP);
972 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
973 }
974 splx(s);
975 break;
976 case TIOCSCTTY: /* become controlling tty */
977 /* Session ctty vnode pointer set in vnode layer. */
978 if (!SESS_LEADER(pr) ||
979 ((pr->ps_session->s_ttyvp || tp->t_session) &&
980 (tp->t_session != pr->ps_session)))
981 return (EPERM);
982 if (tp->t_session)
983 SESSRELE(tp->t_session);
984 SESSHOLD(pr->ps_session);
985 tp->t_session = pr->ps_session;
986 tp->t_pgrp = pr->ps_pgrp;
987 pr->ps_session->s_ttyp = tp;
988 atomic_setbits_int(&pr->ps_flags, PS_CONTROLT);
989 break;
990 case FIOSETOWN: { /* set pgrp of tty */
991 struct pgrp *pgrp;
992 struct process *pr1;
993 pid_t pgid = *(int *)data;
994
995 if (!isctty(pr, tp))
996 return (ENOTTY);
997 if (pgid < 0) {
998 pgrp = pgfind(-pgid);
999 } else {
1000 pr1 = prfind(pgid);
1001 if (pr1 == NULL)
1002 return (ESRCH);
1003 pgrp = pr1->ps_pgrp;
1004 }
1005 if (pgrp == NULL)
1006 return (EINVAL);
1007 else if (pgrp->pg_session != pr->ps_session)
1008 return (EPERM);
1009 tp->t_pgrp = pgrp;
1010 break;
1011 }
1012 case TIOCSPGRP: { /* set pgrp of tty */
1013 struct pgrp *pgrp = pgfind(*(int *)data);
1014
1015 if (!isctty(pr, tp))
1016 return (ENOTTY);
1017 else if (pgrp == NULL)
1018 return (EINVAL);
1019 else if (pgrp->pg_session != pr->ps_session)
1020 return (EPERM);
1021 tp->t_pgrp = pgrp;
1022 break;
1023 }
1024 case TIOCSTAT: /* get load avg stats */
1025 ttyinfo(tp);
1026 break;
1027 case TIOCSWINSZ: /* set window size */
1028 if (bcmp((caddr_t)&tp->t_winsize, data,
1029 sizeof (struct winsize))) {
1030 tp->t_winsize = *(struct winsize *)data;
1031 pgsignal(tp->t_pgrp, SIGWINCH, 1);
1032 }
1033 break;
1034 case TIOCSTSTAMP: {
1035 struct tstamps *ts = (struct tstamps *)data;
1036
1037 s = spltty();
1038 CLR(tp->t_flags, TS_TSTAMPDCDSET);
1039 CLR(tp->t_flags, TS_TSTAMPCTSSET);
1040 CLR(tp->t_flags, TS_TSTAMPDCDCLR);
1041 CLR(tp->t_flags, TS_TSTAMPCTSCLR);
1042 if (ISSET(ts->ts_set, TIOCM_CAR))
1043 SET(tp->t_flags, TS_TSTAMPDCDSET);
1044 if (ISSET(ts->ts_set, TIOCM_CTS))
1045 SET(tp->t_flags, TS_TSTAMPCTSSET);
1046 if (ISSET(ts->ts_clr, TIOCM_CAR))
1047 SET(tp->t_flags, TS_TSTAMPDCDCLR);
1048 if (ISSET(ts->ts_clr, TIOCM_CTS))
1049 SET(tp->t_flags, TS_TSTAMPCTSCLR);
1050 splx(s);
1051 break;
1052 }
1053 default:
1054 return (-1);
1055 }
1056 return (0);
1057 }
1058
1059 const struct filterops ttyread_filtops = {
1060 .f_flags = FILTEROP_ISFD,
1061 .f_attach = NULL,
1062 .f_detach = filt_ttyrdetach,
1063 .f_event = filt_ttyread,
1064 };
1065
1066 const struct filterops ttywrite_filtops = {
1067 .f_flags = FILTEROP_ISFD,
1068 .f_attach = NULL,
1069 .f_detach = filt_ttywdetach,
1070 .f_event = filt_ttywrite,
1071 };
1072
1073 const struct filterops ttyexcept_filtops = {
1074 .f_flags = FILTEROP_ISFD,
1075 .f_attach = NULL,
1076 .f_detach = filt_ttyrdetach,
1077 .f_event = filt_ttyexcept,
1078 };
1079
1080 int
1081 ttkqfilter(dev_t dev, struct knote *kn)
1082 {
1083 struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
1084 struct klist *klist;
1085 int s;
1086
1087 switch (kn->kn_filter) {
1088 case EVFILT_READ:
1089 klist = &tp->t_rsel.si_note;
1090 kn->kn_fop = &ttyread_filtops;
1091 break;
1092 case EVFILT_WRITE:
1093 klist = &tp->t_wsel.si_note;
1094 kn->kn_fop = &ttywrite_filtops;
1095 break;
1096 case EVFILT_EXCEPT:
1097 if (kn->kn_flags & __EV_SELECT) {
1098 /* Prevent triggering exceptfds. */
1099 return (EPERM);
1100 }
1101 if ((kn->kn_flags & __EV_POLL) == 0) {
1102 /* Disallow usage through kevent(2). */
1103 return (EINVAL);
1104 }
1105 klist = &tp->t_rsel.si_note;
1106 kn->kn_fop = &ttyexcept_filtops;
1107 break;
1108 default:
1109 return (EINVAL);
1110 }
1111
1112 kn->kn_hook = tp;
1113
1114 s = spltty();
1115 klist_insert_locked(klist, kn);
1116 splx(s);
1117
1118 return (0);
1119 }
1120
1121 void
1122 filt_ttyrdetach(struct knote *kn)
1123 {
1124 struct tty *tp = kn->kn_hook;
1125 int s;
1126
1127 s = spltty();
1128 klist_remove_locked(&tp->t_rsel.si_note, kn);
1129 splx(s);
1130 }
1131
1132 int
1133 filt_ttyread(struct knote *kn, long hint)
1134 {
1135 struct tty *tp = kn->kn_hook;
1136 int active, s;
1137
1138 s = spltty();
1139 kn->kn_data = ttnread(tp);
1140 active = (kn->kn_data > 0);
1141 if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
1142 kn->kn_flags |= EV_EOF;
1143 if (kn->kn_flags & __EV_POLL)
1144 kn->kn_flags |= __EV_HUP;
1145 active = 1;
1146 } else {
1147 kn->kn_flags &= ~(EV_EOF | __EV_HUP);
1148 }
1149 splx(s);
1150 return (active);
1151 }
1152
1153 void
1154 filt_ttywdetach(struct knote *kn)
1155 {
1156 struct tty *tp = kn->kn_hook;
1157 int s;
1158
1159 s = spltty();
1160 klist_remove_locked(&tp->t_wsel.si_note, kn);
1161 splx(s);
1162 }
1163
1164 int
1165 filt_ttywrite(struct knote *kn, long hint)
1166 {
1167 struct tty *tp = kn->kn_hook;
1168 int active, s;
1169
1170 s = spltty();
1171 kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc;
1172 active = (tp->t_outq.c_cc <= tp->t_lowat);
1173
1174 /* Write-side HUP condition is only for poll(2) and select(2). */
1175 if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) {
1176 if (!ISSET(tp->t_cflag, CLOCAL) &&
1177 !ISSET(tp->t_state, TS_CARR_ON)) {
1178 kn->kn_flags |= __EV_HUP;
1179 active = 1;
1180 } else {
1181 kn->kn_flags &= ~__EV_HUP;
1182 }
1183 }
1184 splx(s);
1185 return (active);
1186 }
1187
1188 int
1189 filt_ttyexcept(struct knote *kn, long hint)
1190 {
1191 struct tty *tp = kn->kn_hook;
1192 int active = 0;
1193 int s;
1194
1195 s = spltty();
1196 if (kn->kn_flags & __EV_POLL) {
1197 if (!ISSET(tp->t_cflag, CLOCAL) &&
1198 !ISSET(tp->t_state, TS_CARR_ON)) {
1199 kn->kn_flags |= __EV_HUP;
1200 active = 1;
1201 } else {
1202 kn->kn_flags &= ~__EV_HUP;
1203 }
1204 }
1205 splx(s);
1206 return (active);
1207 }
1208
1209 static int
1210 ttnread(struct tty *tp)
1211 {
1212 int nread;
1213
1214 splassert(IPL_TTY);
1215
1216 if (ISSET(tp->t_lflag, PENDIN))
1217 ttypend(tp);
1218 nread = tp->t_canq.c_cc;
1219 if (!ISSET(tp->t_lflag, ICANON)) {
1220 nread += tp->t_rawq.c_cc;
1221 if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
1222 nread = 0;
1223 }
1224 return (nread);
1225 }
1226
1227 /*
1228 * Wait for output to drain, or if this times out, flush it.
1229 */
1230 int
1231 ttywait_nsec(struct tty *tp, uint64_t nsecs)
1232 {
1233 int error, s;
1234
1235 error = 0;
1236 s = spltty();
1237 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1238 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL)) &&
1239 tp->t_oproc) {
1240 (*tp->t_oproc)(tp);
1241 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1242 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
1243 && tp->t_oproc) {
1244 SET(tp->t_state, TS_ASLEEP);
1245 error = ttysleep_nsec(tp, &tp->t_outq, TTOPRI | PCATCH,
1246 ttyout, nsecs);
1247 if (error == EWOULDBLOCK)
1248 ttyflush(tp, FWRITE);
1249 if (error)
1250 break;
1251 } else
1252 break;
1253 }
1254 splx(s);
1255 return (error);
1256 }
1257
1258 int
1259 ttywait(struct tty *tp)
1260 {
1261 return (ttywait_nsec(tp, INFSLP));
1262 }
1263
1264 /*
1265 * Flush if successfully wait.
1266 */
1267 int
1268 ttywflush(struct tty *tp)
1269 {
1270 int error;
1271
1272 error = ttywait_nsec(tp, SEC_TO_NSEC(5));
1273 if (error == 0 || error == EWOULDBLOCK)
1274 ttyflush(tp, FREAD);
1275 return (error);
1276 }
1277
1278 /*
1279 * Flush tty read and/or write queues, notifying anyone waiting.
1280 */
1281 void
1282 ttyflush(struct tty *tp, int rw)
1283 {
1284 int s;
1285
1286 s = spltty();
1287 if (rw & FREAD) {
1288 FLUSHQ(&tp->t_canq);
1289 FLUSHQ(&tp->t_rawq);
1290 tp->t_rocount = 0;
1291 tp->t_rocol = 0;
1292 CLR(tp->t_state, TS_LOCAL);
1293 ttyunblock(tp);
1294 ttwakeup(tp);
1295 }
1296 if (rw & FWRITE) {
1297 CLR(tp->t_state, TS_TTSTOP);
1298 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1299 FLUSHQ(&tp->t_outq);
1300 wakeup((caddr_t)&tp->t_outq);
1301 selwakeup(&tp->t_wsel);
1302 }
1303 splx(s);
1304 }
1305
1306 /*
1307 * Copy in the default termios characters.
1308 */
1309 void
1310 ttychars(struct tty *tp)
1311 {
1312
1313 memcpy(tp->t_cc, ttydefchars, sizeof(ttydefchars));
1314 }
1315
1316 /*
1317 * Send stop character on input overflow.
1318 */
1319 static void
1320 ttyblock(struct tty *tp)
1321 {
1322 int total;
1323
1324 total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
1325 if (tp->t_rawq.c_cc > TTYHOG(tp)) {
1326 ttyflush(tp, FREAD | FWRITE);
1327 CLR(tp->t_state, TS_TBLOCK);
1328 }
1329 /*
1330 * Block further input iff: current input > threshold
1331 * AND input is available to user program.
1332 */
1333 if ((total >= TTYHOG(tp) / 2 &&
1334 !ISSET(tp->t_state, TS_TBLOCK) &&
1335 !ISSET(tp->t_lflag, ICANON)) || tp->t_canq.c_cc > 0) {
1336 if (ISSET(tp->t_iflag, IXOFF) &&
1337 tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1338 putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
1339 SET(tp->t_state, TS_TBLOCK);
1340 ttstart(tp);
1341 }
1342 /* Try to block remote output via hardware flow control. */
1343 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1344 (*tp->t_hwiflow)(tp, 1) != 0)
1345 SET(tp->t_state, TS_TBLOCK);
1346 }
1347 }
1348
1349 void
1350 ttrstrt(void *arg)
1351 {
1352 struct tty *tp = (struct tty *)arg;
1353 int s;
1354
1355 #ifdef DIAGNOSTIC
1356 if (tp == NULL)
1357 panic("ttrstrt");
1358 #endif
1359 s = spltty();
1360 CLR(tp->t_state, TS_TIMEOUT);
1361 ttstart(tp);
1362 splx(s);
1363 }
1364
1365 int
1366 ttstart(struct tty *tp)
1367 {
1368
1369 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1370 (*tp->t_oproc)(tp);
1371 return (0);
1372 }
1373
1374 /*
1375 * "close" a line discipline
1376 */
1377 int
1378 ttylclose(struct tty *tp, int flag, struct proc *p)
1379 {
1380
1381 if (flag & FNONBLOCK)
1382 ttyflush(tp, FREAD | FWRITE);
1383 else
1384 ttywflush(tp);
1385 return (0);
1386 }
1387
1388 /*
1389 * Handle modem control transition on a tty.
1390 * Flag indicates new state of carrier.
1391 * Returns 0 if the line should be turned off, otherwise 1.
1392 */
1393 int
1394 ttymodem(struct tty *tp, int flag)
1395 {
1396
1397 if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
1398 /*
1399 * MDMBUF: do flow control according to carrier flag
1400 */
1401 if (flag) {
1402 CLR(tp->t_state, TS_TTSTOP);
1403 ttstart(tp);
1404 } else if (!ISSET(tp->t_state, TS_TTSTOP)) {
1405 SET(tp->t_state, TS_TTSTOP);
1406 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
1407 }
1408 } else if (flag == 0) {
1409 /*
1410 * Lost carrier.
1411 */
1412 CLR(tp->t_state, TS_CARR_ON);
1413 if (ISSET(tp->t_state, TS_ISOPEN) &&
1414 !ISSET(tp->t_cflag, CLOCAL)) {
1415 if (tp->t_session && tp->t_session->s_leader)
1416 prsignal(tp->t_session->s_leader, SIGHUP);
1417 ttyflush(tp, FREAD | FWRITE);
1418 return (0);
1419 }
1420 } else {
1421 /*
1422 * Carrier now on.
1423 */
1424 SET(tp->t_state, TS_CARR_ON);
1425 ttwakeup(tp);
1426 }
1427 return (1);
1428 }
1429
1430 /*
1431 * Default modem control routine (for other line disciplines).
1432 * Return argument flag, to turn off device on carrier drop.
1433 */
1434 int
1435 nullmodem(struct tty *tp, int flag)
1436 {
1437
1438 if (flag)
1439 SET(tp->t_state, TS_CARR_ON);
1440 else {
1441 CLR(tp->t_state, TS_CARR_ON);
1442 if (ISSET(tp->t_state, TS_ISOPEN) &&
1443 !ISSET(tp->t_cflag, CLOCAL)) {
1444 if (tp->t_session && tp->t_session->s_leader)
1445 prsignal(tp->t_session->s_leader, SIGHUP);
1446 ttyflush(tp, FREAD | FWRITE);
1447 return (0);
1448 }
1449 }
1450 return (1);
1451 }
1452
1453 /*
1454 * Reinput pending characters after state switch
1455 * call at spltty().
1456 */
1457 void
1458 ttypend(struct tty *tp)
1459 {
1460 struct clist tq;
1461 int c;
1462
1463 splassert(IPL_TTY);
1464
1465 CLR(tp->t_lflag, PENDIN);
1466 SET(tp->t_state, TS_TYPEN);
1467 tq = tp->t_rawq;
1468 tp->t_rawq.c_cc = 0;
1469 tp->t_rawq.c_cf = tp->t_rawq.c_cl = NULL;
1470 while ((c = getc(&tq)) >= 0)
1471 ttyinput(c, tp);
1472 CLR(tp->t_state, TS_TYPEN);
1473 }
1474
1475 void ttvtimeout(void *);
1476
1477 void
1478 ttvtimeout(void *arg)
1479 {
1480 struct tty *tp = (struct tty *)arg;
1481
1482 wakeup(&tp->t_rawq);
1483 }
1484
1485 /*
1486 * Process a read call on a tty device.
1487 */
1488 int
1489 ttread(struct tty *tp, struct uio *uio, int flag)
1490 {
1491 struct timeout *stime = NULL;
1492 struct proc *p = curproc;
1493 struct process *pr = p->p_p;
1494 int s, first, error = 0;
1495 u_char *cc = tp->t_cc;
1496 struct clist *qp;
1497 int last_cc = 0;
1498 long lflag;
1499 int c;
1500
1501 loop: lflag = tp->t_lflag;
1502 s = spltty();
1503 /*
1504 * take pending input first
1505 */
1506 if (ISSET(lflag, PENDIN))
1507 ttypend(tp);
1508 splx(s);
1509
1510 /*
1511 * Hang process if it's in the background.
1512 */
1513 if (isbackground(pr, tp)) {
1514 if (sigismasked(p, SIGTTIN) ||
1515 pr->ps_flags & PS_PPWAIT || pr->ps_pgrp->pg_jobc == 0) {
1516 error = EIO;
1517 goto out;
1518 }
1519 pgsignal(pr->ps_pgrp, SIGTTIN, 1);
1520 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg);
1521 if (error)
1522 goto out;
1523 goto loop;
1524 }
1525
1526 s = spltty();
1527 if (!ISSET(lflag, ICANON)) {
1528 int min = cc[VMIN];
1529 int time = cc[VTIME] * 100; /* tenths of a second (ms) */
1530
1531 qp = &tp->t_rawq;
1532 /*
1533 * Check each of the four combinations.
1534 * (min > 0 && time == 0) is the normal read case.
1535 * It should be fairly efficient, so we check that and its
1536 * companion case (min == 0 && time == 0) first.
1537 */
1538 if (time == 0) {
1539 if (qp->c_cc < min)
1540 goto sleep;
1541 goto read;
1542 }
1543 if (min > 0) {
1544 if (qp->c_cc <= 0)
1545 goto sleep;
1546 if (qp->c_cc >= min)
1547 goto read;
1548 if (stime == NULL) {
1549 alloc_timer:
1550 stime = malloc(sizeof(*stime), M_TEMP, M_WAITOK);
1551 timeout_set(stime, ttvtimeout, tp);
1552 timeout_add_msec(stime, time);
1553 } else if (qp->c_cc > last_cc) {
1554 /* got a character, restart timer */
1555 timeout_add_msec(stime, time);
1556 }
1557 } else { /* min == 0 */
1558 if (qp->c_cc > 0)
1559 goto read;
1560 if (stime == NULL) {
1561 goto alloc_timer;
1562 }
1563 }
1564 last_cc = qp->c_cc;
1565 if (stime && !timeout_triggered(stime)) {
1566 goto sleep;
1567 }
1568 } else if ((qp = &tp->t_canq)->c_cc <= 0) {
1569 int carrier;
1570
1571 sleep:
1572 /*
1573 * If there is no input, sleep on rawq
1574 * awaiting hardware receipt and notification.
1575 * If we have data, we don't need to check for carrier.
1576 */
1577 carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1578 ISSET(tp->t_cflag, CLOCAL);
1579 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1580 splx(s);
1581 error = 0;
1582 goto out;
1583 }
1584 if (flag & IO_NDELAY) {
1585 splx(s);
1586 error = EWOULDBLOCK;
1587 goto out;
1588 }
1589 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
1590 carrier ? ttyin : ttopen);
1591 splx(s);
1592 if (stime && timeout_triggered(stime))
1593 error = EWOULDBLOCK;
1594 if (cc[VMIN] == 0 && error == EWOULDBLOCK) {
1595 error = 0;
1596 goto out;
1597 }
1598 if (error && error != EWOULDBLOCK)
1599 goto out;
1600 error = 0;
1601 goto loop;
1602 }
1603 read:
1604 splx(s);
1605
1606 /*
1607 * Input present, check for input mapping and processing.
1608 */
1609 first = 1;
1610 while ((c = getc(qp)) >= 0) {
1611 /*
1612 * delayed suspend (^Y)
1613 */
1614 if (CCEQ(cc[VDSUSP], c) &&
1615 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1616 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1617 if (first) {
1618 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1619 ttybg);
1620 if (error)
1621 break;
1622 goto loop;
1623 }
1624 break;
1625 }
1626 /*
1627 * Interpret EOF only in canonical mode.
1628 */
1629 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1630 break;
1631 /*
1632 * Give user character.
1633 */
1634 error = ureadc(c, uio);
1635 if (error)
1636 break;
1637 if (uio->uio_resid == 0)
1638 break;
1639 /*
1640 * In canonical mode check for a "break character"
1641 * marking the end of a "line of input".
1642 */
1643 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1644 break;
1645 first = 0;
1646 }
1647 /*
1648 * Look to unblock output now that (presumably)
1649 * the input queue has gone down.
1650 */
1651 s = spltty();
1652 if (tp->t_rawq.c_cc < TTYHOG(tp)/5)
1653 ttyunblock(tp);
1654 splx(s);
1655
1656 out:
1657 if (stime) {
1658 timeout_del(stime);
1659 free(stime, M_TEMP, sizeof(*stime));
1660 }
1661 return (error);
1662 }
1663
1664 /* Call at spltty */
1665 void
1666 ttyunblock(struct tty *tp)
1667 {
1668 u_char *cc = tp->t_cc;
1669
1670 splassert(IPL_TTY);
1671
1672 if (ISSET(tp->t_state, TS_TBLOCK)) {
1673 if (ISSET(tp->t_iflag, IXOFF) &&
1674 cc[VSTART] != _POSIX_VDISABLE &&
1675 putc(cc[VSTART], &tp->t_outq) == 0) {
1676 CLR(tp->t_state, TS_TBLOCK);
1677 ttstart(tp);
1678 }
1679 /* Try to unblock remote output via hardware flow control. */
1680 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1681 (*tp->t_hwiflow)(tp, 0) != 0)
1682 CLR(tp->t_state, TS_TBLOCK);
1683 }
1684 }
1685
1686 /*
1687 * Check the output queue on tp for space for a kernel message (from uprintf
1688 * or tprintf). Allow some space over the normal hiwater mark so we don't
1689 * lose messages due to normal flow control, but don't let the tty run amok.
1690 * Sleeps here are not interruptible, but we return prematurely if new signals
1691 * arrive.
1692 */
1693 int
1694 ttycheckoutq(struct tty *tp, int wait)
1695 {
1696 int hiwat, s, oldsig;
1697
1698 hiwat = tp->t_hiwat;
1699 s = spltty();
1700 oldsig = wait ? SIGPENDING(curproc) : 0;
1701 if (tp->t_outq.c_cc > hiwat + TTHIWATMINSPACE)
1702 while (tp->t_outq.c_cc > hiwat) {
1703 ttstart(tp);
1704 if (wait == 0 || SIGPENDING(curproc) != oldsig) {
1705 splx(s);
1706 return (0);
1707 }
1708 SET(tp->t_state, TS_ASLEEP);
1709 tsleep_nsec(&tp->t_outq, PZERO - 1, "ttckoutq",
1710 SEC_TO_NSEC(1));
1711 }
1712 splx(s);
1713 return (1);
1714 }
1715
1716 /*
1717 * Process a write call on a tty device.
1718 */
1719 int
1720 ttwrite(struct tty *tp, struct uio *uio, int flag)
1721 {
1722 u_char *cp = NULL;
1723 int cc, ce, obufcc = 0;
1724 struct proc *p;
1725 struct process *pr;
1726 int hiwat, error, s;
1727 size_t cnt;
1728 u_char obuf[OBUFSIZ];
1729
1730 hiwat = tp->t_hiwat;
1731 cnt = uio->uio_resid;
1732 error = 0;
1733 cc = 0;
1734 loop:
1735 s = spltty();
1736 if (!ISSET(tp->t_state, TS_CARR_ON) &&
1737 !ISSET(tp->t_cflag, CLOCAL)) {
1738 if (ISSET(tp->t_state, TS_ISOPEN)) {
1739 splx(s);
1740 error = EIO;
1741 goto done;
1742 } else if (flag & IO_NDELAY) {
1743 splx(s);
1744 error = EWOULDBLOCK;
1745 goto out;
1746 } else {
1747 /* Sleep awaiting carrier. */
1748 error = ttysleep(tp,
1749 &tp->t_rawq, TTIPRI | PCATCH, ttopen);
1750 splx(s);
1751 if (error)
1752 goto out;
1753 goto loop;
1754 }
1755 }
1756 splx(s);
1757 /*
1758 * Hang the process if it's in the background.
1759 */
1760 p = curproc;
1761 pr = p->p_p;
1762 if (isbackground(pr, tp) &&
1763 ISSET(tp->t_lflag, TOSTOP) && (pr->ps_flags & PS_PPWAIT) == 0 &&
1764 !sigismasked(p, SIGTTOU)) {
1765 if (pr->ps_pgrp->pg_jobc == 0) {
1766 error = EIO;
1767 goto out;
1768 }
1769 pgsignal(pr->ps_pgrp, SIGTTOU, 1);
1770 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg);
1771 if (error)
1772 goto out;
1773 goto loop;
1774 }
1775 /*
1776 * Process the user's data in at most OBUFSIZ chunks. Perform any
1777 * output translation. Keep track of high water mark, sleep on
1778 * overflow awaiting device aid in acquiring new space.
1779 */
1780 while (uio->uio_resid > 0 || cc > 0) {
1781 if (ISSET(tp->t_lflag, FLUSHO)) {
1782 uio->uio_resid = 0;
1783 goto done;
1784 }
1785 if (tp->t_outq.c_cc > hiwat)
1786 goto ovhiwat;
1787 /*
1788 * Grab a hunk of data from the user, unless we have some
1789 * leftover from last time.
1790 */
1791 if (cc == 0) {
1792 cc = MIN(uio->uio_resid, OBUFSIZ);
1793 cp = obuf;
1794 error = uiomove(cp, cc, uio);
1795 if (error) {
1796 cc = 0;
1797 break;
1798 }
1799 if (cc > obufcc)
1800 obufcc = cc;
1801
1802 /* duplicate /dev/console output into console buffer */
1803 if (consbufp && cn_tab &&
1804 cn_tab->cn_dev == tp->t_dev && tp->t_gen == 0) {
1805 int i;
1806 for (i = 0; i < cc; i++) {
1807 char c = cp[i];
1808 if (c != '\0' && c != '\r' && c != 0177)
1809 msgbuf_putchar(consbufp, c);
1810 }
1811 }
1812 }
1813 /*
1814 * If nothing fancy need be done, grab those characters we
1815 * can handle without any of ttyoutput's processing and
1816 * just transfer them to the output q. For those chars
1817 * which require special processing (as indicated by the
1818 * bits in char_type), call ttyoutput. After processing
1819 * a hunk of data, look for FLUSHO so ^O's will take effect
1820 * immediately.
1821 */
1822 while (cc > 0) {
1823 int i;
1824 if (!ISSET(tp->t_oflag, OPOST))
1825 ce = cc;
1826 else {
1827 ce = cc - scanc((u_int)cc, cp, char_type,
1828 CCLASSMASK);
1829 /*
1830 * If ce is zero, then we're processing
1831 * a special character through ttyoutput.
1832 */
1833 if (ce == 0) {
1834 tp->t_rocount = 0;
1835 if (ttyoutput(*cp, tp) >= 0) {
1836 /* out of space */
1837 goto ovhiwat;
1838 }
1839 cp++;
1840 cc--;
1841 if (ISSET(tp->t_lflag, FLUSHO) ||
1842 tp->t_outq.c_cc > hiwat)
1843 goto ovhiwat;
1844 continue;
1845 }
1846 }
1847 /*
1848 * A bunch of normal characters have been found.
1849 * Transfer them en masse to the output queue and
1850 * continue processing at the top of the loop.
1851 * If there are any further characters in this
1852 * <= OBUFSIZ chunk, the first should be a character
1853 * requiring special handling by ttyoutput.
1854 */
1855 tp->t_rocount = 0;
1856 i = b_to_q(cp, ce, &tp->t_outq);
1857 ce -= i;
1858 tp->t_column += ce;
1859 cp += ce, cc -= ce, tk_nout += ce;
1860 tp->t_outcc += ce;
1861 if (i > 0) {
1862 /* out of space */
1863 goto ovhiwat;
1864 }
1865 if (ISSET(tp->t_lflag, FLUSHO) ||
1866 tp->t_outq.c_cc > hiwat)
1867 break;
1868 }
1869 ttstart(tp);
1870 }
1871 out:
1872 /*
1873 * If cc is nonzero, we leave the uio structure inconsistent, as the
1874 * offset and iov pointers have moved forward, but it doesn't matter
1875 * (the call will either return short or restart with a new uio).
1876 */
1877 uio->uio_resid += cc;
1878 done:
1879 if (obufcc)
1880 explicit_bzero(obuf, obufcc);
1881 return (error);
1882
1883 ovhiwat:
1884 ttstart(tp);
1885 s = spltty();
1886 /*
1887 * This can only occur if FLUSHO is set in t_lflag,
1888 * or if ttstart/oproc is synchronous (or very fast).
1889 */
1890 if (tp->t_outq.c_cc <= hiwat) {
1891 splx(s);
1892 goto loop;
1893 }
1894 if (flag & IO_NDELAY) {
1895 splx(s);
1896 uio->uio_resid += cc;
1897 if (obufcc)
1898 explicit_bzero(obuf, obufcc);
1899 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1900 }
1901 SET(tp->t_state, TS_ASLEEP);
1902 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout);
1903 splx(s);
1904 if (error)
1905 goto out;
1906 goto loop;
1907 }
1908
1909 /*
1910 * Rubout one character from the rawq of tp
1911 * as cleanly as possible.
1912 */
1913 int
1914 ttyrub(int c, struct tty *tp)
1915 {
1916 u_char *cp;
1917 int savecol;
1918 int tabc, s, cc;
1919
1920 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1921 return 0;
1922 CLR(tp->t_lflag, FLUSHO);
1923 if (ISSET(tp->t_lflag, ECHOE)) {
1924 if (tp->t_rocount == 0) {
1925 /*
1926 * Screwed by ttwrite; retype
1927 */
1928 return ttyretype(tp);
1929 }
1930 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1931 ttyrubo(tp, 2);
1932 else {
1933 CLR(c, ~TTY_CHARMASK);
1934 switch (CCLASS(c)) {
1935 case ORDINARY:
1936 ttyrubo(tp, 1);
1937 break;
1938 case BACKSPACE:
1939 case CONTROL:
1940 case NEWLINE:
1941 case RETURN:
1942 case VTAB:
1943 if (ISSET(tp->t_lflag, ECHOCTL))
1944 ttyrubo(tp, 2);
1945 break;
1946 case TAB:
1947 if (tp->t_rocount < tp->t_rawq.c_cc)
1948 return ttyretype(tp);
1949 s = spltty();
1950 savecol = tp->t_column;
1951 SET(tp->t_state, TS_CNTTB);
1952 SET(tp->t_lflag, FLUSHO);
1953 tp->t_column = tp->t_rocol;
1954 for (cp = firstc(&tp->t_rawq, &tabc, &cc); cp;
1955 cp = nextc(&tp->t_rawq, cp, &tabc, &cc))
1956 ttyecho(tabc, tp);
1957 CLR(tp->t_lflag, FLUSHO);
1958 CLR(tp->t_state, TS_CNTTB);
1959 splx(s);
1960
1961 /* savecol will now be length of the tab. */
1962 savecol -= tp->t_column;
1963 tp->t_column += savecol;
1964 if (savecol > 8)
1965 savecol = 8; /* overflow screw */
1966 while (--savecol >= 0)
1967 (void)ttyoutput('\b', tp);
1968 break;
1969 default: /* XXX */
1970 #define PANICSTR "ttyrub: would panic c = %d, val = %d"
1971 (void)printf(PANICSTR "\n", c, CCLASS(c));
1972 #ifdef notdef
1973 panic(PANICSTR, c, CCLASS(c));
1974 #endif
1975 }
1976 }
1977 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
1978 if (!ISSET(tp->t_state, TS_ERASE)) {
1979 SET(tp->t_state, TS_ERASE);
1980 (void)ttyoutput('\\', tp);
1981 }
1982 ttyecho(c, tp);
1983 } else
1984 ttyecho(tp->t_cc[VERASE], tp);
1985 --tp->t_rocount;
1986 return 0;
1987 }
1988
1989 /*
1990 * Back over cnt characters, erasing them.
1991 */
1992 static void
1993 ttyrubo(struct tty *tp, int cnt)
1994 {
1995
1996 while (cnt-- > 0) {
1997 (void)ttyoutput('\b', tp);
1998 (void)ttyoutput(' ', tp);
1999 (void)ttyoutput('\b', tp);
2000 }
2001 }
2002
2003 /*
2004 * ttyretype --
2005 * Reprint the rawq line. Note, it is assumed that c_cc has already
2006 * been checked.
2007 */
2008 int
2009 ttyretype(struct tty *tp)
2010 {
2011 u_char *cp;
2012 int s, c, cc;
2013
2014 /* Echo the reprint character. */
2015 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2016 ttyecho(tp->t_cc[VREPRINT], tp);
2017
2018 (void)ttyoutput('\n', tp);
2019
2020 s = spltty();
2021 for (cp = firstc(&tp->t_canq, &c, &cc); cp;
2022 cp = nextc(&tp->t_canq, cp, &c, &cc))
2023 ttyecho(c, tp);
2024 for (cp = firstc(&tp->t_rawq, &c, &cc); cp;
2025 cp = nextc(&tp->t_rawq, cp, &c, &cc))
2026 ttyecho(c, tp);
2027 CLR(tp->t_state, TS_ERASE);
2028 splx(s);
2029
2030 tp->t_rocount = tp->t_rawq.c_cc;
2031 tp->t_rocol = 0;
2032 return (1);
2033 }
2034
2035 /*
2036 * Echo a typed character to the terminal.
2037 */
2038 static void
2039 ttyecho(int c, struct tty *tp)
2040 {
2041
2042 if (!ISSET(tp->t_state, TS_CNTTB))
2043 CLR(tp->t_lflag, FLUSHO);
2044 if ((!ISSET(tp->t_lflag, ECHO) &&
2045 (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
2046 ISSET(tp->t_lflag, EXTPROC))
2047 return;
2048 if (((ISSET(tp->t_lflag, ECHOCTL) &&
2049 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
2050 ISSET(c, TTY_CHARMASK) == 0177)) {
2051 (void)ttyoutput('^', tp);
2052 CLR(c, ~TTY_CHARMASK);
2053 if (c == 0177)
2054 c = '?';
2055 else
2056 c += 'A' - 1;
2057 }
2058 (void)ttyoutput(c, tp);
2059 }
2060
2061 /*
2062 * Wakeup any writers if necessary.
2063 */
2064 void
2065 ttwakeupwr(struct tty *tp)
2066 {
2067
2068 if (tp->t_outq.c_cc <= tp->t_lowat) {
2069 if (ISSET(tp->t_state, TS_ASLEEP)) {
2070 CLR(tp->t_state, TS_ASLEEP);
2071 wakeup(&tp->t_outq);
2072 }
2073 selwakeup(&tp->t_wsel);
2074 }
2075 }
2076
2077 /*
2078 * Wake up any readers on a tty.
2079 */
2080 void
2081 ttwakeup(struct tty *tp)
2082 {
2083
2084 selwakeup(&tp->t_rsel);
2085 if (ISSET(tp->t_state, TS_ASYNC))
2086 pgsignal(tp->t_pgrp, SIGIO, 1);
2087 wakeup((caddr_t)&tp->t_rawq);
2088 }
2089
2090 /*
2091 * Look up a code for a specified speed in a conversion table;
2092 * used by drivers to map software speed values to hardware parameters.
2093 */
2094 int
2095 ttspeedtab(int speed, const struct speedtab *table)
2096 {
2097
2098 for ( ; table->sp_speed != -1; table++)
2099 if (table->sp_speed == speed)
2100 return (table->sp_code);
2101 return (-1);
2102 }
2103
2104 /*
2105 * Set tty hi and low water marks.
2106 *
2107 * Try to arrange the dynamics so there's about one second
2108 * from hi to low water.
2109 */
2110 void
2111 ttsetwater(struct tty *tp)
2112 {
2113 int cps, x;
2114
2115 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2116
2117 cps = tp->t_ospeed / 10;
2118 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2119 x += cps;
2120 tp->t_hiwat = CLAMP(x, tp->t_outq.c_cn - TTHIWATMINSPACE, TTMINHIWAT);
2121 #undef CLAMP
2122 }
2123
2124 /*
2125 * Get the total estcpu for a process, summing across threads.
2126 * Returns true if at least one thread is runnable/running.
2127 */
2128 static int
2129 process_sum(struct process *pr, fixpt_t *estcpup)
2130 {
2131 struct proc *p;
2132 fixpt_t estcpu;
2133 int ret;
2134
2135 ret = 0;
2136 estcpu = 0;
2137 TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
2138 if (p->p_stat == SRUN || p->p_stat == SONPROC)
2139 ret = 1;
2140 estcpu += p->p_pctcpu;
2141 }
2142
2143 *estcpup = estcpu;
2144 return (ret);
2145 }
2146
2147 /*
2148 * Report on state of foreground process group.
2149 */
2150 void
2151 ttyinfo(struct tty *tp)
2152 {
2153 struct process *pr, *pickpr;
2154 struct proc *p, *pick;
2155 struct timespec utime, stime;
2156 int tmp;
2157
2158 if (ttycheckoutq(tp,0) == 0)
2159 return;
2160
2161 /* Print load average. */
2162 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2163 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2164
2165 if (tp->t_session == NULL)
2166 ttyprintf(tp, "not a controlling terminal\n");
2167 else if (tp->t_pgrp == NULL)
2168 ttyprintf(tp, "no foreground process group\n");
2169 else if ((pr = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL)
2170 empty: ttyprintf(tp, "empty foreground process group\n");
2171 else {
2172 const char *state;
2173 fixpt_t pctcpu, pctcpu2;
2174 int run, run2;
2175 int calc_pctcpu;
2176 long rss = 0;
2177
2178 /*
2179 * Pick the most active process:
2180 * - prefer at least one running/runnable thread
2181 * - prefer higher total pctcpu
2182 * - prefer non-zombie
2183 * Otherwise take the most recently added to this process group
2184 */
2185 pickpr = pr;
2186 run = process_sum(pickpr, &pctcpu);
2187 while ((pr = LIST_NEXT(pr, ps_pglist)) != NULL) {
2188 run2 = process_sum(pr, &pctcpu2);
2189 if (run) {
2190 /*
2191 * pick is running; is p running w/same or
2192 * more cpu?
2193 */
2194 if (run2 && pctcpu2 >= pctcpu)
2195 goto update_pickpr;
2196 continue;
2197 }
2198 /* pick isn't running; is p running *or* w/more cpu? */
2199 if (run2 || pctcpu2 > pctcpu)
2200 goto update_pickpr;
2201
2202 /* if p has less cpu or is zombie, then it's worse */
2203 if (pctcpu2 < pctcpu || (pr->ps_flags & PS_ZOMBIE))
2204 continue;
2205 update_pickpr:
2206 pickpr = pr;
2207 run = run2;
2208 pctcpu = pctcpu2;
2209 }
2210
2211 /* Calculate percentage cpu, resident set size. */
2212 calc_pctcpu = (pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
2213 if ((pickpr->ps_flags & (PS_EMBRYO | PS_ZOMBIE)) == 0 &&
2214 pickpr->ps_vmspace != NULL)
2215 rss = vm_resident_count(pickpr->ps_vmspace);
2216
2217 calctsru(&pickpr->ps_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
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
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
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
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 *
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
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
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
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
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 }
Cache object: 0b625d2a80081dba7874ffef906f9307
|