]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/tty_dev.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / kern / tty_dev.c
index 87f3cd7ee6a5724eb4e940bdde1fb2e28547ee9e..28fa8508d404803cc009694b9e7438c3035aa846 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1997-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 1997-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
 #include <sys/uio_internal.h>
 #include <sys/kernel.h>
 #include <sys/vnode.h>
-#include <sys/vnode_internal.h>                /* _devfs_setattr() */
-#include <sys/stat.h>                  /* _devfs_setattr() */
+#include <sys/vnode_internal.h>         /* _devfs_setattr() */
+#include <sys/stat.h>                   /* _devfs_setattr() */
 #include <sys/user.h>
 #include <sys/signalvar.h>
 #include <sys/sysctl.h>
 #include <miscfs/devfs/devfs.h>
-#include <miscfs/devfs/devfsdefs.h>    /* DEVFS_LOCK()/DEVFS_UNLOCK() */
+#include <miscfs/devfs/devfsdefs.h>     /* DEVFS_LOCK()/DEVFS_UNLOCK() */
+#include <dev/kmreg_com.h>
 
 #if CONFIG_MACF
 #include <security/mac_framework.h>
@@ -96,21 +97,21 @@ static int _devfs_setattr(void *, unsigned short, uid_t, gid_t);
  * Forward declarations
  */
 static void ptcwakeup(struct tty *tp, int flag);
-__XNU_PRIVATE_EXTERN   d_open_t        ptsopen;
-__XNU_PRIVATE_EXTERN   d_close_t       ptsclose;
-__XNU_PRIVATE_EXTERN   d_read_t        ptsread;
-__XNU_PRIVATE_EXTERN   d_write_t       ptswrite;
-__XNU_PRIVATE_EXTERN   d_ioctl_t       ptyioctl;       /* common ioctl */
-__XNU_PRIVATE_EXTERN   d_stop_t        ptsstop;
-__XNU_PRIVATE_EXTERN   d_reset_t       ptsreset;
-__XNU_PRIVATE_EXTERN   d_select_t      ptsselect;
-__XNU_PRIVATE_EXTERN   d_open_t        ptcopen;
-__XNU_PRIVATE_EXTERN   d_close_t       ptcclose;
-__XNU_PRIVATE_EXTERN   d_read_t        ptcread;
-__XNU_PRIVATE_EXTERN   d_write_t       ptcwrite;
-__XNU_PRIVATE_EXTERN   d_stop_t        ptcstop;        /* NO-OP */
-__XNU_PRIVATE_EXTERN   d_reset_t       ptcreset;
-__XNU_PRIVATE_EXTERN   d_select_t      ptcselect;
+__XNU_PRIVATE_EXTERN    d_open_t        ptsopen;
+__XNU_PRIVATE_EXTERN    d_close_t       ptsclose;
+__XNU_PRIVATE_EXTERN    d_read_t        ptsread;
+__XNU_PRIVATE_EXTERN    d_write_t       ptswrite;
+__XNU_PRIVATE_EXTERN    d_ioctl_t       ptyioctl;       /* common ioctl */
+__XNU_PRIVATE_EXTERN    d_stop_t        ptsstop;
+__XNU_PRIVATE_EXTERN    d_reset_t       ptsreset;
+__XNU_PRIVATE_EXTERN    d_select_t      ptsselect;
+__XNU_PRIVATE_EXTERN    d_open_t        ptcopen;
+__XNU_PRIVATE_EXTERN    d_close_t       ptcclose;
+__XNU_PRIVATE_EXTERN    d_read_t        ptcread;
+__XNU_PRIVATE_EXTERN    d_write_t       ptcwrite;
+__XNU_PRIVATE_EXTERN    d_stop_t        ptcstop;        /* NO-OP */
+__XNU_PRIVATE_EXTERN    d_reset_t       ptcreset;
+__XNU_PRIVATE_EXTERN    d_select_t      ptcselect;
 
 /*
  * XXX Should be devfs function... and use VATTR mechanisms, per
@@ -125,11 +126,11 @@ __XNU_PRIVATE_EXTERN      d_select_t      ptcselect;
 static int
 _devfs_setattr(void * handle, unsigned short mode, uid_t uid, gid_t gid)
 {
-       devdirent_t             *direntp = (devdirent_t *)handle;
-       devnode_t               *devnodep;
-       int                     error = EACCES;
-       vfs_context_t           ctx = vfs_context_current();;
-       struct vnode_attr       va;
+       devdirent_t             *direntp = (devdirent_t *)handle;
+       devnode_t               *devnodep;
+       int                     error = EACCES;
+       vfs_context_t           ctx = vfs_context_current();;
+       struct vnode_attr       va;
 
        VATTR_INIT(&va);
        VATTR_SET(&va, va_uid, uid);
@@ -161,8 +162,9 @@ _devfs_setattr(void * handle, unsigned short mode, uid_t uid, gid_t gid)
                snprintf(name, sizeof(name), "/dev/%s", direntp->de_name);
                NDINIT(&nd, LOOKUP, OP_SETATTR, FOLLOW, UIO_SYSSPACE, CAST_USER_ADDR_T(name), ctx);
                error = namei(&nd);
-               if (error)
+               if (error) {
                        goto out;
+               }
                error = vnode_setattr(nd.ni_vp, &va, ctx);
                vnode_put(nd.ni_vp);
                nameidone(&nd);
@@ -170,10 +172,10 @@ _devfs_setattr(void * handle, unsigned short mode, uid_t uid, gid_t gid)
        }
 
 out:
-       return(error);
+       return error;
 }
 
-#define BUFSIZ 100             /* Chunk size iomoved to/from user */
+#define BUFSIZ 100              /* Chunk size iomoved to/from user */
 
 static struct tty_dev_t *tty_dev_head;
 
