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
);