2 * Copyright (c) 1997-2007 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 */
118 * Debugging assertions for tty locks
122 #define TTY_LOCK_OWNED(tp) do {lck_mtx_assert(&tp->t_lock, LCK_MTX_ASSERT_OWNED); } while (0)
123 #define TTY_LOCK_NOTOWNED(tp) do {lck_mtx_assert(&tp->t_lock, LCK_MTX_ASSERT_NOTOWNED); } while (0)
125 #define TTY_LOCK_OWNED(tp)
126 #define TTY_LOCK_NOTOWNED(tp)
129 static lck_grp_t
*tty_lck_grp
;
130 static lck_grp_attr_t
*tty_lck_grp_attr
;
131 static lck_attr_t
*tty_lck_attr
;
133 __private_extern__
int ttnread(struct tty
*tp
);
134 static void ttyecho(int c
, struct tty
*tp
);
135 static int ttyoutput(int c
, struct tty
*tp
);
136 static void ttypend(struct tty
*tp
);
137 static void ttyretype(struct tty
*tp
);
138 static void ttyrub(int c
, struct tty
*tp
);
139 static void ttyrubo(struct tty
*tp
, int count
);
140 static void ttystop(struct tty
*tp
, int rw
);
141 static void ttyunblock(struct tty
*tp
);
142 static int ttywflush(struct tty
*tp
);
143 static int proc_compare(proc_t p1
, proc_t p2
);
145 static void ttyhold(struct tty
*tp
);
146 static void ttydeallocate(struct tty
*tp
);
148 static int isctty(proc_t p
, struct tty
*tp
);
149 static int isctty_sp(proc_t p
, struct tty
*tp
, struct session
*sessp
);
152 * Table with character classes and parity. The 8th bit indicates parity,
153 * the 7th bit indicates the character is an alphameric or underscore (for
154 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
155 * are 0 then the character needs no special processing on output; classes
156 * other than 0 might be translated or (not currently) require delays.
158 #define E 0x00 /* Even parity. */
159 #define O 0x80 /* Odd parity. */
160 #define PARITY(c) (char_type[c] & O)
162 #define ALPHA 0x40 /* Alpha or underscore. */
163 #define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
165 #define CCLASSMASK 0x3f
166 #define CCLASS(c) (char_type[c] & CCLASSMASK)
167 /* 0b10xxxxxx is the mask for UTF-8 continuations */
168 #define CCONT(c) ((c & 0xc0) == 0x80)
173 #define NA ORDINARY | ALPHA
179 static u_char
const char_type
[] = {
180 E
|CC
, O
|CC
, O
|CC
, E
|CC
, O
|CC
, E
|CC
, E
|CC
, O
|CC
, /* nul - bel */
181 O
|BS
, E
|TB
, E
|NL
, O
|CC
, E
|VT
, O
|CR
, O
|CC
, E
|CC
, /* bs - si */
182 O
|CC
, E
|CC
, E
|CC
, O
|CC
, E
|CC
, O
|CC
, O
|CC
, E
|CC
, /* dle - etb */
183 E
|CC
, O
|CC
, O
|CC
, E
|CC
, O
|CC
, E
|CC
, E
|CC
, O
|CC
, /* can - us */
184 O
|NO
, E
|NO
, E
|NO
, O
|NO
, E
|NO
, O
|NO
, O
|NO
, E
|NO
, /* sp - ' */
185 E
|NO
, O
|NO
, O
|NO
, E
|NO
, O
|NO
, E
|NO
, E
|NO
, O
|NO
, /* ( - / */
186 E
|NA
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* 0 - 7 */
187 O
|NA
, E
|NA
, E
|NO
, O
|NO
, E
|NO
, O
|NO
, O
|NO
, E
|NO
, /* 8 - ? */
188 O
|NO
, E
|NA
, E
|NA
, O
|NA
, E
|NA
, O
|NA
, O
|NA
, E
|NA
, /* @ - G */
189 E
|NA
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* H - O */
190 E
|NA
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* P - W */
191 O
|NA
, E
|NA
, E
|NA
, O
|NO
, E
|NO
, O
|NO
, O
|NO
, O
|NA
, /* X - _ */
192 E
|NO
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* ` - g */
193 O
|NA
, E
|NA
, E
|NA
, O
|NA
, E
|NA
, O
|NA
, O
|NA
, E
|NA
, /* h - o */
194 O
|NA
, E
|NA
, E
|NA
, O
|NA
, E
|NA
, O
|NA
, O
|NA
, E
|NA
, /* p - w */
195 E
|NA
, O
|NA
, O
|NA
, E
|NO
, O
|NO
, E
|NO
, E
|NO
, O
|CC
, /* x - del */
197 * Meta chars; should be settable per character set;
198 * for now, treat them all as normal characters.
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
,
206 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
207 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
208 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
209 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
210 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
211 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
212 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
213 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
214 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
215 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
226 /* Macros to clear/set/test flags. */
227 #define SET(t, f) (t) |= (f)
228 #define CLR(t, f) (t) &= ~(f)
229 #define ISSET(t, f) ((t) & (f))
232 * Input control starts when we would not be able to fit the maximum
233 * contents of the ping-pong buffers and finishes when we would be able
234 * to fit that much plus 1/8 more.
236 #define I_HIGH_WATER (TTYHOG - 2 * 256) /* XXX */
237 #define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
240 termios32to64(struct termios32
*in
, struct user_termios
*out
)
242 out
->c_iflag
= (user_tcflag_t
)in
->c_iflag
;
243 out
->c_oflag
= (user_tcflag_t
)in
->c_oflag
;
244 out
->c_cflag
= (user_tcflag_t
)in
->c_cflag
;
245 out
->c_lflag
= (user_tcflag_t
)in
->c_lflag
;
247 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
248 bcopy(in
->c_cc
, out
->c_cc
, sizeof(in
->c_cc
));
250 out
->c_ispeed
= (user_speed_t
)in
->c_ispeed
;
251 out
->c_ospeed
= (user_speed_t
)in
->c_ospeed
;
255 termios64to32(struct user_termios
*in
, struct termios32
*out
)
257 out
->c_iflag
= (tcflag_t
)in
->c_iflag
;
258 out
->c_oflag
= (tcflag_t
)in
->c_oflag
;
259 out
->c_cflag
= (tcflag_t
)in
->c_cflag
;
260 out
->c_lflag
= (tcflag_t
)in
->c_lflag
;
262 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
263 bcopy(in
->c_cc
, out
->c_cc
, sizeof(in
->c_cc
));
265 out
->c_ispeed
= (speed_t
)in
->c_ispeed
;
266 out
->c_ospeed
= (speed_t
)in
->c_ospeed
;
273 * Initialize the tty line discipline subsystem.
279 * Locks: No ttys can be allocated and no tty locks can be used
280 * until after this function is called
282 * Notes: The intent of this is to set up a log group attribute,
283 * lock group, and loc atribute for subsequent per-tty locks.
284 * This function is called early in bsd_init(), prior to the
285 * console device initialization.
290 tty_lck_grp_attr
= lck_grp_attr_alloc_init();
291 tty_lck_grp
= lck_grp_alloc_init("tty", tty_lck_grp_attr
);
292 tty_lck_attr
= lck_attr_alloc_init();
299 * Lock the requested tty structure.
301 * Parameters: tp The tty we want to lock
305 * Locks: On return, tp is locked
308 tty_lock(struct tty
*tp
)
310 TTY_LOCK_NOTOWNED(tp
); /* debug assert */
311 lck_mtx_lock(&tp
->t_lock
);
318 * Unlock the requested tty structure.
320 * Parameters: tp The tty we want to unlock
324 * Locks: On return, tp is unlocked
327 tty_unlock(struct tty
*tp
)
329 TTY_LOCK_OWNED(tp
); /* debug assert */
330 lck_mtx_unlock(&tp
->t_lock
);
337 * Initial open of tty, or (re)entry to standard tty line discipline.
339 * Locks: Assumes tty_lock() is held prior to calling.
342 ttyopen(dev_t device
, struct tty
*tp
)
344 proc_t p
= current_proc();
345 struct pgrp
*pg
, *oldpg
;
346 struct session
*sessp
, *oldsess
;
349 TTY_LOCK_OWNED(tp
); /* debug assert */
353 if (!ISSET(tp
->t_state
, TS_ISOPEN
)) {
354 SET(tp
->t_state
, TS_ISOPEN
);
355 if (ISSET(tp
->t_cflag
, CLOCAL
)) {
356 SET(tp
->t_state
, TS_CONNECTED
); }
357 bzero(&tp
->t_winsize
, sizeof(tp
->t_winsize
));
361 sessp
= proc_session(p
);
364 * First tty open affter setsid() call makes this tty its controlling
365 * tty, if the tty does not already have a session associated with it.
367 if (SESS_LEADER(p
, sessp
) && /* the process is the session leader */
368 sessp
->s_ttyvp
== NULL
&& /* but has no controlling tty */
369 tp
->t_session
== NULL
) { /* and tty not controlling */
371 if ((sessp
->s_flags
& S_NOCTTY
) == 0) { /* and no O_NOCTTY */
372 oldtp
= sessp
->s_ttyp
;
375 OSBitOrAtomic(P_CONTROLT
, &p
->p_flag
);
376 session_unlock(sessp
);
379 oldsess
= tp
->t_session
;
380 if (oldsess
!= SESSION_NULL
)
381 oldsess
->s_ttypgrpid
= NO_PID
;
382 tp
->t_session
= sessp
;
384 sessp
->s_ttypgrpid
= pg
->pg_id
;
386 /* SAFE: All callers drop the lock on return */
388 if (oldpg
!= PGRP_NULL
)
390 if (oldsess
!= SESSION_NULL
)
391 session_rele(oldsess
);
397 session_unlock(sessp
);
400 /* SAFE: All callers drop the lock on return */
402 if (sessp
!= SESSION_NULL
)
410 /* XXX may be an error code */
417 * Handle close() on a tty line: flush and set to initial state,
418 * bumping generation number so that pending read/write calls
419 * can detect recycling of the tty.
420 * XXX our caller should have done `spltty(); l_close(); ttyclose();'
421 * and l_close() should have flushed, but we repeat the spltty() and
422 * the flush in case there are buggy callers.
424 * Locks: Assumes tty_lock() is held prior to calling.
427 ttyclose(struct tty
*tp
)
430 struct session
* oldsessp
;
432 TTY_LOCK_OWNED(tp
); /* debug assert */
439 * Closing current console tty; disable printing of console
440 * messages at bottom-level driver.
442 (*cdevsw
[major(tp
->t_dev
)].d_ioctl
)
443 (tp
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, current_proc());
446 ttyflush(tp
, FREAD
| FWRITE
);
449 tp
->t_line
= TTYDISC
;
452 oldsessp
= tp
->t_session
;
454 tp
->t_session
= NULL
;
455 if (oldsessp
!= SESSION_NULL
)
456 oldsessp
->s_ttypgrpid
= NO_PID
;
458 /* drop the reference on prev session and pgrp */
459 /* SAFE: All callers drop the lock on return */
461 if (oldsessp
!= SESSION_NULL
)
462 session_rele(oldsessp
);
463 if (oldpg
!= PGRP_NULL
)
467 selthreadclear(&tp
->t_wsel
);
468 selthreadclear(&tp
->t_rsel
);
472 #define FLUSHQ(q) { \
474 ndflush(q, (q)->c_cc); \
477 /* Is 'c' a line delimiter ("break" character)? */
478 #define TTBREAKC(c, lflag) \
479 ((c) == '\n' || (((c) == cc[VEOF] || \
480 (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \
481 (c) != _POSIX_VDISABLE))
486 * Process input of a single character received on a tty.
488 * Parameters: c The character received
489 * tp The tty on which it was received
493 * Locks: Assumes tty_lock() is held prior to calling.
496 ttyinput(int c
, struct tty
*tp
)
498 tcflag_t iflag
, lflag
;
501 int retval
= 0; /* default return value */
503 TTY_LOCK_OWNED(tp
); /* debug assert */
506 * If input is pending take it first.
509 if (ISSET(lflag
, PENDIN
))
514 if (ISSET(lflag
, ICANON
)) {
524 * Block further input iff:
525 * current input > threshold AND input is available to user program
526 * AND input flow control is enabled and not yet invoked.
527 * The 3 is slop for PARMRK.
530 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
> I_HIGH_WATER
- 3 &&
531 (!ISSET(lflag
, ICANON
) || tp
->t_canq
.c_cc
!= 0) &&
532 (ISSET(tp
->t_cflag
, CRTS_IFLOW
) || ISSET(iflag
, IXOFF
)) &&
533 !ISSET(tp
->t_state
, TS_TBLOCK
))
536 /* Handle exceptional conditions (break, parity, framing). */
538 err
= (ISSET(c
, TTY_ERRORMASK
));
540 CLR(c
, TTY_ERRORMASK
);
541 if (ISSET(err
, TTY_BI
)) {
542 if (ISSET(iflag
, IGNBRK
)) {
545 if (ISSET(iflag
, BRKINT
)) {
546 ttyflush(tp
, FREAD
| FWRITE
);
547 /* SAFE: All callers drop the lock on return */
549 tty_pgsignal(tp
, SIGINT
, 1);
553 if (ISSET(iflag
, PARMRK
))
555 } else if ((ISSET(err
, TTY_PE
) && ISSET(iflag
, INPCK
))
556 || ISSET(err
, TTY_FE
)) {
557 if (ISSET(iflag
, IGNPAR
)) {
560 else if (ISSET(iflag
, PARMRK
)) {
562 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
>
565 (void)putc(0377 | TTY_QUOTE
, &tp
->t_rawq
);
566 (void)putc(0 | TTY_QUOTE
, &tp
->t_rawq
);
567 (void)putc(c
| TTY_QUOTE
, &tp
->t_rawq
);
574 if (!ISSET(tp
->t_state
, TS_TYPEN
) && ISSET(iflag
, ISTRIP
))
576 if (!ISSET(lflag
, EXTPROC
)) {
578 * Check for literal nexting very first
580 if (ISSET(tp
->t_state
, TS_LNCH
)) {
582 CLR(tp
->t_state
, TS_LNCH
);
585 * Scan for special characters. This code
586 * is really just a big case statement with
587 * non-constant cases. The bottom of the
588 * case statement is labeled ``endcase'', so goto
589 * it after a case match, or similar.
593 * Control chars which aren't controlled
594 * by ICANON, ISIG, or IXON.
596 if (ISSET(lflag
, IEXTEN
)) {
597 if (CCEQ(cc
[VLNEXT
], c
)) {
598 if (ISSET(lflag
, ECHO
)) {
599 if (ISSET(lflag
, ECHOE
)) {
600 (void)ttyoutput('^', tp
);
601 (void)ttyoutput('\b', tp
);
605 SET(tp
->t_state
, TS_LNCH
);
608 if (CCEQ(cc
[VDISCARD
], c
)) {
609 if (ISSET(lflag
, FLUSHO
))
610 CLR(tp
->t_lflag
, FLUSHO
);
612 ttyflush(tp
, FWRITE
);
614 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
)
616 SET(tp
->t_lflag
, FLUSHO
);
624 if (ISSET(lflag
, ISIG
)) {
625 if (CCEQ(cc
[VINTR
], c
) || CCEQ(cc
[VQUIT
], c
)) {
626 if (!ISSET(lflag
, NOFLSH
))
627 ttyflush(tp
, FREAD
| FWRITE
);
630 * SAFE: All callers drop the lock on return;
631 * SAFE: if we lose a threaded race on change
632 * SAFE: of the interrupt character, we could
633 * SAFE: have lost that race anyway due to the
634 * SAFE: scheduler executing threads in
635 * SAFE: priority order rather than "last
636 * SAFE: active thread" order (FEATURE).
640 CCEQ(cc
[VINTR
], c
) ? SIGINT
: SIGQUIT
, 1);
644 if (CCEQ(cc
[VSUSP
], c
)) {
645 if (!ISSET(lflag
, NOFLSH
))
648 /* SAFE: All callers drop the lock on return */
650 tty_pgsignal(tp
, SIGTSTP
, 1);
656 * Handle start/stop characters.
658 if (ISSET(iflag
, IXON
)) {
659 if (CCEQ(cc
[VSTOP
], c
)) {
660 if (!ISSET(tp
->t_state
, TS_TTSTOP
)) {
661 SET(tp
->t_state
, TS_TTSTOP
);
665 if (!CCEQ(cc
[VSTART
], c
)) {
669 * if VSTART == VSTOP then toggle
673 if (CCEQ(cc
[VSTART
], c
))
677 * IGNCR, ICRNL, & INLCR
680 if (ISSET(iflag
, IGNCR
)) {
683 else if (ISSET(iflag
, ICRNL
))
685 } else if (c
== '\n' && ISSET(iflag
, INLCR
))
688 if (!ISSET(tp
->t_lflag
, EXTPROC
) && ISSET(lflag
, ICANON
)) {
690 * From here on down canonical mode character
691 * processing takes place.
696 if (CCEQ(cc
[VERASE
], c
)) {
697 if (tp
->t_rawq
.c_cc
) {
698 if (ISSET(iflag
, IUTF8
)) {
700 ttyrub((c
= unputc(&tp
->t_rawq
)), tp
);
701 } while(tp
->t_rawq
.c_cc
&& CCONT(c
));
703 ttyrub(unputc(&tp
->t_rawq
), tp
);
711 if (CCEQ(cc
[VKILL
], c
)) {
712 if (ISSET(lflag
, ECHOKE
) &&
713 tp
->t_rawq
.c_cc
== tp
->t_rocount
&&
714 !ISSET(lflag
, ECHOPRT
))
715 while (tp
->t_rawq
.c_cc
)
716 ttyrub(unputc(&tp
->t_rawq
), tp
);
719 if (ISSET(lflag
, ECHOK
) ||
720 ISSET(lflag
, ECHOKE
))
725 CLR(tp
->t_state
, TS_LOCAL
);
731 if (CCEQ(cc
[VWERASE
], c
) && ISSET(lflag
, IEXTEN
)) {
737 while ((c
= unputc(&tp
->t_rawq
)) == ' ' || c
== '\t')
742 * erase last char of word and remember the
743 * next chars type (for ALTWERASE)
746 c
= unputc(&tp
->t_rawq
);
749 if (c
== ' ' || c
== '\t') {
750 (void)putc(c
, &tp
->t_rawq
);
759 c
= unputc(&tp
->t_rawq
);
762 } while (c
!= ' ' && c
!= '\t' &&
763 (!ISSET(lflag
, ALTWERASE
) || ISALPHA(c
) == ctype
));
764 (void)putc(c
, &tp
->t_rawq
);
770 if (CCEQ(cc
[VREPRINT
], c
) && ISSET(lflag
, IEXTEN
)) {
775 * ^T - kernel info and generate SIGINFO
777 if (CCEQ(cc
[VSTATUS
], c
) && ISSET(lflag
, IEXTEN
)) {
778 if (ISSET(lflag
, ISIG
)) {
779 /* SAFE: All callers drop the lock on return */
781 tty_pgsignal(tp
, SIGINFO
, 1);
784 if (!ISSET(lflag
, NOKERNINFO
))
790 * Check for input buffer overflow
792 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
>= MAX_INPUT
) {
794 if (ISSET(iflag
, IMAXBEL
)) {
795 if (tp
->t_outq
.c_cc
< tp
->t_hiwat
)
796 (void)ttyoutput(CTRL('g'), tp
);
801 if ( c
== 0377 && ISSET(iflag
, PARMRK
) && !ISSET(iflag
, ISTRIP
)
802 && ISSET(iflag
, IGNBRK
|IGNPAR
) != (IGNBRK
|IGNPAR
))
803 (void)putc(0377 | TTY_QUOTE
, &tp
->t_rawq
);
806 * Put data char in q for user and
807 * wakeup on seeing a line delimiter.
809 if (putc(c
, &tp
->t_rawq
) >= 0) {
810 if (!ISSET(lflag
, ICANON
)) {
815 if (TTBREAKC(c
, lflag
)) {
817 catq(&tp
->t_rawq
, &tp
->t_canq
);
819 } else if (tp
->t_rocount
++ == 0)
820 tp
->t_rocol
= tp
->t_column
;
821 if (ISSET(tp
->t_state
, TS_ERASE
)) {
823 * end of prterase \.../
825 CLR(tp
->t_state
, TS_ERASE
);
826 (void)ttyoutput('/', tp
);
830 if (CCEQ(cc
[VEOF
], c
) && ISSET(lflag
, ECHO
)) {
832 * Place the cursor over the '^' of the ^D.
834 i
= min(2, tp
->t_column
- i
);
836 (void)ttyoutput('\b', tp
);
844 * IXANY means allow any character to restart output.
846 if (ISSET(tp
->t_state
, TS_TTSTOP
) &&
847 !ISSET(iflag
, IXANY
) && cc
[VSTART
] != cc
[VSTOP
]) {
852 CLR(tp
->t_lflag
, FLUSHO
);
853 CLR(tp
->t_state
, TS_TTSTOP
);
856 /* Start the output */
857 retval
= ttstart(tp
);
867 * Output a single character on a tty, doing output processing
868 * as needed (expanding tabs, newline processing, etc.).
870 * Parameters: c The character to output
871 * tp The tty on which to output on the tty
873 * Returns: < 0 Success
874 * >= 0 Character to resend (failure)
876 * Locks: Assumes tp is locked on entry, remains locked on exit
878 * Notes: Must be recursive.
881 ttyoutput(int c
, struct tty
*tp
)
886 TTY_LOCK_OWNED(tp
); /* debug assert */
889 if (!ISSET(oflag
, OPOST
)) {
890 if (ISSET(tp
->t_lflag
, FLUSHO
))
892 if (putc(c
, &tp
->t_outq
))
899 * Do tab expansion if OXTABS is set. Special case if we external
900 * processing, we don't do the tab expansion because we'll probably
901 * get it wrong. If tab expansion needs to be done, let it happen
904 CLR(c
, ~TTY_CHARMASK
);
906 ISSET(oflag
, OXTABS
) && !ISSET(tp
->t_lflag
, EXTPROC
)) {
907 col
= c
= 8 - (tp
->t_column
& 7);
908 if (!ISSET(tp
->t_lflag
, FLUSHO
)) {
909 c
-= b_to_q((const u_char
*)" ", c
, &tp
->t_outq
);
914 return (c
== col
? -1 : '\t');
916 if (c
== CEOT
&& ISSET(oflag
, ONOEOT
))
920 * Newline translation: if ONLCR is set,
921 * translate newline into "\r\n".
923 if (c
== '\n' && ISSET(tp
->t_oflag
, ONLCR
)) {
926 if (putc('\r', &tp
->t_outq
))
929 /* If OCRNL is set, translate "\r" into "\n". */
930 else if (c
== '\r' && ISSET(tp
->t_oflag
, OCRNL
))
932 /* If ONOCR is set, don't transmit CRs when on column 0. */
933 else if (c
== '\r' && ISSET(tp
->t_oflag
, ONOCR
) && tp
->t_column
== 0)
937 if (!ISSET(tp
->t_lflag
, FLUSHO
) && putc(c
, &tp
->t_outq
))
956 col
= (col
+ 8) & ~7;
964 * Sets the tty state to not allow any more changes of foreground process
965 * group. This is required to be done so that a subsequent revoke on a vnode
966 * is able to always successfully complete.
968 * Locks : Assumes tty_lock held on entry
971 ttysetpgrphup(struct tty
*tp
)
973 TTY_LOCK_OWNED(tp
); /* debug assert */
974 SET(tp
->t_state
, TS_PGRPHUP
);
978 * Locks : Assumes tty lock held on entry
981 ttyclrpgrphup(struct tty
*tp
)
983 TTY_LOCK_OWNED(tp
); /* debug assert */
984 CLR(tp
->t_state
, TS_PGRPHUP
);
990 * Identical to ttioctl_locked, only the lock is not held
992 * Parameters: <See ttioctl_locked()>
994 * Returns: <See ttioctl_locked()>
996 * Locks: This function assumes the tty_lock() is not held on entry;
997 * it takes the lock, and releases it before returning.
999 * Notes: This is supported to ensure the line discipline interfaces
1000 * all have the same locking semantics.
1002 * This function is called from
1005 ttioctl(struct tty
*tp
, u_long cmd
, caddr_t data
, int flag
, proc_t p
)
1010 retval
= ttioctl_locked(tp
, cmd
, data
, flag
, p
);
1020 * Ioctls for all tty devices.
1022 * Parameters: tp Tty on which ioctl() is being called
1023 * cmd ioctl() command parameter
1024 * data ioctl() data argument (if any)
1025 * flag fileglob open modes from fcntl.h;
1026 * if called internally, this is usually
1027 * set to 0, rather than something useful
1028 * p Process context for the call; if the
1029 * call is proxied to a worker thread,
1030 * this will not be the current process!!!
1032 * Returns: 0 Success
1033 * EIO I/O error (no process group, job
1035 * EINTR Interrupted by signal
1036 * EBUSY Attempt to become the console while
1037 * the console is busy
1038 * ENOTTY TIOCGPGRP on a non-controlling tty
1039 * EINVAL Invalid baud rate
1040 * ENXIO TIOCSETD of invalid line discipline
1041 * EPERM TIOCSTI, not root, not open for read
1042 * EACCES TIOCSTI, not root, not your controlling
1044 * EPERM TIOCSCTTY failed
1045 * ENOTTY/EINVAL/EPERM TIOCSPGRP failed
1046 * EPERM TIOCSDRAINWAIT as non-root user
1047 * suser:EPERM Console control denied
1048 * ttywait:EIO t_timeout too small/expired
1049 * ttywait:ERESTART Upper layer must redrive the call;
1050 * this is usually done by the Libc
1051 * stub in user space
1052 * ttywait:EINTR Interrupted (usually a signal)
1056 * ttcompat:ENOTTY TIOCGSID, if no session or session
1058 * ttcompat:ENOTTY All unrecognized ioctls
1059 * *tp->t_param:? TIOCSETA* underlying function
1060 * *linesw[t].l_open:? TIOCSETD line discipline open failure
1063 * Locks: This function assumes that the tty_lock() is held for the
1064 * tp at the time of the call. The lock remains held on return.
1066 * Notes: This function is called after line-discipline specific ioctl
1067 * has been called to do discipline-specific functions and/or
1068 * reject any of these ioctl() commands.
1070 * This function calls ttcompat(), which can re-call ttioctl()
1071 * to a depth of one (FORTRAN style mutual recursion); at some
1072 * point, we should just in-line ttcompat() here.
1075 ttioctl_locked(struct tty
*tp
, u_long cmd
, caddr_t data
, int flag
, proc_t p
)
1079 struct pgrp
*pg
, *oldpg
;
1080 struct session
*sessp
, *oldsessp
;
1083 TTY_LOCK_OWNED(tp
); /* debug assert */
1085 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
1086 /* If the ioctl involves modification, signal if in the background. */
1113 while (isbackground(p
, tp
) &&
1114 (p
->p_lflag
& P_LPPWAIT
) == 0 &&
1115 (p
->p_sigignore
& sigmask(SIGTTOU
)) == 0 &&
1116 (ut
->uu_sigmask
& sigmask(SIGTTOU
)) == 0) {
1118 if (pg
== PGRP_NULL
) {
1122 /* SAFE: All callers drop the lock on return */
1124 if (pg
->pg_jobc
== 0) {
1130 pgsignal(pg
, SIGTTOU
, 1);
1136 * We signalled ourself, so we need to act as if we
1137 * have been "interrupted" from a "sleep" to act on
1138 * the signal. If it's a signal that stops the
1139 * process, that's handled in the signal sending code.
1147 switch (cmd
) { /* Process the ioctl. */
1148 case FIOASYNC
: /* set/clear async i/o */
1150 SET(tp
->t_state
, TS_ASYNC
);
1152 CLR(tp
->t_state
, TS_ASYNC
);
1154 case FIONBIO
: /* set/clear non-blocking i/o */
1155 break; /* XXX: delete. */
1156 case FIONREAD
: /* get # bytes to read */
1157 *(int *)data
= ttnread(tp
);
1159 case TIOCEXCL
: /* set exclusive use of tty */
1160 SET(tp
->t_state
, TS_XCLUDE
);
1162 case TIOCFLUSH
: { /* flush buffers */
1163 int flags
= *(int *)data
;
1166 flags
= FREAD
| FWRITE
;
1168 flags
&= FREAD
| FWRITE
;
1169 ttyflush(tp
, flags
);
1173 /* Set current console device to this line */
1175 data
= (caddr_t
) &bogusData
;
1177 /* No break - Fall through to BSD code */
1179 case TIOCCONS
: { /* become virtual console */
1181 if (constty
&& constty
!= tp
&&
1182 ISSET(constty
->t_state
, TS_CONNECTED
)) {
1186 if ( (error
= suser(kauth_cred_get(), &p
->p_acflag
)) )
1189 } else if (tp
== constty
) {
1193 (*cdevsw
[major(constty
->t_dev
)].d_ioctl
)
1194 (constty
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, p
);
1196 (*cdevsw
[major(tp
->t_dev
)].d_ioctl
)
1197 (tp
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, p
);
1201 case TIOCDRAIN
: /* wait till output drained */
1202 error
= ttywait(tp
);
1206 case TIOCGETA_32
: /* get termios struct */
1208 termios64to32((struct user_termios
*)&tp
->t_termios
, (struct termios32
*)data
);
1210 bcopy(&tp
->t_termios
, data
, sizeof(struct termios
));
1213 case TIOCGETA_64
: /* get termios struct */
1215 bcopy(&tp
->t_termios
, data
, sizeof(struct termios
));
1217 termios32to64((struct termios32
*)&tp
->t_termios
, (struct user_termios
*)data
);
1220 case TIOCGETD
: /* get line discipline */
1221 *(int *)data
= tp
->t_line
;
1223 case TIOCGWINSZ
: /* get window size */
1224 *(struct winsize
*)data
= tp
->t_winsize
;
1226 case TIOCGPGRP
: /* get pgrp of tty */
1227 if (!isctty(p
, tp
)) {
1231 *(int *)data
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
1234 case TIOCHPCL
: /* hang up on last close */
1235 SET(tp
->t_cflag
, HUPCL
);
1238 case TIOCNXCL
: /* reset exclusive use of tty */
1239 CLR(tp
->t_state
, TS_XCLUDE
);
1241 case TIOCOUTQ
: /* output queue size */
1242 *(int *)data
= tp
->t_outq
.c_cc
;
1244 case TIOCSETA_32
: /* set termios struct */
1246 case TIOCSETAW_32
: /* drain output, set */
1248 case TIOCSETAF_32
: /* drn out, fls in, set */
1250 { /* drn out, fls in, set */
1251 struct termios
*t
= (struct termios
*)data
;
1252 struct termios lcl_termios
;
1255 if (cmd
==TIOCSETA_32
|| cmd
==TIOCSETAW_32
|| cmd
==TIOCSETAF_32
) {
1256 termios32to64((struct termios32
*)data
, (struct user_termios
*)&lcl_termios
);
1260 if (cmd
==TIOCSETA_64
|| cmd
==TIOCSETAW_64
|| cmd
==TIOCSETAF_64
) {
1261 termios64to32((struct user_termios
*)data
, (struct termios32
*)&lcl_termios
);
1266 /* XXX bogus test; always false */
1267 if (t
->c_ispeed
< 0 || t
->c_ospeed
< 0) {
1271 #endif /* 0 - leave in; may end up being a conformance issue */
1272 if (t
->c_ispeed
== 0)
1273 t
->c_ispeed
= t
->c_ospeed
;
1274 if (cmd
== TIOCSETAW_32
|| cmd
== TIOCSETAF_32
||
1275 cmd
== TIOCSETAW_64
|| cmd
== TIOCSETAF_64
) {
1276 error
= ttywait(tp
);
1280 if (cmd
== TIOCSETAF_32
|| cmd
== TIOCSETAF_64
)
1281 ttyflush(tp
, FREAD
);
1283 if (!ISSET(t
->c_cflag
, CIGNORE
)) {
1285 * Set device hardware.
1287 if (tp
->t_param
&& (error
= (*tp
->t_param
)(tp
, t
))) {
1290 if (ISSET(t
->c_cflag
, CLOCAL
) &&
1291 !ISSET(tp
->t_cflag
, CLOCAL
)) {
1293 * XXX disconnections would be too hard to
1294 * get rid of without this kludge. The only
1295 * way to get rid of controlling terminals
1296 * is to exit from the session leader.
1298 CLR(tp
->t_state
, TS_ZOMBIE
);
1300 wakeup(TSA_CARR_ON(tp
));
1304 if ((ISSET(tp
->t_state
, TS_CARR_ON
) ||
1305 ISSET(t
->c_cflag
, CLOCAL
)) &&
1306 !ISSET(tp
->t_state
, TS_ZOMBIE
))
1307 SET(tp
->t_state
, TS_CONNECTED
);
1309 CLR(tp
->t_state
, TS_CONNECTED
);
1310 tp
->t_cflag
= t
->c_cflag
;
1311 tp
->t_ispeed
= t
->c_ispeed
;
1312 tp
->t_ospeed
= t
->c_ospeed
;
1315 if (ISSET(t
->c_lflag
, ICANON
) != ISSET(tp
->t_lflag
, ICANON
) &&
1316 cmd
!= TIOCSETAF_32
&& cmd
!= TIOCSETAF_64
) {
1317 if (ISSET(t
->c_lflag
, ICANON
))
1318 SET(tp
->t_lflag
, PENDIN
);
1321 * XXX we really shouldn't allow toggling
1322 * ICANON while we're in a non-termios line
1323 * discipline. Now we have to worry about
1324 * panicing for a null queue.
1326 if (tp
->t_rawq
.c_cs
&& tp
->t_canq
.c_cs
) {
1329 catq(&tp
->t_rawq
, &tp
->t_canq
);
1331 tp
->t_rawq
= tp
->t_canq
;
1334 CLR(tp
->t_lflag
, PENDIN
);
1338 tp
->t_iflag
= t
->c_iflag
;
1339 tp
->t_oflag
= t
->c_oflag
;
1341 * Make the EXTPROC bit read only.
1343 if (ISSET(tp
->t_lflag
, EXTPROC
))
1344 SET(t
->c_lflag
, EXTPROC
);
1346 CLR(t
->c_lflag
, EXTPROC
);
1347 tp
->t_lflag
= t
->c_lflag
| ISSET(tp
->t_lflag
, PENDIN
);
1348 if (t
->c_cc
[VMIN
] != tp
->t_cc
[VMIN
] ||
1349 t
->c_cc
[VTIME
] != tp
->t_cc
[VTIME
])
1351 bcopy(t
->c_cc
, tp
->t_cc
, sizeof(t
->c_cc
));
1354 case TIOCSETD
: { /* set line discipline */
1355 int t
= *(int *)data
;
1356 dev_t device
= tp
->t_dev
;
1358 if (t
>= nlinesw
|| t
< 0) {
1363 * If the new line discipline is not equal to the old one,
1364 * close the old one and open the new one.
1366 if (t
!= tp
->t_line
) {
1367 (*linesw
[tp
->t_line
].l_close
)(tp
, flag
);
1368 error
= (*linesw
[t
].l_open
)(device
, tp
);
1370 /* This is racy; it's possible to lose both */
1371 (void)(*linesw
[tp
->t_line
].l_open
)(device
, tp
);
1378 case TIOCSTART
: /* start output, like ^Q */
1379 if (ISSET(tp
->t_state
, TS_TTSTOP
) ||
1380 ISSET(tp
->t_lflag
, FLUSHO
)) {
1381 CLR(tp
->t_lflag
, FLUSHO
);
1382 CLR(tp
->t_state
, TS_TTSTOP
);
1386 case TIOCSTI
: /* simulate terminal input */
1387 if (suser(kauth_cred_get(), NULL
) && (flag
& FREAD
) == 0) {
1391 if (suser(kauth_cred_get(), NULL
) && !isctty(p
, tp
)) {
1395 (*linesw
[tp
->t_line
].l_rint
)(*(u_char
*)data
, tp
);
1397 case TIOCSTOP
: /* stop output, like ^S */
1398 if (!ISSET(tp
->t_state
, TS_TTSTOP
)) {
1399 SET(tp
->t_state
, TS_TTSTOP
);
1409 case TIOCSCTTY
: /* become controlling tty */
1410 /* Session ctty vnode pointer set in vnode layer. */
1412 sessp
= proc_session(p
);
1413 if (!SESS_LEADER(p
, sessp
) ||
1414 ((sessp
->s_ttyvp
|| tp
->t_session
) &&
1415 (tp
->t_session
!= sessp
))) {
1416 /* SAFE: All callers drop the lock on return */
1418 if (sessp
!= SESSION_NULL
)
1419 session_rele(sessp
);
1420 if (pg
!= PGRP_NULL
)
1427 oldsessp
= tp
->t_session
;
1429 if (oldsessp
!= SESSION_NULL
)
1430 oldsessp
->s_ttypgrpid
= NO_PID
;
1431 /* do not drop refs on sessp and pg as tp holds them */
1432 tp
->t_session
= sessp
;
1433 sessp
->s_ttypgrpid
= pg
->pg_id
;
1436 session_lock(sessp
);
1437 oldtp
= sessp
->s_ttyp
;
1440 session_unlock(sessp
);
1441 OSBitOrAtomic(P_CONTROLT
, &p
->p_flag
);
1442 /* SAFE: All callers drop the lock on return */
1444 /* drop the reference on prev session and pgrp */
1445 if (oldsessp
!= SESSION_NULL
)
1446 session_rele(oldsessp
);
1447 if (oldpg
!= PGRP_NULL
)
1454 case TIOCSPGRP
: { /* set pgrp of tty */
1455 struct pgrp
*pgrp
= PGRP_NULL
;
1457 sessp
= proc_session(p
);
1458 if (!isctty_sp(p
, tp
, sessp
)) {
1459 if (sessp
!= SESSION_NULL
)
1460 session_rele(sessp
);
1464 else if ((pgrp
= pgfind(*(int *)data
)) == PGRP_NULL
) {
1465 if (sessp
!= SESSION_NULL
)
1466 session_rele(sessp
);
1469 } else if (pgrp
->pg_session
!= sessp
) {
1470 /* SAFE: All callers drop the lock on return */
1472 if (sessp
!= SESSION_NULL
)
1473 session_rele(sessp
);
1480 * The session leader is going away and is possibly going to revoke
1481 * the terminal, we can't change the process group when that is the
1484 if (ISSET(tp
->t_state
, TS_PGRPHUP
)) {
1491 sessp
->s_ttypgrpid
= pgrp
->pg_id
;
1493 /* SAFE: All callers drop the lock on return */
1495 if (oldpg
!= PGRP_NULL
)
1497 if (sessp
!= SESSION_NULL
)
1498 session_rele(sessp
);
1502 case TIOCSTAT
: /* simulate control-T */
1505 case TIOCSWINSZ
: /* set window size */
1506 if (bcmp((caddr_t
)&tp
->t_winsize
, data
,
1507 sizeof (struct winsize
))) {
1508 tp
->t_winsize
= *(struct winsize
*)data
;
1509 /* SAFE: All callers drop the lock on return */
1511 tty_pgsignal(tp
, SIGWINCH
, 1);
1515 case TIOCSDRAINWAIT
:
1516 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1520 tp
->t_timeout
= *(int *)data
* hz
;
1521 wakeup(TSA_OCOMPLETE(tp
));
1522 wakeup(TSA_OLOWAT(tp
));
1524 case TIOCGDRAINWAIT
:
1525 *(int *)data
= tp
->t_timeout
/ hz
;
1528 error
= ttcompat(tp
, cmd
, data
, flag
, p
);
1539 * Locks: Assumes tp is locked on entry, remains locked on exit
1542 ttyselect(struct tty
*tp
, int rw
, void *wql
, proc_t p
)
1549 TTY_LOCK_OWNED(tp
); /* debug assert */
1553 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
1557 retval
= ttnread(tp
);
1562 selrecord(p
, &tp
->t_rsel
, wql
);
1565 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
1569 if ((tp
->t_outq
.c_cc
<= tp
->t_lowat
) &&
1570 ISSET(tp
->t_state
, TS_CONNECTED
)) {
1571 retval
= tp
->t_hiwat
- tp
->t_outq
.c_cc
;
1575 selrecord(p
, &tp
->t_wsel
, wql
);
1583 * This is a wrapper for compatibility with the select vector used by
1584 * cdevsw. It relies on a proper xxxdevtotty routine.
1586 * Locks: Assumes tty_lock() is not held prior to calling.
1589 ttselect(dev_t dev
, int rw
, void *wql
, proc_t p
)
1592 struct tty
*tp
= cdevsw
[major(dev
)].d_ttys
[minor(dev
)];
1595 rv
= ttyselect(tp
, rw
, wql
, p
);
1603 * Locks: Assumes tp is locked on entry, remains locked on exit
1605 __private_extern__
int
1606 ttnread(struct tty
*tp
)
1610 TTY_LOCK_OWNED(tp
); /* debug assert */
1612 if (ISSET(tp
->t_lflag
, PENDIN
))
1614 nread
= tp
->t_canq
.c_cc
;
1615 if (!ISSET(tp
->t_lflag
, ICANON
)) {
1616 nread
+= tp
->t_rawq
.c_cc
;
1617 if (nread
< tp
->t_cc
[VMIN
] && tp
->t_cc
[VTIME
] == 0)
1627 * Wait for output to drain.
1629 * Parameters: tp Tty on which to wait for output to drain
1631 * Returns: 0 Success
1632 * EIO t_timeout too small/expired
1633 * ttysleep:ERESTART Upper layer must redrive the call;
1634 * this is usually done by the Libc
1635 * stub in user space
1636 * ttysleep:EINTR Interrupted (usually a signal)
1638 * Notes: Called from proc_exit() and vproc_exit().
1640 * Locks: Assumes tp is locked on entry, remains locked on exit
1643 ttywait(struct tty
*tp
)
1647 TTY_LOCK_OWNED(tp
); /* debug assert */
1650 while ((tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)) &&
1651 ISSET(tp
->t_state
, TS_CONNECTED
) && tp
->t_oproc
) {
1653 if ((tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)) &&
1654 ISSET(tp
->t_state
, TS_CONNECTED
)) {
1655 SET(tp
->t_state
, TS_SO_OCOMPLETE
);
1656 error
= ttysleep(tp
, TSA_OCOMPLETE(tp
),
1657 TTOPRI
| PCATCH
, "ttywai",
1660 if (error
== EWOULDBLOCK
)
1667 if (!error
&& (tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)))
1673 * Stop the underlying device driver.
1675 * Locks: Assumes tty_lock() is held prior to calling.
1678 ttystop(struct tty
*tp
, int rw
)
1680 TTY_LOCK_OWNED(tp
); /* debug assert */
1682 (*cdevsw
[major(tp
->t_dev
)].d_stop
)(tp
, rw
);
1686 * Flush if successfully wait.
1688 * Locks: Assumes tty_lock() is held prior to calling.
1691 ttywflush(struct tty
*tp
)
1695 TTY_LOCK_OWNED(tp
); /* debug assert */
1697 if ((error
= ttywait(tp
)) == 0)
1698 ttyflush(tp
, FREAD
);
1703 * Flush tty read and/or write queues, notifying anyone waiting.
1705 * Locks: Assumes tty_lock() is held prior to calling.
1708 ttyflush(struct tty
*tp
, int rw
)
1710 TTY_LOCK_OWNED(tp
); /* debug assert */
1716 FLUSHQ(&tp
->t_outq
);
1717 CLR(tp
->t_state
, TS_TTSTOP
);
1721 FLUSHQ(&tp
->t_canq
);
1722 FLUSHQ(&tp
->t_rawq
);
1723 CLR(tp
->t_lflag
, PENDIN
);
1726 CLR(tp
->t_state
, TS_LOCAL
);
1728 if (ISSET(tp
->t_state
, TS_TBLOCK
)) {
1730 FLUSHQ(&tp
->t_outq
);
1734 * Don't let leave any state that might clobber the
1735 * next line discipline (although we should do more
1736 * to send the START char). Not clearing the state
1737 * may have caused the "putc to a clist with no
1738 * reserved cblocks" panic/printf.
1740 CLR(tp
->t_state
, TS_TBLOCK
);
1742 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1743 if (ISSET(tp
->t_iflag
, IXOFF
)) {
1745 * XXX wait a bit in the hope that the stop
1746 * character (if any) will go out. Waiting
1747 * isn't good since it allows races. This
1748 * will be fixed when the stop character is
1749 * put in a special queue. Don't bother with
1750 * the checks in ttywait() since the timeout
1753 SET(tp
->t_state
, TS_SO_OCOMPLETE
);
1754 ttysleep(tp
, TSA_OCOMPLETE(tp
), TTOPRI
,
1757 * Don't try sending the stop character again.
1759 CLR(tp
->t_state
, TS_TBLOCK
);
1766 FLUSHQ(&tp
->t_outq
);
1772 * Copy in the default termios characters.
1774 * Locks: Assumes tty_lock() is held prior to calling.
1776 * Notes: No assertion; tp is not in scope.
1779 termioschars(struct termios
*t
)
1781 bcopy(ttydefchars
, t
->c_cc
, sizeof t
->c_cc
);
1786 * Handle input high water. Send stop character for the IXOFF case. Turn
1787 * on our input flow control bit and propagate the changes to the driver.
1788 * XXX the stop character should be put in a special high priority queue.
1790 * Locks: Assumes tty_lock() is held for the call.
1793 ttyblock(struct tty
*tp
)
1795 TTY_LOCK_OWNED(tp
); /* debug assert */
1797 SET(tp
->t_state
, TS_TBLOCK
);
1798 if (ISSET(tp
->t_iflag
, IXOFF
) && tp
->t_cc
[VSTOP
] != _POSIX_VDISABLE
&&
1799 putc(tp
->t_cc
[VSTOP
], &tp
->t_outq
) != 0)
1800 CLR(tp
->t_state
, TS_TBLOCK
); /* try again later */
1806 * Handle input low water. Send start character for the IXOFF case. Turn
1807 * off our input flow control bit and propagate the changes to the driver.
1808 * XXX the start character should be put in a special high priority queue.
1810 * Locks: Assumes tty_lock() is held for the call.
1813 ttyunblock(struct tty
*tp
)
1815 TTY_LOCK_OWNED(tp
); /* debug assert */
1817 CLR(tp
->t_state
, TS_TBLOCK
);
1818 if (ISSET(tp
->t_iflag
, IXOFF
) && tp
->t_cc
[VSTART
] != _POSIX_VDISABLE
&&
1819 putc(tp
->t_cc
[VSTART
], &tp
->t_outq
) != 0)
1820 SET(tp
->t_state
, TS_TBLOCK
); /* try again later */
1830 * Parameters: tp tty on which to start output
1832 * Returns: 0 Success
1834 * Locks: Assumes tty_lock() is held for the call.
1836 * Notes: This function might as well be void; it always returns success
1838 * Called from ttioctl_locked(), LDISC routines, and
1839 * ttycheckoutq(), ttyblock(), ttyunblock(), and tputchar()
1842 ttstart(struct tty
*tp
)
1844 TTY_LOCK_OWNED(tp
); /* debug assert */
1846 if (tp
->t_oproc
!= NULL
) /* XXX: Kludge for pty. */
1856 * "close" a line discipline
1858 * Locks: Assumes tty_lock() is held prior to calling.
1861 ttylclose(struct tty
*tp
, int flag
)
1863 TTY_LOCK_OWNED(tp
); /* debug assert */
1865 if ( (flag
& FNONBLOCK
) || ttywflush(tp
))
1866 ttyflush(tp
, FREAD
| FWRITE
);
1875 * Handle modem control transition on a tty.
1876 * Flag indicates new state of carrier.
1877 * Returns 0 if the line should be turned off, otherwise 1.
1879 * Locks: Assumes tty_lock() is held prior to calling.
1882 ttymodem(struct tty
*tp
, int flag
)
1884 int rval
= 1; /* default return value */
1886 TTY_LOCK_OWNED(tp
); /* debug assert */
1888 if (ISSET(tp
->t_state
, TS_CARR_ON
) && ISSET(tp
->t_cflag
, MDMBUF
)) {
1890 * MDMBUF: do flow control according to carrier flag
1891 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP
1892 * works if IXON and IXANY are clear.
1895 CLR(tp
->t_state
, TS_CAR_OFLOW
);
1896 CLR(tp
->t_state
, TS_TTSTOP
);
1898 } else if (!ISSET(tp
->t_state
, TS_CAR_OFLOW
)) {
1899 SET(tp
->t_state
, TS_CAR_OFLOW
);
1900 SET(tp
->t_state
, TS_TTSTOP
);
1903 } else if (flag
== 0) {
1907 CLR(tp
->t_state
, TS_CARR_ON
);
1908 if (ISSET(tp
->t_state
, TS_ISOPEN
) &&
1909 !ISSET(tp
->t_cflag
, CLOCAL
)) {
1910 SET(tp
->t_state
, TS_ZOMBIE
);
1911 CLR(tp
->t_state
, TS_CONNECTED
);
1912 if (tp
->t_session
&& tp
->t_session
->s_leader
)
1913 psignal(tp
->t_session
->s_leader
, SIGHUP
);
1914 ttyflush(tp
, FREAD
| FWRITE
);
1922 SET(tp
->t_state
, TS_CARR_ON
);
1923 if (!ISSET(tp
->t_state
, TS_ZOMBIE
))
1924 SET(tp
->t_state
, TS_CONNECTED
);
1925 wakeup(TSA_CARR_ON(tp
));
1936 * Reinput pending characters after state switch
1939 * Locks: Assumes tty_lock() is held for the call.
1942 ttypend(struct tty
*tp
)
1947 TTY_LOCK_OWNED(tp
); /* debug assert */
1949 CLR(tp
->t_lflag
, PENDIN
);
1950 SET(tp
->t_state
, TS_TYPEN
);
1952 tp
->t_rawq
.c_cc
= 0;
1953 tp
->t_rawq
.c_cf
= tp
->t_rawq
.c_cl
= NULL
;
1954 while ((c
= getc(&tq
)) >= 0)
1956 CLR(tp
->t_state
, TS_TYPEN
);
1963 * Process a read call on a tty device.
1965 * Locks: Assumes tty_lock() is held prior to calling.
1968 ttread(struct tty
*tp
, struct uio
*uio
, int flag
)
1973 cc_t
*cc
= tp
->t_cc
;
1974 proc_t p
= current_proc();
1975 int first
, error
= 0;
1976 int has_etime
= 0, last_cc
= 0;
1977 long slp
= 0; /* XXX this should be renamed `timo'. */
1981 TTY_LOCK_OWNED(tp
); /* debug assert */
1983 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
1986 lflag
= tp
->t_lflag
;
1988 * take pending input first
1990 if (ISSET(lflag
, PENDIN
)) {
1992 lflag
= tp
->t_lflag
; /* XXX ttypend() clobbers it */
1996 * Signal the process if it's in the background.
1998 if (isbackground(p
, tp
)) {
1999 if ((p
->p_sigignore
& sigmask(SIGTTIN
)) ||
2000 (ut
->uu_sigmask
& sigmask(SIGTTIN
)) ||
2001 p
->p_lflag
& P_LPPWAIT
) {
2006 if (pg
== PGRP_NULL
) {
2010 if (pg
->pg_jobc
== 0) {
2011 /* SAFE: All callers drop the lock on return */
2018 /* SAFE: All callers drop the lock on return */
2020 pgsignal(pg
, SIGTTIN
, 1);
2025 * We signalled ourself, so we need to act as if we
2026 * have been "interrupted" from a "sleep" to act on
2027 * the signal. If it's a signal that stops the
2028 * process, that's handled in the signal sending code.
2034 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
2035 /* EOF - returning 0 */
2040 * If canonical, use the canonical queue,
2041 * else use the raw queue.
2043 * (should get rid of clists...)
2045 qp
= ISSET(lflag
, ICANON
) ? &tp
->t_canq
: &tp
->t_rawq
;
2047 if (flag
& IO_NDELAY
) {
2050 if (ISSET(lflag
, ICANON
) || cc
[VMIN
] != 0) {
2051 error
= EWOULDBLOCK
;
2053 /* else polling - returning 0 */
2056 if (!ISSET(lflag
, ICANON
)) {
2059 struct timeval timecopy
;
2060 struct timeval etime
= {0, 0}; /* protected by !has_etime */
2063 * Check each of the four combinations.
2064 * (m > 0 && t == 0) is the normal read case.
2065 * It should be fairly efficient, so we check that and its
2066 * companion case (m == 0 && t == 0) first.
2067 * For the other two cases, we compute the target sleep time
2076 /* m, t and qp->c_cc are all 0. 0 is enough input. */
2079 t
*= 100000; /* time in us */
2080 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
2081 ((t1).tv_usec - (t2).tv_usec))
2087 microuptime(&timecopy
);
2089 /* first character, start timer */
2092 etime
.tv_sec
= t
/ 1000000;
2093 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
2094 timeradd(&etime
, &timecopy
, &etime
);
2097 } else if (qp
->c_cc
> last_cc
) {
2098 /* got a character, restart timer */
2100 etime
.tv_sec
= t
/ 1000000;
2101 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
2102 timeradd(&etime
, &timecopy
, &etime
);
2106 /* nothing, check expiration */
2107 if (timercmp(&etime
, &timecopy
, <=))
2110 slp
= diff(etime
, timecopy
);
2113 } else { /* m == 0 */
2116 microuptime(&timecopy
);
2120 etime
.tv_sec
= t
/ 1000000;
2121 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
2122 timeradd(&etime
, &timecopy
, &etime
);
2126 if (timercmp(&etime
, &timecopy
, <=)) {
2127 /* Timed out, but 0 is enough input. */
2130 slp
= diff(etime
, timecopy
);
2135 * Rounding down may make us wake up just short
2136 * of the target, so we round up.
2137 * The formula is ceiling(slp * hz/1000000).
2138 * 32-bit arithmetic is enough for hz < 169.
2139 * XXX see hzto() for how to avoid overflow if hz
2140 * is large (divide by `tick' and/or arrange to
2141 * use hzto() if hz is large).
2143 slp
= (long) (((u_int32_t
)slp
* hz
) + 999999) / 1000000;
2146 if (qp
->c_cc
<= 0) {
2149 * There is no input, or not enough input and we can block.
2151 error
= ttysleep(tp
, TSA_HUP_OR_INPUT(tp
), TTIPRI
| PCATCH
,
2152 ISSET(tp
->t_state
, TS_CONNECTED
) ?
2153 "ttyin" : "ttyhup", (int)slp
);
2154 if (error
== EWOULDBLOCK
)
2160 * XXX what happens if another process eats some input
2161 * while we are asleep (not just here)? It would be
2162 * safest to detect changes and reset our state variables
2163 * (has_stime and last_cc).
2170 * Input present, check for input mapping and processing.
2173 if (ISSET(lflag
, ICANON
)
2174 || (ISSET(lflag
, IEXTEN
| ISIG
) == (IEXTEN
| ISIG
)) )
2180 icc
= MIN(uio_resid(uio
), IBUFSIZ
);
2181 icc
= q_to_b(qp
, (u_char
*)ibuf
, icc
);
2187 error
= uiomove(ibuf
, icc
, uio
);
2189 * XXX if there was an error then we should ungetc() the
2190 * unmoved chars and reduce icc here.
2194 if (uio_resid(uio
) == 0)
2208 * delayed suspend (^Y)
2210 if (CCEQ(cc
[VDSUSP
], c
) &&
2211 ISSET(lflag
, IEXTEN
| ISIG
) == (IEXTEN
| ISIG
)) {
2213 * SAFE: All callers drop the lock on return and
2214 * SAFE: current thread will not change out from
2215 * SAFE: under us in the "goto loop" case.
2218 tty_pgsignal(tp
, SIGTSTP
, 1);
2221 error
= ttysleep(tp
, &ttread
, TTIPRI
| PCATCH
,
2230 * Interpret EOF only in canonical mode.
2232 if (CCEQ(cc
[VEOF
], c
) && ISSET(lflag
, ICANON
))
2235 * Give user character.
2237 error
= ureadc(c
, uio
);
2239 /* XXX should ungetc(c, qp). */
2241 if (uio_resid(uio
) == 0)
2244 * In canonical mode check for a "break character"
2245 * marking the end of a "line of input".
2247 if (ISSET(lflag
, ICANON
) && TTBREAKC(c
, lflag
))
2254 * Look to unblock input now that (presumably)
2255 * the input queue has gone down.
2257 if (ISSET(tp
->t_state
, TS_TBLOCK
) &&
2258 tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
<= I_LOW_WATER
)
2267 * Check the output queue on tp for space for a kernel message (from uprintf
2268 * or tprintf). Allow some space over the normal hiwater mark so we don't
2269 * lose messages due to normal flow control, but don't let the tty run amok.
2270 * Sleeps here are not interruptible, but we return prematurely if new signals
2273 * Locks: Assumes tty_lock() is held before calling
2275 * Notes: This function is called from tprintf() in subr_prf.c
2278 ttycheckoutq(struct tty
*tp
, int wait
)
2284 TTY_LOCK_OWNED(tp
); /* debug assert */
2286 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
2288 hiwat
= tp
->t_hiwat
;
2289 oldsig
= wait
? ut
->uu_siglist
: 0;
2290 if (tp
->t_outq
.c_cc
> hiwat
+ OBUFSIZ
+ 100)
2291 while (tp
->t_outq
.c_cc
> hiwat
) {
2293 if (tp
->t_outq
.c_cc
<= hiwat
)
2295 if (wait
== 0 || ut
->uu_siglist
!= oldsig
) {
2298 SET(tp
->t_state
, TS_SO_OLOWAT
);
2299 ttysleep(tp
, TSA_OLOWAT(tp
), PZERO
- 1, "ttoutq", hz
);
2308 * Process a write call on a tty device.
2310 * Locks: Assumes tty_lock() is held prior to calling.
2313 ttwrite(struct tty
*tp
, struct uio
*uio
, int flag
)
2318 int i
, hiwat
, error
;
2324 TTY_LOCK_OWNED(tp
); /* debug assert */
2326 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
2327 hiwat
= tp
->t_hiwat
;
2328 count
= uio_resid(uio
);
2332 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
2333 if (uio_resid(uio
) == count
)
2337 if (!ISSET(tp
->t_state
, TS_CONNECTED
)) {
2338 if (flag
& IO_NDELAY
) {
2339 error
= EWOULDBLOCK
;
2342 error
= ttysleep(tp
, TSA_CARR_ON(tp
), TTIPRI
| PCATCH
,
2349 * Signal the process if it's in the background.
2352 if (isbackground(p
, tp
) &&
2353 ISSET(tp
->t_lflag
, TOSTOP
) && (p
->p_lflag
& P_LPPWAIT
) == 0 &&
2354 (p
->p_sigignore
& sigmask(SIGTTOU
)) == 0 &&
2355 (ut
->uu_sigmask
& sigmask(SIGTTOU
)) == 0) {
2358 if (pg
== PGRP_NULL
) {
2362 if (pg
->pg_jobc
== 0) {
2363 /* SAFE: All callers drop the lock on return */
2370 /* SAFE: All callers drop the lock on return */
2372 pgsignal(pg
, SIGTTOU
, 1);
2376 * We signalled ourself, so we need to act as if we
2377 * have been "interrupted" from a "sleep" to act on
2378 * the signal. If it's a signal that stops the
2379 * process, that's handled in the signal sending code.
2385 * Process the user's data in at most OBUFSIZ chunks. Perform any
2386 * output translation. Keep track of high water mark, sleep on
2387 * overflow awaiting device aid in acquiring new space.
2389 while (uio_resid(uio
) > 0 || cc
> 0) {
2390 if (ISSET(tp
->t_lflag
, FLUSHO
)) {
2391 uio_setresid(uio
, 0);
2394 if (tp
->t_outq
.c_cc
> hiwat
)
2397 * Grab a hunk of data from the user, unless we have some
2398 * leftover from last time.
2401 cc
= MIN(uio_resid(uio
), OBUFSIZ
);
2403 error
= uiomove(cp
, cc
, uio
);
2410 * If nothing fancy need be done, grab those characters we
2411 * can handle without any of ttyoutput's processing and
2412 * just transfer them to the output q. For those chars
2413 * which require special processing (as indicated by the
2414 * bits in char_type), call ttyoutput. After processing
2415 * a hunk of data, look for FLUSHO so ^O's will take effect
2419 if (!ISSET(tp
->t_oflag
, OPOST
))
2422 ce
= cc
- scanc((u_int
)cc
, (u_char
*)cp
,
2423 char_type
, CCLASSMASK
);
2425 * If ce is zero, then we're processing
2426 * a special character through ttyoutput.
2430 if (ttyoutput(*cp
, tp
) >= 0) {
2436 if (ISSET(tp
->t_lflag
, FLUSHO
) ||
2437 tp
->t_outq
.c_cc
> hiwat
)
2443 * A bunch of normal characters have been found.
2444 * Transfer them en masse to the output queue and
2445 * continue processing at the top of the loop.
2446 * If there are any further characters in this
2447 * <= OBUFSIZ chunk, the first should be a character
2448 * requiring special handling by ttyoutput.
2451 i
= b_to_q((u_char
*)cp
, ce
, &tp
->t_outq
);
2454 cp
+= ce
, cc
-= ce
, tk_nout
+= ce
;
2460 if (ISSET(tp
->t_lflag
, FLUSHO
) ||
2461 tp
->t_outq
.c_cc
> hiwat
)
2468 * If cc is nonzero, we leave the uio structure inconsistent, as the
2469 * offset and iov pointers have moved forward, but it doesn't matter
2470 * (the call will either return short or restart with a new uio).
2472 uio_setresid(uio
, (uio_resid(uio
) + cc
));
2478 * Since we are using ring buffers, if we can't insert any more into
2479 * the output queue, we can assume the ring is full and that someone
2480 * forgot to set the high water mark correctly. We set it and then
2481 * proceed as normal.
2483 hiwat
= tp
->t_outq
.c_cc
- 1;
2488 * This can only occur if FLUSHO is set in t_lflag,
2489 * or if ttstart/oproc is synchronous (or very fast).
2491 if (tp
->t_outq
.c_cc
<= hiwat
) {
2494 if (flag
& IO_NDELAY
) {
2495 uio_setresid(uio
, (uio_resid(uio
) + cc
));
2496 return (uio_resid(uio
) == count
? EWOULDBLOCK
: 0);
2498 SET(tp
->t_state
, TS_SO_OLOWAT
);
2499 error
= ttysleep(tp
, TSA_OLOWAT(tp
), TTOPRI
| PCATCH
, "ttywri",
2501 if (error
== EWOULDBLOCK
)
2510 * Rubout one character from the rawq of tp
2511 * as cleanly as possible.
2513 * Locks: Assumes tty_lock() is held prior to calling.
2516 ttyrub(int c
, struct tty
*tp
)
2522 TTY_LOCK_OWNED(tp
); /* debug assert */
2524 if (!ISSET(tp
->t_lflag
, ECHO
) || ISSET(tp
->t_lflag
, EXTPROC
))
2526 CLR(tp
->t_lflag
, FLUSHO
);
2527 if (ISSET(tp
->t_lflag
, ECHOE
)) {
2528 if (tp
->t_rocount
== 0) {
2530 * Messed up by ttwrite; retype
2535 if (c
== ('\t' | TTY_QUOTE
) || c
== ('\n' | TTY_QUOTE
))
2538 CLR(c
, ~TTY_CHARMASK
);
2539 switch (CCLASS(c
)) {
2541 if(!(ISSET(tp
->t_iflag
, IUTF8
) && CCONT(c
))) {
2550 if (ISSET(tp
->t_lflag
, ECHOCTL
))
2554 if (tp
->t_rocount
< tp
->t_rawq
.c_cc
) {
2558 savecol
= tp
->t_column
;
2559 SET(tp
->t_state
, TS_CNTTB
);
2560 SET(tp
->t_lflag
, FLUSHO
);
2561 tp
->t_column
= tp
->t_rocol
;
2562 for (cp
= firstc(&tp
->t_rawq
, &tabc
); cp
;
2563 cp
= nextc(&tp
->t_rawq
, cp
, &tabc
))
2565 CLR(tp
->t_lflag
, FLUSHO
);
2566 CLR(tp
->t_state
, TS_CNTTB
);
2568 /* savecol will now be length of the tab. */
2569 savecol
-= tp
->t_column
;
2570 tp
->t_column
+= savecol
;
2572 savecol
= 8; /* overflow fixup */
2573 while (--savecol
>= 0)
2574 (void)ttyoutput('\b', tp
);
2577 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
2578 printf(PANICSTR
, c
, CCLASS(c
));
2580 panic(PANICSTR
, c
, CCLASS(c
));
2584 } else if (ISSET(tp
->t_lflag
, ECHOPRT
)) {
2585 if (!ISSET(tp
->t_state
, TS_ERASE
)) {
2586 SET(tp
->t_state
, TS_ERASE
);
2587 (void)ttyoutput('\\', tp
);
2591 ttyecho(tp
->t_cc
[VERASE
], tp
);
2597 * Back over count characters, erasing them.
2599 * Locks: Assumes tty_lock() is held prior to calling.
2602 ttyrubo(struct tty
*tp
, int count
)
2604 TTY_LOCK_OWNED(tp
); /* debug assert */
2606 while (count
-- > 0) {
2607 (void)ttyoutput('\b', tp
);
2608 (void)ttyoutput(' ', tp
);
2609 (void)ttyoutput('\b', tp
);
2616 * Reprint the rawq line. Note, it is assumed that c_cc has already
2619 * Locks: Assumes tty_lock() is held prior to calling.
2622 ttyretype(struct tty
*tp
)
2627 TTY_LOCK_OWNED(tp
); /* debug assert */
2629 /* Echo the reprint character. */
2630 if (tp
->t_cc
[VREPRINT
] != _POSIX_VDISABLE
)
2631 ttyecho(tp
->t_cc
[VREPRINT
], tp
);
2633 (void)ttyoutput('\n', tp
);
2637 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2638 * BIT OF FIRST CHAR.
2640 for (cp
= firstc(&tp
->t_canq
, &c
); cp
; cp
= nextc(&tp
->t_canq
, cp
, &c
))
2642 for (cp
= firstc(&tp
->t_rawq
, &c
); cp
; cp
= nextc(&tp
->t_rawq
, cp
, &c
))
2644 CLR(tp
->t_state
, TS_ERASE
);
2646 tp
->t_rocount
= tp
->t_rawq
.c_cc
;
2652 * Echo a typed character to the terminal.
2654 * Locks: Assumes tty_lock() is held prior to calling.
2657 ttyecho(int c
, struct tty
*tp
)
2659 TTY_LOCK_OWNED(tp
); /* debug assert */
2661 if (!ISSET(tp
->t_state
, TS_CNTTB
))
2662 CLR(tp
->t_lflag
, FLUSHO
);
2663 if ((!ISSET(tp
->t_lflag
, ECHO
) &&
2664 (c
!= '\n' || !ISSET(tp
->t_lflag
, ECHONL
))) ||
2665 ISSET(tp
->t_lflag
, EXTPROC
))
2667 if (ISSET(tp
->t_lflag
, ECHOCTL
) &&
2668 ((ISSET(c
, TTY_CHARMASK
) <= 037 && c
!= '\t' && c
!= '\n') ||
2669 ISSET(c
, TTY_CHARMASK
) == 0177)) {
2670 (void)ttyoutput('^', tp
);
2671 CLR(c
, ~TTY_CHARMASK
);
2677 (void)ttyoutput(c
, tp
);
2682 * Wake up any readers on a tty.
2684 * Locks: Assumes tty_lock() is held for the call.
2687 ttwakeup(struct tty
*tp
)
2689 TTY_LOCK_OWNED(tp
); /* debug assert */
2691 selwakeup(&tp
->t_rsel
);
2692 KNOTE(&tp
->t_rsel
.si_note
, 1);
2693 if (ISSET(tp
->t_state
, TS_ASYNC
)) {
2695 * XXX: Callers may not revalidate it the tty is closed
2696 * XXX: out from under them by another thread, but we do
2697 * XXX: not support queued signals. This should be safe,
2698 * XXX: since the process we intend to wakeup is in the
2699 * XXX: process group, and will wake up because of the
2700 * XXX: signal anyway.
2703 tty_pgsignal(tp
, SIGIO
, 1);
2706 wakeup(TSA_HUP_OR_INPUT(tp
));
2713 * Wake up any writers on a tty.
2715 * Locks: Assumes tty_lock() is held prior to calling.
2718 ttwwakeup(struct tty
*tp
)
2720 TTY_LOCK_OWNED(tp
); /* debug assert */
2722 if (tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
2723 selwakeup(&tp
->t_wsel
);
2724 KNOTE(&tp
->t_wsel
.si_note
, 1);
2726 if (ISSET(tp
->t_state
, TS_BUSY
| TS_SO_OCOMPLETE
) ==
2727 TS_SO_OCOMPLETE
&& tp
->t_outq
.c_cc
== 0) {
2728 CLR(tp
->t_state
, TS_SO_OCOMPLETE
);
2729 wakeup(TSA_OCOMPLETE(tp
));
2731 if (ISSET(tp
->t_state
, TS_SO_OLOWAT
) &&
2732 tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
2733 CLR(tp
->t_state
, TS_SO_OLOWAT
);
2734 wakeup(TSA_OLOWAT(tp
));
2740 * Look up a code for a specified speed in a conversion table;
2741 * used by drivers to map software speed values to hardware parameters.
2743 * Notes: No locks are assumed for this function; it does not
2744 * directly access struct tty.
2747 ttspeedtab(int speed
, struct speedtab
*table
)
2749 for ( ; table
->sp_speed
!= -1; table
++)
2750 if (table
->sp_speed
== speed
)
2751 return (table
->sp_code
);
2757 * Set tty hi and low water marks.
2759 * Try to arrange the dynamics so there's about one second
2760 * from hi to low water.
2762 * Locks: Assumes tty_lock() is held prior to calling.
2765 ttsetwater(struct tty
*tp
)
2770 TTY_LOCK_OWNED(tp
); /* debug assert */
2772 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2774 cps
= tp
->t_ospeed
/ 10;
2775 tp
->t_lowat
= x
= CLAMP(cps
/ 2, TTMAXLOWAT
, TTMINLOWAT
);
2777 x
= CLAMP(x
, TTMAXHIWAT
, TTMINHIWAT
);
2778 tp
->t_hiwat
= roundup(x
, CBSIZE
);
2782 /* ttyinfo has been converted to the MACH kernel */
2783 #include <mach/thread_info.h>
2785 /* XXX Should be in Mach header <kern/thread.h>, but doesn't work */
2786 extern kern_return_t
thread_info_internal(thread_t thread
,
2787 thread_flavor_t flavor
,
2788 thread_info_t thread_info_out
,
2789 mach_msg_type_number_t
*thread_info_count
);
2793 * Report on state of foreground process group.
2795 * Locks: Assumes tty_lock() is held prior to calling.
2798 ttyinfo_locked(struct tty
*tp
)
2807 struct timeval utime
;
2808 struct timeval stime
;
2809 thread_basic_info_data_t basic_info
;
2810 mach_msg_type_number_t mmtn
= THREAD_BASIC_INFO_COUNT
;
2813 TTY_LOCK_OWNED(tp
); /* debug assert */
2815 if (ttycheckoutq(tp
,0) == 0)
2818 /* Print load average. */
2819 load
= (averunnable
.ldavg
[0] * 100 + FSCALE
/ 2) >> FSHIFT
;
2820 ttyprintf(tp
, "load: %d.%02d ", load
/ 100, load
% 100);
2823 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
2824 * that pending input will be retyped on BS.
2826 if (tp
->t_session
== NULL
) {
2827 ttyprintf(tp
, "not a controlling terminal\n");
2831 if (tp
->t_pgrp
== NULL
) {
2832 ttyprintf(tp
, "no foreground process group\n");
2836 /* first process in process group */
2837 /* XXX is there a need for pgrp lock ? */
2838 if ((p
= tp
->t_pgrp
->pg_members
.lh_first
) == NULL
) {
2839 ttyprintf(tp
, "empty foreground process group\n");
2845 * Pick the most interesting process and copy some of its
2846 * state for printing later.
2850 /* the proc_compare is non blocking fn, no need to use iterator */
2851 for (pick
= NULL
; p
!= NULL
; p
= p
->p_pglist
.le_next
) {
2852 if (proc_compare(pick
, p
)) {
2856 pickpid
= pick
->p_pid
;
2860 /* SAFE: All callers drop the lock on return */
2865 pick
= proc_find(pickpid
);
2866 if (pick
== PROC_NULL
)
2869 if (TAILQ_EMPTY(&pick
->p_uthlist
) ||
2870 (uthread
= TAILQ_FIRST(&pick
->p_uthlist
)) == NULL
||
2871 (thread
= vfs_context_thread(&uthread
->uu_context
)) == NULL
||
2872 (thread_info_internal(thread
, THREAD_BASIC_INFO
, (thread_info_t
)&basic_info
, &mmtn
) != KERN_SUCCESS
)) {
2873 ttyprintf(tp
, "foreground process without thread\n");
2879 switch(basic_info
.run_state
) {
2880 case TH_STATE_RUNNING
:
2883 case TH_STATE_STOPPED
:
2886 case TH_STATE_WAITING
:
2889 case TH_STATE_UNINTERRUPTIBLE
:
2890 state
= "uninterruptible";
2892 case TH_STATE_HALTED
:
2899 calcru(pick
, &utime
, &stime
, NULL
);
2902 /* Print command, pid, state, utime, and stime */
2903 ttyprintf(tp
, " cmd: %s %d %s %ld.%02du %ld.%02ds\n",
2907 (long)utime
.tv_sec
, utime
.tv_usec
/ 10000,
2908 (long)stime
.tv_sec
, stime
.tv_usec
/ 10000);
2914 * Returns 1 if p2 is "better" than p1
2916 * The algorithm for picking the "interesting" process is thus:
2918 * 1) Only foreground processes are eligible - implied.
2919 * 2) Runnable processes are favored over anything else. The runner
2920 * with the highest cpu utilization is picked (p_estcpu). Ties are
2921 * broken by picking the highest pid.
2922 * 3) The sleeper with the shortest sleep time is next.
2923 * 4) Further ties are broken by picking the highest pid.
2925 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
2926 #define TESTAB(a, b) ((a)<<1 | (b))
2932 * Locks: pgrp_lock(p2) held on call to this function
2933 * tty_lock(tp) for p2's tty, for which p2 is the foreground
2934 * process, held on call to this function
2937 proc_compare(proc_t p1
, proc_t p2
)
2939 /* NOTE THIS FN needs to be NON BLOCKING */
2944 * see if at least one of them is runnable
2946 switch (TESTAB(ISRUN(p1
), ISRUN(p2
))) {
2953 * tie - favor one with highest recent cpu utilization
2955 #ifdef _PROC_HAS_SCHEDINFO_
2956 /* Without the support the fields are always zero */
2957 if (p2
->p_estcpu
> p1
->p_estcpu
)
2959 if (p1
->p_estcpu
> p2
->p_estcpu
)
2961 #endif /* _PROC_HAS_SCHEDINFO_ */
2962 return (p2
->p_pid
> p1
->p_pid
); /* tie - return highest pid */
2967 switch (TESTAB(p1
->p_stat
== SZOMB
, p2
->p_stat
== SZOMB
)) {
2973 return (p2
->p_pid
> p1
->p_pid
); /* tie - return highest pid */
2976 * pick the one with the smallest sleep time
2978 #ifdef _PROC_HAS_SCHEDINFO_
2979 /* Without the support the fields are always zero */
2980 if (p2
->p_slptime
> p1
->p_slptime
)
2982 if (p1
->p_slptime
> p2
->p_slptime
)
2984 #endif /* _PROC_HAS_SCHEDINFO_ */
2985 return (p2
->p_pid
> p1
->p_pid
); /* tie - return highest pid */
2990 * Output char to tty; console putchar style.
2992 * Locks: Assumes tty_lock() is held prior to calling.
2994 * Notes: Only ever called from putchar() in subr_prf.c
2997 tputchar(int c
, struct tty
*tp
)
2999 TTY_LOCK_OWNED(tp
); /* debug assert */
3001 if (!ISSET(tp
->t_state
, TS_CONNECTED
)) {
3005 (void)ttyoutput('\r', tp
);
3006 (void)ttyoutput(c
, tp
);
3015 * Sleep on a wait channel waiting for an interrupt or a condition to come
3016 * true so that we are woken up.
3018 * Parameters: tp Tty going to sleep
3019 * chan The sleep channel (usually an address
3020 * of a structure member)
3021 * pri priority and flags
3022 * wmesg Wait message; shows up in debugger,
3023 * should show up in "ps", but doesn't
3024 * timo Timeout for the sleep
3026 * Returns: 0 Condition came true
3027 * ERESTART Upper layer must redrive the call;
3028 * this is usually done by the Libc
3029 * stub in user space
3030 * msleep0:EINTR Interrupted (usually a signal)
3031 * msleep0:ERESTART Interrupted (usually a masked signal)
3032 * msleep0:EWOULDBLOCK Timeout (timo) already expired
3034 * Locks: Assumes tty_lock() is held prior to calling.
3036 * Sleep on chan, returning ERESTART if tty changed while we napped and
3037 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by msleep0. If
3038 * the tty is revoked, restarting a pending call will redo validation done
3039 * at the start of the call.
3042 ttysleep(struct tty
*tp
, void *chan
, int pri
, const char *wmesg
, int timo
)
3050 /* Use of msleep0() avoids conversion timo/timespec/timo */
3051 error
= msleep0(chan
, &tp
->t_lock
, pri
, wmesg
, timo
, (int (*)(int))0);
3054 return (tp
->t_gen
== gen
? 0 : ERESTART
);
3059 * Allocate a tty structure and its associated buffers.
3063 * Returns: !NULL Address of new struct tty
3064 * NULL Error ("ENOMEM")
3066 * Locks: The tty_lock() of the returned tty is not held when it
3074 MALLOC(tp
, struct tty
*, sizeof(struct tty
), M_TTYS
, M_WAITOK
|M_ZERO
);
3076 /* XXX: default to TTYCLSIZE(1024) chars for now */
3077 clalloc(&tp
->t_rawq
, TTYCLSIZE
, 1);
3078 clalloc(&tp
->t_canq
, TTYCLSIZE
, 1);
3079 /* output queue doesn't need quoting */
3080 clalloc(&tp
->t_outq
, TTYCLSIZE
, 0);
3081 lck_mtx_init(&tp
->t_lock
, tty_lck_grp
, tty_lck_attr
);
3082 klist_init(&tp
->t_rsel
.si_note
);
3083 klist_init(&tp
->t_wsel
.si_note
);
3090 * Increment the reference count on a tty.
3093 ttyhold(struct tty
*tp
)
3100 * Drops a reference count on a tty structure; if the reference count reaches
3101 * zero, then also frees the structure and associated buffers.
3104 ttyfree(struct tty
*tp
)
3106 TTY_LOCK_NOTOWNED(tp
);
3109 if (--tp
->t_refcnt
== 0) {
3112 } else if (tp
->t_refcnt
< 0) {
3113 panic("%s: freeing free tty %p", __func__
, tp
);
3119 * Deallocate a tty structure and its buffers.
3121 * Locks: The tty_lock() is assumed to not be held at the time of
3122 * the free; this function destroys the mutex.
3125 ttydeallocate(struct tty
*tp
)
3127 TTY_LOCK_NOTOWNED(tp
); /* debug assert */
3130 if (!(SLIST_EMPTY(&tp
->t_rsel
.si_note
) && SLIST_EMPTY(&tp
->t_wsel
.si_note
))) {
3131 panic("knotes hooked into a tty when the tty is freed.\n");
3135 clfree(&tp
->t_rawq
);
3136 clfree(&tp
->t_canq
);
3137 clfree(&tp
->t_outq
);
3138 lck_mtx_destroy(&tp
->t_lock
, tty_lck_grp
);
3144 * Locks: Assumes tty_lock() is held prior to calling.
3147 isbackground(proc_t p
, struct tty
*tp
)
3151 return (tp
->t_session
!= NULL
&& p
->p_pgrp
!= NULL
&& (p
->p_pgrp
!= tp
->t_pgrp
) && isctty_sp(p
, tp
, p
->p_pgrp
->pg_session
));
3155 isctty(proc_t p
, struct tty
*tp
)
3158 struct session
* sessp
;
3160 sessp
= proc_session(p
);
3161 retval
= (sessp
== tp
->t_session
&& p
->p_flag
& P_CONTROLT
);
3162 session_rele(sessp
);
3167 isctty_sp(proc_t p
, struct tty
*tp
, struct session
*sessp
)
3169 return(sessp
== tp
->t_session
&& p
->p_flag
& P_CONTROLT
);