@@ -268,37 +270,41 @@ ptsopen(dev_t dev, int flag, __unused int devtype, __unused struct proc *p)
        tty_lock(tp);
 
        if ((tp->t_state & TS_ISOPEN) == 0) {
-               termioschars(&tp->t_termios);   /* Set up default chars */
+               termioschars(&tp->t_termios);   /* Set up default chars */
                tp->t_iflag = TTYDEF_IFLAG;
                tp->t_oflag = TTYDEF_OFLAG;
                tp->t_lflag = TTYDEF_LFLAG;
                tp->t_cflag = TTYDEF_CFLAG;
                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
-               ttsetwater(tp);         /* would be done in xxparam() */
+               ttsetwater(tp);         /* would be done in xxparam() */
        } else if ((tp->t_state & TS_XCLUDE) && kauth_cred_issuser(kauth_cred_get())) {
-               error = EBUSY;
+               error = EBUSY;
                goto out;
        }
-       if (tp->t_oproc)                        /* Ctrlr still around. */
+       if (tp->t_oproc) {                      /* Ctrlr still around. */
                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
+       }
        while ((tp->t_state & TS_CARR_ON) == 0) {
-               if (flag&FNONBLOCK)
+               if (flag & FNONBLOCK) {
                        break;
+               }
                error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH, __FUNCTION__, 0);
-               if (error)
+               if (error) {
                        goto out;
+               }
        }
        error = (*linesw[tp->t_line].l_open)(dev, tp);
        /* Successful open; mark as open by the slave */
 
        pti->pt_flags |= PF_OPEN_S;
        CLR(tp->t_state, TS_IOCTL_NOT_OK);
-       if (error == 0)
-               ptcwakeup(tp, FREAD|FWRITE);
+       if (error == 0) {
+               ptcwakeup(tp, FREAD | FWRITE);
+       }
 
 out:
        tty_unlock(tp);
-       return (error);
+       return error;
 }
 
 __private_extern__ int
@@ -311,27 +317,35 @@ ptsclose(dev_t dev, int flag, __unused int mode, __unused proc_t p)
         * are fixed.  They are hanging with a deadlock
         * where close() will not complete without t_timeout set
         */
-#define        FIX_VSX_HANG    1
-#ifdef FIX_VSX_HANG
+#define FIX_VSX_HANG    1
+#ifdef  FIX_VSX_HANG
        int save_timeout;
 #endif
        struct tty_dev_t *driver;
        struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
        struct tty *tp;
-       
-       if (pti == NULL)
-               return (ENXIO);
+
+       if (pti == NULL) {
+               return ENXIO;
+       }
 
        tp = pti->pt_tty;
        tty_lock(tp);
-#ifdef FIX_VSX_HANG
+#ifdef  FIX_VSX_HANG
        save_timeout = tp->t_timeout;
        tp->t_timeout = 60;
 #endif
+       /*
+        * Close the line discipline and backing TTY structures.
+        */
        err = (*linesw[tp->t_line].l_close)(tp, flag);
