]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/tty_dev.c
xnu-4903.241.1.tar.gz
[apple/xnu.git] / bsd / kern / tty_dev.c
index dac57968b64558c5f9c25cc4cb69e83b94fe9fca..1e1fe83f448d21fbe5df9436326993d83b27b8d7 100644 (file)
@@ -318,7 +318,7 @@ ptsclose(dev_t dev, int flag, __unused int mode, __unused proc_t p)
        struct tty_dev_t *driver;
        struct ptmx_ioctl *pti = pty_get_ioctl(dev, 0, &driver);
        struct tty *tp;
-       
+
        if (pti == NULL)
                return (ENXIO);
 
@@ -328,9 +328,16 @@ ptsclose(dev_t dev, int flag, __unused int mode, __unused proc_t p)
        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);
+       (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
@@ -556,29 +563,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);