2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
30 /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
32 * Copyright (c) 1982, 1986, 1990, 1991, 1993
33 * The Regents of the University of California. All rights reserved.
34 * (c) UNIX System Laboratories, Inc.
35 * All or some portions of this file are derived from material licensed
36 * to the University of California by American Telephone and Telegraph
37 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
38 * the permission of UNIX System Laboratories, Inc.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the University of
51 * California, Berkeley and its contributors.
52 * 4. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * @(#)tty.c 8.8 (Berkeley) 1/21/94
72 * o Fix races for sending the start char in ttyflush().
73 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
74 * With luck, there will be MIN chars before select() returns().
75 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it.
76 * o Don't allow input in TS_ZOMBIE case. It would be visible through
78 * o Do the new sio locking stuff here and use it to avoid special
81 * o Move EXTPROC and/or PENDIN to t_state?
82 * o Wrap most of ttioctl in spltty/splx.
83 * o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
84 * o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
85 * o Don't allow certain termios flags to affect disciplines other
86 * than TTYDISC. Cancel their effects before switch disciplines
87 * and ignore them if they are set while we are in another
89 * o Handle c_ispeed = 0 to c_ispeed = c_ospeed conversion here instead
90 * of in drivers and fix drivers that write to tp->t_termios.
91 * o Check for TS_CARR_ON being set while everything is closed and not
92 * waiting for carrier. TS_CARR_ON isn't cleared if nothing is open,
93 * so it would live until the next open even if carrier drops.
94 * o Restore TS_WOPEN since it is useful in pstat. It must be cleared
95 * only when _all_ openers leave open().
101 #include "opt_uconsole.h"
104 #include <sys/param.h>
105 #define TTYDEFCHARS 1
106 #include <sys/systm.h>
108 #include <sys/ioctl.h>
109 #include <sys/proc_internal.h>
110 #include <sys/kauth.h>
111 #include <sys/file_internal.h>
112 #include <sys/conf.h>
113 #include <sys/dkstat.h>
115 #include <sys/kernel.h>
116 #include <sys/vnode.h>
117 #include <sys/syslog.h>
118 #include <sys/user.h>
119 #include <sys/signalvar.h>
120 #include <sys/signalvar.h>
122 #include <sys/resourcevar.h>
124 #include <sys/malloc.h>
126 #include <sys/snoop.h>
131 #include <vm/vm_param.h>
132 #include <vm/vm_prot.h>
135 #include <vm/vm_map.h>
137 #include <dev/kmreg_com.h>
138 #include <machine/cons.h>
139 #include <machine/spl.h>
141 #include <machdep/machine/pmap.h>
144 #include <sys/resource.h> /* averunnable */
147 static int proc_compare(struct proc
*p1
, struct proc
*p2
);
149 static int ttnread(struct tty
*tp
);
150 static void ttyecho(int c
, struct tty
*tp
);
151 static int ttyoutput(int c
, register struct tty
*tp
);
152 static void ttypend(struct tty
*tp
);
153 static void ttyretype(struct tty
*tp
);
154 static void ttyrub(int c
, struct tty
*tp
);
155 static void ttyrubo(struct tty
*tp
, int count
);
156 static void ttystop(struct tty
*tp
, int rw
);
157 static void ttyunblock(struct tty
*tp
);
158 static int ttywflush(struct tty
*tp
);
159 static int proc_compare(struct proc
*p1
, struct proc
*p2
);
162 * Table with character classes and parity. The 8th bit indicates parity,
163 * the 7th bit indicates the character is an alphameric or underscore (for
164 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
165 * are 0 then the character needs no special processing on output; classes
166 * other than 0 might be translated or (not currently) require delays.
168 #define E 0x00 /* Even parity. */
169 #define O 0x80 /* Odd parity. */
170 #define PARITY(c) (char_type[c] & O)
172 #define ALPHA 0x40 /* Alpha or underscore. */
173 #define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
175 #define CCLASSMASK 0x3f
176 #define CCLASS(c) (char_type[c] & CCLASSMASK)
181 #define NA ORDINARY | ALPHA
187 static u_char
const char_type
[] = {
188 E
|CC
, O
|CC
, O
|CC
, E
|CC
, O
|CC
, E
|CC
, E
|CC
, O
|CC
, /* nul - bel */
189 O
|BS
, E
|TB
, E
|NL
, O
|CC
, E
|VT
, O
|CR
, O
|CC
, E
|CC
, /* bs - si */
190 O
|CC
, E
|CC
, E
|CC
, O
|CC
, E
|CC
, O
|CC
, O
|CC
, E
|CC
, /* dle - etb */
191 E
|CC
, O
|CC
, O
|CC
, E
|CC
, O
|CC
, E
|CC
, E
|CC
, O
|CC
, /* can - us */
192 O
|NO
, E
|NO
, E
|NO
, O
|NO
, E
|NO
, O
|NO
, O
|NO
, E
|NO
, /* sp - ' */
193 E
|NO
, O
|NO
, O
|NO
, E
|NO
, O
|NO
, E
|NO
, E
|NO
, O
|NO
, /* ( - / */
194 E
|NA
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* 0 - 7 */
195 O
|NA
, E
|NA
, E
|NO
, O
|NO
, E
|NO
, O
|NO
, O
|NO
, E
|NO
, /* 8 - ? */
196 O
|NO
, E
|NA
, E
|NA
, O
|NA
, E
|NA
, O
|NA
, O
|NA
, E
|NA
, /* @ - G */
197 E
|NA
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* H - O */
198 E
|NA
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* P - W */
199 O
|NA
, E
|NA
, E
|NA
, O
|NO
, E
|NO
, O
|NO
, O
|NO
, O
|NA
, /* X - _ */
200 E
|NO
, O
|NA
, O
|NA
, E
|NA
, O
|NA
, E
|NA
, E
|NA
, O
|NA
, /* ` - g */
201 O
|NA
, E
|NA
, E
|NA
, O
|NA
, E
|NA
, O
|NA
, O
|NA
, E
|NA
, /* h - o */
202 O
|NA
, E
|NA
, E
|NA
, O
|NA
, E
|NA
, O
|NA
, O
|NA
, E
|NA
, /* p - w */
203 E
|NA
, O
|NA
, O
|NA
, E
|NO
, O
|NO
, E
|NO
, E
|NO
, O
|CC
, /* x - del */
205 * Meta chars; should be settable per character set;
206 * for now, treat them all as normal characters.
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
,
216 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
217 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
218 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
219 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
220 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
221 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
222 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
223 NA
, NA
, NA
, NA
, NA
, NA
, NA
, NA
,
234 /* Macros to clear/set/test flags. */
235 #define SET(t, f) (t) |= (f)
236 #define CLR(t, f) (t) &= ~(f)
237 #define ISSET(t, f) ((t) & (f))
240 * Input control starts when we would not be able to fit the maximum
241 * contents of the ping-pong buffers and finishes when we would be able
242 * to fit that much plus 1/8 more.
244 #define I_HIGH_WATER (TTYHOG - 2 * 256) /* XXX */
245 #define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
247 #undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */
248 #define MAX_INPUT TTYHOG
251 termios32to64(struct termios
*in
, struct user_termios
*out
)
253 out
->c_iflag
= (user_tcflag_t
)in
->c_iflag
;
254 out
->c_oflag
= (user_tcflag_t
)in
->c_oflag
;
255 out
->c_cflag
= (user_tcflag_t
)in
->c_cflag
;
256 out
->c_lflag
= (user_tcflag_t
)in
->c_lflag
;
258 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
259 bcopy(in
->c_cc
, out
->c_cc
, sizeof(in
->c_cc
));
261 out
->c_ispeed
= (user_speed_t
)in
->c_ispeed
;
262 out
->c_ospeed
= (user_speed_t
)in
->c_ospeed
;
266 termios64to32(struct user_termios
*in
, struct termios
*out
)
268 out
->c_iflag
= (tcflag_t
)in
->c_iflag
;
269 out
->c_oflag
= (tcflag_t
)in
->c_oflag
;
270 out
->c_cflag
= (tcflag_t
)in
->c_cflag
;
271 out
->c_lflag
= (tcflag_t
)in
->c_lflag
;
273 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
274 bcopy(in
->c_cc
, out
->c_cc
, sizeof(in
->c_cc
));
276 out
->c_ispeed
= (speed_t
)in
->c_ispeed
;
277 out
->c_ospeed
= (speed_t
)in
->c_ospeed
;
282 * Initial open of tty, or (re)entry to standard tty line discipline.
287 register struct tty
*tp
;
290 boolean_t funnel_state
;
292 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
295 if (!ISSET(tp
->t_state
, TS_ISOPEN
)) {
296 SET(tp
->t_state
, TS_ISOPEN
);
297 if (ISSET(tp
->t_cflag
, CLOCAL
)) {
298 SET(tp
->t_state
, TS_CONNECTED
); }
299 bzero(&tp
->t_winsize
, sizeof(tp
->t_winsize
));
304 * Initialize or restore a cblock allocation policy suitable for
305 * the standard line discipline.
307 clist_alloc_cblocks(&tp
->t_canq
, TTYHOG
, 512);
308 clist_alloc_cblocks(&tp
->t_outq
, TTMAXHIWAT
+ OBUFSIZ
+ 100,
309 TTMAXHIWAT
+ OBUFSIZ
+ 100);
310 clist_alloc_cblocks(&tp
->t_rawq
, TTYHOG
, TTYHOG
);
314 thread_funnel_set(kernel_flock
, funnel_state
);
319 * Handle close() on a tty line: flush and set to initial state,
320 * bumping generation number so that pending read/write calls
321 * can detect recycling of the tty.
322 * XXX our caller should have done `spltty(); l_close(); ttyclose();'
323 * and l_close() should have flushed, but we repeat the spltty() and
324 * the flush in case there are buggy callers.
328 register struct tty
*tp
;
341 * Closing current console tty; disable printing of console
342 * messages at bottom-level driver.
344 (*cdevsw
[major(tp
->t_dev
)].d_ioctl
)
345 (tp
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, current_proc());
349 ttyflush(tp
, FREAD
| FWRITE
);
351 clist_free_cblocks(&tp
->t_canq
);
352 clist_free_cblocks(&tp
->t_outq
);
353 clist_free_cblocks(&tp
->t_rawq
);
357 if (ISSET(tp
->t_state
, TS_SNOOP
) && tp
->t_sc
!= NULL
)
358 snpdown((struct snoop
*)tp
->t_sc
);
362 tp
->t_line
= TTYDISC
;
364 tp
->t_session
= NULL
;
367 selthreadclear(&tp
->t_wsel
);
368 selthreadclear(&tp
->t_rsel
);
374 #define FLUSHQ(q) { \
376 ndflush(q, (q)->c_cc); \
379 /* Is 'c' a line delimiter ("break" character)? */
380 #define TTBREAKC(c, lflag) \
381 ((c) == '\n' || (((c) == cc[VEOF] || \
382 (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \
383 (c) != _POSIX_VDISABLE))
386 * Process input of a single character received on a tty.
391 register struct tty
*tp
;
393 register tcflag_t iflag
, lflag
;
396 boolean_t funnel_state
;
398 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
401 * If input is pending take it first.
404 if (ISSET(lflag
, PENDIN
))
409 if (ISSET(lflag
, ICANON
)) {
419 * Block further input iff:
420 * current input > threshold AND input is available to user program
421 * AND input flow control is enabled and not yet invoked.
422 * The 3 is slop for PARMRK.
425 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
> I_HIGH_WATER
- 3 &&
426 (!ISSET(lflag
, ICANON
) || tp
->t_canq
.c_cc
!= 0) &&
427 (ISSET(tp
->t_cflag
, CRTS_IFLOW
) || ISSET(iflag
, IXOFF
)) &&
428 !ISSET(tp
->t_state
, TS_TBLOCK
))
431 /* Handle exceptional conditions (break, parity, framing). */
433 err
= (ISSET(c
, TTY_ERRORMASK
));
435 CLR(c
, TTY_ERRORMASK
);
436 if (ISSET(err
, TTY_BI
)) {
437 if (ISSET(iflag
, IGNBRK
)) {
438 thread_funnel_set(kernel_flock
, funnel_state
);
441 if (ISSET(iflag
, BRKINT
)) {
442 ttyflush(tp
, FREAD
| FWRITE
);
443 pgsignal(tp
->t_pgrp
, SIGINT
, 1);
446 if (ISSET(iflag
, PARMRK
))
448 } else if ((ISSET(err
, TTY_PE
) && ISSET(iflag
, INPCK
))
449 || ISSET(err
, TTY_FE
)) {
450 if (ISSET(iflag
, IGNPAR
)) {
451 thread_funnel_set(kernel_flock
, funnel_state
);
454 else if (ISSET(iflag
, PARMRK
)) {
456 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
>
459 (void)putc(0377 | TTY_QUOTE
, &tp
->t_rawq
);
460 (void)putc(0 | TTY_QUOTE
, &tp
->t_rawq
);
461 (void)putc(c
| TTY_QUOTE
, &tp
->t_rawq
);
468 if (!ISSET(tp
->t_state
, TS_TYPEN
) && ISSET(iflag
, ISTRIP
))
470 if (!ISSET(lflag
, EXTPROC
)) {
472 * Check for literal nexting very first
474 if (ISSET(tp
->t_state
, TS_LNCH
)) {
476 CLR(tp
->t_state
, TS_LNCH
);
479 * Scan for special characters. This code
480 * is really just a big case statement with
481 * non-constant cases. The bottom of the
482 * case statement is labeled ``endcase'', so goto
483 * it after a case match, or similar.
487 * Control chars which aren't controlled
488 * by ICANON, ISIG, or IXON.
490 if (ISSET(lflag
, IEXTEN
)) {
491 if (CCEQ(cc
[VLNEXT
], c
)) {
492 if (ISSET(lflag
, ECHO
)) {
493 if (ISSET(lflag
, ECHOE
)) {
494 (void)ttyoutput('^', tp
);
495 (void)ttyoutput('\b', tp
);
499 SET(tp
->t_state
, TS_LNCH
);
502 if (CCEQ(cc
[VDISCARD
], c
)) {
503 if (ISSET(lflag
, FLUSHO
))
504 CLR(tp
->t_lflag
, FLUSHO
);
506 ttyflush(tp
, FWRITE
);
508 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
)
510 SET(tp
->t_lflag
, FLUSHO
);
518 if (ISSET(lflag
, ISIG
)) {
519 if (CCEQ(cc
[VINTR
], c
) || CCEQ(cc
[VQUIT
], c
)) {
520 if (!ISSET(lflag
, NOFLSH
))
521 ttyflush(tp
, FREAD
| FWRITE
);
524 CCEQ(cc
[VINTR
], c
) ? SIGINT
: SIGQUIT
, 1);
527 if (CCEQ(cc
[VSUSP
], c
)) {
528 if (!ISSET(lflag
, NOFLSH
))
531 pgsignal(tp
->t_pgrp
, SIGTSTP
, 1);
536 * Handle start/stop characters.
538 if (ISSET(iflag
, IXON
)) {
539 if (CCEQ(cc
[VSTOP
], c
)) {
540 if (!ISSET(tp
->t_state
, TS_TTSTOP
)) {
541 SET(tp
->t_state
, TS_TTSTOP
);
543 thread_funnel_set(kernel_flock
, funnel_state
);
546 if (!CCEQ(cc
[VSTART
], c
)) {
547 thread_funnel_set(kernel_flock
, funnel_state
);
551 * if VSTART == VSTOP then toggle
555 if (CCEQ(cc
[VSTART
], c
))
559 * IGNCR, ICRNL, & INLCR
562 if (ISSET(iflag
, IGNCR
)) {
563 thread_funnel_set(kernel_flock
, funnel_state
);
566 else if (ISSET(iflag
, ICRNL
))
568 } else if (c
== '\n' && ISSET(iflag
, INLCR
))
571 if (!ISSET(tp
->t_lflag
, EXTPROC
) && ISSET(lflag
, ICANON
)) {
573 * From here on down canonical mode character
574 * processing takes place.
579 if (CCEQ(cc
[VERASE
], c
)) {
581 ttyrub(unputc(&tp
->t_rawq
), tp
);
587 if (CCEQ(cc
[VKILL
], c
)) {
588 if (ISSET(lflag
, ECHOKE
) &&
589 tp
->t_rawq
.c_cc
== tp
->t_rocount
&&
590 !ISSET(lflag
, ECHOPRT
))
591 while (tp
->t_rawq
.c_cc
)
592 ttyrub(unputc(&tp
->t_rawq
), tp
);
595 if (ISSET(lflag
, ECHOK
) ||
596 ISSET(lflag
, ECHOKE
))
601 CLR(tp
->t_state
, TS_LOCAL
);
607 if (CCEQ(cc
[VWERASE
], c
) && ISSET(lflag
, IEXTEN
)) {
613 while ((c
= unputc(&tp
->t_rawq
)) == ' ' || c
== '\t')
618 * erase last char of word and remember the
619 * next chars type (for ALTWERASE)
622 c
= unputc(&tp
->t_rawq
);
625 if (c
== ' ' || c
== '\t') {
626 (void)putc(c
, &tp
->t_rawq
);
635 c
= unputc(&tp
->t_rawq
);
638 } while (c
!= ' ' && c
!= '\t' &&
639 (!ISSET(lflag
, ALTWERASE
) || ISALPHA(c
) == ctype
));
640 (void)putc(c
, &tp
->t_rawq
);
646 if (CCEQ(cc
[VREPRINT
], c
) && ISSET(lflag
, IEXTEN
)) {
651 * ^T - kernel info and generate SIGINFO
653 if (CCEQ(cc
[VSTATUS
], c
) && ISSET(lflag
, IEXTEN
)) {
654 if (ISSET(lflag
, ISIG
))
655 pgsignal(tp
->t_pgrp
, SIGINFO
, 1);
656 if (!ISSET(lflag
, NOKERNINFO
))
662 * Check for input buffer overflow
664 if (tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
>= MAX_INPUT
) {
666 if (ISSET(iflag
, IMAXBEL
)) {
667 if (tp
->t_outq
.c_cc
< tp
->t_hiwat
)
668 (void)ttyoutput(CTRL('g'), tp
);
673 if ( c
== 0377 && ISSET(iflag
, PARMRK
) && !ISSET(iflag
, ISTRIP
)
674 && ISSET(iflag
, IGNBRK
|IGNPAR
) != (IGNBRK
|IGNPAR
))
675 (void)putc(0377 | TTY_QUOTE
, &tp
->t_rawq
);
678 * Put data char in q for user and
679 * wakeup on seeing a line delimiter.
681 if (putc(c
, &tp
->t_rawq
) >= 0) {
682 if (!ISSET(lflag
, ICANON
)) {
687 if (TTBREAKC(c
, lflag
)) {
689 catq(&tp
->t_rawq
, &tp
->t_canq
);
691 } else if (tp
->t_rocount
++ == 0)
692 tp
->t_rocol
= tp
->t_column
;
693 if (ISSET(tp
->t_state
, TS_ERASE
)) {
695 * end of prterase \.../
697 CLR(tp
->t_state
, TS_ERASE
);
698 (void)ttyoutput('/', tp
);
702 if (CCEQ(cc
[VEOF
], c
) && ISSET(lflag
, ECHO
)) {
704 * Place the cursor over the '^' of the ^D.
706 i
= min(2, tp
->t_column
- i
);
708 (void)ttyoutput('\b', tp
);
715 * IXANY means allow any character to restart output.
717 if (ISSET(tp
->t_state
, TS_TTSTOP
) &&
718 !ISSET(iflag
, IXANY
) && cc
[VSTART
] != cc
[VSTOP
]) {
719 thread_funnel_set(kernel_flock
, funnel_state
);
723 CLR(tp
->t_lflag
, FLUSHO
);
724 CLR(tp
->t_state
, TS_TTSTOP
);
726 retval
= ttstart(tp
);
727 thread_funnel_set(kernel_flock
, funnel_state
);
732 * Output a single character on a tty, doing output processing
733 * as needed (expanding tabs, newline processing, etc.).
734 * Returns < 0 if succeeds, otherwise returns char to resend.
740 register struct tty
*tp
;
742 register tcflag_t oflag
;
746 if (!ISSET(oflag
, OPOST
)) {
747 if (ISSET(tp
->t_lflag
, FLUSHO
))
749 if (putc(c
, &tp
->t_outq
))
756 * Do tab expansion if OXTABS is set. Special case if we external
757 * processing, we don't do the tab expansion because we'll probably
758 * get it wrong. If tab expansion needs to be done, let it happen
761 CLR(c
, ~TTY_CHARMASK
);
763 ISSET(oflag
, OXTABS
) && !ISSET(tp
->t_lflag
, EXTPROC
)) {
764 c
= 8 - (tp
->t_column
& 7);
765 if (!ISSET(tp
->t_lflag
, FLUSHO
)) {
766 s
= spltty(); /* Don't interrupt tabs. */
767 c
-= b_to_q(" ", c
, &tp
->t_outq
);
773 return (c
? -1 : '\t');
775 if (c
== CEOT
&& ISSET(oflag
, ONOEOT
))
779 * Newline translation: if ONLCR is set,
780 * translate newline into "\r\n".
782 if (c
== '\n' && ISSET(tp
->t_oflag
, ONLCR
)) {
785 if (putc('\r', &tp
->t_outq
))
790 if (!ISSET(tp
->t_lflag
, FLUSHO
) && putc(c
, &tp
->t_outq
))
809 col
= (col
+ 8) & ~7;
817 * Ioctls for all tty devices. Called after line-discipline specific ioctl
818 * has been called to do discipline-specific functions and/or reject any
819 * of these ioctl commands.
823 ttioctl(register struct tty
*tp
,
824 u_long cmd
, caddr_t data
, int flag
,
830 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
831 /* If the ioctl involves modification, hang if in the background. */
847 #if COMPAT_43_TTY || defined(COMPAT_SUNOS)
857 while (isbackground(p
, tp
) &&
858 (p
->p_flag
& P_PPWAIT
) == 0 &&
859 (p
->p_sigignore
& sigmask(SIGTTOU
)) == 0 &&
860 (ut
->uu_sigmask
& sigmask(SIGTTOU
)) == 0) {
861 if (p
->p_pgrp
->pg_jobc
== 0)
863 pgsignal(p
->p_pgrp
, SIGTTOU
, 1);
864 error
= ttysleep(tp
, &lbolt
, TTOPRI
| PCATCH
| PTTYBLOCK
, "ttybg1",
872 switch (cmd
) { /* Process the ioctl. */
873 case FIOASYNC
: /* set/clear async i/o */
876 SET(tp
->t_state
, TS_ASYNC
);
878 CLR(tp
->t_state
, TS_ASYNC
);
881 case FIONBIO
: /* set/clear non-blocking i/o */
882 break; /* XXX: delete. */
883 case FIONREAD
: /* get # bytes to read */
885 *(int *)data
= ttnread(tp
);
888 case TIOCEXCL
: /* set exclusive use of tty */
890 SET(tp
->t_state
, TS_XCLUDE
);
893 case TIOCFLUSH
: { /* flush buffers */
894 register int flags
= *(int *)data
;
897 flags
= FREAD
| FWRITE
;
899 flags
&= FREAD
| FWRITE
;
905 /* Set current console device to this line */
907 data
= (caddr_t
) &bogusData
;
909 /* No break - Fall through to BSD code */
912 case TIOCCONS
: { /* become virtual console */
914 if (constty
&& constty
!= tp
&&
915 ISSET(constty
->t_state
, TS_CONNECTED
)) {
918 #if defined(NeXT) || !defined(UCONSOLE)
919 if ( (error
= suser(kauth_cred_get(), &p
->p_acflag
)) )
923 } else if (tp
== constty
) {
928 (*cdevsw
[major(cons
.t_dev
)].d_ioctl
)
929 (cons
.t_dev
, KMIOCDISABLCONS
, NULL
, 0, p
);
931 (*cdevsw
[major(tp
->t_dev
)].d_ioctl
)
932 (tp
->t_dev
, KMIOCDISABLCONS
, NULL
, 0, p
);
937 case TIOCDRAIN
: /* wait till output drained */
942 case TIOCGETA
: /* get termios struct */
943 case TIOCGETA_64
: { /* get termios struct */
944 if (IS_64BIT_PROCESS(p
)) {
945 termios32to64(&tp
->t_termios
, (struct user_termios
*)data
);
947 bcopy(&tp
->t_termios
, data
, sizeof(struct termios
));
951 case TIOCGETD
: /* get line discipline */
952 *(int *)data
= tp
->t_line
;
954 case TIOCGWINSZ
: /* get window size */
955 *(struct winsize
*)data
= tp
->t_winsize
;
957 case TIOCGPGRP
: /* get pgrp of tty */
960 *(int *)data
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
963 case TIOCHPCL
: /* hang up on last close */
965 SET(tp
->t_cflag
, HUPCL
);
969 case TIOCNXCL
: /* reset exclusive use of tty */
971 CLR(tp
->t_state
, TS_XCLUDE
);
974 case TIOCOUTQ
: /* output queue size */
975 *(int *)data
= tp
->t_outq
.c_cc
;
977 case TIOCSETA
: /* set termios struct */
979 case TIOCSETAW
: /* drain output, set */
981 case TIOCSETAF
: /* drn out, fls in, set */
982 case TIOCSETAF_64
: { /* drn out, fls in, set */
983 register struct termios
*t
= (struct termios
*)data
;
984 struct termios lcl_termios
;
986 if (IS_64BIT_PROCESS(p
)) {
987 termios64to32((struct user_termios
*)data
, &lcl_termios
);
990 if (t
->c_ispeed
< 0 || t
->c_ospeed
< 0)
993 if (cmd
== TIOCSETAW
|| cmd
== TIOCSETAF
||
994 cmd
== TIOCSETAW_64
|| cmd
== TIOCSETAF_64
) {
1000 if (cmd
== TIOCSETAF
|| cmd
== TIOCSETAF_64
)
1001 ttyflush(tp
, FREAD
);
1003 if (!ISSET(t
->c_cflag
, CIGNORE
)) {
1005 * Set device hardware.
1007 if (tp
->t_param
&& (error
= (*tp
->t_param
)(tp
, t
))) {
1011 if (ISSET(t
->c_cflag
, CLOCAL
) &&
1012 !ISSET(tp
->t_cflag
, CLOCAL
)) {
1014 * XXX disconnections would be too hard to
1015 * get rid of without this kludge. The only
1016 * way to get rid of controlling terminals
1017 * is to exit from the session leader.
1019 CLR(tp
->t_state
, TS_ZOMBIE
);
1021 wakeup(TSA_CARR_ON(tp
));
1025 if ((ISSET(tp
->t_state
, TS_CARR_ON
) ||
1026 ISSET(t
->c_cflag
, CLOCAL
)) &&
1027 !ISSET(tp
->t_state
, TS_ZOMBIE
))
1028 SET(tp
->t_state
, TS_CONNECTED
);
1030 CLR(tp
->t_state
, TS_CONNECTED
);
1031 tp
->t_cflag
= t
->c_cflag
;
1032 tp
->t_ispeed
= t
->c_ispeed
;
1033 tp
->t_ospeed
= t
->c_ospeed
;
1036 if (ISSET(t
->c_lflag
, ICANON
) != ISSET(tp
->t_lflag
, ICANON
) &&
1037 cmd
!= TIOCSETAF
&& cmd
!= TIOCSETAF_64
) {
1038 if (ISSET(t
->c_lflag
, ICANON
))
1039 SET(tp
->t_lflag
, PENDIN
);
1042 * XXX we really shouldn't allow toggling
1043 * ICANON while we're in a non-termios line
1044 * discipline. Now we have to worry about
1045 * panicing for a null queue.
1048 if (tp
->t_canq
.c_cbreserved
> 0 &&
1049 tp
->t_rawq
.c_cbreserved
> 0) {
1050 catq(&tp
->t_rawq
, &tp
->t_canq
);
1052 * XXX the queue limits may be
1053 * different, so the old queue
1054 * swapping method no longer works.
1056 catq(&tp
->t_canq
, &tp
->t_rawq
);
1059 if (tp
->t_rawq
.c_cs
&& tp
->t_canq
.c_cs
) {
1062 catq(&tp
->t_rawq
, &tp
->t_canq
);
1064 tp
->t_rawq
= tp
->t_canq
;
1068 CLR(tp
->t_lflag
, PENDIN
);
1072 tp
->t_iflag
= t
->c_iflag
;
1073 tp
->t_oflag
= t
->c_oflag
;
1075 * Make the EXTPROC bit read only.
1077 if (ISSET(tp
->t_lflag
, EXTPROC
))
1078 SET(t
->c_lflag
, EXTPROC
);
1080 CLR(t
->c_lflag
, EXTPROC
);
1081 tp
->t_lflag
= t
->c_lflag
| ISSET(tp
->t_lflag
, PENDIN
);
1082 if (t
->c_cc
[VMIN
] != tp
->t_cc
[VMIN
] ||
1083 t
->c_cc
[VTIME
] != tp
->t_cc
[VTIME
])
1085 bcopy(t
->c_cc
, tp
->t_cc
, sizeof(t
->c_cc
));
1089 case TIOCSETD
: { /* set line discipline */
1090 register int t
= *(int *)data
;
1091 dev_t device
= tp
->t_dev
;
1095 if (t
!= tp
->t_line
) {
1097 (*linesw
[tp
->t_line
].l_close
)(tp
, flag
);
1098 error
= (*linesw
[t
].l_open
)(device
, tp
);
1100 (void)(*linesw
[tp
->t_line
].l_open
)(device
, tp
);
1109 case TIOCSTART
: /* start output, like ^Q */
1111 if (ISSET(tp
->t_state
, TS_TTSTOP
) ||
1112 ISSET(tp
->t_lflag
, FLUSHO
)) {
1113 CLR(tp
->t_lflag
, FLUSHO
);
1114 CLR(tp
->t_state
, TS_TTSTOP
);
1119 case TIOCSTI
: /* simulate terminal input */
1120 if (suser(kauth_cred_get(), NULL
) && (flag
& FREAD
) == 0)
1122 if (suser(kauth_cred_get(), NULL
) && !isctty(p
, tp
))
1125 (*linesw
[tp
->t_line
].l_rint
)(*(u_char
*)data
, tp
);
1128 case TIOCSTOP
: /* stop output, like ^S */
1130 if (!ISSET(tp
->t_state
, TS_TTSTOP
)) {
1131 SET(tp
->t_state
, TS_TTSTOP
);
1136 case TIOCSCTTY
: /* become controlling tty */
1137 /* Session ctty vnode pointer set in vnode layer. */
1138 if (!SESS_LEADER(p
) ||
1139 ((p
->p_session
->s_ttyvp
|| tp
->t_session
) &&
1140 (tp
->t_session
!= p
->p_session
)))
1142 tp
->t_session
= p
->p_session
;
1143 tp
->t_pgrp
= p
->p_pgrp
;
1144 p
->p_session
->s_ttyp
= tp
;
1145 p
->p_flag
|= P_CONTROLT
;
1146 /* The backgrounded process blocking on tty now
1147 * could be foregound process. Wake such processes
1149 tty_pgsignal(tp
->t_pgrp
, SIGCONT
);
1151 case TIOCSPGRP
: { /* set pgrp of tty */
1152 register struct pgrp
*pgrp
= pgfind(*(int *)data
);
1156 else if (pgrp
== NULL
|| pgrp
->pg_session
!= p
->p_session
)
1159 /* The backgrounded process blocking on tty now
1160 * could be foregound process. Wake such processes
1162 tty_pgsignal(tp
->t_pgrp
, SIGCONT
);
1165 case TIOCSTAT
: /* simulate control-T */
1170 case TIOCSWINSZ
: /* set window size */
1171 if (bcmp((caddr_t
)&tp
->t_winsize
, data
,
1172 sizeof (struct winsize
))) {
1173 tp
->t_winsize
= *(struct winsize
*)data
;
1174 pgsignal(tp
->t_pgrp
, SIGWINCH
, 1);
1177 case TIOCSDRAINWAIT
:
1178 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1181 tp
->t_timeout
= *(int *)data
* hz
;
1182 wakeup(TSA_OCOMPLETE(tp
));
1183 wakeup(TSA_OLOWAT(tp
));
1185 case TIOCGDRAINWAIT
:
1186 *(int *)data
= tp
->t_timeout
/ hz
;
1189 #if COMPAT_43_TTY || defined(COMPAT_SUNOS)
1191 return (ttcompat(tp
, cmd
, data
, flag
, p
));
1193 return (ttcompat(tp
, cmd
, data
, flag
));
1204 ttyselect(tp
, rw
, wql
, p
)
1218 if (ttnread(tp
) > 0 || ISSET(tp
->t_state
, TS_ZOMBIE
))
1220 selrecord(p
, &tp
->t_rsel
, wql
);
1223 if ((tp
->t_outq
.c_cc
<= tp
->t_lowat
&&
1224 ISSET(tp
->t_state
, TS_CONNECTED
))
1225 || ISSET(tp
->t_state
, TS_ZOMBIE
)) {
1229 selrecord(p
, &tp
->t_wsel
, wql
);
1237 * This is a wrapper for compatibility with the select vector used by
1238 * cdevsw. It relies on a proper xxxdevtotty routine.
1241 ttselect(dev
, rw
, wql
, p
)
1248 return ttyselect((*cdevsw
[major(dev
)]->d_devtotty
)(dev
), rw
, wql
, p
);
1250 return ttyselect(cdevsw
[major(dev
)].d_ttys
[minor(dev
)], rw
, wql
, p
);
1255 * Must be called at spltty().
1263 if (ISSET(tp
->t_lflag
, PENDIN
))
1265 nread
= tp
->t_canq
.c_cc
;
1266 if (!ISSET(tp
->t_lflag
, ICANON
)) {
1267 nread
+= tp
->t_rawq
.c_cc
;
1268 if (nread
< tp
->t_cc
[VMIN
] && tp
->t_cc
[VTIME
] == 0)
1275 * Wait for output to drain.
1279 register struct tty
*tp
;
1285 while ((tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)) &&
1286 ISSET(tp
->t_state
, TS_CONNECTED
) && tp
->t_oproc
) {
1288 if ((tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)) &&
1289 ISSET(tp
->t_state
, TS_CONNECTED
)) {
1290 SET(tp
->t_state
, TS_SO_OCOMPLETE
);
1291 error
= ttysleep(tp
, TSA_OCOMPLETE(tp
),
1292 TTOPRI
| PCATCH
, "ttywai",
1295 if (error
== EWOULDBLOCK
)
1302 if (!error
&& (tp
->t_outq
.c_cc
|| ISSET(tp
->t_state
, TS_BUSY
)))
1313 #ifdef sun4c /* XXX */
1314 (*tp
->t_stop
)(tp
, rw
);
1316 (*cdevsw
[major(tp
->t_dev
)].d_stop
)(tp
, rw
);
1318 (*cdevsw
[major(tp
->t_dev
)]->d_stop
)(tp
, rw
);
1323 * Flush if successfully wait.
1331 if ((error
= ttywait(tp
)) == 0)
1332 ttyflush(tp
, FREAD
);
1337 * Flush tty read and/or write queues, notifying anyone waiting.
1341 register struct tty
*tp
;
1351 FLUSHQ(&tp
->t_outq
);
1352 CLR(tp
->t_state
, TS_TTSTOP
);
1356 FLUSHQ(&tp
->t_canq
);
1357 FLUSHQ(&tp
->t_rawq
);
1358 CLR(tp
->t_lflag
, PENDIN
);
1361 CLR(tp
->t_state
, TS_LOCAL
);
1363 if (ISSET(tp
->t_state
, TS_TBLOCK
)) {
1365 FLUSHQ(&tp
->t_outq
);
1369 * Don't let leave any state that might clobber the
1370 * next line discipline (although we should do more
1371 * to send the START char). Not clearing the state
1372 * may have caused the "putc to a clist with no
1373 * reserved cblocks" panic/printf.
1375 CLR(tp
->t_state
, TS_TBLOCK
);
1377 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1378 if (ISSET(tp
->t_iflag
, IXOFF
)) {
1380 * XXX wait a bit in the hope that the stop
1381 * character (if any) will go out. Waiting
1382 * isn't good since it allows races. This
1383 * will be fixed when the stop character is
1384 * put in a special queue. Don't bother with
1385 * the checks in ttywait() since the timeout
1388 SET(tp
->t_state
, TS_SO_OCOMPLETE
);
1389 ttysleep(tp
, TSA_OCOMPLETE(tp
), TTOPRI
,
1392 * Don't try sending the stop character again.
1394 CLR(tp
->t_state
, TS_TBLOCK
);
1401 FLUSHQ(&tp
->t_outq
);
1408 * Copy in the default termios characters.
1415 bcopy(ttydefchars
, t
->c_cc
, sizeof t
->c_cc
);
1426 termioschars(&tp
->t_termios
);
1430 * Handle input high water. Send stop character for the IXOFF case. Turn
1431 * on our input flow control bit and propagate the changes to the driver.
1432 * XXX the stop character should be put in a special high priority queue.
1439 SET(tp
->t_state
, TS_TBLOCK
);
1440 if (ISSET(tp
->t_iflag
, IXOFF
) && tp
->t_cc
[VSTOP
] != _POSIX_VDISABLE
&&
1441 putc(tp
->t_cc
[VSTOP
], &tp
->t_outq
) != 0)
1442 CLR(tp
->t_state
, TS_TBLOCK
); /* try again later */
1447 * Handle input low water. Send start character for the IXOFF case. Turn
1448 * off our input flow control bit and propagate the changes to the driver.
1449 * XXX the start character should be put in a special high priority queue.
1456 CLR(tp
->t_state
, TS_TBLOCK
);
1457 if (ISSET(tp
->t_iflag
, IXOFF
) && tp
->t_cc
[VSTART
] != _POSIX_VDISABLE
&&
1458 putc(tp
->t_cc
[VSTART
], &tp
->t_outq
) != 0)
1459 SET(tp
->t_state
, TS_TBLOCK
); /* try again later */
1463 #if defined(NeXT) || defined(notyet)
1464 /* FreeBSD: Not used by any current (i386) drivers. */
1466 * Restart after an inter-char delay.
1482 CLR(tp
->t_state
, TS_TIMEOUT
);
1487 #endif /* NeXT || notyet */
1493 boolean_t funnel_state
;
1495 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
1497 if (tp
->t_oproc
!= NULL
) /* XXX: Kludge for pty. */
1499 thread_funnel_set(kernel_flock
, funnel_state
);
1504 * "close" a line discipline
1511 boolean_t funnel_state
;
1513 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
1514 if ( (flag
& FNONBLOCK
) || ttywflush(tp
))
1515 ttyflush(tp
, FREAD
| FWRITE
);
1516 thread_funnel_set(kernel_flock
, funnel_state
);
1521 * Handle modem control transition on a tty.
1522 * Flag indicates new state of carrier.
1523 * Returns 0 if the line should be turned off, otherwise 1.
1527 register struct tty
*tp
;
1530 boolean_t funnel_state
;
1532 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
1534 if (ISSET(tp
->t_state
, TS_CARR_ON
) && ISSET(tp
->t_cflag
, MDMBUF
)) {
1536 * MDMBUF: do flow control according to carrier flag
1537 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP
1538 * works if IXON and IXANY are clear.
1541 CLR(tp
->t_state
, TS_CAR_OFLOW
);
1542 CLR(tp
->t_state
, TS_TTSTOP
);
1544 } else if (!ISSET(tp
->t_state
, TS_CAR_OFLOW
)) {
1545 SET(tp
->t_state
, TS_CAR_OFLOW
);
1546 SET(tp
->t_state
, TS_TTSTOP
);
1549 } else if (flag
== 0) {
1553 CLR(tp
->t_state
, TS_CARR_ON
);
1554 if (ISSET(tp
->t_state
, TS_ISOPEN
) &&
1555 !ISSET(tp
->t_cflag
, CLOCAL
)) {
1556 SET(tp
->t_state
, TS_ZOMBIE
);
1557 CLR(tp
->t_state
, TS_CONNECTED
);
1558 if (tp
->t_session
&& tp
->t_session
->s_leader
)
1559 psignal(tp
->t_session
->s_leader
, SIGHUP
);
1560 ttyflush(tp
, FREAD
| FWRITE
);
1561 thread_funnel_set(kernel_flock
, funnel_state
);
1568 SET(tp
->t_state
, TS_CARR_ON
);
1569 if (!ISSET(tp
->t_state
, TS_ZOMBIE
))
1570 SET(tp
->t_state
, TS_CONNECTED
);
1571 wakeup(TSA_CARR_ON(tp
));
1575 thread_funnel_set(kernel_flock
, funnel_state
);
1580 * Reinput pending characters after state switch
1585 register struct tty
*tp
;
1590 CLR(tp
->t_lflag
, PENDIN
);
1591 SET(tp
->t_state
, TS_TYPEN
);
1594 * XXX this assumes too much about clist internals. It may even
1595 * fail if the cblock slush pool is empty. We can't allocate more
1596 * cblocks here because we are called from an interrupt handler
1597 * and clist_alloc_cblocks() can wait.
1600 bzero(&tp
->t_rawq
, sizeof tp
->t_rawq
);
1601 tp
->t_rawq
.c_cbmax
= tq
.c_cbmax
;
1602 tp
->t_rawq
.c_cbreserved
= tq
.c_cbreserved
;
1605 tp
->t_rawq
.c_cc
= 0;
1606 tp
->t_rawq
.c_cf
= tp
->t_rawq
.c_cl
= 0;
1608 while ((c
= getc(&tq
)) >= 0)
1610 CLR(tp
->t_state
, TS_TYPEN
);
1614 * Process a read call on a tty device.
1617 ttread(tp
, uio
, flag
)
1618 register struct tty
*tp
;
1622 register struct clist
*qp
;
1624 register tcflag_t lflag
;
1625 register cc_t
*cc
= tp
->t_cc
;
1626 register struct proc
*p
= current_proc();
1627 int s
, first
, error
= 0;
1628 int has_etime
= 0, last_cc
= 0;
1629 long slp
= 0; /* XXX this should be renamed `timo'. */
1630 boolean_t funnel_state
;
1633 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
1635 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
1639 lflag
= tp
->t_lflag
;
1641 * take pending input first
1643 if (ISSET(lflag
, PENDIN
)) {
1645 splx(s
); /* reduce latency */
1647 lflag
= tp
->t_lflag
; /* XXX ttypend() clobbers it */
1651 * Hang process if it's in the background.
1653 if (isbackground(p
, tp
)) {
1655 if ((p
->p_sigignore
& sigmask(SIGTTIN
)) ||
1656 (ut
->uu_sigmask
& sigmask(SIGTTIN
)) ||
1657 p
->p_flag
& P_PPWAIT
|| p
->p_pgrp
->pg_jobc
== 0) {
1658 thread_funnel_set(kernel_flock
, funnel_state
);
1661 pgsignal(p
->p_pgrp
, SIGTTIN
, 1);
1662 error
= ttysleep(tp
, &lbolt
, TTIPRI
| PCATCH
| PTTYBLOCK
, "ttybg2", 0);
1664 thread_funnel_set(kernel_flock
, funnel_state
);
1670 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
1672 thread_funnel_set(kernel_flock
, funnel_state
);
1673 return (0); /* EOF */
1677 * If canonical, use the canonical queue,
1678 * else use the raw queue.
1680 * (should get rid of clists...)
1682 qp
= ISSET(lflag
, ICANON
) ? &tp
->t_canq
: &tp
->t_rawq
;
1684 if (flag
& IO_NDELAY
) {
1687 if (!ISSET(lflag
, ICANON
) && cc
[VMIN
] == 0) {
1689 thread_funnel_set(kernel_flock
, funnel_state
);
1693 thread_funnel_set(kernel_flock
, funnel_state
);
1694 return (EWOULDBLOCK
);
1696 if (!ISSET(lflag
, ICANON
)) {
1699 struct timeval etime
, timecopy
;
1702 * Check each of the four combinations.
1703 * (m > 0 && t == 0) is the normal read case.
1704 * It should be fairly efficient, so we check that and its
1705 * companion case (m == 0 && t == 0) first.
1706 * For the other two cases, we compute the target sleep time
1715 /* m, t and qp->c_cc are all 0. 0 is enough input. */
1717 thread_funnel_set(kernel_flock
, funnel_state
);
1720 t
*= 100000; /* time in us */
1721 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1722 ((t1).tv_usec - (t2).tv_usec))
1728 microuptime(&timecopy
);
1730 /* first character, start timer */
1733 etime
.tv_sec
= t
/ 1000000;
1734 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
1735 timeradd(&etime
, &timecopy
, &etime
);
1738 } else if (qp
->c_cc
> last_cc
) {
1739 /* got a character, restart timer */
1741 etime
.tv_sec
= t
/ 1000000;
1742 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
1743 timeradd(&etime
, &timecopy
, &etime
);
1747 /* nothing, check expiration */
1748 if (timercmp(&etime
, &timecopy
, <=))
1751 slp
= diff(etime
, timecopy
);
1754 } else { /* m == 0 */
1757 microuptime(&timecopy
);
1761 etime
.tv_sec
= t
/ 1000000;
1762 etime
.tv_usec
= (t
- (etime
.tv_sec
* 1000000));
1763 timeradd(&etime
, &timecopy
, &etime
);
1767 if (timercmp(&etime
, &timecopy
, <=)) {
1768 /* Timed out, but 0 is enough input. */
1770 thread_funnel_set(kernel_flock
, funnel_state
);
1773 slp
= diff(etime
, timecopy
);
1778 * Rounding down may make us wake up just short
1779 * of the target, so we round up.
1780 * The formula is ceiling(slp * hz/1000000).
1781 * 32-bit arithmetic is enough for hz < 169.
1782 * XXX see hzto() for how to avoid overflow if hz
1783 * is large (divide by `tick' and/or arrange to
1784 * use hzto() if hz is large).
1786 slp
= (long) (((u_long
)slp
* hz
) + 999999) / 1000000;
1789 if (qp
->c_cc
<= 0) {
1792 * There is no input, or not enough input and we can block.
1794 error
= ttysleep(tp
, TSA_HUP_OR_INPUT(tp
), TTIPRI
| PCATCH
,
1795 ISSET(tp
->t_state
, TS_CONNECTED
) ?
1796 "ttyin" : "ttyhup", (int)slp
);
1798 if (error
== EWOULDBLOCK
)
1801 thread_funnel_set(kernel_flock
, funnel_state
);
1805 * XXX what happens if another process eats some input
1806 * while we are asleep (not just here)? It would be
1807 * safest to detect changes and reset our state variables
1808 * (has_stime and last_cc).
1816 * Input present, check for input mapping and processing.
1820 if (ISSET(lflag
, ICANON
)
1821 || (ISSET(lflag
, IEXTEN
| ISIG
) == (IEXTEN
| ISIG
)) )
1823 if (ISSET(lflag
, ICANON
| ISIG
))
1830 icc
= min(uio_resid(uio
), IBUFSIZ
);
1831 icc
= q_to_b(qp
, ibuf
, icc
);
1837 error
= uiomove(ibuf
, icc
, uio
);
1839 * XXX if there was an error then we should ungetc() the
1840 * unmoved chars and reduce icc here.
1843 if (ISSET(tp
->t_lflag
, ECHO
) &&
1844 ISSET(tp
->t_state
, TS_SNOOP
) && tp
->t_sc
!= NULL
)
1845 snpin((struct snoop
*)tp
->t_sc
, ibuf
, icc
);
1849 if (uio_resid(uio
) == 0)
1863 * delayed suspend (^Y)
1865 if (CCEQ(cc
[VDSUSP
], c
) &&
1866 ISSET(lflag
, IEXTEN
| ISIG
) == (IEXTEN
| ISIG
)) {
1867 pgsignal(tp
->t_pgrp
, SIGTSTP
, 1);
1869 error
= ttysleep(tp
, &lbolt
, TTIPRI
| PCATCH
,
1878 * Interpret EOF only in canonical mode.
1880 if (CCEQ(cc
[VEOF
], c
) && ISSET(lflag
, ICANON
))
1883 * Give user character.
1885 error
= ureadc(c
, uio
);
1887 /* XXX should ungetc(c, qp). */
1891 * Only snoop directly on input in echo mode. Non-echoed
1892 * input will be snooped later iff the application echoes it.
1894 if (ISSET(tp
->t_lflag
, ECHO
) &&
1895 ISSET(tp
->t_state
, TS_SNOOP
) && tp
->t_sc
!= NULL
)
1896 snpinc((struct snoop
*)tp
->t_sc
, (char)c
);
1898 if (uio_resid(uio
) == 0)
1901 * In canonical mode check for a "break character"
1902 * marking the end of a "line of input".
1904 if (ISSET(lflag
, ICANON
) && TTBREAKC(c
, lflag
))
1911 * Look to unblock input now that (presumably)
1912 * the input queue has gone down.
1915 if (ISSET(tp
->t_state
, TS_TBLOCK
) &&
1916 tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
<= I_LOW_WATER
)
1920 thread_funnel_set(kernel_flock
, funnel_state
);
1925 * Check the output queue on tp for space for a kernel message (from uprintf
1926 * or tprintf). Allow some space over the normal hiwater mark so we don't
1927 * lose messages due to normal flow control, but don't let the tty run amok.
1928 * Sleeps here are not interruptible, but we return prematurely if new signals
1932 ttycheckoutq(tp
, wait
)
1933 register struct tty
*tp
;
1940 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
1942 hiwat
= tp
->t_hiwat
;
1944 oldsig
= wait
? ut
->uu_siglist
: 0;
1945 if (tp
->t_outq
.c_cc
> hiwat
+ OBUFSIZ
+ 100)
1946 while (tp
->t_outq
.c_cc
> hiwat
) {
1948 if (tp
->t_outq
.c_cc
<= hiwat
)
1950 if (wait
== 0 || ut
->uu_siglist
!= oldsig
) {
1954 SET(tp
->t_state
, TS_SO_OLOWAT
);
1955 tsleep(TSA_OLOWAT(tp
), PZERO
- 1, "ttoutq", hz
);
1962 * Process a write call on a tty device.
1965 ttwrite(tp
, uio
, flag
)
1966 register struct tty
*tp
;
1967 register struct uio
*uio
;
1970 register char *cp
= NULL
;
1971 register int cc
, ce
;
1972 register struct proc
*p
;
1973 int i
, hiwat
, count
, error
, s
;
1975 boolean_t funnel_state
;
1978 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
1980 ut
= (struct uthread
*)get_bsdthread_info(current_thread());
1981 hiwat
= tp
->t_hiwat
;
1982 // LP64todo - fix this!
1983 count
= uio_resid(uio
);
1988 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) {
1990 if (uio_resid(uio
) == count
)
1994 if (!ISSET(tp
->t_state
, TS_CONNECTED
)) {
1995 if (flag
& IO_NDELAY
) {
1997 error
= EWOULDBLOCK
;
2000 error
= ttysleep(tp
, TSA_CARR_ON(tp
), TTIPRI
| PCATCH
,
2009 * Hang the process if it's in the background.
2012 if (isbackground(p
, tp
) &&
2013 ISSET(tp
->t_lflag
, TOSTOP
) && (p
->p_flag
& P_PPWAIT
) == 0 &&
2014 (p
->p_sigignore
& sigmask(SIGTTOU
)) == 0 &&
2015 (ut
->uu_sigmask
& sigmask(SIGTTOU
)) == 0) {
2016 if (p
->p_pgrp
->pg_jobc
== 0) {
2020 pgsignal(p
->p_pgrp
, SIGTTOU
, 1);
2021 error
= ttysleep(tp
, &lbolt
, TTIPRI
| PCATCH
| PTTYBLOCK
, "ttybg4", 0);
2027 * Process the user's data in at most OBUFSIZ chunks. Perform any
2028 * output translation. Keep track of high water mark, sleep on
2029 * overflow awaiting device aid in acquiring new space.
2031 while (uio_resid(uio
) > 0 || cc
> 0) {
2032 if (ISSET(tp
->t_lflag
, FLUSHO
)) {
2033 uio_setresid(uio
, 0);
2034 thread_funnel_set(kernel_flock
, funnel_state
);
2037 if (tp
->t_outq
.c_cc
> hiwat
)
2040 * Grab a hunk of data from the user, unless we have some
2041 * leftover from last time.
2044 cc
= min(uio_resid(uio
), OBUFSIZ
);
2046 error
= uiomove(cp
, cc
, uio
);
2052 if (ISSET(tp
->t_state
, TS_SNOOP
) && tp
->t_sc
!= NULL
)
2053 snpin((struct snoop
*)tp
->t_sc
, cp
, cc
);
2057 * If nothing fancy need be done, grab those characters we
2058 * can handle without any of ttyoutput's processing and
2059 * just transfer them to the output q. For those chars
2060 * which require special processing (as indicated by the
2061 * bits in char_type), call ttyoutput. After processing
2062 * a hunk of data, look for FLUSHO so ^O's will take effect
2066 if (!ISSET(tp
->t_oflag
, OPOST
))
2069 ce
= cc
- scanc((u_int
)cc
, (u_char
*)cp
,
2070 char_type
, CCLASSMASK
);
2072 * If ce is zero, then we're processing
2073 * a special character through ttyoutput.
2077 if (ttyoutput(*cp
, tp
) >= 0) {
2082 /* No Clists, wait a bit. */
2084 if (flag
& IO_NDELAY
) {
2085 error
= EWOULDBLOCK
;
2088 error
= ttysleep(tp
, &lbolt
,
2098 if (ISSET(tp
->t_lflag
, FLUSHO
) ||
2099 tp
->t_outq
.c_cc
> hiwat
)
2105 * A bunch of normal characters have been found.
2106 * Transfer them en masse to the output queue and
2107 * continue processing at the top of the loop.
2108 * If there are any further characters in this
2109 * <= OBUFSIZ chunk, the first should be a character
2110 * requiring special handling by ttyoutput.
2113 i
= b_to_q(cp
, ce
, &tp
->t_outq
);
2116 cp
+= ce
, cc
-= ce
, tk_nout
+= ce
;
2123 /* No Clists, wait a bit. */
2125 if (flag
& IO_NDELAY
) {
2126 error
= EWOULDBLOCK
;
2129 error
= ttysleep(tp
, &lbolt
, TTOPRI
| PCATCH
,
2136 if (ISSET(tp
->t_lflag
, FLUSHO
) ||
2137 tp
->t_outq
.c_cc
> hiwat
)
2144 * If cc is nonzero, we leave the uio structure inconsistent, as the
2145 * offset and iov pointers have moved forward, but it doesn't matter
2146 * (the call will either return short or restart with a new uio).
2148 uio_setresid(uio
, (uio_resid(uio
) + cc
));
2149 thread_funnel_set(kernel_flock
, funnel_state
);
2156 * Since we are using ring buffers, if we can't insert any more into
2157 * the output queue, we can assume the ring is full and that someone
2158 * forgot to set the high water mark correctly. We set it and then
2159 * proceed as normal.
2161 hiwat
= tp
->t_outq
.c_cc
- 1;
2168 * This can only occur if FLUSHO is set in t_lflag,
2169 * or if ttstart/oproc is synchronous (or very fast).
2171 if (tp
->t_outq
.c_cc
<= hiwat
) {
2175 if (flag
& IO_NDELAY
) {
2177 uio_setresid(uio
, (uio_resid(uio
) + cc
));
2178 thread_funnel_set(kernel_flock
, funnel_state
);
2179 return (uio_resid(uio
) == count
? EWOULDBLOCK
: 0);
2181 SET(tp
->t_state
, TS_SO_OLOWAT
);
2182 error
= ttysleep(tp
, TSA_OLOWAT(tp
), TTOPRI
| PCATCH
, "ttywri",
2185 if (error
== EWOULDBLOCK
)
2193 * Rubout one character from the rawq of tp
2194 * as cleanly as possible.
2199 register struct tty
*tp
;
2201 register u_char
*cp
;
2202 register int savecol
;
2205 if (!ISSET(tp
->t_lflag
, ECHO
) || ISSET(tp
->t_lflag
, EXTPROC
))
2207 CLR(tp
->t_lflag
, FLUSHO
);
2208 if (ISSET(tp
->t_lflag
, ECHOE
)) {
2209 if (tp
->t_rocount
== 0) {
2211 * Messed up by ttwrite; retype
2216 if (c
== ('\t' | TTY_QUOTE
) || c
== ('\n' | TTY_QUOTE
))
2219 CLR(c
, ~TTY_CHARMASK
);
2220 switch (CCLASS(c
)) {
2229 if (ISSET(tp
->t_lflag
, ECHOCTL
))
2233 if (tp
->t_rocount
< tp
->t_rawq
.c_cc
) {
2238 savecol
= tp
->t_column
;
2239 SET(tp
->t_state
, TS_CNTTB
);
2240 SET(tp
->t_lflag
, FLUSHO
);
2241 tp
->t_column
= tp
->t_rocol
;
2243 cp
= tp
->t_rawq
.c_cf
;
2245 tabc
= *cp
; /* XXX FIX NEXTC */
2246 for (; cp
; cp
= nextc(&tp
->t_rawq
, cp
, &tabc
))
2249 for (cp
= firstc(&tp
->t_rawq
, &tabc
); cp
;
2250 cp
= nextc(&tp
->t_rawq
, cp
, &tabc
))
2253 CLR(tp
->t_lflag
, FLUSHO
);
2254 CLR(tp
->t_state
, TS_CNTTB
);
2257 /* savecol will now be length of the tab. */
2258 savecol
-= tp
->t_column
;
2259 tp
->t_column
+= savecol
;
2261 savecol
= 8; /* overflow fixup */
2262 while (--savecol
>= 0)
2263 (void)ttyoutput('\b', tp
);
2266 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
2267 (void)printf(PANICSTR
, c
, CCLASS(c
));
2269 panic(PANICSTR
, c
, CCLASS(c
));
2273 } else if (ISSET(tp
->t_lflag
, ECHOPRT
)) {
2274 if (!ISSET(tp
->t_state
, TS_ERASE
)) {
2275 SET(tp
->t_state
, TS_ERASE
);
2276 (void)ttyoutput('\\', tp
);
2280 ttyecho(tp
->t_cc
[VERASE
], tp
);
2285 * Back over count characters, erasing them.
2288 ttyrubo(struct tty
*tp
, int count
)
2291 while (count
-- > 0) {
2292 (void)ttyoutput('\b', tp
);
2293 (void)ttyoutput(' ', tp
);
2294 (void)ttyoutput('\b', tp
);
2300 * Reprint the rawq line. Note, it is assumed that c_cc has already
2305 register struct tty
*tp
;
2307 register u_char
*cp
;
2310 /* Echo the reprint character. */
2311 if (tp
->t_cc
[VREPRINT
] != _POSIX_VDISABLE
)
2312 ttyecho(tp
->t_cc
[VREPRINT
], tp
);
2314 (void)ttyoutput('\n', tp
);
2318 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2319 * BIT OF FIRST CHAR.
2323 for (cp
= tp
->t_canq
.c_cf
, c
= (cp
!= NULL
? *cp
: 0);
2324 cp
!= NULL
; cp
= nextc(&tp
->t_canq
, cp
, &c
))
2326 for (cp
= tp
->t_rawq
.c_cf
, c
= (cp
!= NULL
? *cp
: 0);
2327 cp
!= NULL
; cp
= nextc(&tp
->t_rawq
, cp
, &c
))
2330 for (cp
= firstc(&tp
->t_canq
, &c
); cp
; cp
= nextc(&tp
->t_canq
, cp
, &c
))
2332 for (cp
= firstc(&tp
->t_rawq
, &c
); cp
; cp
= nextc(&tp
->t_rawq
, cp
, &c
))
2335 CLR(tp
->t_state
, TS_ERASE
);
2338 tp
->t_rocount
= tp
->t_rawq
.c_cc
;
2343 * Echo a typed character to the terminal.
2348 register struct tty
*tp
;
2351 if (!ISSET(tp
->t_state
, TS_CNTTB
))
2352 CLR(tp
->t_lflag
, FLUSHO
);
2353 if ((!ISSET(tp
->t_lflag
, ECHO
) &&
2354 (c
!= '\n' || !ISSET(tp
->t_lflag
, ECHONL
))) ||
2355 ISSET(tp
->t_lflag
, EXTPROC
))
2357 if (ISSET(tp
->t_lflag
, ECHOCTL
) &&
2358 ((ISSET(c
, TTY_CHARMASK
) <= 037 && c
!= '\t' && c
!= '\n') ||
2359 ISSET(c
, TTY_CHARMASK
) == 0177)) {
2360 (void)ttyoutput('^', tp
);
2361 CLR(c
, ~TTY_CHARMASK
);
2367 (void)ttyoutput(c
, tp
);
2371 * Wake up any readers on a tty.
2375 register struct tty
*tp
;
2379 if (tp
->t_rsel
.si_pid
!= 0)
2381 selwakeup(&tp
->t_rsel
);
2382 if (ISSET(tp
->t_state
, TS_ASYNC
))
2383 pgsignal(tp
->t_pgrp
, SIGIO
, 1);
2384 wakeup(TSA_HUP_OR_INPUT(tp
));
2388 * Wake up any writers on a tty.
2392 register struct tty
*tp
;
2395 if (tp
->t_wsel
.si_pid
!= 0 && tp
->t_outq
.c_cc
<= tp
->t_lowat
)
2397 if (tp
->t_outq
.c_cc
<= tp
->t_lowat
)
2399 selwakeup(&tp
->t_wsel
);
2400 if (ISSET(tp
->t_state
, TS_BUSY
| TS_SO_OCOMPLETE
) ==
2401 TS_SO_OCOMPLETE
&& tp
->t_outq
.c_cc
== 0) {
2402 CLR(tp
->t_state
, TS_SO_OCOMPLETE
);
2403 wakeup(TSA_OCOMPLETE(tp
));
2405 if (ISSET(tp
->t_state
, TS_SO_OLOWAT
) &&
2406 tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
2407 CLR(tp
->t_state
, TS_SO_OLOWAT
);
2408 wakeup(TSA_OLOWAT(tp
));
2413 * Look up a code for a specified speed in a conversion table;
2414 * used by drivers to map software speed values to hardware parameters.
2417 ttspeedtab(speed
, table
)
2419 register struct speedtab
*table
;
2422 for ( ; table
->sp_speed
!= -1; table
++)
2423 if (table
->sp_speed
== speed
)
2424 return (table
->sp_code
);
2429 * Set tty hi and low water marks.
2431 * Try to arrange the dynamics so there's about one second
2432 * from hi to low water.
2436 ttsetwater(struct tty
*tp
)
2441 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2443 cps
= tp
->t_ospeed
/ 10;
2444 tp
->t_lowat
= x
= CLAMP(cps
/ 2, TTMAXLOWAT
, TTMINLOWAT
);
2446 x
= CLAMP(x
, TTMAXHIWAT
, TTMINHIWAT
);
2447 tp
->t_hiwat
= roundup(x
, CBSIZE
);
2451 /* NeXT ttyinfo has been converted to the MACH kernel */
2452 #include <mach/thread_info.h>
2454 /* XXX Should be in Mach header <kern/thread.h>, but doesn't work */
2455 extern kern_return_t
thread_info_internal(thread_t thread
,
2456 thread_flavor_t flavor
,
2457 thread_info_t thread_info_out
,
2458 mach_msg_type_number_t
*thread_info_count
);
2461 * Report on state of foreground process group.
2464 ttyinfo(struct tty
*tp
)
2472 struct timeval utime
;
2473 struct timeval stime
;
2474 thread_basic_info_data_t basic_info
;
2475 mach_msg_type_number_t mmtn
= THREAD_BASIC_INFO_COUNT
;
2477 if (ttycheckoutq(tp
,0) == 0)
2480 /* Print load average. */
2481 load
= (averunnable
.ldavg
[0] * 100 + FSCALE
/ 2) >> FSHIFT
;
2482 ttyprintf(tp
, "load: %d.%02d ", load
/ 100, load
% 100);
2485 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
2486 * that pending input will be retyped on BS.
2488 if (tp
->t_session
== NULL
) {
2489 ttyprintf(tp
, "not a controlling terminal\n");
2493 if (tp
->t_pgrp
== NULL
) {
2494 ttyprintf(tp
, "no foreground process group\n");
2498 /* first process in process group */
2499 if ((p
= tp
->t_pgrp
->pg_members
.lh_first
) == NULL
) {
2500 ttyprintf(tp
, "empty foreground process group\n");
2506 * Pick the most interesting process and copy some of its
2507 * state for printing later.
2509 for (pick
= NULL
; p
!= NULL
; p
= p
->p_pglist
.le_next
) {
2510 if (proc_compare(pick
, p
))
2514 if (TAILQ_EMPTY(&pick
->p_uthlist
) ||
2515 (uthread
= TAILQ_FIRST(&pick
->p_uthlist
)) == NULL
||
2516 (thread
= uthread
->uu_act
) == NULL
||
2517 (thread_info_internal(thread
, THREAD_BASIC_INFO
, (thread_info_t
)&basic_info
, &mmtn
) != KERN_SUCCESS
)) {
2518 ttyprintf(tp
, "foreground process without thread\n");
2523 switch(basic_info
.run_state
) {
2524 case TH_STATE_RUNNING
:
2527 case TH_STATE_STOPPED
:
2530 case TH_STATE_WAITING
:
2533 case TH_STATE_UNINTERRUPTIBLE
:
2534 state
= "uninterruptible";
2536 case TH_STATE_HALTED
:
2543 calcru(pick
, &utime
, &stime
, NULL
);
2545 /* Print command, pid, state, utime, and stime */
2546 ttyprintf(tp
, " cmd: %s %d %s %ld.%02ldu %ld.%02lds\n",
2550 (long)utime
.tv_sec
, utime
.tv_usec
/ 10000,
2551 (long)stime
.tv_sec
, stime
.tv_usec
/ 10000);
2556 * Returns 1 if p2 is "better" than p1
2558 * The algorithm for picking the "interesting" process is thus:
2560 * 1) Only foreground processes are eligible - implied.
2561 * 2) Runnable processes are favored over anything else. The runner
2562 * with the highest cpu utilization is picked (p_estcpu). Ties are
2563 * broken by picking the highest pid.
2564 * 3) The sleeper with the shortest sleep time is next.
2565 * 4) Further ties are broken by picking the highest pid.
2567 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
2568 #define TESTAB(a, b) ((a)<<1 | (b))
2574 proc_compare(p1
, p2
)
2575 register struct proc
*p1
, *p2
;
2581 * see if at least one of them is runnable
2583 switch (TESTAB(ISRUN(p1
), ISRUN(p2
))) {
2590 * tie - favor one with highest recent cpu utilization
2592 if (p2
->p_estcpu
> p1
->p_estcpu
)
2594 if (p1
->p_estcpu
> p2
->p_estcpu
)
2596 return (p2
->p_pid
> p1
->p_pid
); /* tie - return highest pid */
2601 switch (TESTAB(p1
->p_stat
== SZOMB
, p2
->p_stat
== SZOMB
)) {
2607 return (p2
->p_pid
> p1
->p_pid
); /* tie - return highest pid */
2610 * pick the one with the smallest sleep time
2612 if (p2
->p_slptime
> p1
->p_slptime
)
2614 if (p1
->p_slptime
> p2
->p_slptime
)
2616 return (p2
->p_pid
> p1
->p_pid
); /* tie - return highest pid */
2620 * Output char to tty; console putchar style.
2630 if (!ISSET(tp
->t_state
, TS_CONNECTED
)) {
2635 (void)ttyoutput('\r', tp
);
2636 (void)ttyoutput(c
, tp
);
2643 * Sleep on chan, returning ERESTART if tty changed while we napped and
2644 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep. If
2645 * the tty is revoked, restarting a pending call will redo validation done
2646 * at the start of the call.
2649 ttysleep(struct tty
*tp
, void *chan
, int pri
, const char *wmesg
, int timo
)
2655 error
= tsleep(chan
, pri
, wmesg
, timo
);
2658 return (tp
->t_gen
== gen
? 0 : ERESTART
);
2663 * Allocate a tty structure and its associated buffers.
2670 MALLOC(tp
, struct tty
*, sizeof(struct tty
), M_TTYS
, M_WAITOK
|M_ZERO
);
2672 /* XXX: default to TTYCLSIZE(1024) chars for now */
2673 clalloc(&tp
->t_rawq
, TTYCLSIZE
, 1);
2674 clalloc(&tp
->t_canq
, TTYCLSIZE
, 1);
2675 /* output queue doesn't need quoting */
2676 clalloc(&tp
->t_outq
, TTYCLSIZE
, 0);
2682 * Free a tty structure and its buffers.
2688 clfree(&tp
->t_rawq
);
2689 clfree(&tp
->t_canq
);
2690 clfree(&tp
->t_outq
);
2698 * XXX this is usable not useful or used. Most tty drivers have
2699 * ifdefs for using ttymalloc() but assume a different interface.
2702 * Allocate a tty struct. Clists in the struct will be allocated by
2710 MALLOC(tp
, struct tty
*, sizeof *tp
, M_TTYS
, M_WAITOK
|M_ZERO
);
2715 #if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */
2717 * Free a tty struct. Clists in the struct should have been freed by