-       ptsstop(tp, FREAD|FWRITE);
-       (void) ttyclose(tp);
-#ifdef FIX_VSX_HANG
+       (void)ttyclose(tp);
+
+       /*
+        * Flush data and notify any waiters on the master side of this PTY.
+        */
+       ptsstop(tp, FREAD | FWRITE);
+#ifdef  FIX_VSX_HANG
        tp->t_timeout = save_timeout;
 #endif
        tty_unlock(tp);
@@ -342,7 +356,7 @@ ptsclose(dev_t dev, int flag, __unused int mode, __unused proc_t p)
        /* unconditional, just like ttyclose() */
        pty_free_ioctl(dev, PF_OPEN_S);
 
-       return (err);
+       return err;
 }
 
 __private_extern__ int
@@ -355,8 +369,9 @@ ptsread(dev_t dev, struct uio *uio, int flag)
        struct uthread *ut;
        struct pgrp *pg;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL) {
+               return ENXIO;
+       }
        tp = pti->pt_tty;
        tty_lock(tp);
 
@@ -393,8 +408,9 @@ again:
                        tty_lock(tp);
 
                        error = ttysleep(tp, &ptsread, TTIPRI | PCATCH | PTTYBLOCK, __FUNCTION__, hz);
-                       if (error)
-                               goto out;
+                       if (error) {
+                               goto out;
+                       }
                }
                if (tp->t_canq.c_cc == 0) {
                        if (flag & IO_NDELAY) {
@@ -402,8 +418,9 @@ again:
                                goto out;
                        }
                        error = ttysleep(tp, TSA_PTS_READ(tp), TTIPRI | PCATCH, __FUNCTION__, 0);
-                       if (error)
-                               goto out;
+                       if (error) {
+                               goto out;
+                       }
                        goto again;
                }
                while (tp->t_canq.c_cc > 1 && uio_resid(uio) > 0) {
@@ -415,20 +432,23 @@ again:
                        cc = MIN(cc, tp->t_canq.c_cc - 1);
                        cc = q_to_b(&tp->t_canq, (u_char *)buf, cc);
                        error = uiomove(buf, cc, uio);
-                       if (error)
+                       if (error) {
                                break;
+                       }
                }
-               if (tp->t_canq.c_cc == 1)
+               if (tp->t_canq.c_cc == 1) {
                        (void) getc(&tp->t_canq);
-               if (tp->t_canq.c_cc)
-                       goto out;
-       } else
-               if (tp->t_oproc)
-                       error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
+               }
+               if (tp->t_canq.c_cc) {
+                       goto out;
+               }
+       } else if (tp->t_oproc) {
+               error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
+       }
        ptcwakeup(tp, FWRITE);
 out:
        tty_unlock(tp);
-       return (error);
+       return error;
 }
 
 /*
@@ -443,19 +463,21 @@ ptswrite(dev_t dev, struct uio *uio, int flag)
        struct tty *tp;
        int error;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL) {
+               return ENXIO;
+       }
        tp = pti->pt_tty;
        tty_lock(tp);
 
-       if (tp->t_oproc == 0)
+       if (tp->t_oproc == 0) {
                error = EIO;
-       else
-               error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
+       } else {
+               error = (*linesw[tp->t_line].l_write)(tp, uio, flag);
+       }
 
        tty_unlock(tp);
 
-       return (error);
+       return error;
 }
 
 /*
@@ -470,10 +492,12 @@ static void
 ptsstart(struct tty *tp)
 {
        struct ptmx_ioctl *pti = pty_get_ioctl(tp->t_dev, 0, NULL);
-       if (pti == NULL)
+       if (pti == NULL) {
+               goto out;
+       }
+       if (tp->t_state & TS_TTSTOP) {
                goto out;
-       if (tp->t_state & TS_TTSTOP)
-               goto out;
+       }
        if (pti->pt_flags & PF_STOPPED) {
                pti->pt_flags &= ~PF_STOPPED;
                pti->pt_send = TIOCPKT_START;
@@ -483,6 +507,16 @@ out:
        return;
 }
 
+static void
+ptcwakeup_knote(struct selinfo *sip, long hint)
+{
+       if ((sip->si_flags & SI_KNPOSTING) == 0) {
+               sip->si_flags |= SI_KNPOSTING;
+               KNOTE(&sip->si_note, hint);
+               sip->si_flags &= ~SI_KNPOSTING;
+       }
+}
+
 /*
  * Locks:      Assumes tty_lock() is held over this call.
  */
