2 * Copyright (c) 1997-2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1982, 1986, 1990, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
31 * (c) UNIX System Laboratories, Inc.
32 * All or some portions of this file are derived from material licensed
33 * to the University of California by American Telephone and Telegraph
34 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
35 * the permission of UNIX System Laboratories, Inc.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by the University of
48 * California, Berkeley and its contributors.
49 * 4. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * @(#)tty.c 8.8 (Berkeley) 1/21/94
69 * o Fix races for sending the start char in ttyflush().
70 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
71 * With luck, there will be MIN chars before select() returns().
72 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it.
73 * o Don't allow input in TS_ZOMBIE case. It would be visible through
75 * o Do the new sio locking stuff here and use it to avoid special
78 * o Move EXTPROC and/or PENDIN to t_state?
79 * o Wrap most of ttioctl in spltty/splx.
80 * o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
81 * o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
82 * o Don't allow certain termios flags to affect disciplines other
83 * than TTYDISC. Cancel their effects before switch disciplines
84 * and ignore them if they are set while we are in another
86 * o Handle c_ispeed = 0 to c_ispeed = c_ospeed conversion here instead
87 * of in drivers and fix drivers that write to tp->t_termios.
88 * o Check for TS_CARR_ON being set while everything is closed and not
89 * waiting for carrier. TS_CARR_ON isn't cleared if nothing is open,
90 * so it would live until the next open even if carrier drops.
91 * o Restore TS_WOPEN since it is useful in pstat. It must be cleared
92 * only when _all_ openers leave open().
94 #include <sys/param.h>
96 #include <sys/systm.h>
98 #include <sys/ioctl.h>
99 #include <sys/proc_internal.h>
100 #include <sys/kauth.h>
101 #include <sys/file_internal.h>
102 #include <sys/conf.h>
103 #include <sys/dkstat.h>
104 #include <sys/uio_internal.h>
105 #include <sys/kernel.h>
106 #include <sys/vnode.h>
107 #include <sys/syslog.h>
108 #include <sys/user.h>
109 #include <sys/signalvar.h>
110 #include <sys/signalvar.h>
111 #include <sys/malloc.h>
113 #include <dev/kmreg_com.h>
114 #include <machine/cons.h>
115 #include <sys/resource.h> /* averunnable */
116 #include <kern/waitq.h>
117 #include <libkern/section_keywords.h>
119 static lck_grp_t
*tty_lck_grp
;
120 static lck_grp_attr_t
*tty_lck_grp_attr
;
121 static lck_attr_t
*tty_lck_attr
;
123 __private_extern__
int ttnread(struct tty
*tp
);
124 static void ttyecho(int c
, struct tty
*tp
);
125 static int ttyoutput(int c
, struct tty
*tp
);
126 static void ttypend(struct tty
*tp
);
127 static void ttyretype(struct tty
*tp
);
128 static void ttyrub(int c
, struct tty
*tp
);
129 static void ttyrubo(struct tty
*tp
, int count
);
130 static void ttystop(struct tty
*tp
, int rw
);
131 static void ttyunblock(struct tty
*tp
);
132 static int ttywflush(struct tty
*tp
);
133 static int proc_compare(proc_t p1
, proc_t p2
);
135 void ttyhold(struct tty
*tp
);
136 static void ttydeallocate(struct tty
*tp
);
138 static int isctty(proc_t p
, struct tty
*tp
);
139 static int isctty_sp(proc_t p
, struct tty
*tp
, struct session
*sessp
);
142 * Table with character classes and parity. The 8th bit indicates parity,
143 * the 7th bit indicates the character is an alphameric or underscore (for
144 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
145 * are 0 then the character needs no special processing on output; classes
146 * other than 0 might be translated or (not currently) require delays.
148 #define E 0x00 /* Even parity. */
149 #define O 0x80 /* Odd parity. */
150 #define PARITY(c) (char_type[c] & O)
152 #define ALPHA 0x40 /* Alpha or underscore. */
153 #define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
155 #define CCLASSMASK 0x3f
156 #define CCLASS(c) (char_type[c] & CCLASSMASK)
157 /* 0b10xxxxxx is the mask for UTF-8 continuations */
158 #define CCONT(c) ((c & 0xc0) == 0x80)
163 #define NA ORDINARY | ALPHA
169 static u_char
const char_type
[] = {
170 E
| CC
, O
| CC
, O
| CC
, E
| CC
, O
| CC
, E
| CC
, E
| CC
, O
| CC
, /* nul - bel */
171 O
| BS
, E
| TB
, E
| NL
, O
| CC
, E
| VT
, O
| CR
, O
| CC
, E
| CC
, /* bs - si */
172 O
| CC
, E
| CC
, E
| CC
, O
| CC
, E
| CC
, O
| CC
, O
| CC
, E
| CC
, /* dle - etb */
173 E
| CC
, O
| CC
, O
| CC
, E
| CC
, O
| CC
, E
| CC
, E
| CC
, O
| CC
, /* can - us */
174 O
| NO
, E
| NO
, E
| NO
, O
| NO
, E
| NO
, O
| NO
, O
| NO
, E
| NO
, /* sp - ' */
175 E
| NO
, O
| NO
, O
| NO
, E
| NO
, O
| NO
, E
| NO
, E
| NO
, O
| NO
, /* ( - / */
176 E
| NA
, O
| NA
, O
| NA
, E
| NA
, O
| NA
, E
| NA
, E
| NA
, O
| NA
, /* 0 - 7 */
177 O
| NA
, E
| NA
, E
| NO
, O
| NO
, E
| NO
, O
| NO
, O
| NO
, E
| NO
, /* 8 - ? */
178 O
| NO
, E
| NA
, E
| NA
, O
| NA
, E
| NA
, O
| NA
, O
| NA
, E
| NA
, /* @ - G */
179 E
| NA
, O
| NA
, O
| NA
, E
| NA
, O
| NA
, E
| NA
, E
| NA
, O
| NA
, /* H - O */
180 E
| NA
, O
| NA
, O
| NA
, E
| NA
, O
| NA
, E
| NA
, E
| NA
, O
| NA
, /* P - W */
181 O
| NA
, E
| NA
, E
| NA
, O
| NO
, E
| NO
, O
| NO
, O
| NO
, O
| NA
, /* X - _ */
182 E
| NO
, O
| NA
, O
| NA
, E
| NA
, O
| NA
, E
| NA
, E
| NA
, O
| NA
, /* ` - g */
183 O
| NA
, E
| NA
, E
| NA
, O
| NA
, E
| NA
, O
| NA
, O
| NA
, E
| NA
, /* h - o */
184 O
| NA
, E
| NA
, E
| NA
, O
| NA
, E
| NA
, O
| NA
, O
| NA
, E
| NA
, /* p - w */
185 E
| NA
, O
| NA
, O
| NA
, E
| NO
, O
| NO
, E
| NO
, E
| NO
, O
| CC
, /* x - del */
187 * Meta chars; should be settable per character set;
188 * for now, treat them all as normal characters.
190 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
191 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
192 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
193 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
194 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
195 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
196 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
197 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
198 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
199 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
200 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
201 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
202 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
203 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
204 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
205 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
216 /* Macros to clear/set/test flags. */
217 #define SET(t, f) (t) |= (f)
218 #define CLR(t, f) (t) &= ~(f)
219 #define ISSET(t, f) ((t) & (f))
222 * Input control starts when we would not be able to fit the maximum
223 * contents of the ping-pong buffers and finishes when we would be able
224 * to fit that much plus 1/8 more.
226 #define I_HIGH_WATER (TTYHOG - 2 * 256) /* XXX */
227 #define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
230 termios32to64(struct termios32
*in
, struct user_termios
*out
)
232 out
->c_iflag
= (user_tcflag_t
)in
->c_iflag
;
233 out
->c_oflag
= (user_tcflag_t
)in
->c_oflag
;
234 out
->c_cflag
= (user_tcflag_t
)in
->c_cflag
;
235 out
->c_lflag
= (user_tcflag_t
)in
->c_lflag
;
237 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
238 bcopy(in
->c_cc
, out
->c_cc
, sizeof(in
->c_cc
));
240 out
->c_ispeed
= (user_speed_t
)in
->c_ispeed
;
241 out
->c_ospeed
= (user_speed_t
)in
->c_ospeed
;
245 termios64to32(struct user_termios
*in
, struct termios32
*out
)
247 out
->c_iflag
= (tcflag_t
)in
->c_iflag
;
248 out
->c_oflag
= (tcflag_t
)in
->c_oflag
;
249 out
->c_cflag
= (tcflag_t
)in
->c_cflag
;
250 out
->c_lflag
= (tcflag_t
)in
->c_lflag
;
252 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
253 bcopy(in
->c_cc
, out
->c_cc
, sizeof(in
->c_cc
));
255 out
->c_ispeed
= (speed_t
)in
->c_ispeed
;
256 out
->c_ospeed
= (speed_t
)in
->c_ospeed
;
263 * Initialize the tty line discipline subsystem.
269 * Locks: No ttys can be allocated and no tty locks can be used
270 * until after this function is called
272 * Notes: The intent of this is to set up a log group attribute,
273 * lock group, and loc atribute for subsequent per-tty locks.
274 * This function is called early in bsd_init(), prior to the
275 * console device initialization.
280 tty_lck_grp_attr
= lck_grp_attr_alloc_init();
281 tty_lck_grp
= lck_grp_alloc_init("tty", tty_lck_grp_attr
);
282 tty_lck_attr
= lck_attr_alloc_init();
289 * Lock the requested tty structure.
291 * Parameters: tp The tty we want to lock
295 * Locks: On return, tp is locked
298 tty_lock(struct tty
*tp
)
300 TTY_LOCK_NOTOWNED(tp
); /* debug assert */
301 lck_mtx_lock(&tp
->t_lock
);
308 * Unlock the requested tty structure.
310 * Parameters: tp The tty we want to unlock
314 * Locks: On return, tp is unlocked
317 tty_unlock(struct tty
*tp
)
319 TTY_LOCK_OWNED(tp
); /* debug assert */
320 lck_mtx_unlock(&tp
->t_lock
);
326 * Initial open of tty, or (re)entry to standard tty line discipline.
328 * Locks: Assumes tty_lock() is held prior to calling.
331 ttyopen(dev_t device
, struct tty
*tp
)
333 TTY_LOCK_OWNED(tp
); /* debug assert */
337 if (!ISSET(tp
->t_state
, TS_ISOPEN
)) {
338 SET(tp
->t_state
, TS_ISOPEN
);
339 if (ISSET(tp
->t_cflag
, CLOCAL
)) {
340 SET(tp
->t_state
, TS_CONNECTED
);
342 bzero(&tp
->t_winsize
, sizeof(tp
->t_winsize
));
351 * Handle close() on a tty line: flush and set to initial state,
352 * bumping generation number so that pending read/write calls
353 * can detect recycling of the tty.
354 * XXX our caller should have done `spltty(); l_close(); ttyclose();'
355 * and l_close() should have flushed, but we repeat the spltty() and
356 * the flush in case there are buggy callers.
358 * Locks: Assumes tty_lock() is held prior to calling.
361 ttyclose(struct tty
*tp
)
364 struct session
* oldsessp
;
367 TTY_LOCK_OWNED(tp
); /* debug assert */
374 * Closing current console tty; disable printing of console
375 * messages at bottom-level driver.
377 (*cdevsw
[major(tp
->t_dev
)].d_ioctl
)
378 (tp
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, current_proc());
381 ttyflush(tp
, FREAD
| FWRITE
);
384 tp
->t_line
= TTYDISC
;
387 oldsessp
= tp
->t_session
;
389 tp
->t_session
= NULL
;
390 if (oldsessp
!= SESSION_NULL
) {
391 oldsessp
->s_ttypgrpid
= NO_PID
;
394 /* drop the reference on prev session and pgrp */
395 /* SAFE: All callers drop the lock on return */
397 if (oldsessp
!= SESSION_NULL
) {
398 session_rele(oldsessp
);
400 if (oldpg
!= PGRP_NULL
) {
405 SLIST_FOREACH(kn
, &tp
->t_wsel
.si_note
, kn_selnext
) {
406 KNOTE_DETACH(&tp
->t_wsel
.si_note
, kn
);
408 selthreadclear(&tp
->t_wsel
);
409 SLIST_FOREACH(kn
, &tp
->t_rsel
.si_note
, kn_selnext
) {
410 KNOTE_DETACH(&tp
->t_rsel
.si_note
, kn
);
412 selthreadclear(&tp
->t_rsel
);
417 #define FLUSHQ(q) { \
419 ndflush(q, (q)->c_cc); \
422 /* Is 'c' a line delimiter ("break" character)? */
423 #define TTBREAKC(c, lflag) \
424 ((c) == '\n' || (((c) == cc[VEOF] || \
425 (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \
426 (c) != _POSIX_VDISABLE))
431 * Process input of a single character received on a tty.
433 * Parameters: c The character received
434 * tp The tty on which it was received
438 * Locks: Assumes tty_lock() is held prior to calling.
441 ttyinput(int c
, struct tty
*tp
)
443 tcflag_t iflag
, lflag
;
446 int retval
= 0; /* default return value */
448 TTY_LOCK_OWNED(tp
); /* debug assert */
451 * If input is pending take it first.
454 if (ISSET(lflag
, PENDIN
)) {
460 if (ISSET(lflag
, ICANON
)) {
470 * Block further input iff:
471 * current input > threshold AND input is available to user program
472 * AND input flow control is enabled and not yet invoked.
473 * The 3 is slop for PARMRK.
476 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
> I_HIGH_WATER
- 3 &&
477 (!ISSET(lflag
, ICANON
) || tp
->t_canq
.c_cc
!= 0) &&
478 (ISSET(tp
->t_cflag
, CRTS_IFLOW
) || ISSET(iflag
, IXOFF
)) &&
479 !ISSET(tp
->t_state
, TS_TBLOCK
)) {
483 /* Handle exceptional conditions (break, parity, framing). */
485 err
= (ISSET(c
, TTY_ERRORMASK
));
487 CLR(c
, TTY_ERRORMASK
);
488 if (ISSET(err
, TTY_BI
)) {
489 if (ISSET(iflag
, IGNBRK
)) {
492 if (ISSET(iflag
, BRKINT
)) {
493 ttyflush(tp
, FREAD
| FWRITE
);
494 /* SAFE: All callers drop the lock on return */
496 tty_pgsignal(tp
, SIGINT
, 1);
500 if (ISSET(iflag
, PARMRK
)) {
503 } else if ((ISSET(err
, TTY_PE
) && ISSET(iflag
, INPCK
))
504 || ISSET(err
, TTY_FE
)) {
505 if (ISSET(iflag
, IGNPAR
)) {
507 } else if (ISSET(iflag
, PARMRK
)) {
509 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
>
513 (void)putc(0377 | TTY_QUOTE
, &tp
->t_rawq
);
514 (void)putc(0 | TTY_QUOTE
, &tp
->t_rawq
);
515 (void)putc(c
| TTY_QUOTE
, &tp
->t_rawq
);
523 if (!ISSET(tp
->t_state
, TS_TYPEN
) && ISSET(iflag
, ISTRIP
)) {
526 if (!ISSET(lflag
, EXTPROC
)) {
528 * Check for literal nexting very first
530 if (ISSET(tp
->t_state
, TS_LNCH
)) {
532 CLR(tp
->t_state
, TS_LNCH
);
535 * Scan for special characters. This code
536 * is really just a big case statement with
537 * non-constant cases. The bottom of the
538 * case statement is labeled ``endcase'', so goto
539 * it after a case match, or similar.
543 * Control chars which aren't controlled
544 * by ICANON, ISIG, or IXON.
546 if (ISSET(lflag
, IEXTEN
)) {
547 if (CCEQ(cc
[VLNEXT
], c
)) {
548 if (ISSET(lflag
, ECHO
)) {
549 if (ISSET(lflag
, ECHOE
)) {
550 (void)ttyoutput('^', tp
);
551 (void)ttyoutput('\b', tp
);
556 SET(tp
->t_state
, TS_LNCH
);
559 if (CCEQ(cc
[VDISCARD
], c
)) {
560 if (ISSET(lflag
, FLUSHO
)) {
561 CLR(tp
->t_lflag
, FLUSHO
);
563 ttyflush(tp
, FWRITE
);
565 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
) {
568 SET(tp
->t_lflag
, FLUSHO
);
576 if (ISSET(lflag
, ISIG
)) {
577 if (CCEQ(cc
[VINTR
], c
) || CCEQ(cc
[VQUIT
], c
)) {
578 if (!ISSET(lflag
, NOFLSH
)) {
579 ttyflush(tp
, FREAD
| FWRITE
);
583 * SAFE: All callers drop the lock on return;
584 * SAFE: if we lose a threaded race on change
585 * SAFE: of the interrupt character, we could
586 * SAFE: have lost that race anyway due to the
587 * SAFE: scheduler executing threads in
588 * SAFE: priority order rather than "last
589 * SAFE: active thread" order (FEATURE).
593 CCEQ(cc
[VINTR
], c
) ? SIGINT
: SIGQUIT
, 1);
597 if (CCEQ(cc
[VSUSP
], c
)) {
598 if (!ISSET(lflag
, NOFLSH
)) {
602 /* SAFE: All callers drop the lock on return */
604 tty_pgsignal(tp
, SIGTSTP
, 1);
610 * Handle start/stop characters.
612 if (ISSET(iflag
, IXON
)) {
613 if (CCEQ(cc
[VSTOP
], c
)) {
614 if (!ISSET(tp
->t_state
, TS_TTSTOP
)) {
615 SET(tp
->t_state
, TS_TTSTOP
);
619 if (!CCEQ(cc
[VSTART
], c
)) {
623 * if VSTART == VSTOP then toggle
627 if (CCEQ(cc
[VSTART
], c
)) {
632 * IGNCR, ICRNL, & INLCR
635 if (ISSET(iflag
, IGNCR
)) {
637 } else if (ISSET(iflag
, ICRNL
)) {
640 } else if (c
== '\n' && ISSET(iflag
, INLCR
)) {
644 if (!ISSET(tp
->t_lflag
, EXTPROC
) && ISSET(lflag
, ICANON
)) {
646 * From here on down canonical mode character
647 * processing takes place.
652 if (CCEQ(cc
[VERASE
], c
)) {
653 if (tp
->t_rawq
.c_cc
) {
654 if (ISSET(iflag
, IUTF8
)) {
656 ttyrub((c
= unputc(&tp
->t_rawq
)), tp
);
657 } while (tp
->t_rawq
.c_cc
&& CCONT(c
));
659 ttyrub(unputc(&tp
->t_rawq
), tp
);
667 if (CCEQ(cc
[VKILL
], c
)) {
668 if (ISSET(lflag
, ECHOKE
) &&
669 tp
->t_rawq
.c_cc
== tp
->t_rocount
&&
670 !ISSET(lflag
, ECHOPRT
)) {
671 while (tp
->t_rawq
.c_cc
) {
672 ttyrub(unputc(&tp
->t_rawq
), tp
);
676 if (ISSET(lflag
, ECHOK
) ||
677 ISSET(lflag
, ECHOKE
)) {
683 CLR(tp
->t_state
, TS_LOCAL
);
689 if (CCEQ(cc
[VWERASE
], c
) && ISSET(lflag
, IEXTEN
)) {
695 while ((c
= unputc(&tp
->t_rawq
)) == ' ' || c
== '\t') {
702 * erase last char of word and remember the
703 * next chars type (for ALTWERASE)
706 c
= unputc(&tp
->t_rawq
);
710 if (c
== ' ' || c
== '\t') {
711 (void)putc(c
, &tp
->t_rawq
);
720 c
= unputc(&tp
->t_rawq
);
724 } while (c
!= ' ' && c
!= '\t' &&
725 (!ISSET(lflag
, ALTWERASE
) || ISALPHA(c
) == ctype
));
726 (void)putc(c
, &tp
->t_rawq
);
732 if (CCEQ(cc
[VREPRINT
], c
) && ISSET(lflag
, IEXTEN
)) {
737 * ^T - kernel info and generate SIGINFO
739 if (CCEQ(cc
[VSTATUS
], c
) && ISSET(lflag
, IEXTEN
)) {
740 if (ISSET(lflag
, ISIG
)) {
741 /* SAFE: All callers drop the lock on return */
743 tty_pgsignal(tp
, SIGINFO
, 1);
746 if (!ISSET(lflag
, NOKERNINFO
)) {
753 * Check for input buffer overflow
755 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
>= MAX_INPUT
) {
757 if (ISSET(iflag
, IMAXBEL
)) {
758 if (tp
->t_outq
.c_cc
< tp
->t_hiwat
) {
759 (void)ttyoutput(CTRL('g'), tp
);
765 if (c
== 0377 && ISSET(iflag
, PARMRK
) && !ISSET(iflag
, ISTRIP
)
766 && ISSET(iflag
, IGNBRK
| IGNPAR
) != (IGNBRK
| IGNPAR
)) {
767 (void)putc(0377 | TTY_QUOTE
, &tp
->t_rawq
);
771 * Put data char in q for user and
772 * wakeup on seeing a line delimiter.
774 if (putc(c
, &tp
->t_rawq
) >= 0) {
775 if (!ISSET(lflag
, ICANON
)) {
780 if (TTBREAKC(c
, lflag
)) {
782 catq(&tp
->t_rawq
, &tp
->t_canq
);
784 } else if (tp
->t_rocount
++ == 0) {
785 tp
->t_rocol
= tp
->t_column
;
787 if (ISSET(tp
->t_state
, TS_ERASE
)) {
789 * end of prterase \.../
791 CLR(tp
->t_state
, TS_ERASE
);
792 (void)ttyoutput('/', tp
);
796 if (CCEQ(cc
[VEOF
], c
) && ISSET(lflag
, ECHO
)) {
798 * Place the cursor over the '^' of the ^D.
800 i
= min(2, tp
->t_column
- i
);
802 (void)ttyoutput('\b', tp
);
810 * IXANY means allow any character to restart output.
812 if (ISSET(tp
->t_state
, TS_TTSTOP
) &&
813 !ISSET(iflag
, IXANY
) && cc
[VSTART
] != cc
[VSTOP
]) {
818 CLR(tp
->t_lflag
, FLUSHO
);
819 CLR(tp
->t_state
, TS_TTSTOP
);
822 /* Start the output */
823 retval
= ttstart(tp
);
833 * Output a single character on a tty, doing output processing
834 * as needed (expanding tabs, newline processing, etc.).
836 * Parameters: c The character to output
837 * tp The tty on which to output on the tty
839 * Returns: < 0 Success
840 * >= 0 Character to resend (failure)
842 * Locks: Assumes tp is locked on entry, remains locked on exit
844 * Notes: Must be recursive.
847 ttyoutput(int c
, struct tty
*tp
)
852 TTY_LOCK_OWNED(tp
); /* debug assert */
855 if (!ISSET(oflag
, OPOST
)) {
856 if (ISSET(tp
->t_lflag
, FLUSHO
)) {
859 if (putc(c
, &tp
->t_outq
)) {
867 * Do tab expansion if OXTABS is set. Special case if we external
868 * processing, we don't do the tab expansion because we'll probably
869 * get it wrong. If tab expansion needs to be done, let it happen
872 CLR(c
, ~TTY_CHARMASK
);
874 ISSET(oflag
, OXTABS
) && !ISSET(tp
->t_lflag
, EXTPROC
)) {
875 col
= c
= 8 - (tp
->t_column
& 7);
876 if (!ISSET(tp
->t_lflag
, FLUSHO
)) {
877 c
-= b_to_q((const u_char
*)" ", c
, &tp
->t_outq
);
882 return c
== col
? -1 : '\t';
884 if (c
== CEOT
&& ISSET(oflag
, ONOEOT
)) {
889 * Newline translation: if ONLCR is set,
890 * translate newline into "\r\n".
892 if (c
== '\n' && ISSET(tp
->t_oflag
, ONLCR
)) {
895 if (putc('\r', &tp
->t_outq
)) {
899 /* If OCRNL is set, translate "\r" into "\n". */
900 else if (c
== '\r' && ISSET(tp
->t_oflag
, OCRNL
)) {
903 /* If ONOCR is set, don't transmit CRs when on column 0. */
904 else if (c
== '\r' && ISSET(tp
->t_oflag
, ONOCR
) && tp
->t_column
== 0) {
909 if (!ISSET(tp
->t_lflag
, FLUSHO
) && putc(c
, &tp
->t_outq
)) {
930 col
= (col
+ 8) & ~7;
938 * Sets the tty state to not allow any more changes of foreground process
939 * group. This is required to be done so that a subsequent revoke on a vnode
940 * is able to always successfully complete.
942 * Locks : Assumes tty_lock held on entry
945 ttysetpgrphup(struct tty
*tp
)
947 TTY_LOCK_OWNED(tp
); /* debug assert */
948 SET(tp
->t_state
, TS_PGRPHUP
);
950 * Also wake up sleeping readers which may or may not belong to the
951 * current foreground process group.
953 * This forces any non-fg readers (which entered read when
954 * that process group was in the fg) to return with EIO (if they're
955 * catching SIGTTIN or with SIGTTIN). The ones which do belong to the fg
956 * process group will promptly go back to sleep and get a SIGHUP shortly
957 * This would normally happen as part of the close in revoke but if
958 * there is a sleeping reader from a non-fg process group we never get
959 * to the close because the sleeping reader holds an iocount on the
960 * vnode of the terminal which is going to get revoked->reclaimed.
962 wakeup(TSA_HUP_OR_INPUT(tp
));
966 * Locks : Assumes tty lock held on entry
969 ttyclrpgrphup(struct tty
*tp
)
971 TTY_LOCK_OWNED(tp
); /* debug assert */
972 CLR(tp
->t_state
, TS_PGRPHUP
);
978 * Identical to ttioctl_locked, only the lock is not held
980 * Parameters: <See ttioctl_locked()>
982 * Returns: <See ttioctl_locked()>
984 * Locks: This function assumes the tty_lock() is not held on entry;
985 * it takes the lock, and releases it before returning.
987 * Notes: This is supported to ensure the line discipline interfaces
988 * all have the same locking semantics.
990 * This function is called from
993 ttioctl(struct tty
*tp
, u_long cmd
, caddr_t data
, int flag
, proc_t p
)
998 retval
= ttioctl_locked(tp
, cmd
, data
, flag
, p
);
1008 * Ioctls for all tty devices.
1010 * Parameters: tp Tty on which ioctl() is being called
1011 * cmd ioctl() command parameter
1012 * data ioctl() data argument (if any)
1013 * flag fileglob open modes from fcntl.h;
1014 * if called internally, this is usually
1015 * set to 0, rather than something useful
1016 * p Process context for the call; if the
1017 * call is proxied to a worker thread,
1018 * this will not be the current process!!!
1020 * Returns: 0 Success
1021 * EIO I/O error (no process group, job
1023 * EINTR Interrupted by signal
1024 * EBUSY Attempt to become the console while
1025 * the console is busy
1026 * ENOTTY TIOCGPGRP on a non-controlling tty
1027 * EINVAL Invalid baud rate
1028 * ENXIO TIOCSETD of invalid line discipline
1029 * EPERM TIOCSTI, not root, not open for read
1030 * EACCES TIOCSTI, not root, not your controlling
1032 * EPERM TIOCSCTTY failed
1033 * ENOTTY/EINVAL/EPERM TIOCSPGRP failed
1034 * EPERM TIOCSDRAINWAIT as non-root user
1035 * suser:EPERM Console control denied
1036 * ttywait:EIO t_timeout too small/expired
1037 * ttywait:ERESTART Upper layer must redrive the call;
1038 * this is usually done by the Libc
1039 * stub in user space
1040 * ttywait:EINTR Interrupted (usually a signal)
1044 * ttcompat:ENOTTY TIOCGSID, if no session or session
1046 * ttcompat:ENOTTY All unrecognized ioctls
1047 * *tp->t_param:? TIOCSETA* underlying function
1048 * *linesw[t].l_open:? TIOCSETD line discipline open failure
1051 * Locks: This function assumes that the tty_lock() is held for the
1052 * tp at the time of the call. The lock remains held on return.
1054 * Notes: This function is called after line-discipline specific ioctl
1055 * has been called to do discipline-specific functions and/or
1056 * reject any of these ioctl() commands.
1058 * This function calls ttcompat(), which can re-call ttioctl()
1059 * to a depth of one (FORTRAN style mutual recursion); at some
1060 * point, we should just in-line ttcompat() here.
1063 ttioctl_locked(struct tty
*tp
, u_long cmd
, caddr_t data
, int flag
, proc_t p
)
1068 struct pgrp
*pg
, *oldpg
;
1069 struct session
*sessp
, *oldsessp
;
1072 TTY_LOCK_OWNED(tp
); /* debug assert */
1074 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
1075 /* If the ioctl involves modification, signal if in the background. */
1102 while (isbackground(p
, tp
) &&
1103 (p
->p_lflag
& P_LPPWAIT
) == 0 &&
1104 (p
->p_sigignore
& sigmask(SIGTTOU
)) == 0 &&
1105 (ut
->uu_sigmask
& sigmask(SIGTTOU
)) == 0) {
1107 if (pg
== PGRP_NULL
) {
1111 /* SAFE: All callers drop the lock on return */
1113 if (pg
->pg_jobc
== 0) {
1119 pgsignal(pg
, SIGTTOU
, 1);
1125 * We signalled ourself, so we need to act as if we
1126 * have been "interrupted" from a "sleep" to act on
1127 * the signal. If it's a signal that stops the
1128 * process, that's handled in the signal sending code.
1136 switch (cmd
) { /* Process the ioctl. */
1137 case FIOASYNC
: /* set/clear async i/o */
1139 SET(tp
->t_state
, TS_ASYNC
);
1141 CLR(tp
->t_state
, TS_ASYNC
);
1144 case FIONBIO
: /* set/clear non-blocking i/o */
1145 break; /* XXX: delete. */
1146 case FIONREAD
: /* get # bytes to read */
1147 *(int *)data
= ttnread(tp
);
1149 case TIOCEXCL
: /* set exclusive use of tty */
1150 SET(tp
->t_state
, TS_XCLUDE
);
1152 case TIOCFLUSH
: { /* flush buffers */
1153 int flags
= *(int *)data
;
1156 flags
= FREAD
| FWRITE
;
1158 flags
&= FREAD
| FWRITE
;
1160 ttyflush(tp
, flags
);
1164 /* Set current console device to this line */
1165 data
= (caddr_t
) &bogusData
;
1167 /* No break - Fall through to BSD code */
1169 case TIOCCONS
: { /* become virtual console */
1171 if (constty
&& constty
!= tp
&&
1172 ISSET(constty
->t_state
, TS_CONNECTED
)) {
1176 if ((error
= suser(kauth_cred_get(), &p
->p_acflag
))) {
1180 } else if (tp
== constty
) {
1184 (*cdevsw
[major(constty
->t_dev
)].d_ioctl
)
1185 (constty
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, p
);
1187 (*cdevsw
[major(tp
->t_dev
)].d_ioctl
)
1188 (tp
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, p
);
1192 case TIOCDRAIN
: /* wait till output drained */
1193 error
= ttywait(tp
);
1198 case TIOCGETA_32
: /* get termios struct */
1200 termios64to32((struct user_termios
*)&tp
->t_termios
, (struct termios32
*)data
);
1202 bcopy(&tp
->t_termios
, data
, sizeof(struct termios
));
1205 case TIOCGETA_64
: /* get termios struct */
1207 bcopy(&tp
->t_termios
, data
, sizeof(struct termios
));
1209 termios32to64((struct termios32
*)&tp
->t_termios
, (struct user_termios
*)data
);
1212 case TIOCGETD
: /* get line discipline */
1213 *(int *)data
= tp
->t_line
;
1215 case TIOCGWINSZ
: /* get window size */
1216 *(struct winsize
*)data
= tp
->t_winsize
;
1218 case TIOCGPGRP
: /* get pgrp of tty */
1219 if (!isctty(p
, tp
)) {
1223 *(int *)data
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
1226 case TIOCHPCL
: /* hang up on last close */
1227 SET(tp
->t_cflag
, HUPCL
);
1230 case TIOCNXCL
: /* reset exclusive use of tty */
1231 CLR(tp
->t_state
, TS_XCLUDE
);
1233 case TIOCOUTQ
: /* output queue size */
1234 *(int *)data
= tp
->t_outq
.c_cc
;
1236 case TIOCSETA_32
: /* set termios struct */
1238 case TIOCSETAW_32
: /* drain output, set */
1240 case TIOCSETAF_32
: /* drn out, fls in, set */
1242 { /* drn out, fls in, set */
1243 struct termios
*t
= (struct termios
*)data
;
1244 struct termios lcl_termios
;
1247 if (cmd
== TIOCSETA_32
|| cmd
== TIOCSETAW_32
|| cmd
== TIOCSETAF_32
) {
1248 termios32to64((struct termios32
*)data
, (struct user_termios
*)&lcl_termios
);
1252 if (cmd
== TIOCSETA_64
|| cmd
== TIOCSETAW_64
|| cmd
== TIOCSETAF_64
) {
1253 termios64to32((struct user_termios
*)data
, (struct termios32
*)&lcl_termios
);
1258 /* XXX bogus test; always false */
1259 if (t
->c_ispeed
< 0 || t
->c_ospeed
< 0) {
1263 #endif /* 0 - leave in; may end up being a conformance issue */
1264 if (t
->c_ispeed
== 0) {
1265 t
->c_ispeed
= t
->c_ospeed
;
1267 if (cmd
== TIOCSETAW_32
|| cmd
== TIOCSETAF_32
||
1268 cmd
== TIOCSETAW_64
|| cmd
== TIOCSETAF_64
) {
1269 error
= ttywait(tp
);
1273 if (cmd
== TIOCSETAF_32
|| cmd
== TIOCSETAF_64
) {
1274 ttyflush(tp
, FREAD
);
1277 if (!ISSET(t
->c_cflag
, CIGNORE
)) {
1279 * Set device hardware.
1281 if (tp
->t_param
&& (error
= (*tp
->t_param
)(tp
, t
))) {
1284 if (ISSET(t
->c_cflag
, CLOCAL
) &&
1285 !ISSET(tp
->t_cflag
, CLOCAL
)) {
1287 * XXX disconnections would be too hard to
1288 * get rid of without this kludge. The only
1289 * way to get rid of controlling terminals
1290 * is to exit from the session leader.
1292 CLR(tp
->t_state
, TS_ZOMBIE
);
1294 wakeup(TSA_CARR_ON(tp
));
1298 if ((ISSET(tp
->t_state
, TS_CARR_ON
) ||
1299 ISSET(t
->c_cflag
, CLOCAL
)) &&
1300 !ISSET(tp
->t_state
, TS_ZOMBIE
)) {
1301 SET(tp
->t_state
, TS_CONNECTED
);
1303 CLR(tp
->t_state
, TS_CONNECTED
);
1305 tp
->t_cflag
= t
->c_cflag
;
1306 tp
->t_ispeed
= t
->c_ispeed
;
1307 tp
->t_ospeed
= t
->c_ospeed
;
1310 if (ISSET(t
->c_lflag
, ICANON
) != ISSET(tp
->t_lflag
, ICANON
) &&
1311 cmd
!= TIOCSETAF_32
&& cmd
!= TIOCSETAF_64
) {
1312 if (ISSET(t
->c_lflag
, ICANON
)) {
1313 SET(tp
->t_lflag
, PENDIN
);
1316 * XXX we really shouldn't allow toggling
1317 * ICANON while we're in a non-termios line
1318 * discipline. Now we have to worry about
1319 * panicing for a null queue.
1321 if (tp
->t_rawq
.c_cs
&& tp
->t_canq
.c_cs
) {
1324 catq(&tp
->t_rawq
, &tp
->t_canq
);
1326 tp
->t_rawq
= tp
->t_canq
;
1329 CLR(tp
->t_lflag
, PENDIN
);
1333 tp
->t_iflag
= t
->c_iflag
;
1334 tp
->t_oflag
= t
->c_oflag
;
1336 * Make the EXTPROC bit read only.
1338 if (ISSET(tp
->t_lflag
, EXTPROC
)) {
1339 SET(t
->c_lflag
, EXTPROC
);
1341 CLR(t
->c_lflag
, EXTPROC
);
1343 tp
->t_lflag
= t
->c_lflag
| ISSET(tp
->t_lflag
, PENDIN
);
1344 if (t
->c_cc
[VMIN
] != tp
->t_cc
[VMIN
] ||
1345 t
->c_cc
[VTIME
] != tp
->t_cc
[VTIME
]) {
1348 bcopy(t
->c_cc
, tp
->t_cc
, sizeof(t
->c_cc
));
1351 case TIOCSETD
: { /* set line discipline */
1352 int t
= *(int *)data
;
1353 dev_t device
= tp
->t_dev
;
1355 if (t
>= nlinesw
|| t
< 0) {
1360 * If the new line discipline is not equal to the old one,
1361 * close the old one and open the new one.
1363 if (t
!= tp
->t_line
) {
1364 (*linesw
[tp
->t_line
].l_close
)(tp
, flag
);
1365 error
= (*linesw
[t
].l_open
)(device
, tp
);
1367 /* This is racy; it's possible to lose both */
1368 (void)(*linesw
[tp
->t_line
].l_open
)(device
, tp
);
1375 case TIOCSTART
: /* start output, like ^Q */
1376 if (ISSET(tp
->t_state
, TS_TTSTOP
) ||
1377 ISSET(tp
->t_lflag
, FLUSHO
)) {
1378 CLR(tp
->t_lflag
, FLUSHO
);
1379 CLR(tp
->t_state
, TS_TTSTOP
);
1383 case TIOCSTI
: /* simulate terminal input */
1384 if (suser(kauth_cred_get(), NULL
) && (flag
& FREAD
) == 0) {
1388 if (suser(kauth_cred_get(), NULL
) && !isctty(p
, tp
)) {
1392 (*linesw
[tp
->t_line
].l_rint
)(*(u_char
*)data
, tp
);
1394 case TIOCSTOP
: /* stop output, like ^S */
1395 if (!ISSET(tp
->t_state
, TS_TTSTOP
)) {
1396 SET(tp
->t_state
, TS_TTSTOP
);
1406 case TIOCSCTTY
: /* become controlling tty */
1407 /* Session ctty vnode pointer set in vnode layer. */
1408 sessp
= proc_session(p
);
1409 if (sessp
== SESSION_NULL
) {
1415 * This can only be done by a session leader.
1417 if (!SESS_LEADER(p
, sessp
)) {
1418 /* SAFE: All callers drop the lock on return */
1420 session_rele(sessp
);
1426 * If this terminal is already the controlling terminal for the
1427 * session, nothing to do here.
1429 if (tp
->t_session
== sessp
) {
1430 /* SAFE: All callers drop the lock on return */
1432 session_rele(sessp
);
1439 * Deny if the terminal is already attached to another session or
1440 * the session already has a terminal vnode.
1442 session_lock(sessp
);
1443 if (sessp
->s_ttyvp
|| tp
->t_session
) {
1444 session_unlock(sessp
);
1445 /* SAFE: All callers drop the lock on return */
1447 if (pg
!= PGRP_NULL
) {
1450 session_rele(sessp
);
1455 sessp
->s_ttypgrpid
= pg
->pg_id
;
1456 oldtp
= sessp
->s_ttyp
;
1459 session_unlock(sessp
);
1461 oldsessp
= tp
->t_session
;
1463 if (oldsessp
!= SESSION_NULL
) {
1464 oldsessp
->s_ttypgrpid
= NO_PID
;
1466 /* do not drop refs on sessp and pg as tp holds them */
1467 tp
->t_session
= sessp
;
1470 OSBitOrAtomic(P_CONTROLT
, &p
->p_flag
);
1471 /* SAFE: All callers drop the lock on return */
1473 /* drop the reference on prev session and pgrp */
1474 if (oldsessp
!= SESSION_NULL
) {
1475 session_rele(oldsessp
);
1477 if (oldpg
!= PGRP_NULL
) {
1480 if (NULL
!= oldtp
) {
1486 case TIOCSPGRP
: { /* set pgrp of tty */
1487 struct pgrp
*pgrp
= PGRP_NULL
;
1489 sessp
= proc_session(p
);
1490 if (!isctty_sp(p
, tp
, sessp
)) {
1491 if (sessp
!= SESSION_NULL
) {
1492 session_rele(sessp
);
1496 } else if ((pgrp
= pgfind(*(int *)data
)) == PGRP_NULL
) {
1497 if (sessp
!= SESSION_NULL
) {
1498 session_rele(sessp
);
1502 } else if (pgrp
->pg_session
!= sessp
) {
1503 /* SAFE: All callers drop the lock on return */
1505 if (sessp
!= SESSION_NULL
) {
1506 session_rele(sessp
);
1514 * The session leader is going away and is possibly going to revoke
1515 * the terminal, we can't change the process group when that is the
1518 if (ISSET(tp
->t_state
, TS_PGRPHUP
)) {
1519 if (sessp
!= SESSION_NULL
) {
1520 session_rele(sessp
);
1529 sessp
->s_ttypgrpid
= pgrp
->pg_id
;
1533 * Wakeup readers to recheck if they are still the foreground
1536 * ttwakeup() isn't called because the readers aren't getting
1537 * woken up becuse there is something to read but to force
1538 * the re-evaluation of their foreground process group status.
1540 * Ordinarily leaving these readers waiting wouldn't be an issue
1541 * as launchd would send them a termination signal eventually
1542 * (if nobody else does). But if this terminal happens to be
1543 * /dev/console, launchd itself could get blocked forever behind
1544 * a revoke of /dev/console and leave the system deadlocked.
1546 wakeup(TSA_HUP_OR_INPUT(tp
));
1548 /* SAFE: All callers drop the lock on return */
1550 if (oldpg
!= PGRP_NULL
) {
1553 if (sessp
!= SESSION_NULL
) {
1554 session_rele(sessp
);
1559 case TIOCSTAT
: /* simulate control-T */
1562 case TIOCSWINSZ
: /* set window size */
1563 if (bcmp((caddr_t
)&tp
->t_winsize
, data
,
1564 sizeof(struct winsize
))) {
1565 tp
->t_winsize
= *(struct winsize
*)data
;
1566 /* SAFE: All callers drop the lock on return */
1568 tty_pgsignal(tp
, SIGWINCH
, 1);
1572 case TIOCSDRAINWAIT
:
1573 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1577 tp
->t_timeout
= *(int *)data
* hz
;
1578 wakeup(TSA_OCOMPLETE(tp
));
1579 wakeup(TSA_OLOWAT(tp
));
1581 case TIOCGDRAINWAIT
:
1582 *(int *)data
= tp
->t_timeout
/ hz
;
1585 if (ISSET(tp
->t_state
, TS_PGRPHUP
)) {
1587 wakeup(TSA_HUP_OR_INPUT(tp
));
1591 error
= ttcompat(tp
, cmd
, data
, flag
, p
);
1602 * Locks: Assumes tp is locked on entry, remains locked on exit
1605 ttyselect(struct tty
*tp
, int rw
, void *wql
, proc_t p
)
1609 * Attaching knotes to TTYs needs to call selrecord in order to hook
1610 * up the waitq to the selinfo, regardless of data being ready. See
1613 bool needs_selrecord
= rw
& FMARK
;
1622 if (tp
->t_state
& TS_ZOMBIE
) {
1629 retval
= ttnread(tp
);
1634 selrecord(p
, &tp
->t_rsel
, wql
);
1637 if ((tp
->t_outq
.c_cc
<= tp
->t_lowat
) &&
1638 (tp
->t_state
& TS_CONNECTED
)) {
1639 retval
= tp
->t_hiwat
- tp
->t_outq
.c_cc
;
1643 selrecord(p
, &tp
->t_wsel
, wql
);
1648 if (retval
> 0 && needs_selrecord
) {
1651 selrecord(p
, &tp
->t_rsel
, wql
);
1654 selrecord(p
, &tp
->t_wsel
, wql
);
1664 * This is a wrapper for compatibility with the select vector used by
1665 * cdevsw. It relies on a proper xxxdevtotty routine.
1667 * Locks: Assumes tty_lock() is not held prior to calling.
1670 ttselect(dev_t dev
, int rw
, void *wql
, proc_t p
)
1673 struct tty
*tp
= cdevsw
[major(dev
)].d_ttys
[minor(dev
)];
1676 rv
= ttyselect(tp
, rw
, wql
, p
);
1684 * Locks: Assumes tp is locked on entry, remains locked on exit
1686 __private_extern__
int
1687 ttnread(struct tty
*tp
)
1691 TTY_LOCK_OWNED(tp
); /* debug assert */
1693 if (ISSET(tp
->t_lflag
, PENDIN
)) {
1696 nread
= tp
->t_canq
.c_cc
;
1697 if (!ISSET(tp
->t_lflag
, ICANON
)) {
1698 nread
+= tp
->t_rawq
.c_cc
;
1699 if (nread
< tp
->t_cc
[VMIN
] && tp
->t_cc
[VTIME
] == 0) {
1710 * Wait for output to drain.
1712 * Parameters: tp Tty on which to wait for output to drain
1714 * Returns: 0 Success
1715 * EIO t_timeout too small/expired
1716 * ttysleep:ERESTART Upper layer must redrive the call;
1717 * this is usually done by the Libc
1718 * stub in user space
1719 * ttysleep:EINTR Interrupted (usually a signal)
1721 * Notes: Called from proc_exit() and vproc_exit().
1723 * Locks: Assumes tp is locked on entry, remains locked on exit
1726 ttywait(struct tty
*tp
)
1730 TTY_LOCK_OWNED(tp
); /* debug assert */
1733 while ((tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)) &&
1734 ISSET(tp
->t_state
, TS_CONNECTED
) && tp
->t_oproc
) {
1736 if ((tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)) &&
1737 ISSET(tp
->t_state
, TS_CONNECTED
)) {
1738 SET(tp
->t_state
, TS_SO_OCOMPLETE
);
1739 error
= ttysleep(tp
, TSA_OCOMPLETE(tp
),
1740 TTOPRI
| PCATCH
, "ttywai",
1743 if (error
== EWOULDBLOCK
) {
1752 if (!error
&& (tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
))) {
1759 * Stop the underlying device driver.
1761 * Locks: Assumes tty_lock() is held prior to calling.
1764 ttystop(struct tty
*tp
, int rw
)
1766 TTY_LOCK_OWNED(tp
); /* debug assert */
1768 (*cdevsw
[major(tp
->t_dev
)].d_stop
)(tp
, rw
);
1772 * Flush if successfully wait.
1774 * Locks: Assumes tty_lock() is held prior to calling.
1777 ttywflush(struct tty
*tp
)
1781 TTY_LOCK_OWNED(tp
); /* debug assert */
1783 if ((error
= ttywait(tp
)) == 0) {
1784 ttyflush(tp
, FREAD
);
1790 * Flush tty read and/or write queues, notifying anyone waiting.
1792 * Locks: Assumes tty_lock() is held prior to calling.
1795 ttyflush(struct tty
*tp
, int rw
)
1797 TTY_LOCK_OWNED(tp
); /* debug assert */
1803 FLUSHQ(&tp
->t_outq
);
1804 CLR(tp
->t_state
, TS_TTSTOP
);
1808 FLUSHQ(&tp
->t_canq
);
1809 FLUSHQ(&tp
->t_rawq
);
1810 CLR(tp
->t_lflag
, PENDIN
);
1813 CLR(tp
->t_state
, TS_LOCAL
);
1815 if (ISSET(tp
->t_state
, TS_TBLOCK
)) {
1817 FLUSHQ(&tp
->t_outq
);
1822 * Don't let leave any state that might clobber the
1823 * next line discipline (although we should do more
1824 * to send the START char). Not clearing the state
1825 * may have caused the "putc to a clist with no
1826 * reserved cblocks" panic/printf.
1828 CLR(tp
->t_state
, TS_TBLOCK
);
1830 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1831 if (ISSET(tp
->t_iflag
, IXOFF
)) {
1833 * XXX wait a bit in the hope that the stop
1834 * character (if any) will go out. Waiting
1835 * isn't good since it allows races. This
1836 * will be fixed when the stop character is
1837 * put in a special queue. Don't bother with
1838 * the checks in ttywait() since the timeout
1841 SET(tp
->t_state
, TS_SO_OCOMPLETE
);
1842 ttysleep(tp
, TSA_OCOMPLETE(tp
), TTOPRI
,
1845 * Don't try sending the stop character again.
1847 CLR(tp
->t_state
, TS_TBLOCK
);
1854 FLUSHQ(&tp
->t_outq
);
1860 * Copy in the default termios characters.
1862 * Locks: Assumes tty_lock() is held prior to calling.
1864 * Notes: No assertion; tp is not in scope.
1867 termioschars(struct termios
*t
)
1869 bcopy(ttydefchars
, t
->c_cc
, sizeof t
->c_cc
);
1874 * Handle input high water. Send stop character for the IXOFF case. Turn
1875 * on our input flow control bit and propagate the changes to the driver.
1876 * XXX the stop character should be put in a special high priority queue.
1878 * Locks: Assumes tty_lock() is held for the call.
1881 ttyblock(struct tty
*tp
)
1883 TTY_LOCK_OWNED(tp
); /* debug assert */
1885 SET(tp
->t_state
, TS_TBLOCK
);
1886 if (ISSET(tp
->t_iflag
, IXOFF
) && tp
->t_cc
[VSTOP
] != _POSIX_VDISABLE
&&
1887 putc(tp
->t_cc
[VSTOP
], &tp
->t_outq
) != 0) {
1888 CLR(tp
->t_state
, TS_TBLOCK
); /* try again later */
1895 * Handle input low water. Send start character for the IXOFF case. Turn
1896 * off our input flow control bit and propagate the changes to the driver.
1897 * XXX the start character should be put in a special high priority queue.
1899 * Locks: Assumes tty_lock() is held for the call.
1902 ttyunblock(struct tty
*tp
)
1904 TTY_LOCK_OWNED(tp
); /* debug assert */
1906 CLR(tp
->t_state
, TS_TBLOCK
);
1907 if (ISSET(tp
->t_iflag
, IXOFF
) && tp
->t_cc
[VSTART
] != _POSIX_VDISABLE
&&
1908 putc(tp
->t_cc
[VSTART
], &tp
->t_outq
) != 0) {
1909 SET(tp
->t_state
, TS_TBLOCK
); /* try again later */
1920 * Parameters: tp tty on which to start output
1922 * Returns: 0 Success
1924 * Locks: Assumes tty_lock() is held for the call.
1926 * Notes: This function might as well be void; it always returns success
1928 * Called from ttioctl_locked(), LDISC routines, and
1929 * ttycheckoutq(), ttyblock(), ttyunblock(), and tputchar()
1932 ttstart(struct tty
*tp
)
1934 TTY_LOCK_OWNED(tp
); /* debug assert */
1936 if (tp
->t_oproc
!= NULL
) { /* XXX: Kludge for pty. */
1947 * "close" a line discipline
1949 * Locks: Assumes tty_lock() is held prior to calling.
1952 ttylclose(struct tty
*tp
, int flag
)
1954 TTY_LOCK_OWNED(tp
); /* debug assert */
1956 if ((flag
& FNONBLOCK
) || ttywflush(tp
)) {
1957 ttyflush(tp
, FREAD
| FWRITE
);
1967 * Handle modem control transition on a tty.
1968 * Flag indicates new state of carrier.
1969 * Returns 0 if the line should be turned off, otherwise 1.
1971 * Locks: Assumes tty_lock() is held prior to calling.
1974 ttymodem(struct tty
*tp
, int flag
)
1976 int rval
= 1; /* default return value */
1978 TTY_LOCK_OWNED(tp
); /* debug assert */
1980 if (ISSET(tp
->t_state
, TS_CARR_ON
) && ISSET(tp
->t_cflag
, MDMBUF
)) {
1982 * MDMBUF: do flow control according to carrier flag
1983 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP
1984 * works if IXON and IXANY are clear.
1987 CLR(tp
->t_state
, TS_CAR_OFLOW
);
1988 CLR(tp
->t_state
, TS_TTSTOP
);
1990 } else if (!ISSET(tp
->t_state
, TS_CAR_OFLOW
)) {
1991 SET(tp
->t_state
, TS_CAR_OFLOW
);
1992 SET(tp
->t_state
, TS_TTSTOP
);
1995 } else if (flag
== 0) {
1999 CLR(tp
->t_state
, TS_CARR_ON
);
2000 if (ISSET(tp
->t_state
, TS_ISOPEN
) &&
2001 !ISSET(tp
->t_cflag
, CLOCAL
)) {
2002 SET(tp
->t_state
, TS_ZOMBIE
);
2003 CLR(tp
->t_state
, TS_CONNECTED
);
2004 if (tp
->t_session
&& tp
->t_session
->s_leader
) {
2005 psignal(tp
->t_session
->s_leader
, SIGHUP
);
2007 ttyflush(tp
, FREAD
| FWRITE
);
2015 SET(tp
->t_state
, TS_CARR_ON
);
2016 if (!ISSET(tp
->t_state
, TS_ZOMBIE
)) {
2017 SET(tp
->t_state
, TS_CONNECTED
);
2019 wakeup(TSA_CARR_ON(tp
));
2030 * Reinput pending characters after state switch
2033 * Locks: Assumes tty_lock() is held for the call.
2036 ttypend(struct tty
*tp
)
2041 TTY_LOCK_OWNED(tp
); /* debug assert */
2043 CLR(tp
->t_lflag
, PENDIN
);
2044 SET(tp
->t_state
, TS_TYPEN
);
2046 tp
->t_rawq
.c_cc
= 0;
2047 tp
->t_rawq
.c_cf
= tp
->t_rawq
.c_cl
= NULL
;
2048 while ((c
= getc(&tq
)) >= 0) {
2051 CLR(tp
->t_state
, TS_TYPEN
);
2058 * Process a read call on a tty device.
2060 * Locks: Assumes tty_lock() is held prior to calling.
2063 ttread(struct tty
*tp
, struct uio
*uio
, int flag
)
2068 cc_t
*cc
= tp
->t_cc
;
2069 proc_t p
= current_proc();
2070 int first
, error
= 0;
2071 int has_etime
= 0, last_cc
= 0;
2072 long slp
= 0; /* XXX this should be renamed `timo'. */
2076 TTY_LOCK_OWNED(tp
); /* debug assert */
2078 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
2081 lflag
= tp
->t_lflag
;
2083 * take pending input first
2085 if (ISSET(lflag
, PENDIN
)) {
2087 lflag
= tp
->t_lflag
; /* XXX ttypend() clobbers it */
2091 * Signal the process if it's in the background.
2093 if (isbackground(p
, tp
)) {
2094 if ((p
->p_sigignore
& sigmask(SIGTTIN
)) ||
2095 (ut
->uu_sigmask
& sigmask(SIGTTIN
)) ||
2096 p
->p_lflag
& P_LPPWAIT
) {
2101 if (pg
== PGRP_NULL
) {
2105 if (pg
->pg_jobc
== 0) {
2106 /* SAFE: All callers drop the lock on return */
2113 /* SAFE: All callers drop the lock on return */
2115 pgsignal(pg
, SIGTTIN
, 1);
2120 * We signalled ourself, so we need to act as if we
2121 * have been "interrupted" from a "sleep" to act on
2122 * the signal. If it's a signal that stops the
2123 * process, that's handled in the signal sending code.
2129 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
2130 /* EOF - returning 0 */
2135 * If canonical, use the canonical queue,
2136 * else use the raw queue.
2138 * (should get rid of clists...)
2140 qp
= ISSET(lflag
, ICANON
) ? &tp
->t_canq
: &tp
->t_rawq
;
2142 if (flag
& IO_NDELAY
) {
2146 if (ISSET(lflag
, ICANON
) || cc
[VMIN
] != 0) {
2147 error
= EWOULDBLOCK
;
2149 /* else polling - returning 0 */
2152 if (!ISSET(lflag
, ICANON
)) {
2155 struct timeval timecopy
;
2156 struct timeval etime
= {.tv_sec
= 0, .tv_usec
= 0}; /* protected by !has_etime */
2159 * Check each of the four combinations.
2160 * (m > 0 && t == 0) is the normal read case.
2161 * It should be fairly efficient, so we check that and its
2162 * companion case (m == 0 && t == 0) first.
2163 * For the other two cases, we compute the target sleep time
2174 /* m, t and qp->c_cc are all 0. 0 is enough input. */
2177 t
*= 100000; /* time in us */
2178 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
2179 ((t1).tv_usec - (t2).tv_usec))
2181 if (qp
->c_cc
<= 0) {
2184 if (qp
->c_cc
>= m
) {
2187 microuptime(&timecopy
);
2189 /* first character, start timer */
2192 etime
.tv_sec
= t
/ 1000000;
2193 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
2194 timeradd(&etime
, &timecopy
, &etime
);
2197 } else if (qp
->c_cc
> last_cc
) {
2198 /* got a character, restart timer */
2200 etime
.tv_sec
= t
/ 1000000;
2201 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
2202 timeradd(&etime
, &timecopy
, &etime
);
2206 /* nothing, check expiration */
2207 if (timercmp(&etime
, &timecopy
, <=)) {
2211 slp
= diff(etime
, timecopy
);
2214 } else { /* m == 0 */
2218 microuptime(&timecopy
);
2222 etime
.tv_sec
= t
/ 1000000;
2223 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
2224 timeradd(&etime
, &timecopy
, &etime
);
2228 if (timercmp(&etime
, &timecopy
, <=)) {
2229 /* Timed out, but 0 is enough input. */
2232 slp
= diff(etime
, timecopy
);
2237 * Rounding down may make us wake up just short
2238 * of the target, so we round up.
2239 * The formula is ceiling(slp * hz/1000000).
2240 * 32-bit arithmetic is enough for hz < 169.
2241 * XXX see hzto() for how to avoid overflow if hz
2242 * is large (divide by `tick' and/or arrange to
2243 * use hzto() if hz is large).
2245 slp
= (long) (((u_int32_t
)slp
* hz
) + 999999) / 1000000;
2248 if (qp
->c_cc
<= 0) {
2251 * There is no input, or not enough input and we can block.
2253 error
= ttysleep(tp
, TSA_HUP_OR_INPUT(tp
), TTIPRI
| PCATCH
,
2254 ISSET(tp
->t_state
, TS_CONNECTED
) ?
2255 "ttyin" : "ttyhup", (int)slp
);
2256 if (error
== EWOULDBLOCK
) {
2262 * XXX what happens if another process eats some input
2263 * while we are asleep (not just here)? It would be
2264 * safest to detect changes and reset our state variables
2265 * (has_stime and last_cc).
2272 * Input present, check for input mapping and processing.
2275 if (ISSET(lflag
, ICANON
)
2276 || (ISSET(lflag
, IEXTEN
| ISIG
) == (IEXTEN
| ISIG
))) {
2283 icc
= MIN(uio_resid(uio
), IBUFSIZ
);
2284 icc
= q_to_b(qp
, (u_char
*)ibuf
, icc
);
2291 error
= uiomove(ibuf
, icc
, uio
);
2293 * XXX if there was an error then we should ungetc() the
2294 * unmoved chars and reduce icc here.
2299 if (uio_resid(uio
) == 0) {
2315 * delayed suspend (^Y)
2317 if (CCEQ(cc
[VDSUSP
], c
) &&
2318 ISSET(lflag
, IEXTEN
| ISIG
) == (IEXTEN
| ISIG
)) {
2320 * SAFE: All callers drop the lock on return and
2321 * SAFE: current thread will not change out from
2322 * SAFE: under us in the "goto loop" case.
2325 tty_pgsignal(tp
, SIGTSTP
, 1);
2328 error
= ttysleep(tp
, &ttread
, TTIPRI
| PCATCH
,
2338 * Interpret EOF only in canonical mode.
2340 if (CCEQ(cc
[VEOF
], c
) && ISSET(lflag
, ICANON
)) {
2344 * Give user character.
2346 error
= ureadc(c
, uio
);
2348 /* XXX should ungetc(c, qp). */
2351 if (uio_resid(uio
) == 0) {
2355 * In canonical mode check for a "break character"
2356 * marking the end of a "line of input".
2358 if (ISSET(lflag
, ICANON
) && TTBREAKC(c
, lflag
)) {
2366 * Look to unblock input now that (presumably)
2367 * the input queue has gone down.
2369 if (ISSET(tp
->t_state
, TS_TBLOCK
) &&
2370 tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
<= I_LOW_WATER
) {
2380 * Check the output queue on tp for space for a kernel message (from uprintf
2381 * or tprintf). Allow some space over the normal hiwater mark so we don't
2382 * lose messages due to normal flow control, but don't let the tty run amok.
2383 * Sleeps here are not interruptible, but we return prematurely if new signals
2386 * Locks: Assumes tty_lock() is held before calling
2388 * Notes: This function is called from tprintf() in subr_prf.c
2391 ttycheckoutq(struct tty
*tp
, int wait
)
2397 TTY_LOCK_OWNED(tp
); /* debug assert */
2399 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
2401 hiwat
= tp
->t_hiwat
;
2402 oldsig
= wait
? ut
->uu_siglist
: 0;
2403 if (tp
->t_outq
.c_cc
> hiwat
+ OBUFSIZ
+ 100) {
2404 while (tp
->t_outq
.c_cc
> hiwat
) {
2406 if (tp
->t_outq
.c_cc
<= hiwat
) {
2409 if (wait
== 0 || ut
->uu_siglist
!= oldsig
) {
2412 SET(tp
->t_state
, TS_SO_OLOWAT
);
2413 ttysleep(tp
, TSA_OLOWAT(tp
), PZERO
- 1, "ttoutq", hz
);
2423 * Process a write call on a tty device.
2425 * Locks: Assumes tty_lock() is held prior to calling.
2428 ttwrite(struct tty
*tp
, struct uio
*uio
, int flag
)
2433 int i
, hiwat
, error
;
2439 TTY_LOCK_OWNED(tp
); /* debug assert */
2441 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
2442 hiwat
= tp
->t_hiwat
;
2443 count
= uio_resid(uio
);
2447 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
2448 if (uio_resid(uio
) == count
) {
2453 if (!ISSET(tp
->t_state
, TS_CONNECTED
)) {
2454 if (flag
& IO_NDELAY
) {
2455 error
= EWOULDBLOCK
;
2458 error
= ttysleep(tp
, TSA_CARR_ON(tp
), TTIPRI
| PCATCH
,
2466 * Signal the process if it's in the background.
2469 if (isbackground(p
, tp
) &&
2470 ISSET(tp
->t_lflag
, TOSTOP
) && (p
->p_lflag
& P_LPPWAIT
) == 0 &&
2471 (p
->p_sigignore
& sigmask(SIGTTOU
)) == 0 &&
2472 (ut
->uu_sigmask
& sigmask(SIGTTOU
)) == 0) {
2474 if (pg
== PGRP_NULL
) {
2478 if (pg
->pg_jobc
== 0) {
2479 /* SAFE: All callers drop the lock on return */
2486 /* SAFE: All callers drop the lock on return */
2488 pgsignal(pg
, SIGTTOU
, 1);
2492 * We signalled ourself, so we need to act as if we
2493 * have been "interrupted" from a "sleep" to act on
2494 * the signal. If it's a signal that stops the
2495 * process, that's handled in the signal sending code.
2501 * Process the user's data in at most OBUFSIZ chunks. Perform any
2502 * output translation. Keep track of high water mark, sleep on
2503 * overflow awaiting device aid in acquiring new space.
2505 while (uio_resid(uio
) > 0 || cc
> 0) {
2506 if (ISSET(tp
->t_lflag
, FLUSHO
)) {
2507 uio_setresid(uio
, 0);
2510 if (tp
->t_outq
.c_cc
> hiwat
) {
2514 * Grab a hunk of data from the user, unless we have some
2515 * leftover from last time.
2518 cc
= MIN(uio_resid(uio
), OBUFSIZ
);
2520 error
= uiomove(cp
, cc
, uio
);
2527 * If nothing fancy need be done, grab those characters we
2528 * can handle without any of ttyoutput's processing and
2529 * just transfer them to the output q. For those chars
2530 * which require special processing (as indicated by the
2531 * bits in char_type), call ttyoutput. After processing
2532 * a hunk of data, look for FLUSHO so ^O's will take effect
2536 if (!ISSET(tp
->t_oflag
, OPOST
)) {
2539 ce
= cc
- scanc((u_int
)cc
, (u_char
*)cp
,
2540 char_type
, CCLASSMASK
);
2542 * If ce is zero, then we're processing
2543 * a special character through ttyoutput.
2547 if (ttyoutput(*cp
, tp
) >= 0) {
2553 if (ISSET(tp
->t_lflag
, FLUSHO
) ||
2554 tp
->t_outq
.c_cc
> hiwat
) {
2561 * A bunch of normal characters have been found.
2562 * Transfer them en masse to the output queue and
2563 * continue processing at the top of the loop.
2564 * If there are any further characters in this
2565 * <= OBUFSIZ chunk, the first should be a character
2566 * requiring special handling by ttyoutput.
2569 i
= b_to_q((u_char
*)cp
, ce
, &tp
->t_outq
);
2580 if (ISSET(tp
->t_lflag
, FLUSHO
) ||
2581 tp
->t_outq
.c_cc
> hiwat
) {
2589 * If cc is nonzero, we leave the uio structure inconsistent, as the
2590 * offset and iov pointers have moved forward, but it doesn't matter
2591 * (the call will either return short or restart with a new uio).
2593 uio_setresid(uio
, (uio_resid(uio
) + cc
));
2599 * Since we are using ring buffers, if we can't insert any more into
2600 * the output queue, we can assume the ring is full and that someone
2601 * forgot to set the high water mark correctly. We set it and then
2602 * proceed as normal.
2604 hiwat
= tp
->t_outq
.c_cc
- 1;
2609 * This can only occur if FLUSHO is set in t_lflag,
2610 * or if ttstart/oproc is synchronous (or very fast).
2612 if (tp
->t_outq
.c_cc
<= hiwat
) {
2615 if (flag
& IO_NDELAY
) {
2616 uio_setresid(uio
, (uio_resid(uio
) + cc
));
2617 return uio_resid(uio
) == count
? EWOULDBLOCK
: 0;
2619 SET(tp
->t_state
, TS_SO_OLOWAT
);
2620 error
= ttysleep(tp
, TSA_OLOWAT(tp
), TTOPRI
| PCATCH
, "ttywri",
2622 if (error
== EWOULDBLOCK
) {
2633 * Rubout one character from the rawq of tp
2634 * as cleanly as possible.
2636 * Locks: Assumes tty_lock() is held prior to calling.
2639 ttyrub(int c
, struct tty
*tp
)
2645 TTY_LOCK_OWNED(tp
); /* debug assert */
2647 if (!ISSET(tp
->t_lflag
, ECHO
) || ISSET(tp
->t_lflag
, EXTPROC
)) {
2650 CLR(tp
->t_lflag
, FLUSHO
);
2651 if (ISSET(tp
->t_lflag
, ECHOE
)) {
2652 if (tp
->t_rocount
== 0) {
2654 * Messed up by ttwrite; retype
2659 if (c
== ('\t' | TTY_QUOTE
) || c
== ('\n' | TTY_QUOTE
)) {
2662 CLR(c
, ~TTY_CHARMASK
);
2663 switch (CCLASS(c
)) {
2665 if (!(ISSET(tp
->t_iflag
, IUTF8
) && CCONT(c
))) {
2674 if (ISSET(tp
->t_lflag
, ECHOCTL
)) {
2679 if (tp
->t_rocount
< tp
->t_rawq
.c_cc
) {
2683 savecol
= tp
->t_column
;
2684 SET(tp
->t_state
, TS_CNTTB
);
2685 SET(tp
->t_lflag
, FLUSHO
);
2686 tp
->t_column
= tp
->t_rocol
;
2687 for (cp
= firstc(&tp
->t_rawq
, &tabc
); cp
;
2688 cp
= nextc(&tp
->t_rawq
, cp
, &tabc
)) {
2691 CLR(tp
->t_lflag
, FLUSHO
);
2692 CLR(tp
->t_state
, TS_CNTTB
);
2694 /* savecol will now be length of the tab. */
2695 savecol
-= tp
->t_column
;
2696 tp
->t_column
+= savecol
;
2698 savecol
= 8; /* overflow fixup */
2700 while (--savecol
>= 0) {
2701 (void)ttyoutput('\b', tp
);
2705 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
2706 printf(PANICSTR
, c
, CCLASS(c
));
2708 panic(PANICSTR
, c
, CCLASS(c
));
2712 } else if (ISSET(tp
->t_lflag
, ECHOPRT
)) {
2713 if (!ISSET(tp
->t_state
, TS_ERASE
)) {
2714 SET(tp
->t_state
, TS_ERASE
);
2715 (void)ttyoutput('\\', tp
);
2719 ttyecho(tp
->t_cc
[VERASE
], tp
);
2726 * Back over count characters, erasing them.
2728 * Locks: Assumes tty_lock() is held prior to calling.
2731 ttyrubo(struct tty
*tp
, int count
)
2733 TTY_LOCK_OWNED(tp
); /* debug assert */
2735 while (count
-- > 0) {
2736 (void)ttyoutput('\b', tp
);
2737 (void)ttyoutput(' ', tp
);
2738 (void)ttyoutput('\b', tp
);
2745 * Reprint the rawq line. Note, it is assumed that c_cc has already
2748 * Locks: Assumes tty_lock() is held prior to calling.
2751 ttyretype(struct tty
*tp
)
2756 TTY_LOCK_OWNED(tp
); /* debug assert */
2758 /* Echo the reprint character. */
2759 if (tp
->t_cc
[VREPRINT
] != _POSIX_VDISABLE
) {
2760 ttyecho(tp
->t_cc
[VREPRINT
], tp
);
2763 (void)ttyoutput('\n', tp
);
2767 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2768 * BIT OF FIRST CHAR.
2770 for (cp
= firstc(&tp
->t_canq
, &c
); cp
; cp
= nextc(&tp
->t_canq
, cp
, &c
)) {
2773 for (cp
= firstc(&tp
->t_rawq
, &c
); cp
; cp
= nextc(&tp
->t_rawq
, cp
, &c
)) {
2776 CLR(tp
->t_state
, TS_ERASE
);
2778 tp
->t_rocount
= tp
->t_rawq
.c_cc
;
2784 * Echo a typed character to the terminal.
2786 * Locks: Assumes tty_lock() is held prior to calling.
2789 ttyecho(int c
, struct tty
*tp
)
2791 TTY_LOCK_OWNED(tp
); /* debug assert */
2793 if (!ISSET(tp
->t_state
, TS_CNTTB
)) {
2794 CLR(tp
->t_lflag
, FLUSHO
);
2796 if ((!ISSET(tp
->t_lflag
, ECHO
) &&
2797 (c
!= '\n' || !ISSET(tp
->t_lflag
, ECHONL
))) ||
2798 ISSET(tp
->t_lflag
, EXTPROC
)) {
2801 if (ISSET(tp
->t_lflag
, ECHOCTL
) &&
2802 ((ISSET(c
, TTY_CHARMASK
) <= 037 && c
!= '\t' && c
!= '\n') ||
2803 ISSET(c
, TTY_CHARMASK
) == 0177)) {
2804 (void)ttyoutput('^', tp
);
2805 CLR(c
, ~TTY_CHARMASK
);
2812 (void)ttyoutput(c
, tp
);
2816 ttwakeup_knote(struct selinfo
*sip
, long hint
)
2818 if ((sip
->si_flags
& SI_KNPOSTING
) == 0) {
2819 sip
->si_flags
|= SI_KNPOSTING
;
2820 KNOTE(&sip
->si_note
, hint
);
2821 sip
->si_flags
&= ~SI_KNPOSTING
;
2827 * Wake up any readers on a tty.
2829 * Locks: Assumes tty_lock() is held for the call.
2832 ttwakeup(struct tty
*tp
)
2834 TTY_LOCK_OWNED(tp
); /* debug assert */
2836 selwakeup(&tp
->t_rsel
);
2837 ttwakeup_knote(&tp
->t_rsel
, 0);
2838 if (ISSET(tp
->t_state
, TS_ASYNC
)) {
2840 * XXX: Callers may not revalidate it the tty is closed
2841 * XXX: out from under them by another thread, but we do
2842 * XXX: not support queued signals. This should be safe,
2843 * XXX: since the process we intend to wakeup is in the
2844 * XXX: process group, and will wake up because of the
2845 * XXX: signal anyway.
2848 tty_pgsignal(tp
, SIGIO
, 1);
2851 wakeup(TSA_HUP_OR_INPUT(tp
));
2858 * Wake up any writers on a tty.
2860 * Locks: Assumes tty_lock() is held prior to calling.
2863 ttwwakeup(struct tty
*tp
)
2865 TTY_LOCK_OWNED(tp
); /* debug assert */
2867 if (tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
2868 selwakeup(&tp
->t_wsel
);
2869 ttwakeup_knote(&tp
->t_wsel
, 0);
2871 if (ISSET(tp
->t_state
, TS_BUSY
| TS_SO_OCOMPLETE
) ==
2872 TS_SO_OCOMPLETE
&& tp
->t_outq
.c_cc
== 0) {
2873 CLR(tp
->t_state
, TS_SO_OCOMPLETE
);
2874 wakeup(TSA_OCOMPLETE(tp
));
2876 if (ISSET(tp
->t_state
, TS_SO_OLOWAT
) &&
2877 tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
2878 CLR(tp
->t_state
, TS_SO_OLOWAT
);
2879 wakeup(TSA_OLOWAT(tp
));
2885 * Look up a code for a specified speed in a conversion table;
2886 * used by drivers to map software speed values to hardware parameters.
2888 * Notes: No locks are assumed for this function; it does not
2889 * directly access struct tty.
2892 ttspeedtab(int speed
, struct speedtab
*table
)
2894 for (; table
->sp_speed
!= -1; table
++) {
2895 if (table
->sp_speed
== speed
) {
2896 return table
->sp_code
;
2904 * Set tty hi and low water marks.
2906 * Try to arrange the dynamics so there's about one second
2907 * from hi to low water.
2909 * Locks: Assumes tty_lock() is held prior to calling.
2912 ttsetwater(struct tty
*tp
)
2917 TTY_LOCK_OWNED(tp
); /* debug assert */
2919 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2921 cps
= tp
->t_ospeed
/ 10;
2922 tp
->t_lowat
= x
= CLAMP(cps
/ 2, TTMAXLOWAT
, TTMINLOWAT
);
2924 x
= CLAMP(x
, TTMAXHIWAT
, TTMINHIWAT
);
2925 tp
->t_hiwat
= roundup(x
, CBSIZE
);
2929 /* ttyinfo has been converted to the MACH kernel */
2930 #include <mach/thread_info.h>
2932 /* XXX Should be in Mach header <kern/thread.h>, but doesn't work */
2933 extern kern_return_t
thread_info_internal(thread_t thread
,
2934 thread_flavor_t flavor
,
2935 thread_info_t thread_info_out
,
2936 mach_msg_type_number_t
*thread_info_count
);
2940 * Report on state of foreground process group.
2942 * Locks: Assumes tty_lock() is held prior to calling.
2945 ttyinfo_locked(struct tty
*tp
)
2954 struct timeval utime
;
2955 struct timeval stime
;
2956 thread_basic_info_data_t basic_info
;
2957 mach_msg_type_number_t mmtn
= THREAD_BASIC_INFO_COUNT
;
2960 TTY_LOCK_OWNED(tp
); /* debug assert */
2962 if (ttycheckoutq(tp
, 0) == 0) {
2966 /* Print load average. */
2967 load
= (averunnable
.ldavg
[0] * 100 + FSCALE
/ 2) >> FSHIFT
;
2968 ttyprintf(tp
, "load: %d.%02d ", load
/ 100, load
% 100);
2971 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
2972 * that pending input will be retyped on BS.
2974 if (tp
->t_session
== NULL
) {
2975 ttyprintf(tp
, "not a controlling terminal\n");
2979 if (tp
->t_pgrp
== NULL
) {
2980 ttyprintf(tp
, "no foreground process group\n");
2984 /* first process in process group */
2985 /* XXX is there a need for pgrp lock ? */
2986 if ((p
= tp
->t_pgrp
->pg_members
.lh_first
) == NULL
) {
2987 ttyprintf(tp
, "empty foreground process group\n");
2993 * Pick the most interesting process and copy some of its
2994 * state for printing later.
2998 /* the proc_compare is non blocking fn, no need to use iterator */
2999 for (pick
= NULL
; p
!= NULL
; p
= p
->p_pglist
.le_next
) {
3000 if (proc_compare(pick
, p
)) {
3004 pickpid
= pick
->p_pid
;
3008 /* SAFE: All callers drop the lock on return */
3013 pick
= proc_find(pickpid
);
3014 if (pick
== PROC_NULL
) {
3018 if (TAILQ_EMPTY(&pick
->p_uthlist
) ||
3019 (uthread
= TAILQ_FIRST(&pick
->p_uthlist
)) == NULL
||
3020 (thread
= vfs_context_thread(&uthread
->uu_context
)) == NULL
||
3021 (thread_info_internal(thread
, THREAD_BASIC_INFO
, (thread_info_t
)&basic_info
, &mmtn
) != KERN_SUCCESS
)) {
3022 ttyprintf(tp
, "foreground process without thread\n");
3028 switch (basic_info
.run_state
) {
3029 case TH_STATE_RUNNING
:
3032 case TH_STATE_STOPPED
:
3035 case TH_STATE_WAITING
:
3038 case TH_STATE_UNINTERRUPTIBLE
:
3039 state
= "uninterruptible";
3041 case TH_STATE_HALTED
:
3048 calcru(pick
, &utime
, &stime
, NULL
);
3050 /* Print command, pid, state, utime, and stime */
3051 ttyprintf(tp
, " cmd: %s %d %s %ld.%02du %ld.%02ds\n",
3055 (long)utime
.tv_sec
, utime
.tv_usec
/ 10000,
3056 (long)stime
.tv_sec
, stime
.tv_usec
/ 10000);
3064 * Returns 1 if p2 is "better" than p1
3066 * The algorithm for picking the "interesting" process is thus:
3068 * 1) Only foreground processes are eligible - implied.
3069 * 2) Runnable processes are favored over anything else. The runner
3070 * with the highest cpu utilization is picked (p_estcpu). Ties are
3071 * broken by picking the highest pid.
3072 * 3) The sleeper with the shortest sleep time is next.
3073 * 4) Further ties are broken by picking the highest pid.
3075 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
3076 #define TESTAB(a, b) ((a)<<1 | (b))
3082 * Locks: pgrp_lock(p2) held on call to this function
3083 * tty_lock(tp) for p2's tty, for which p2 is the foreground
3084 * process, held on call to this function
3087 proc_compare(proc_t p1
, proc_t p2
)
3089 /* NOTE THIS FN needs to be NON BLOCKING */
3095 * see if at least one of them is runnable
3097 switch (TESTAB(ISRUN(p1
), ISRUN(p2
))) {
3104 * tie - favor one with highest recent cpu utilization
3106 #ifdef _PROC_HAS_SCHEDINFO_
3107 /* Without the support the fields are always zero */
3108 if (p2
->p_estcpu
> p1
->p_estcpu
) {
3111 if (p1
->p_estcpu
> p2
->p_estcpu
) {
3114 #endif /* _PROC_HAS_SCHEDINFO_ */
3115 return p2
->p_pid
> p1
->p_pid
; /* tie - return highest pid */
3120 switch (TESTAB(p1
->p_stat
== SZOMB
, p2
->p_stat
== SZOMB
)) {
3126 return p2
->p_pid
> p1
->p_pid
; /* tie - return highest pid */
3129 * pick the one with the smallest sleep time
3131 #ifdef _PROC_HAS_SCHEDINFO_
3132 /* Without the support the fields are always zero */
3133 if (p2
->p_slptime
> p1
->p_slptime
) {
3136 if (p1
->p_slptime
> p2
->p_slptime
) {
3139 #endif /* _PROC_HAS_SCHEDINFO_ */
3140 return p2
->p_pid
> p1
->p_pid
; /* tie - return highest pid */
3145 * Output char to tty; console putchar style.
3147 * Locks: Assumes tty_lock() is held prior to calling.
3149 * Notes: Only ever called from putchar() in subr_prf.c
3152 tputchar(int c
, struct tty
*tp
)
3154 TTY_LOCK_OWNED(tp
); /* debug assert */
3156 if (!ISSET(tp
->t_state
, TS_CONNECTED
)) {
3160 (void)ttyoutput('\r', tp
);
3162 (void)ttyoutput(c
, tp
);
3171 * Sleep on a wait channel waiting for an interrupt or a condition to come
3172 * true so that we are woken up.
3174 * Parameters: tp Tty going to sleep
3175 * chan The sleep channel (usually an address
3176 * of a structure member)
3177 * pri priority and flags
3178 * wmesg Wait message; shows up in debugger,
3179 * should show up in "ps", but doesn't
3180 * timo Timeout for the sleep
3182 * Returns: 0 Condition came true
3183 * ERESTART Upper layer must redrive the call;
3184 * this is usually done by the Libc
3185 * stub in user space
3186 * msleep0:EINTR Interrupted (usually a signal)
3187 * msleep0:ERESTART Interrupted (usually a masked signal)
3188 * msleep0:EWOULDBLOCK Timeout (timo) already expired
3190 * Locks: Assumes tty_lock() is held prior to calling.
3192 * Sleep on chan, returning ERESTART if tty changed while we napped and
3193 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by msleep0. If
3194 * the tty is revoked, restarting a pending call will redo validation done
3195 * at the start of the call.
3198 ttysleep(struct tty
*tp
, void *chan
, int pri
, const char *wmesg
, int timo
)
3206 /* Use of msleep0() avoids conversion timo/timespec/timo */
3207 error
= msleep0(chan
, &tp
->t_lock
, pri
, wmesg
, timo
, (int (*)(int))0);
3211 return tp
->t_gen
== gen
? 0 : ERESTART
;
3216 * Allocate a tty structure and its associated buffers.
3220 * Returns: !NULL Address of new struct tty
3221 * NULL Error ("ENOMEM")
3223 * Locks: The tty_lock() of the returned tty is not held when it
3231 MALLOC(tp
, struct tty
*, sizeof(struct tty
), M_TTYS
, M_WAITOK
| M_ZERO
);
3233 /* XXX: default to TTYCLSIZE(1024) chars for now */
3234 clalloc(&tp
->t_rawq
, TTYCLSIZE
, 1);
3235 clalloc(&tp
->t_canq
, TTYCLSIZE
, 1);
3236 /* output queue doesn't need quoting */
3237 clalloc(&tp
->t_outq
, TTYCLSIZE
, 0);
3238 lck_mtx_init(&tp
->t_lock
, tty_lck_grp
, tty_lck_attr
);
3239 klist_init(&tp
->t_rsel
.si_note
);
3240 klist_init(&tp
->t_wsel
.si_note
);
3247 * Increment the reference count on a tty.
3250 ttyhold(struct tty
*tp
)
3257 * Drops a reference count on a tty structure; if the reference count reaches
3258 * zero, then also frees the structure and associated buffers.
3261 ttyfree(struct tty
*tp
)
3263 TTY_LOCK_NOTOWNED(tp
);
3266 if (--tp
->t_refcnt
== 0) {
3269 } else if (tp
->t_refcnt
< 0) {
3270 panic("%s: freeing free tty %p", __func__
, tp
);
3277 * Deallocate a tty structure and its buffers.
3279 * Locks: The tty_lock() is assumed to not be held at the time of
3280 * the free; this function destroys the mutex.
3283 ttydeallocate(struct tty
*tp
)
3285 TTY_LOCK_NOTOWNED(tp
); /* debug assert */
3288 if (!(SLIST_EMPTY(&tp
->t_rsel
.si_note
) && SLIST_EMPTY(&tp
->t_wsel
.si_note
))) {
3289 panic("knotes hooked into a tty when the tty is freed.\n");
3293 clfree(&tp
->t_rawq
);
3294 clfree(&tp
->t_canq
);
3295 clfree(&tp
->t_outq
);
3296 lck_mtx_destroy(&tp
->t_lock
, tty_lck_grp
);
3302 * Locks: Assumes tty_lock() is held prior to calling.
3305 isbackground(proc_t p
, struct tty
*tp
)
3309 return tp
->t_session
!= NULL
&& p
->p_pgrp
!= NULL
&& (p
->p_pgrp
!= tp
->t_pgrp
) && isctty_sp(p
, tp
, p
->p_pgrp
->pg_session
);
3313 isctty(proc_t p
, struct tty
*tp
)
3316 struct session
* sessp
;
3318 sessp
= proc_session(p
);
3319 retval
= (sessp
== tp
->t_session
&& p
->p_flag
& P_CONTROLT
);
3320 session_rele(sessp
);
3325 isctty_sp(proc_t p
, struct tty
*tp
, struct session
*sessp
)
3327 return sessp
== tp
->t_session
&& p
->p_flag
& P_CONTROLT
;
3331 static int filt_ttyattach(struct knote
*kn
, struct kevent_qos_s
*kev
);
3332 static void filt_ttydetach(struct knote
*kn
);
3333 static int filt_ttyevent(struct knote
*kn
, long hint
);
3334 static int filt_ttytouch(struct knote
*kn
, struct kevent_qos_s
*kev
);
3335 static int filt_ttyprocess(struct knote
*kn
, struct kevent_qos_s
*kev
);
3337 SECURITY_READ_ONLY_EARLY(struct filterops
) tty_filtops
= {
3339 .f_attach
= filt_ttyattach
,
3340 .f_detach
= filt_ttydetach
,
3341 .f_event
= filt_ttyevent
,
3342 .f_touch
= filt_ttytouch
,
3343 .f_process
= filt_ttyprocess
3347 * Called with struct tty locked. Returns non-zero if there is data to be read
3351 filt_tty_common(struct knote
*kn
, struct kevent_qos_s
*kev
, struct tty
*tp
)
3356 TTY_LOCK_OWNED(tp
); /* debug assert */
3358 switch (kn
->kn_filter
) {
3361 * ttnread can change the tty state,
3362 * hence must be done upfront, before any other check.
3365 retval
= (data
!= 0);
3368 if ((tp
->t_outq
.c_cc
<= tp
->t_lowat
) &&
3369 (tp
->t_state
& TS_CONNECTED
)) {
3370 data
= tp
->t_hiwat
- tp
->t_outq
.c_cc
;
3371 retval
= (data
!= 0);
3375 panic("tty kevent: unexpected filter: %d, kn = %p, tty = %p",
3376 kn
->kn_filter
, kn
, tp
);
3381 * TODO(mwidmann, jandrus): For native knote low watermark support,
3382 * check the kn_sfflags for NOTE_LOWAT and check against kn_sdata.
3384 * res = ((kn->kn_sfflags & NOTE_LOWAT) != 0) ?
3385 * (kn->kn_data >= kn->kn_sdata) : kn->kn_data;
3388 if (tp
->t_state
& TS_ZOMBIE
) {
3389 kn
->kn_flags
|= EV_EOF
;
3391 if (kn
->kn_flags
& EV_EOF
) {
3394 if (retval
&& kev
) {
3395 knote_fill_kevent(kn
, kev
, data
);
3402 * Find the struct tty from a waitq, which is a member of one of the two struct
3403 * selinfos inside the struct tty. Use the seltype to determine which selinfo.
3406 tty_from_waitq(struct waitq
*wq
, int seltype
)
3409 struct tty
*tp
= NULL
;
3412 * The waitq is part of the selinfo structure managed by the driver. For
3413 * certain drivers, we want to hook the knote into the selinfo
3414 * structure's si_note field so selwakeup can call KNOTE.
3416 * While 'wq' is not really a queue element, this macro only uses the
3417 * pointer to calculate the offset into a structure given an element
3420 si
= qe_element(wq
, struct selinfo
, si_waitq
);
3423 * For TTY drivers, the selinfo structure is somewhere in the struct
3424 * tty. There are two different selinfo structures, and the one used
3425 * corresponds to the type of filter requested.
3427 * While 'si' is not really a queue element, this macro only uses the
3428 * pointer to calculate the offset into a structure given an element
3433 tp
= qe_element(si
, struct tty
, t_rsel
);
3436 tp
= qe_element(si
, struct tty
, t_wsel
);
3444 tty_from_knote(struct knote
*kn
)
3446 return (struct tty
*)kn
->kn_hook
;
3450 * Set the knote's struct tty to the kn_hook field.
3452 * The idea is to fake a call to select with our own waitq set. If the driver
3453 * calls selrecord, we'll get a link to their waitq and access to the tty
3456 * Returns -1 on failure, with the error set in the knote, or selres on success.
3459 tty_set_knote_hook(struct knote
*kn
)
3465 struct waitq
*wq
= NULL
;
3466 struct waitq_set
*old_wqs
;
3467 struct waitq_set tmp_wqs
;
3468 uint64_t rsvd
, rsvd_arg
;
3469 uint64_t *rlptr
= NULL
;
3473 uth
= get_bsdthread_info(current_thread());
3475 ctx
= vfs_context_current();
3476 vp
= (vnode_t
)kn
->kn_fp
->f_fglob
->fg_data
;
3479 * Reserve a link element to avoid potential allocation under
3482 rsvd
= rsvd_arg
= waitq_link_reserve(NULL
);
3483 rlptr
= (void *)&rsvd_arg
;
3486 * Trick selrecord into hooking a known waitq set into the device's selinfo
3487 * waitq. Once the link is in place, we can get back into the selinfo from
3488 * the waitq and subsequently the tty (see tty_from_waitq).
3490 * We can't use a real waitq set (such as the kqueue's) because wakeups
3491 * might happen before we can unlink it.
3493 kr
= waitq_set_init(&tmp_wqs
, SYNC_POLICY_FIFO
| SYNC_POLICY_PREPOST
, NULL
,
3495 assert(kr
== KERN_SUCCESS
);
3498 * Lazy allocate the waitqset to avoid potential allocation under
3501 waitq_set_lazy_init_link(&tmp_wqs
);
3503 old_wqs
= uth
->uu_wqset
;
3504 uth
->uu_wqset
= &tmp_wqs
;
3506 * FMARK forces selects to always call selrecord, even if data is
3507 * available. See ttselect, ptsselect, ptcselect.
3509 * selres also contains the data currently available in the tty.
3511 selres
= VNOP_SELECT(vp
, knote_get_seltype(kn
) | FMARK
, 0, rlptr
, ctx
);
3512 uth
->uu_wqset
= old_wqs
;
3515 * Make sure to cleanup the reserved link - this guards against
3516 * drivers that may not actually call selrecord().
3518 waitq_link_release(rsvd
);
3519 if (rsvd
== rsvd_arg
) {
3521 * The driver didn't call selrecord -- there's no tty hooked up so we
3524 knote_set_error(kn
, ENOTTY
);
3529 /* rlptr may not point to a properly aligned pointer */
3530 memcpy(&wq
, rlptr
, sizeof(void *));
3532 tp
= tty_from_waitq(wq
, knote_get_seltype(kn
));
3536 * Take a reference and stash the tty in the knote.
3545 * Cleaning up the wqset will unlink its waitq and clean up any preposts
3546 * that occurred as a result of data coming in while the tty was attached.
3548 waitq_set_deinit(&tmp_wqs
);
3554 filt_ttyattach(struct knote
*kn
, __unused
struct kevent_qos_s
*kev
)
3560 * This function should be called from filt_specattach (spec_vnops.c),
3561 * so most of the knote data structure should already be initialized.
3564 /* don't support offsets in ttys or drivers that don't use struct tty */
3565 if (kn
->kn_vnode_use_ofst
|| !kn
->kn_vnode_kqok
) {
3566 knote_set_error(kn
, ENOTSUP
);
3571 * Connect the struct tty to the knote through the selinfo structure
3572 * referenced by the waitq within the selinfo.
3574 selres
= tty_set_knote_hook(kn
);
3580 * Attach the knote to selinfo's klist.
3582 tp
= tty_from_knote(kn
);
3585 switch (kn
->kn_filter
) {
3587 KNOTE_ATTACH(&tp
->t_rsel
.si_note
, kn
);
3590 KNOTE_ATTACH(&tp
->t_wsel
.si_note
, kn
);
3593 panic("invalid knote %p attach, filter: %d", kn
, kn
->kn_filter
);
3602 filt_ttydetach(struct knote
*kn
)
3604 struct tty
*tp
= tty_from_knote(kn
);
3608 switch (kn
->kn_filter
) {
3610 KNOTE_DETACH(&tp
->t_rsel
.si_note
, kn
);
3613 KNOTE_DETACH(&tp
->t_wsel
.si_note
, kn
);
3616 panic("invalid knote %p detach, filter: %d", kn
, kn
->kn_filter
);
3625 filt_ttyevent(struct knote
*kn
, long hint
)
3627 struct tty
*tp
= tty_from_knote(kn
);
3632 if (hint
& NOTE_REVOKE
) {
3633 kn
->kn_flags
|= EV_EOF
| EV_ONESHOT
;
3636 ret
= filt_tty_common(kn
, NULL
, tp
);
3643 filt_ttytouch(struct knote
*kn
, struct kevent_qos_s
*kev
)
3645 struct tty
*tp
= tty_from_knote(kn
);
3650 kn
->kn_sdata
= kev
->data
;
3651 kn
->kn_sfflags
= kev
->fflags
;
3653 if (kn
->kn_vnode_kqok
) {
3654 res
= filt_tty_common(kn
, NULL
, tp
);
3663 filt_ttyprocess(struct knote
*kn
, struct kevent_qos_s
*kev
)
3665 struct tty
*tp
= tty_from_knote(kn
);
3670 res
= filt_tty_common(kn
, kev
, tp
);