2  * Copyright (c) 1997-2010 Apple Computer, 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, 1989, 1993 
  30  *      The Regents of the University of California.  All rights reserved. 
  32  * Redistribution and use in source and binary forms, with or without 
  33  * modification, are permitted provided that the following conditions 
  35  * 1. Redistributions of source code must retain the above copyright 
  36  *    notice, this list of conditions and the following disclaimer. 
  37  * 2. Redistributions in binary form must reproduce the above copyright 
  38  *    notice, this list of conditions and the following disclaimer in the 
  39  *    documentation and/or other materials provided with the distribution. 
  40  * 3. All advertising materials mentioning features or use of this software 
  41  *    must display the following acknowledgement: 
  42  *      This product includes software developed by the University of 
  43  *      California, Berkeley and its contributors. 
  44  * 4. Neither the name of the University nor the names of its contributors 
  45  *    may be used to endorse or promote products derived from this software 
  46  *    without specific prior written permission. 
  48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  60  *      @(#)tty_pty.c   8.4 (Berkeley) 2/20/95 
  64  * Pseudo-teletype Driver 
  65  * (Actually two drivers, requiring two entries in 'cdevsw') 
  67 #include "pty.h"                /* XXX */ 
  69 #include <sys/param.h> 
  70 #include <sys/systm.h> 
  71 #include <sys/ioctl.h> 
  72 #include <sys/proc_internal.h> 
  73 #include <sys/kauth.h> 
  76 #include <sys/file_internal.h> 
  77 #include <sys/uio_internal.h> 
  78 #include <sys/kernel.h> 
  79 #include <sys/vnode.h> 
  80 #include <sys/vnode_internal.h>         /* _devfs_setattr() */ 
  81 #include <sys/stat.h>                   /* _devfs_setattr() */ 
  83 #include <sys/signalvar.h> 
  84 #include <sys/sysctl.h> 
  85 #include <miscfs/devfs/devfs.h> 
  86 #include <miscfs/devfs/devfsdefs.h>     /* DEVFS_LOCK()/DEVFS_UNLOCK() */ 
  89 #include <security/mac_framework.h> 
  92 /* XXX belongs in devfs somewhere - LATER */ 
  93 int _devfs_setattr(void *, unsigned short, uid_t
, gid_t
); 
  96 #define FREE_BSDSTATIC __private_extern__ 
  97 #define d_devtotty_t    struct tty ** 
 100  * Forward declarations 
 102 int ptmx_init(int n_ptys
); 
 103 static void ptsd_start(struct tty 
*tp
); 
 104 static void ptmx_wakeup(struct tty 
*tp
, int flag
); 
 105 __XNU_PRIVATE_EXTERN    d_open_t        ptsd_open
; 
 106 __XNU_PRIVATE_EXTERN    d_close_t       ptsd_close
; 
 107 __XNU_PRIVATE_EXTERN    d_read_t        ptsd_read
; 
 108 __XNU_PRIVATE_EXTERN    d_write_t       ptsd_write
; 
 109 __XNU_PRIVATE_EXTERN    d_ioctl_t       cptyioctl
;      /* common ioctl */ 
 110 __XNU_PRIVATE_EXTERN    d_stop_t        ptsd_stop
; 
 111 __XNU_PRIVATE_EXTERN    d_reset_t       ptsd_reset
; 
 112 __XNU_PRIVATE_EXTERN    d_open_t        ptmx_open
; 
 113 __XNU_PRIVATE_EXTERN    d_close_t       ptmx_close
; 
 114 __XNU_PRIVATE_EXTERN    d_read_t        ptmx_read
; 
 115 __XNU_PRIVATE_EXTERN    d_write_t       ptmx_write
; 
 116 __XNU_PRIVATE_EXTERN    d_stop_t        ptmx_stop
;      /* NO-OP */ 
 117 __XNU_PRIVATE_EXTERN    d_reset_t       ptmx_reset
; 
 118 __XNU_PRIVATE_EXTERN    d_select_t      ptmx_select
; 
 119 __XNU_PRIVATE_EXTERN    d_select_t      ptsd_select
; 
 121 extern  d_devtotty_t    ptydevtotty
; 
 123 static int ptmx_major
;          /* dynamically assigned major number */ 
 124 static struct cdevsw ptmx_cdev 
= { 
 125         ptmx_open
,      ptmx_close
,     ptmx_read
,      ptmx_write
, 
 126         cptyioctl
,      ptmx_stop
,      ptmx_reset
,     0, 
 127         ptmx_select
,    eno_mmap
,       eno_strat
,      eno_getc
, 
 131 static int ptsd_major
;          /* dynamically assigned major number */ 
 132 static struct cdevsw ptsd_cdev 
= { 
 133         ptsd_open
,      ptsd_close
,     ptsd_read
,      ptsd_write
, 
 134         cptyioctl
,      ptsd_stop
,      ptsd_reset
,     0, 
 135         ptsd_select
,    eno_mmap
,       eno_strat
,      eno_getc
, 
 140  * XXX Should be devfs function... and use VATTR mechanisms, per 
 141  * XXX vnode_setattr2(); only we maybe can't really get back to the 
 142  * XXX vnode here for cloning devices (but it works for *cloned* devices 
 143  * XXX that are not themselves cloning). 
 150 _devfs_setattr(void * handle
, unsigned short mode
, uid_t uid
, gid_t gid
) 
 152         devdirent_t             
*direntp 
= (devdirent_t 
*)handle
; 
 155         vfs_context_t           ctx 
= vfs_context_current();; 
 156         struct vnode_attr       va
; 
 159         VATTR_SET(&va
, va_uid
, uid
); 
 160         VATTR_SET(&va
, va_gid
, gid
); 
 161         VATTR_SET(&va
, va_mode
, mode 
& ALLPERMS
); 
 164          * If the TIOCPTYGRANT loses the race with the clone operation because 
 165          * this function is not part of devfs, and therefore can't take the 
 166          * devfs lock to protect the direntp update, then force user space to 
 167          * redrive the grant request. 
 169         if (direntp 
== NULL 
|| (devnodep 
= direntp
->de_dnp
) == NULL
) { 
 175          * Only do this if we are operating on device that doesn't clone 
 176          * each time it's referenced.  We perform a lookup on the device 
 177          * to insure we get the right instance.  We can't just use the call 
 178          * to devfs_dntovn() to get the vp for the operation, because 
 179          * dn_dvm may not have been initialized. 
 181         if (devnodep
->dn_clone 
== NULL
) { 
 185                 snprintf(name
, sizeof(name
), "/dev/%s", direntp
->de_name
); 
 186                 NDINIT(&nd
, LOOKUP
, OP_SETATTR
, FOLLOW
, UIO_SYSSPACE
, CAST_USER_ADDR_T(name
), ctx
); 
 190                 error 
= vnode_setattr(nd
.ni_vp
, &va
, ctx
); 
 202 #define BUFSIZ 100              /* Chunk size iomoved to/from user */ 
 206  * ptsd == /dev/pts[0123456789]{3} 
 208 #define PTMX_TEMPLATE   "ptmx" 
 209 #define PTSD_TEMPLATE   "ttys%03d" 
 212  * System-wide limit on the max number of cloned ptys 
 214 #define PTMX_MAX_DEFAULT        127     /* 128 entries */ 
 215 #define PTMX_MAX_HARD           999     /* 1000 entries, due to PTSD_TEMPLATE */ 
 217 static int ptmx_max 
= PTMX_MAX_DEFAULT
; /* default # of clones we allow */ 
 219 /* Range enforcement for the sysctl */ 
 221 sysctl_ptmx_max(__unused 
struct sysctl_oid 
*oidp
, __unused 
void *arg1
, 
 222                 __unused 
int arg2
, struct sysctl_req 
*req
) 
 224         int new_value
, changed
; 
 225         int error 
= sysctl_io_number(req
, ptmx_max
, sizeof(int), &new_value
, &changed
); 
 227                 if (new_value 
> 0 && new_value 
<= PTMX_MAX_HARD
) 
 228                         ptmx_max 
= new_value
; 
 235 SYSCTL_NODE(_kern
, KERN_TTY
, tty
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0, "TTY"); 
 236 SYSCTL_PROC(_kern_tty
, OID_AUTO
, ptmx_max
, 
 237                 CTLTYPE_INT 
| CTLFLAG_RW 
| CTLFLAG_LOCKED
, 
 238                 &ptmx_max
, 0, &sysctl_ptmx_max
, "I", "ptmx_max"); 
 242  * ptmx_ioctl is a pointer to a list of pointers to tty structures which is 
 243  * grown, as necessary, copied, and replaced, but never shrunk.  The ioctl 
 244  * structures themselves pointed to from this list come and go as needed. 
 247         struct tty      
*pt_tty
;        /* pointer to ttymalloc()'ed data */ 
 249         struct selinfo  pt_selr
; 
 250         struct selinfo  pt_selw
; 
 253         void            *pt_devhandle
;  /* cloned slave device handle */ 
 256 #define PF_PKT          0x0008          /* packet mode */ 
 257 #define PF_STOPPED      0x0010          /* user told stopped */ 
 258 #define PF_REMOTE       0x0020          /* remote and flow controlled input */ 
 259 #define PF_NOSTOP       0x0040 
 260 #define PF_UCNTL        0x0080          /* user control mode */ 
 261 #define PF_UNLOCKED     0x0100          /* slave unlock (master open resets) */ 
 262 #define PF_OPEN_M       0x0200          /* master is open */ 
 263 #define PF_OPEN_S       0x0400          /* slave is open */ 
 265 static int      ptmx_clone(dev_t dev
, int minor
); 
 268  * Set of locks to keep the interaction between kevents and revoke 
 269  * from causing havoc. 
 272 #define LOG2_PTSD_KE_NLCK       2 
 273 #define PTSD_KE_NLCK            (1l << LOG2_PTSD_KE_NLCK) 
 274 #define PTSD_KE_LOCK_INDEX(x)   ((x) & (PTSD_KE_NLCK - 1)) 
 276 static lck_mtx_t ptsd_kevent_lock
[PTSD_KE_NLCK
]; 
 279 ptsd_kevent_lock_init(void) 
 282         lck_grp_t 
*lgrp 
= lck_grp_alloc_init("ptsd kevent", LCK_GRP_ATTR_NULL
); 
 284         for (i 
= 0; i 
< PTSD_KE_NLCK
; i
++) 
 285                 lck_mtx_init(&ptsd_kevent_lock
[i
], lgrp
, LCK_ATTR_NULL
); 
 289 ptsd_kevent_mtx_lock(int minor
) 
 291         lck_mtx_lock(&ptsd_kevent_lock
[PTSD_KE_LOCK_INDEX(minor
)]); 
 295 ptsd_kevent_mtx_unlock(int minor
) 
 297         lck_mtx_unlock(&ptsd_kevent_lock
[PTSD_KE_LOCK_INDEX(minor
)]); 
 301 ptmx_init( __unused 
int config_count
) 
 304          * We start looking at slot 10, since there are inits that will 
 305          * stomp explicit slots (e.g. vndevice stomps 1) below that. 
 308         /* Get a major number for /dev/ptmx */ 
 309         if((ptmx_major 
= cdevsw_add(-15, &ptmx_cdev
)) == -1) { 
 310                 printf("ptmx_init: failed to obtain /dev/ptmx major number\n"); 
 314         if (cdevsw_setkqueueok(ptmx_major
, &ptmx_cdev
, 0) == -1) { 
 315                 panic("Failed to set flags on ptmx cdevsw entry."); 
 318         /* Get a major number for /dev/pts/nnn */ 
 319         if ((ptsd_major 
= cdevsw_add(-15, &ptsd_cdev
)) == -1) { 
 320                 (void)cdevsw_remove(ptmx_major
, &ptmx_cdev
); 
 321                 printf("ptmx_init: failed to obtain /dev/ptmx major number\n"); 
 325         if (cdevsw_setkqueueok(ptsd_major
, &ptsd_cdev
, 0) == -1) { 
 326                 panic("Failed to set flags on ptmx cdevsw entry."); 
 330          * Locks to guard against races between revoke and kevents 
 332         ptsd_kevent_lock_init(); 
 334         /* Create the /dev/ptmx device {<major>,0} */ 
 335         (void)devfs_make_node_clone(makedev(ptmx_major
, 0), 
 336                                 DEVFS_CHAR
, UID_ROOT
, GID_TTY
, 0666, 
 337                                 ptmx_clone
, PTMX_TEMPLATE
); 
 342 static struct _ptmx_ioctl_state 
{ 
 343         struct ptmx_ioctl       
**pis_ioctl_list
;       /* pointer vector */ 
 344         int                     pis_total
;              /* total slots */ 
 345         int                     pis_free
;               /* free slots */ 
 347 #define PTMX_GROW_VECTOR        16      /* Grow by this many slots at a time */ 
 350  * Given a minor number, return the corresponding structure for that minor 
 351  * number.  If there isn't one, and the create flag is specified, we create 
 354  * Parameters:  minor                   Minor number of ptmx device 
 355  *              open_flag               PF_OPEN_M       First open of master 
 356  *                                      PF_OPEN_S       First open of slave 
 357  *                                      0               Just want ioctl struct 
 359  * Returns:     NULL                    Did not exist/could not create 
 360  *              !NULL                   structure corresponding minor number 
 362  * Locks:       tty_lock() on ptmx_ioctl->pt_tty NOT held on entry or exit. 
 364 static struct ptmx_ioctl 
* 
 365 ptmx_get_ioctl(int minor
, int open_flag
) 
 367         struct ptmx_ioctl 
*new_ptmx_ioctl
; 
 369         if (open_flag 
& PF_OPEN_M
) { 
 372                  * If we are about to allocate more memory, but we have 
 373                  * already hit the administrative limit, then fail the 
 376                  * Note:        Subtract free from total when making this 
 377                  *              check to allow unit increments, rather than 
 378                  *              snapping to the nearest PTMX_GROW_VECTOR... 
 380                 if ((_state
.pis_total 
- _state
.pis_free
) >= ptmx_max
) { 
 384                 MALLOC(new_ptmx_ioctl
, struct ptmx_ioctl 
*, sizeof(struct ptmx_ioctl
), M_TTYS
, M_WAITOK
|M_ZERO
); 
 385                 if (new_ptmx_ioctl 
== NULL
) { 
 389                 if ((new_ptmx_ioctl
->pt_tty 
= ttymalloc()) == NULL
) { 
 390                         FREE(new_ptmx_ioctl
, M_TTYS
); 
 395                  * Hold the DEVFS_LOCK() over this whole operation; devfs 
 396                  * itself does this over malloc/free as well, so this should 
 397                  * be safe to do.  We hold it longer than we want to, but 
 398                  * doing so avoids a reallocation race on the minor number. 
 401                 /* Need to allocate a larger vector? */ 
 402                 if (_state
.pis_free 
== 0) { 
 403                         struct ptmx_ioctl 
**new_pis_ioctl_list
; 
 404                         struct ptmx_ioctl 
**old_pis_ioctl_list 
= NULL
; 
 407                         MALLOC(new_pis_ioctl_list
, struct ptmx_ioctl 
**, sizeof(struct ptmx_ioctl 
*) * (_state
.pis_total 
+ PTMX_GROW_VECTOR
), M_TTYS
, M_WAITOK
|M_ZERO
); 
 408                         if (new_pis_ioctl_list 
== NULL
) { 
 409                                 ttyfree(new_ptmx_ioctl
->pt_tty
); 
 411                                 FREE(new_ptmx_ioctl
, M_TTYS
); 
 415                         /* If this is not the first time, copy the old over */ 
 416                         bcopy(_state
.pis_ioctl_list
, new_pis_ioctl_list
, sizeof(struct ptmx_ioctl 
*) * _state
.pis_total
); 
 417                         old_pis_ioctl_list 
= _state
.pis_ioctl_list
; 
 418                         _state
.pis_ioctl_list 
= new_pis_ioctl_list
; 
 419                         _state
.pis_free 
+= PTMX_GROW_VECTOR
; 
 420                         _state
.pis_total 
+= PTMX_GROW_VECTOR
; 
 421                         if (old_pis_ioctl_list
) 
 422                                 FREE(old_pis_ioctl_list
, M_TTYS
); 
 425                 if (_state
.pis_ioctl_list
[minor
] != NULL
) { 
 426                         ttyfree(new_ptmx_ioctl
->pt_tty
); 
 428                         FREE(new_ptmx_ioctl
, M_TTYS
); 
 430                         /* Special error value so we know to redrive the open, we've been raced */ 
 431                         return (struct ptmx_ioctl
*)-1;  
 435                 /* Vector is large enough; grab a new ptmx_ioctl */ 
 437                 /* Now grab a free slot... */ 
 438                 _state
.pis_ioctl_list
[minor
] = new_ptmx_ioctl
; 
 440                 /* reduce free count */ 
 443                 _state
.pis_ioctl_list
[minor
]->pt_flags 
|= PF_OPEN_M
; 
 446                 /* Create the /dev/ttysXXX device {<major>,XXX} */ 
 447                 _state
.pis_ioctl_list
[minor
]->pt_devhandle 
= devfs_make_node( 
 448                                 makedev(ptsd_major
, minor
), 
 449                                 DEVFS_CHAR
, UID_ROOT
, GID_TTY
, 0620, 
 450                                 PTSD_TEMPLATE
, minor
); 
 451                 if (_state
.pis_ioctl_list
[minor
]->pt_devhandle 
== NULL
) { 
 452                         printf("devfs_make_node() call failed for ptmx_get_ioctl()!!!!\n"); 
 454         } else if (open_flag 
& PF_OPEN_S
) { 
 456                 _state
.pis_ioctl_list
[minor
]->pt_flags 
|= PF_OPEN_S
; 
 459         return (_state
.pis_ioctl_list
[minor
]); 
 463  * Locks:       tty_lock() of old_ptmx_ioctl->pt_tty NOT held for this call. 
 466 ptmx_free_ioctl(int minor
, int open_flag
) 
 468         struct ptmx_ioctl 
*old_ptmx_ioctl 
= NULL
; 
 471         _state
.pis_ioctl_list
[minor
]->pt_flags 
&= ~(open_flag
); 
 474          * Was this the last close?  We will recognize it because we only get 
 475          * a notification on the last close of a device, and we will have 
 476          * cleared both the master and the slave open bits in the flags. 
 478         if (!(_state
.pis_ioctl_list
[minor
]->pt_flags 
& (PF_OPEN_M
|PF_OPEN_S
))) { 
 479                 /* Mark as free so it can be reallocated later */ 
 480                 old_ptmx_ioctl 
= _state
.pis_ioctl_list
[ minor
]; 
 484         /* Free old after dropping lock */ 
 485         if (old_ptmx_ioctl 
!= NULL
) { 
 487                  * XXX See <rdar://5348651> and <rdar://4854638> 
 489                  * XXX Conditional to be removed when/if tty/pty reference 
 490                  * XXX counting and mutex implemented. 
 492                 if (old_ptmx_ioctl
->pt_devhandle 
!= NULL
) 
 493                         devfs_remove(old_ptmx_ioctl
->pt_devhandle
); 
 494                 ttyfree(old_ptmx_ioctl
->pt_tty
); 
 495                 FREE(old_ptmx_ioctl
, M_TTYS
); 
 497                 /* Don't remove the entry until the devfs slot is free */ 
 499                 _state
.pis_ioctl_list
[ minor
] = NULL
; 
 504         return (0);     /* Success */ 
 511  * Given the dev entry that's being opened, we clone the device.  This driver 
 512  * doesn't actually use the dev entry, since we alreaqdy know who we are by 
 513  * being called from this code.  This routine is a callback registered from 
 514  * devfs_make_node_clone() in ptmx_init(); it's purpose is to provide a new 
 515  * minor number, or to return -1, if one can't be provided. 
 517  * Parameters:  dev                     The device we are cloning from 
 519  * Returns:     >= 0                    A new minor device number 
 520  *              -1                      Error: ENOMEM ("Can't alloc device") 
 522  * NOTE:        Called with DEVFS_LOCK() held 
 525 ptmx_clone(__unused dev_t dev
, int action
) 
 529         if (action 
== DEVFS_CLONE_ALLOC
) { 
 531                 if (_state
.pis_total 
== 0) 
 535                  * Note: We can add hinting on free slots, if this linear search 
 536                  * ends up being a performance bottleneck... 
 538                 for(i 
= 0; i 
< _state
.pis_total
; i
++) { 
 539                         if (_state
.pis_ioctl_list
[ i
] == NULL
) 
 544                  * XXX We fall off the end here; if we did this twice at the 
 545                  * XXX same time, we could return the same minor to two 
 546                  * XXX callers; we should probably exand the pointer vector 
 547                  * XXX here, but I need more information on the MALLOC/FREE 
 548                  * XXX locking to ensure against a deadlock.  Maybe we can 
 549                  * XXX just high watermark it at 1/2 of PTMX_GROW_VECTOR? 
 550                  * XXX That would require returning &minor as implict return 
 551                  * XXX and an error code ("EAGAIN/ERESTART") or 0 as our 
 552                  * XXX explicit return. 
 555                 return (i
);     /* empty slot or next slot */ 
 561 ptsd_open(dev_t dev
, int flag
, __unused 
int devtype
, __unused proc_t p
) 
 564         struct ptmx_ioctl 
*pti
; 
 567         if ((pti 
= ptmx_get_ioctl(minor(dev
), 0)) == NULL
) { 
 571         if (!(pti
->pt_flags 
& PF_UNLOCKED
)) { 
 578         if ((tp
->t_state 
& TS_ISOPEN
) == 0) { 
 579                 termioschars(&tp
->t_termios
);   /* Set up default chars */ 
 580                 tp
->t_iflag 
= TTYDEF_IFLAG
; 
 581                 tp
->t_oflag 
= TTYDEF_OFLAG
; 
 582                 tp
->t_lflag 
= TTYDEF_LFLAG
; 
 583                 tp
->t_cflag 
= TTYDEF_CFLAG
; 
 584                 tp
->t_ispeed 
= tp
->t_ospeed 
= TTYDEF_SPEED
; 
 585                 ttsetwater(tp
);         /* would be done in xxparam() */ 
 586         } else if (tp
->t_state
&TS_XCLUDE 
&& suser(kauth_cred_get(), NULL
)) { 
 590         if (tp
->t_oproc
)                        /* Ctrlr still around. */ 
 591                 (void)(*linesw
[tp
->t_line
].l_modem
)(tp
, 1); 
 592         while ((tp
->t_state 
& TS_CARR_ON
) == 0) { 
 595                 error 
= ttysleep(tp
, TSA_CARR_ON(tp
), TTIPRI 
| PCATCH
, 
 600         error 
= (*linesw
[tp
->t_line
].l_open
)(dev
, tp
); 
 601         /* Successful open; mark as open by the slave */ 
 602         pti
->pt_flags 
|= PF_OPEN_S
; 
 603         CLR(tp
->t_state
, TS_IOCTL_NOT_OK
); 
 605                 ptmx_wakeup(tp
, FREAD
|FWRITE
); 
 611 static void ptsd_revoke_knotes(dev_t
, struct tty 
*); 
 614 ptsd_close(dev_t dev
, int flag
, __unused 
int mode
, __unused proc_t p
) 
 617         struct ptmx_ioctl 
*pti
; 
 621          * This is temporary until the VSX conformance tests 
 622          * are fixed.  They are hanging with a deadlock 
 623          * where close(ptsd) will not complete without t_timeout set 
 625 #define FIX_VSX_HANG    1 
 629         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
 635         save_timeout 
= tp
->t_timeout
; 
 638         err 
= (*linesw
[tp
->t_line
].l_close
)(tp
, flag
); 
 639         ptsd_stop(tp
, FREAD
|FWRITE
); 
 642         tp
->t_timeout 
= save_timeout
; 
 646         if ((flag 
& IO_REVOKE
) == IO_REVOKE
) 
 647                 ptsd_revoke_knotes(dev
, tp
); 
 649         /* unconditional, just like ttyclose() */ 
 650         ptmx_free_ioctl(minor(dev
), PF_OPEN_S
); 
 656 ptsd_read(dev_t dev
, struct uio 
*uio
, int flag
) 
 658         proc_t p 
= current_proc(); 
 661         struct ptmx_ioctl 
*pti
; 
 666         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
 671         ut 
= (struct uthread 
*)get_bsdthread_info(current_thread()); 
 673         if (pti
->pt_flags 
& PF_REMOTE
) { 
 674                 while (isbackground(p
, tp
)) { 
 675                         if ((p
->p_sigignore 
& sigmask(SIGTTIN
)) || 
 676                             (ut
->uu_sigmask 
& sigmask(SIGTTIN
)) || 
 677                             p
->p_lflag 
& P_LPPWAIT
) { 
 682                         if (pg 
== PGRP_NULL
) { 
 687                          * SAFE: We about to drop the lock ourselves by 
 688                          * SAFE: erroring out or sleeping anyway. 
 691                         if (pg
->pg_jobc 
== 0) { 
 697                         pgsignal(pg
, SIGTTIN
, 1); 
 701                         error 
= ttysleep(tp
, &ptsd_read
, TTIPRI 
| PCATCH 
| PTTYBLOCK
, "ptsd_bg", 
 706                 if (tp
->t_canq
.c_cc 
== 0) { 
 707                         if (flag 
& IO_NDELAY
) { 
 711                         error 
= ttysleep(tp
, TSA_PTS_READ(tp
), TTIPRI 
| PCATCH
, 
 717                 while (tp
->t_canq
.c_cc 
> 1 && uio_resid(uio
) > 0) { 
 721                         cc 
= MIN(uio_resid(uio
), BUFSIZ
); 
 722                         // Don't copy the very last byte 
 723                         cc 
= MIN(cc
, tp
->t_canq
.c_cc 
- 1); 
 724                         cc 
= q_to_b(&tp
->t_canq
, (u_char 
*)buf
, cc
); 
 725                         error 
= uiomove(buf
, cc
, uio
); 
 729                 if (tp
->t_canq
.c_cc 
== 1) 
 730                         (void) getc(&tp
->t_canq
); 
 735                         error 
= (*linesw
[tp
->t_line
].l_read
)(tp
, uio
, flag
); 
 736         ptmx_wakeup(tp
, FWRITE
); 
 743  * Write to pseudo-tty. 
 744  * Wakeups of controlling tty will happen 
 745  * indirectly, when tty driver calls ptsd_start. 
 748 ptsd_write(dev_t dev
, struct uio 
*uio
, int flag
) 
 751         struct ptmx_ioctl 
*pti
; 
 754         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
 759         if (tp
->t_oproc 
== 0) 
 762                 error 
= (*linesw
[tp
->t_line
].l_write
)(tp
, uio
, flag
); 
 769  * Start output on pseudo-tty. 
 770  * Wake up process selecting or sleeping for input from controlling tty. 
 772  * t_oproc for this driver; called from within the line discipline 
 774  * Locks:       Assumes tp is locked on entry, remains locked on exit 
 777 ptsd_start(struct tty 
*tp
) 
 779         struct ptmx_ioctl 
*pti
; 
 781         pti 
= ptmx_get_ioctl(minor(tp
->t_dev
), 0); 
 783         if (tp
->t_state 
& TS_TTSTOP
) 
 785         if (pti
->pt_flags 
& PF_STOPPED
) { 
 786                 pti
->pt_flags 
&= ~PF_STOPPED
; 
 787                 pti
->pt_send 
= TIOCPKT_START
; 
 789         ptmx_wakeup(tp
, FREAD
); 
 795  * Locks:       Assumes tty_lock() is held over this call. 
 798 ptmx_wakeup(struct tty 
*tp
, int flag
) 
 800         struct ptmx_ioctl 
*pti
; 
 802         pti 
= ptmx_get_ioctl(minor(tp
->t_dev
), 0); 
 805                 selwakeup(&pti
->pt_selr
); 
 806                 wakeup(TSA_PTC_READ(tp
)); 
 809                 selwakeup(&pti
->pt_selw
); 
 810                 wakeup(TSA_PTC_WRITE(tp
)); 
 815 ptmx_open(dev_t dev
, __unused 
int flag
, __unused 
int devtype
, __unused proc_t p
) 
 818         struct ptmx_ioctl 
*pti
; 
 821         pti 
= ptmx_get_ioctl(minor(dev
), PF_OPEN_M
); 
 824         } else if (pti 
== (struct ptmx_ioctl
*)-1) { 
 825                 return (EREDRIVEOPEN
); 
 831         /* If master is open OR slave is still draining, pty is still busy */ 
 832         if (tp
->t_oproc 
|| (tp
->t_state 
& TS_ISOPEN
)) { 
 835                  * If master is closed, we are the only reference, so we 
 836                  * need to clear the master open bit 
 839                         ptmx_free_ioctl(minor(dev
), PF_OPEN_M
); 
 843         tp
->t_oproc 
= ptsd_start
; 
 844         CLR(tp
->t_state
, TS_ZOMBIE
); 
 845         SET(tp
->t_state
, TS_IOCTL_NOT_OK
); 
 847         tp
->t_stop 
= ptsd_stop
; 
 849         (void)(*linesw
[tp
->t_line
].l_modem
)(tp
, 1); 
 850         tp
->t_lflag 
&= ~EXTPROC
; 
 858 ptmx_close(dev_t dev
, __unused 
int flags
, __unused 
int fmt
, __unused proc_t p
) 
 861         struct ptmx_ioctl 
*pti
; 
 863         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
 868         (void)(*linesw
[tp
->t_line
].l_modem
)(tp
, 0); 
 871          * XXX MDMBUF makes no sense for ptys but would inhibit the above 
 872          * l_modem().  CLOCAL makes sense but isn't supported.   Special 
 873          * l_modem()s that ignore carrier drop make no sense for ptys but 
 874          * may be in use because other parts of the line discipline make 
 875          * sense for ptys.  Recover by doing everything that a normal 
 876          * ttymodem() would have done except for sending a SIGHUP. 
 878         if (tp
->t_state 
& TS_ISOPEN
) { 
 879                 tp
->t_state 
&= ~(TS_CARR_ON 
| TS_CONNECTED
); 
 880                 tp
->t_state 
|= TS_ZOMBIE
; 
 881                 ttyflush(tp
, FREAD 
| FWRITE
); 
 884         tp
->t_oproc 
= 0;                /* mark closed */ 
 888         ptmx_free_ioctl(minor(dev
), PF_OPEN_M
); 
 891         mac_pty_notify_close(p
, tp
, dev
, NULL
); 
 898 ptmx_read(dev_t dev
, struct uio 
*uio
, int flag
) 
 901         struct ptmx_ioctl 
*pti
; 
 905         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
 911          * We want to block until the slave 
 912          * is open, and there's something to read; 
 913          * but if we lost the slave or we're NBIO, 
 914          * then return the appropriate error instead. 
 917                 if (tp
->t_state
&TS_ISOPEN
) { 
 918                         if (pti
->pt_flags 
& PF_PKT 
&& pti
->pt_send
) { 
 919                                 error 
= ureadc((int)pti
->pt_send
, uio
); 
 922                                 if (pti
->pt_send 
& TIOCPKT_IOCTL
) { 
 923                                         cc 
= MIN(uio_resid(uio
), 
 924                                                 (user_ssize_t
)sizeof(tp
->t_termios
)); 
 925                                         uiomove((caddr_t
)&tp
->t_termios
, cc
, 
 931                         if (pti
->pt_flags 
& PF_UCNTL 
&& pti
->pt_ucntl
) { 
 932                                 error 
= ureadc((int)pti
->pt_ucntl
, uio
); 
 938                         if (tp
->t_outq
.c_cc 
&& (tp
->t_state
&TS_TTSTOP
) == 0) 
 941                 if ((tp
->t_state 
& TS_CONNECTED
) == 0) 
 943                 if (flag 
& IO_NDELAY
) { 
 947                 error 
= ttysleep(tp
, TSA_PTC_READ(tp
), TTIPRI 
| PCATCH
, "ptmx_in", 0); 
 951         if (pti
->pt_flags 
& (PF_PKT
|PF_UCNTL
)) 
 952                 error 
= ureadc(0, uio
); 
 953         while (uio_resid(uio
) > 0 && error 
== 0) { 
 954                 cc 
= q_to_b(&tp
->t_outq
, (u_char 
*)buf
, MIN(uio_resid(uio
), BUFSIZ
)); 
 957                 error 
= uiomove(buf
, cc
, uio
); 
 959         (*linesw
[tp
->t_line
].l_start
)(tp
); 
 967  * Line discipline callback 
 969  * Locks:       tty_lock() is assumed held on entry and exit. 
 972 ptsd_stop(struct tty 
*tp
, int flush
) 
 974         struct ptmx_ioctl 
*pti
; 
 977         pti 
= ptmx_get_ioctl(minor(tp
->t_dev
), 0); 
 979         /* note: FLUSHREAD and FLUSHWRITE already ok */ 
 981                 flush 
= TIOCPKT_STOP
; 
 982                 pti
->pt_flags 
|= PF_STOPPED
; 
 984                 pti
->pt_flags 
&= ~PF_STOPPED
; 
 985         pti
->pt_send 
|= flush
; 
 986         /* change of perspective */ 
 992         ptmx_wakeup(tp
, flag
); 
 998 ptsd_reset(__unused 
int uban
) 
1004  * Reinput pending characters after state switch 
1007  * XXX Code duplication: static function, should be inlined 
1010 ttypend(struct tty 
*tp
) 
1015         CLR(tp
->t_lflag
, PENDIN
); 
1016         SET(tp
->t_state
, TS_TYPEN
); 
1018         tp
->t_rawq
.c_cc 
= 0; 
1019         tp
->t_rawq
.c_cf 
= tp
->t_rawq
.c_cl 
= 0; 
1020         while ((c 
= getc(&tq
)) >= 0) 
1022         CLR(tp
->t_state
, TS_TYPEN
); 
1026  * Must be called at spltty(). 
1028  * XXX Code duplication: static function, should be inlined 
1031 ttnread(struct tty 
*tp
) 
1035         if (ISSET(tp
->t_lflag
, PENDIN
)) 
1037         nread 
= tp
->t_canq
.c_cc
; 
1038         if (!ISSET(tp
->t_lflag
, ICANON
)) { 
1039                 nread 
+= tp
->t_rawq
.c_cc
; 
1040                 if (nread 
< tp
->t_cc
[VMIN
] && tp
->t_cc
[VTIME
] == 0) 
1047 ptsd_select(dev_t dev
, int rw
, void *wql
, proc_t p
) 
1049         struct ptmx_ioctl 
*pti
; 
1053         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
1064                 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) { 
1069                 retval 
= ttnread(tp
); 
1074                 selrecord(p
, &tp
->t_rsel
, wql
); 
1077                 if (ISSET(tp
->t_state
, TS_ZOMBIE
)) { 
1082                 if ((tp
->t_outq
.c_cc 
<= tp
->t_lowat
) && 
1083                                 ISSET(tp
->t_state
, TS_CONNECTED
)) { 
1084                         retval 
= tp
->t_hiwat 
- tp
->t_outq
.c_cc
; 
1088                 selrecord(p
, &tp
->t_wsel
, wql
); 
1097 ptmx_select(dev_t dev
, int rw
, void *wql
, proc_t p
) 
1100         struct ptmx_ioctl 
*pti
; 
1103         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
1108         if ((tp
->t_state 
& TS_CONNECTED
) == 0) { 
1115                  * Need to block timeouts (ttrstart). 
1117                 if ((tp
->t_state
&TS_ISOPEN
) && 
1118                      tp
->t_outq
.c_cc 
&& (tp
->t_state
&TS_TTSTOP
) == 0) { 
1119                         retval 
= tp
->t_outq
.c_cc
; 
1124         case 0:                                 /* exceptional */ 
1125                 if ((tp
->t_state
&TS_ISOPEN
) && 
1126                     ((pti
->pt_flags 
& PF_PKT 
&& pti
->pt_send
) || 
1127                      (pti
->pt_flags 
& PF_UCNTL 
&& pti
->pt_ucntl
))) { 
1131                 selrecord(p
, &pti
->pt_selr
, wql
); 
1135                 if (tp
->t_state
&TS_ISOPEN
) { 
1136                         if (pti
->pt_flags 
& PF_REMOTE
) { 
1137                             if (tp
->t_canq
.c_cc 
== 0) { 
1138                                 retval 
= (TTYHOG 
-1) ; 
1142                             retval 
= (TTYHOG 
- 2) - (tp
->t_rawq
.c_cc 
+ tp
->t_canq
.c_cc
); 
1146                             if (tp
->t_canq
.c_cc 
== 0 && (tp
->t_lflag
&ICANON
)) { 
1153                 selrecord(p
, &pti
->pt_selw
, wql
); 
1163 ptmx_stop(__unused 
struct tty 
*tp
, __unused 
int flush
) 
1169 ptmx_reset(__unused 
int uban
) 
1175 ptmx_write(dev_t dev
, struct uio 
*uio
, int flag
) 
1178         struct ptmx_ioctl 
*pti
; 
1181         u_char locbuf
[BUFSIZ
]; 
1185         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
1191         if ((tp
->t_state
&TS_ISOPEN
) == 0) 
1193         if (pti
->pt_flags 
& PF_REMOTE
) { 
1194                 if (tp
->t_canq
.c_cc
) 
1196                 while ((uio_resid(uio
) > 0 || cc 
> 0) && 
1197                        tp
->t_canq
.c_cc 
< TTYHOG 
- 1) { 
1199                                 cc 
= MIN(uio_resid(uio
), BUFSIZ
); 
1200                                 cc 
= MIN(cc
, TTYHOG 
- 1 - tp
->t_canq
.c_cc
); 
1202                                 error 
= uiomove((caddr_t
)cp
, cc
, uio
); 
1205                                 /* check again for safety */ 
1206                                 if ((tp
->t_state 
& TS_ISOPEN
) == 0) { 
1207                                         /* adjust as usual */ 
1208                                         uio_setresid(uio
, (uio_resid(uio
) + cc
)); 
1214                                 cc 
= b_to_q((u_char 
*)cp
, cc
, &tp
->t_canq
); 
1216                                  * XXX we don't guarantee that the canq size 
1217                                  * is >= TTYHOG, so the above b_to_q() may 
1218                                  * leave some bytes uncopied.  However, space 
1219                                  * is guaranteed for the null terminator if 
1220                                  * we don't fail here since (TTYHOG - 1) is 
1221                                  * not a multiple of CBSIZE. 
1227                 /* adjust for data copied in but not written */ 
1228                 uio_setresid(uio
, (uio_resid(uio
) + cc
)); 
1229                 (void) putc(0, &tp
->t_canq
); 
1231                 wakeup(TSA_PTS_READ(tp
)); 
1234         while (uio_resid(uio
) > 0 || cc 
> 0) { 
1236                         cc 
= MIN(uio_resid(uio
), BUFSIZ
); 
1238                         error 
= uiomove((caddr_t
)cp
, cc
, uio
); 
1241                         /* check again for safety */ 
1242                         if ((tp
->t_state 
& TS_ISOPEN
) == 0) { 
1243                                 /* adjust for data copied in but not written */ 
1244                                 uio_setresid(uio
, (uio_resid(uio
) + cc
)); 
1250                         if ((tp
->t_rawq
.c_cc 
+ tp
->t_canq
.c_cc
) >= TTYHOG 
- 2 && 
1251                            (tp
->t_canq
.c_cc 
> 0 || !(tp
->t_lflag
&ICANON
))) { 
1252                                 wakeup(TSA_HUP_OR_INPUT(tp
)); 
1255                         (*linesw
[tp
->t_line
].l_rint
)(*cp
++, tp
); 
1268          * Come here to wait for slave to open, for space 
1269          * in outq, or space in rawq, or an empty canq. 
1271         if ((tp
->t_state 
& TS_CONNECTED
) == 0) { 
1272                 /* adjust for data copied in but not written */ 
1273                 uio_setresid(uio
, (uio_resid(uio
) + cc
)); 
1277         if (flag 
& IO_NDELAY
) { 
1278                 /* adjust for data copied in but not written */ 
1279                 uio_setresid(uio
, (uio_resid(uio
) + cc
)); 
1281                         error 
= EWOULDBLOCK
; 
1284         error 
= ttysleep(tp
, TSA_PTC_WRITE(tp
), TTOPRI 
| PCATCH
, "ptmx_out", 0); 
1286                 /* adjust for data copied in but not written */ 
1287                 uio_setresid(uio
, (uio_resid(uio
) + cc
)); 
1295 cptyioctl(dev_t dev
, u_long cmd
, caddr_t data
, int flag
, proc_t p
) 
1298         struct ptmx_ioctl 
*pti
; 
1300         int stop
, error 
= 0; 
1301         int allow_ext_ioctl 
= 1; 
1303         pti 
= ptmx_get_ioctl(minor(dev
), 0); 
1311          * Do not permit extended ioctls on the master side of the pty unless 
1312          * the slave side has been successfully opened and initialized. 
1314         if (cdevsw
[major(dev
)].d_open 
== ptmx_open 
&& ISSET(tp
->t_state
, TS_IOCTL_NOT_OK
)) 
1315                 allow_ext_ioctl 
= 0; 
1318          * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG. 
1319          * ttywflush(tp) will hang if there are characters in the outq. 
1321         if (cmd 
== TIOCEXT 
&& allow_ext_ioctl
) { 
1323                  * When the EXTPROC bit is being toggled, we need 
1324                  * to send an TIOCPKT_IOCTL if the packet driver 
1328                         if (pti
->pt_flags 
& PF_PKT
) { 
1329                                 pti
->pt_send 
|= TIOCPKT_IOCTL
; 
1330                                 ptmx_wakeup(tp
, FREAD
); 
1332                         tp
->t_lflag 
|= EXTPROC
; 
1334                         if ((tp
->t_lflag 
& EXTPROC
) && 
1335                             (pti
->pt_flags 
& PF_PKT
)) { 
1336                                 pti
->pt_send 
|= TIOCPKT_IOCTL
; 
1337                                 ptmx_wakeup(tp
, FREAD
); 
1339                         tp
->t_lflag 
&= ~EXTPROC
; 
1343         if (cdevsw
[major(dev
)].d_open 
== ptmx_open
) { 
1348                          * We aviod calling ttioctl on the controller since, 
1349                          * in that case, tp must be the controlling terminal. 
1351                         *(int *)data 
= tp
->t_pgrp 
? tp
->t_pgrp
->pg_id 
: 0; 
1356                                 if (pti
->pt_flags 
& PF_UCNTL
) { 
1360                                 pti
->pt_flags 
|= PF_PKT
; 
1362                                 pti
->pt_flags 
&= ~PF_PKT
; 
1367                                 if (pti
->pt_flags 
& PF_PKT
) { 
1371                                 pti
->pt_flags 
|= PF_UCNTL
; 
1373                                 pti
->pt_flags 
&= ~PF_UCNTL
; 
1378                                 pti
->pt_flags 
|= PF_REMOTE
; 
1380                                 pti
->pt_flags 
&= ~PF_REMOTE
; 
1381                         ttyflush(tp
, FREAD
|FWRITE
); 
1393                         ndflush(&tp
->t_outq
, tp
->t_outq
.c_cc
); 
1397                         if (*(unsigned int *)data 
>= NSIG 
|| 
1398                             *(unsigned int *)data 
== 0) { 
1402                         if ((tp
->t_lflag
&NOFLSH
) == 0) 
1403                                 ttyflush(tp
, FREAD
|FWRITE
); 
1404                         if ((*(unsigned int *)data 
== SIGINFO
) && 
1405                             ((tp
->t_lflag
&NOKERNINFO
) == 0)) 
1408                          * SAFE: All callers drop the lock on return and 
1409                          * SAFE: the linesw[] will short circut this call 
1410                          * SAFE: if the ioctl() is eaten before the lower 
1411                          * SAFE: level code gets to see it. 
1414                         tty_pgsignal(tp
, *(unsigned int *)data
, 1); 
1418                 case TIOCPTYGRANT
:      /* grantpt(3) */ 
1420                          * Change the uid of the slave to that of the calling 
1421                          * thread, change the gid of the slave to GID_TTY, 
1422                          * change the mode to 0620 (rw--w----). 
1425                                 error 
= _devfs_setattr(pti
->pt_devhandle
, 0620, kauth_getuid(), GID_TTY
); 
1429                                         mac_pty_notify_grant(p
, tp
, dev
, NULL
); 
1436                 case TIOCPTYGNAME
:      /* ptsname(3) */ 
1438                          * Report the name of the slave device in *data 
1439                          * (128 bytes max.).  Use the same template string 
1440                          * used for calling devfs_make_node() to create it. 
1442                         snprintf(data
, 128, "/dev/" PTSD_TEMPLATE
, minor(dev
)); 
1446                 case TIOCPTYUNLK
:       /* unlockpt(3) */ 
1448                          * Unlock the slave device so that it can be opened. 
1450                         pti
->pt_flags 
|= PF_UNLOCKED
; 
1456                  * Fail all other calls; pty masters are not serial devices; 
1457                  * we only pretend they are when the slave side of the pty is 
1460                 if (!allow_ext_ioctl
) { 
1465         error 
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, data
, flag
, p
); 
1466         if (error 
== ENOTTY
) { 
1467                 error 
= ttioctl_locked(tp
, cmd
, data
, flag
, p
); 
1468                 if (error 
== ENOTTY
) { 
1469                         if (pti
->pt_flags 
& PF_UCNTL 
&& (cmd 
& ~0xff) == UIOCCMD(0)) { 
1470                                 /* Process the UIOCMD ioctl group */ 
1472                                         pti
->pt_ucntl 
= (u_char
)cmd
; 
1473                                         ptmx_wakeup(tp
, FREAD
); 
1477                         } else if (cmd 
== TIOCSBRK 
|| cmd 
== TIOCCBRK
) { 
1479                                  * POSIX conformance; rdar://3936338 
1481                                  * Clear ENOTTY in the case of setting or 
1482                                  * clearing a break failing because pty's 
1483                                  * don't support break like real serial 
1493          * If external processing and packet mode send ioctl packet. 
1495         if ((tp
->t_lflag
&EXTPROC
) && (pti
->pt_flags 
& PF_PKT
)) { 
1510                         pti
->pt_send 
|= TIOCPKT_IOCTL
; 
1511                         ptmx_wakeup(tp
, FREAD
); 
1516         stop 
= (tp
->t_iflag 
& IXON
) && CCEQ(cc
[VSTOP
], CTRL('s')) 
1517                 && CCEQ(cc
[VSTART
], CTRL('q')); 
1518         if (pti
->pt_flags 
& PF_NOSTOP
) { 
1520                         pti
->pt_send 
&= ~TIOCPKT_NOSTOP
; 
1521                         pti
->pt_send 
|= TIOCPKT_DOSTOP
; 
1522                         pti
->pt_flags 
&= ~PF_NOSTOP
; 
1523                         ptmx_wakeup(tp
, FREAD
); 
1527                         pti
->pt_send 
&= ~TIOCPKT_DOSTOP
; 
1528                         pti
->pt_send 
|= TIOCPKT_NOSTOP
; 
1529                         pti
->pt_flags 
|= PF_NOSTOP
; 
1530                         ptmx_wakeup(tp
, FREAD
); 
1541 int ptsd_kqfilter(dev_t
, struct knote 
*);  
1542 static void ptsd_kqops_detach(struct knote 
*); 
1543 static int ptsd_kqops_event(struct knote 
*, long); 
1545 static struct filterops ptsd_kqops 
= { 
1547         .f_detach 
= ptsd_kqops_detach
, 
1548         .f_event 
= ptsd_kqops_event
, 
1551 #define PTSD_KNOTE_VALID        NULL 
1552 #define PTSD_KNOTE_REVOKED      ((void *)-911l) 
1555  * In the normal case, by the time the driver_close() routine is called 
1556  * on the slave, all knotes have been detached.  However in the revoke(2) 
1557  * case, the driver's close routine is called while there are knotes active 
1558  * that reference the handlers below.  And we have no obvious means to 
1559  * reach from the driver out to the kqueue's that reference them to get 
1564 ptsd_kqops_detach(struct knote 
*kn
) 
1566         struct ptmx_ioctl 
*pti
; 
1568         dev_t dev
, lockdev 
= (dev_t
)kn
->kn_hookid
; 
1570         ptsd_kevent_mtx_lock(minor(lockdev
)); 
1572         if ((dev 
= (dev_t
)kn
->kn_hookid
) != 0) { 
1573                 pti 
= ptmx_get_ioctl(minor(dev
), 0); 
1574                 if (pti 
!= NULL 
&& (tp 
= pti
->pt_tty
) != NULL
) { 
1576                         if (kn
->kn_filter 
== EVFILT_READ
) 
1577                                 KNOTE_DETACH(&tp
->t_rsel
.si_note
, kn
); 
1579                                 KNOTE_DETACH(&tp
->t_wsel
.si_note
, kn
); 
1585         ptsd_kevent_mtx_unlock(minor(lockdev
)); 
1589 ptsd_kqops_event(struct knote 
*kn
, long hint
) 
1591         struct ptmx_ioctl 
*pti
; 
1593         dev_t dev 
= (dev_t
)kn
->kn_hookid
; 
1596         ptsd_kevent_mtx_lock(minor(dev
)); 
1599                 if (kn
->kn_hook 
!= PTSD_KNOTE_VALID 
) { 
1600                         /* We were revoked */ 
1602                         kn
->kn_flags 
|= EV_EOF
; 
1607                 pti 
= ptmx_get_ioctl(minor(dev
), 0); 
1608                 if (pti 
== NULL 
|| (tp 
= pti
->pt_tty
) == NULL
) { 
1609                         kn
->kn_data 
= ENXIO
; 
1610                         kn
->kn_flags 
|= EV_ERROR
; 
1618                 if (kn
->kn_filter 
== EVFILT_READ
) { 
1619                         kn
->kn_data 
= ttnread(tp
); 
1620                         if (kn
->kn_data 
> 0) 
1622                         if (ISSET(tp
->t_state
, TS_ZOMBIE
)) { 
1623                                 kn
->kn_flags 
|= EV_EOF
; 
1626                 } else {        /* EVFILT_WRITE */ 
1627                         if ((tp
->t_outq
.c_cc 
<= tp
->t_lowat
) && 
1628                             ISSET(tp
->t_state
, TS_CONNECTED
)) { 
1629                                 kn
->kn_data 
= tp
->t_outq
.c_cn 
- tp
->t_outq
.c_cc
; 
1632                         if (ISSET(tp
->t_state
, TS_ZOMBIE
)) { 
1633                                 kn
->kn_flags 
|= EV_EOF
; 
1642         ptsd_kevent_mtx_unlock(minor(dev
)); 
1647 ptsd_kqfilter(dev_t dev
, struct knote 
*kn
) 
1649         struct tty 
*tp 
= NULL
;  
1650         struct ptmx_ioctl 
*pti 
= NULL
; 
1653         /* make sure we're talking about the right device type */ 
1654         if (cdevsw
[major(dev
)].d_open 
!= ptsd_open
) { 
1658         if ((pti 
= ptmx_get_ioctl(minor(dev
), 0)) == NULL
) { 
1665         kn
->kn_hookid 
= dev
; 
1666         kn
->kn_hook 
= PTSD_KNOTE_VALID
; 
1667         kn
->kn_fop 
= &ptsd_kqops
; 
1669         switch (kn
->kn_filter
) { 
1671                 KNOTE_ATTACH(&tp
->t_rsel
.si_note
, kn
); 
1674                 KNOTE_ATTACH(&tp
->t_wsel
.si_note
, kn
); 
1686  * Support for revoke(2). 
1688  * Mark all the kn_hook fields so that future invocations of the 
1689  * f_event op will just say "EOF" *without* looking at the 
1690  * ptmx_ioctl structure (which may disappear or be recycled at 
1691  * the end of ptsd_close).  Issue wakeups to post that EOF to 
1692  * anyone listening.  And finally remove the knotes from the 
1693  * tty's klists to keep ttyclose() happy, and set the hookid to 
1694  * zero to make the final detach passively successful. 
1697 ptsd_revoke_knotes(dev_t dev
, struct tty 
*tp
) 
1700         struct knote 
*kn
, *tkn
; 
1702         /* (Hold and drop the right locks in the right order.) */ 
1704         ptsd_kevent_mtx_lock(minor(dev
)); 
1707         list 
= &tp
->t_rsel
.si_note
; 
1708         SLIST_FOREACH(kn
, list
, kn_selnext
) 
1709                 kn
->kn_hook 
= PTSD_KNOTE_REVOKED
; 
1711         list 
= &tp
->t_wsel
.si_note
; 
1712         SLIST_FOREACH(kn
, list
, kn_selnext
) 
1713                 kn
->kn_hook 
= PTSD_KNOTE_REVOKED
; 
1716         ptsd_kevent_mtx_unlock(minor(dev
)); 
1723         ptsd_kevent_mtx_lock(minor(dev
)); 
1726         list 
= &tp
->t_rsel
.si_note
; 
1727         SLIST_FOREACH_SAFE(kn
, list
, kn_selnext
, tkn
) { 
1728                 (void) KNOTE_DETACH(list
, kn
); 
1732         list 
= &tp
->t_wsel
.si_note
; 
1733         SLIST_FOREACH_SAFE(kn
, list
, kn_selnext
, tkn
) { 
1734                 (void) KNOTE_DETACH(list
, kn
); 
1739         ptsd_kevent_mtx_unlock(minor(dev
));