@@ -490,16 +524,19 @@ static void
 ptcwakeup(struct tty *tp, int flag)
 {
        struct ptmx_ioctl *pti = pty_get_ioctl(tp->t_dev, 0, NULL);
-       if (pti == NULL)
+       if (pti == NULL) {
                return;
+       }
 
        if (flag & FREAD) {
                selwakeup(&pti->pt_selr);
                wakeup(TSA_PTC_READ(tp));
+               ptcwakeup_knote(&pti->pt_selr, 1);
        }
        if (flag & FWRITE) {
                selwakeup(&pti->pt_selw);
                wakeup(TSA_PTC_WRITE(tp));
+               ptcwakeup_knote(&pti->pt_selw, 1);
        }
 }
 
@@ -509,9 +546,9 @@ ptcopen(dev_t dev, __unused int flag, __unused int devtype, __unused proc_t p)
        struct tty_dev_t *driver;
        struct ptmx_ioctl *pti = pty_get_ioctl(dev, PF_OPEN_M, &driver);
        if (pti == NULL) {
-               return (ENXIO);
+               return ENXIO;
        } else if (pti == (struct ptmx_ioctl*)-1) {
-               return (EREDRIVEOPEN);
+               return EREDRIVEOPEN;
        }
 
        struct tty *tp = pti->pt_tty;
@@ -554,29 +591,46 @@ ptcclose(dev_t dev, __unused int flags, __unused int fmt, __unused proc_t p)
        struct tty_dev_t *driver;
        struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
        struct tty *tp;
+       struct knote *kn;
+
+       if (!pti) {
+               return ENXIO;
+       }
 
-       if (pti == NULL)
-               return (ENXIO);
        tp = pti->pt_tty;
        tty_lock(tp);
 
-       (void)(*linesw[tp->t_line].l_modem)(tp, 0);
-
        /*
-        * XXX MDMBUF makes no sense for ptys but would inhibit the above
-        * l_modem().  CLOCAL makes sense but isn't supported.   Special
-        * l_modem()s that ignore carrier drop make no sense for ptys but
-        * may be in use because other parts of the line discipline make
-        * sense for ptys.  Recover by doing everything that a normal
-        * ttymodem() would have done except for sending a SIGHUP.
+        * XXX MDMBUF makes no sense for PTYs, but would inhibit an `l_modem`.
+        * CLOCAL makes sense but isn't supported.  Special `l_modem`s that ignore
+        * carrier drop make no sense for PTYs but may be in use because other parts
+        * of the line discipline make sense for PTYs.  Recover by doing everything
+        * that a normal `ttymodem` would have done except for sending SIGHUP.
         */
+       (void)(*linesw[tp->t_line].l_modem)(tp, 0);
        if (tp->t_state & TS_ISOPEN) {
                tp->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
                tp->t_state |= TS_ZOMBIE;
                ttyflush(tp, FREAD | FWRITE);
        }
 
-       tp->t_oproc = 0;                /* mark closed */
+       /*
+        * Null out the backing TTY struct's open procedure to prevent starting
+        * slaves through `ptsstart`.
+        */
+       tp->t_oproc = NULL;
+
+       /*
+        * Clear any select or kevent waiters under the lock.
+        */
+       SLIST_FOREACH(kn, &pti->pt_selr.si_note, kn_selnext) {
+               KNOTE_DETACH(&pti->pt_selr.si_note, kn);
+       }
+       selthreadclear(&pti->pt_selr);
+       SLIST_FOREACH(kn, &pti->pt_selw.si_note, kn_selnext) {
+               KNOTE_DETACH(&pti->pt_selw.si_note, kn);
+       }
+       selthreadclear(&pti->pt_selw);
 
        tty_unlock(tp);
 
@@ -587,7 +641,7 @@ ptcclose(dev_t dev, __unused int flags, __unused int fmt, __unused proc_t p)
        }
 #endif
 
-       return (0);
+       return 0;
 }
 
 __private_extern__ int
@@ -598,8 +652,9 @@ ptcread(dev_t dev, struct uio *uio, int flag)
        char buf[BUFSIZ];
        int error = 0, cc;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL) {
+               return ENXIO;
+       }
        tp = pti->pt_tty;
        tty_lock(tp);
 
@@ -613,43 +668,65 @@ ptcread(dev_t dev, struct uio *uio, int flag)
                if (tp->t_state & TS_ISOPEN) {
                        if (pti->pt_flags & PF_PKT && pti->pt_send) {
                                error = ureadc((int)pti->pt_send, uio);
-                               if (error)
+                               if (error) {
                                        goto out;
+                               }
                                if (pti->pt_send & TIOCPKT_IOCTL) {
-                                       cc = MIN((int)uio_resid(uio),
-                                               (int)sizeof(tp->t_termios));
-                                       uiomove((caddr_t)&tp->t_termios, cc,
-                                               uio);
+#ifdef __LP64__
+                                       if (uio->uio_segflg == UIO_USERSPACE32) {
+                                               static struct termios32 tio32;
+                                               cc = MIN((int)uio_resid(uio), (int)sizeof(tio32));
+                                               termios64to32((struct user_termios *)&tp->t_termios,
+                                                   (struct termios32 *)&tio32);
+                                               uiomove((caddr_t)&tio32, cc, uio);
+#else
+                                       if (uio->uio_segflg == UIO_USERSPACE64) {
+                                               static struct user_termios tio64;
+                                               cc = MIN((int)uio_resid(uio), (int)sizeof(tio64));
+                                               termios32to64((struct termios32 *)&tp->t_termios,
+                                                   (struct user_termios *)&tio64);
+                                               uiomove((caddr_t)&tio64, cc, uio);
+#endif
+                                       } else {
+                                               cc = MIN((int)uio_resid(uio), (int)sizeof(tp->t_termios));
+                                               uiomove((caddr_t)&tp->t_termios, cc, uio);
+                                       }
                                }
                                pti->pt_send = 0;
                                goto out;
                        }
                        if (pti->pt_flags & PF_UCNTL && pti->pt_ucntl) {
                                error = ureadc((int)pti->pt_ucntl, uio);
-                               if (error)
+                               if (error) {
                                        goto out;
+                               }
                                pti->pt_ucntl = 0;
                                goto out;
                        }
-                       if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
+                       if (tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) {
                                break;
+                       }
+               }
+               if ((tp->t_state & TS_CONNECTED) == 0) {
+                       goto out;       /* EOF */
                }
-               if ((tp->t_state & TS_CONNECTED) == 0)
-                       goto out;       /* EOF */
                if (flag & IO_NDELAY) {
                        error = EWOULDBLOCK;
                        goto out;
                }
                error = ttysleep(tp, TSA_PTC_READ(tp), TTIPRI | PCATCH, __FUNCTION__, 0);
-               if (error)
-                       goto out;
+               if (error) {
+                       goto out;
+               }
        }
-       if (pti->pt_flags & (PF_PKT|PF_UCNTL))
+       if (pti->pt_flags & (PF_PKT | PF_UCNTL)) {
                error = ureadc(0, uio);
+       }
        while (uio_resid(uio) > 0 && error == 0) {
                cc = q_to_b(&tp->t_outq, (u_char *)buf, MIN((int)uio_resid(uio), BUFSIZ));
-               if (cc <= 0)
+               if (cc <= 0) {
                        break;
+               }
                error = uiomove(buf, cc, uio);
        }
        (*linesw[tp->t_line].l_start)(tp);
@@ -657,7 +734,7 @@ ptcread(dev_t dev, struct uio *uio, int flag)
 out:
        tty_unlock(tp);
 
-       return (error);
+       return error;
 }
 
 /*
@@ -671,22 +748,26 @@ ptsstop(struct tty* tp, int flush)
        struct ptmx_ioctl *pti = pty_get_ioctl(tp->t_dev, 0, NULL);
        int flag;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL) {
+               return ENXIO;
+       }
 
        /* note: FLUSHREAD and FLUSHWRITE already ok */
        if (flush == 0) {
                flush = TIOCPKT_STOP;
                pti->pt_flags |= PF_STOPPED;
-       } else
+       } else {
                pti->pt_flags &= ~PF_STOPPED;
+       }
        pti->pt_send |= flush;
        /* change of perspective */
        flag = 0;
-       if (flush & FREAD)
+       if (flush & FREAD) {
                flag |= FWRITE;
-       if (flush & FWRITE)
+       }
+       if (flush & FWRITE) {
                flag |= FREAD;
+       }
        ptcwakeup(tp, flag);
        return 0;
 }
@@ -694,7 +775,7 @@ ptsstop(struct tty* tp, int flush)
 __private_extern__ int
 ptsreset(__unused int uban)
 {
-       return (0);
+       return 0;
 }
 
 int
@@ -704,11 +785,13 @@ ptsselect(dev_t dev, int rw, void *wql, proc_t p)
        struct tty *tp;
        int retval = 0;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL) {
+               return ENXIO;
+       }
        tp = pti->pt_tty;
-       if (tp == NULL)
-               return (ENXIO);
+       if (tp == NULL) {
+               return ENXIO;
+       }
 
        tty_lock(tp);
 
@@ -733,7 +816,7 @@ ptsselect(dev_t dev, int rw, void *wql, proc_t p)
                }
 
                if ((tp->t_outq.c_cc <= tp->t_lowat) &&
-                               ISSET(tp->t_state, TS_CONNECTED)) {
+                   ISSET(tp->t_state, TS_CONNECTED)) {
                        retval = tp->t_hiwat - tp->t_outq.c_cc;
                        break;
                }
@@ -743,7 +826,7 @@ ptsselect(dev_t dev, int rw, void *wql, proc_t p)
        }
 
        tty_unlock(tp);
-       return (retval);
+       return retval;
 }
 
 __private_extern__ int
@@ -754,8 +837,9 @@ ptcselect(dev_t dev, int rw, void *wql, proc_t p)
        struct tty *tp;
        int retval = 0;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL) {
+               return ENXIO;
+       }
        tp = pti->pt_tty;
        tty_lock(tp);
 
@@ -764,22 +848,21 @@ ptcselect(dev_t dev, int rw, void *wql, proc_t p)
                goto out;
        }
        switch (rw) {
-
        case FREAD:
                /*
                 * Need to block timeouts (ttrstart).
                 */
-               if ((tp->t_state&TS_ISOPEN) &&
-                    tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0) {
+               if ((tp->t_state & TS_ISOPEN) &&
+                   tp->t_outq.c_cc && (tp->t_state & TS_TTSTOP) == 0) {
                        retval = (driver->fix_7828447) ? tp->t_outq.c_cc : 1;
                        break;
                }
-               /* FALLTHROUGH */
+               OS_FALLTHROUGH;
 
-       case 0:                                 /* exceptional */
-               if ((tp->t_state&TS_ISOPEN) &&
-                   ((pti->pt_flags & PF_PKT && pti->pt_send) ||
-                    (pti->pt_flags & PF_UCNTL && pti->pt_ucntl))) {
+       case 0: /* exceptional */
+               if ((tp->t_state & TS_ISOPEN) &&
+                   (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
+                   ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl))) {
                        retval = 1;
                        break;
                }
@@ -788,45 +871,44 @@ ptcselect(dev_t dev, int rw, void *wql, proc_t p)
 
 
        case FWRITE:
-               if (tp->t_state&TS_ISOPEN) {
+               if (tp->t_state & TS_ISOPEN) {
                        if (pti->pt_flags & PF_REMOTE) {
-                           if (tp->t_canq.c_cc == 0) {
-                               retval = (driver->fix_7828447) ? (TTYHOG - 1) : 1;
-                               break;
-                           }
+                               if (tp->t_canq.c_cc == 0) {
+                                       retval = (driver->fix_7828447) ? (TTYHOG - 1) : 1;
+                                       break;
+                               }
                        } else {
-                           retval = (TTYHOG - 2) - (tp->t_rawq.c_cc + tp->t_canq.c_cc);
-                           if (retval > 0) {
-                                   retval = (driver->fix_7828447) ? retval : 1;
-                                   break;
-                           }
-                           if (tp->t_canq.c_cc == 0 && (tp->t_lflag&ICANON)) {
-                                   retval = 1;
-                                   break;
-                           }
-                           retval = 0;
+                               retval = (TTYHOG - 2) - (tp->t_rawq.c_cc + tp->t_canq.c_cc);
+                               if (retval > 0) {
+                                       retval = (driver->fix_7828447) ? retval : 1;
+                                       break;
+                               }
+                               if (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON)) {
+                                       retval = 1;
+                                       break;
+                               }
+                               retval = 0;
                        }
                }
                selrecord(p, &pti->pt_selw, wql);
                break;
-
        }
 out:
        tty_unlock(tp);
 
-       return (retval);
+       return retval;
 }
 
 __private_extern__ int
 ptcstop(__unused struct tty *tp, __unused int flush)
 {
-       return (0);
+       return 0;
 }
 
 __private_extern__ int
 ptcreset(__unused int uban)
 {
-       return (0);
+       return 0;
 }
 
 __private_extern__ int
@@ -840,26 +922,30 @@ ptcwrite(dev_t dev, struct uio *uio, int flag)
        int wcnt = 0;
        int error = 0;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL) {
+               return ENXIO;
+       }
        tp = pti->pt_tty;
        tty_lock(tp);
 
 again:
-       if ((tp->t_state & TS_ISOPEN) == 0)
+       if ((tp->t_state & TS_ISOPEN) == 0) {
                goto block;
+       }
        if (pti->pt_flags & PF_REMOTE) {
-               if (tp->t_canq.c_cc)
+               if (tp->t_canq.c_cc) {
                        goto block;
+               }
                while ((uio_resid(uio) > 0 || cc > 0) &&
-                      tp->t_canq.c_cc < TTYHOG - 1) {
+                   tp->t_canq.c_cc < TTYHOG - 1) {
                        if (cc == 0) {
                                cc = MIN((int)uio_resid(uio), BUFSIZ);
                                cc = MIN(cc, TTYHOG - 1 - tp->t_canq.c_cc);
                                cp = locbuf;
                                error = uiomove((caddr_t)cp, cc, uio);
-                               if (error)
+                               if (error) {
                                        goto out;
+                               }
                                /* check again for safety */
                                if ((tp->t_state & TS_ISOPEN) == 0) {
                                        /* adjust as usual */
@@ -878,8 +964,9 @@ again:
                                 * we don't fail here since (TTYHOG - 1) is
                                 * not a multiple of CBSIZE.
                                 */
-                               if (cc > 0)
+                               if (cc > 0) {
                                        break;
+                               }
                        }
                }
                /* adjust for data copied in but not written */
@@ -894,8 +981,9 @@ again:
                        cc = MIN((int)uio_resid(uio), BUFSIZ);
                        cp = locbuf;
                        error = uiomove((caddr_t)cp, cc, uio);
-                       if (error)
+                       if (error) {
                                goto out;
+                       }
                        /* check again for safety */
                        if ((tp->t_state & TS_ISOPEN) == 0) {
                                /* adjust for data copied in but not written */
@@ -906,7 +994,7 @@ again:
                }
                while (cc > 0) {
                        if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 &&
-                          (tp->t_canq.c_cc > 0 || !(tp->t_lflag&ICANON))) {
+                           (tp->t_canq.c_cc > 0 || !(tp->t_lflag & ICANON))) {
                                wakeup(TSA_HUP_OR_INPUT(tp));
                                goto block;
                        }
@@ -919,7 +1007,7 @@ again:
 out:
        tty_unlock(tp);
 
-       return (error);
+       return error;
 
 block:
        /*
@@ -935,8 +1023,9 @@ block:
        if (flag & IO_NDELAY) {
                /* adjust for data copied in but not written */
                uio_setresid(uio, (uio_resid(uio) + cc));
-               if (wcnt == 0)
+               if (wcnt == 0) {
                        error = EWOULDBLOCK;
+               }
                goto out;
        }
        error = ttysleep(tp, TSA_PTC_WRITE(tp), TTOPRI | PCATCH, __FUNCTION__, 0);
@@ -948,6 +1037,9 @@ block:
        goto again;
 }
 
+/*
+ * ptyioctl: Assumes dev was opened and lock was initilized
+ */
 __private_extern__ int
 ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 {
@@ -957,8 +1049,14 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
        int stop, error = 0;
        int allow_ext_ioctl = 1;
 
-       if (pti == NULL)
-               return (ENXIO);
+       if (pti == NULL || pti->pt_tty == NULL) {
+               return ENXIO;
+       }
+
+       if (cmd == KMIOCDISABLCONS) {
+               return 0;
+       }
+
        tp = pti->pt_tty;
        tty_lock(tp);
 
@@ -999,10 +1097,8 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                        tp->t_lflag &= ~EXTPROC;
                }
                goto out;
-       } else
-       if (cdevsw[major(dev)].d_open == ptcopen) {
+       } else if (cdevsw[major(dev)].d_open == ptcopen) {
                switch (cmd) {
-
                case TIOCGPGRP:
                        /*
                         * We aviod calling ttioctl on the controller since,
@@ -1013,32 +1109,35 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 
                case TIOCPKT:
                        if (*(int *)data) {
-                               if (pti->pt_flags & PF_UCNTL) {
+                               if (pti->pt_flags & PF_UCNTL) {
                                        error = EINVAL;
                                        goto out;
                                }
                                pti->pt_flags |= PF_PKT;
-                       } else
+                       } else {
                                pti->pt_flags &= ~PF_PKT;
+                       }
                        goto out;
 
                case TIOCUCNTL:
                        if (*(int *)data) {
-                               if (pti->pt_flags & PF_PKT) {
+                               if (pti->pt_flags & PF_PKT) {
                                        error = EINVAL;
                                        goto out;
                                }
                                pti->pt_flags |= PF_UCNTL;
-                       } else
+                       } else {
                                pti->pt_flags &= ~PF_UCNTL;
+                       }
                        goto out;
 
                case TIOCREMOTE:
-                       if (*(int *)data)
+                       if (*(int *)data) {
                                pti->pt_flags |= PF_REMOTE;
-                       else
+                       } else {
                                pti->pt_flags &= ~PF_REMOTE;
-                       ttyflush(tp, FREAD|FWRITE);
+                       }
+                       ttyflush(tp, FREAD | FWRITE);
                        goto out;
 
                case TIOCSETP:
@@ -1059,11 +1158,13 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                                error = EINVAL;
                                goto out;
                        }
-                       if ((tp->t_lflag&NOFLSH) == 0)
-                               ttyflush(tp, FREAD|FWRITE);
+                       if ((tp->t_lflag & NOFLSH) == 0) {
+                               ttyflush(tp, FREAD | FWRITE);
+                       }
                        if ((*(unsigned int *)data == SIGINFO) &&
-                           ((tp->t_lflag&NOKERNINFO) == 0))
+                           ((tp->t_lflag & NOKERNINFO) == 0)) {
                                ttyinfo_locked(tp);
+                       }
                        /*
                         * SAFE: All callers drop the lock on return and
                         * SAFE: the linesw[] will short circut this call
@@ -1075,31 +1176,31 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                        tty_lock(tp);
                        goto out;
 
-               case TIOCPTYGRANT:      /* grantpt(3) */
+               case TIOCPTYGRANT:      /* grantpt(3) */
                        /*
                         * Change the uid of the slave to that of the calling
                         * thread, change the gid of the slave to GID_TTY,
                         * change the mode to 0620 (rw--w----).
                         */
-                       {
-                               error = _devfs_setattr(pti->pt_devhandle, 0620, kauth_getuid(), GID_TTY);
-                               if (major(dev) == driver->master) {
-                                       if (driver->mac_notify) {
+               {
+                       error = _devfs_setattr(pti->pt_devhandle, 0620, kauth_getuid(), GID_TTY);
+                       if (major(dev) == driver->master) {
+                               if (driver->mac_notify) {
 #if CONFIG_MACF
-                                               if (!error) {
-                                                       tty_unlock(tp);
-                                                       mac_pty_notify_grant(p, tp, dev, NULL);
-                                                       tty_lock(tp);
-                                               }
-#endif
-                                       } else {
-                                               error = 0;
+                                       if (!error) {
+                                               tty_unlock(tp);
+                                               mac_pty_notify_grant(p, tp, dev, NULL);
+                                               tty_lock(tp);
                                        }
+#endif
+                               } else {
+                                       error = 0;
                                }
-                               goto out;
                        }
+                       goto out;
+               }
 
-               case TIOCPTYGNAME:      /* ptsname(3) */
+               case TIOCPTYGNAME:      /* ptsname(3) */
                        /*
                         * Report the name of the slave device in *data
                         * (128 bytes max.).  Use the same template string
@@ -1108,8 +1209,8 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                        pty_get_name(dev, data, 128);
                        error = 0;
                        goto out;
-               
-               case TIOCPTYUNLK:       /* unlockpt(3) */
+
+               case TIOCPTYUNLK:       /* unlockpt(3) */
                        /*
                         * Unlock the slave device so that it can be opened.
                         */
@@ -1160,8 +1261,8 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
        /*
         * If external processing and packet mode send ioctl packet.
         */
-       if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
-               switch(cmd) {
+       if ((tp->t_lflag & EXTPROC) && (pti->pt_flags & PF_PKT)) {
+               switch (cmd) {
                case TIOCSETA_32:
                case TIOCSETAW_32:
                case TIOCSETAF_32:
@@ -1177,12 +1278,13 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                case TIOCLSET:
                        pti->pt_send |= TIOCPKT_IOCTL;
                        ptcwakeup(tp, FREAD);
+                       break;
                default:
                        break;
                }
        }
        stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
-               && CCEQ(cc[VSTART], CTRL('q'));
+           && CCEQ(cc[VSTART], CTRL('q'));
        if (pti->pt_flags & PF_NOSTOP) {
                if (stop) {
                        pti->pt_send &= ~TIOCPKT_NOSTOP;
@@ -1201,5 +1303,5 @@ ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 out:
        tty_unlock(tp);
 
-       return (error);
+       return error;
 }