]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/tty.c
xnu-2782.40.9.tar.gz
[apple/xnu.git] / bsd / kern / tty.c
index 4d7c5b9fa7f8fa06435db603030a63f878bdf5ac..2586c482fe01d2f6beb8c2a146ac50f1037e28cf 100644 (file)
@@ -130,7 +130,7 @@ static lck_grp_t    *tty_lck_grp;
 static lck_grp_attr_t  *tty_lck_grp_attr;
 static lck_attr_t      *tty_lck_attr;
 
-static int     ttnread(struct tty *tp);
+__private_extern__ int ttnread(struct tty *tp);
 static void    ttyecho(int c, struct tty *tp);
 static int     ttyoutput(int c, struct tty *tp);
 static void    ttypend(struct tty *tp);
@@ -960,6 +960,29 @@ ttyoutput(int c, struct tty *tp)
        return (-1);
 }
 
+/*
+ * Sets the tty state to not allow any more changes of foreground process
+ * group. This is required to be done so that a subsequent revoke on a vnode
+ * is able to always successfully complete.
+ *
+ * Locks :   Assumes tty_lock held on entry
+ */
+void
+ttysetpgrphup(struct tty *tp)
+{
+       TTY_LOCK_OWNED(tp);     /* debug assert */
+       SET(tp->t_state, TS_PGRPHUP);
+}
+
+/*
+ * Locks : Assumes tty lock held on entry
+ */
+void
+ttyclrpgrphup(struct tty *tp)
+{
+       TTY_LOCK_OWNED(tp);     /* debug assert */
+       CLR(tp->t_state, TS_PGRPHUP);
+}
 
 /*
  * ttioctl
@@ -1453,6 +1476,15 @@ ttioctl_locked(struct tty *tp, u_long cmd, caddr_t data, int flag, proc_t p)
                        error = EPERM;
                        goto out;
                }
+               /*
+                * The session leader is going away and is possibly going to revoke
+                * the terminal, we can't change the process group when that is the
+                * case.
+                */
+               if (ISSET(tp->t_state, TS_PGRPHUP)) {
+                       error = EPERM;
+                       goto out;
+               }
                proc_list_lock();
                oldpg = tp->t_pgrp;
                tp->t_pgrp = pgrp;
@@ -1570,7 +1602,7 @@ ttselect(dev_t dev, int rw, void *wql, proc_t p)
 /*
  * Locks:      Assumes tp is locked on entry, remains locked on exit
  */
-static int
+__private_extern__ int
 ttnread(struct tty *tp)
 {
        int nread;
@@ -2145,7 +2177,7 @@ read:
                char ibuf[IBUFSIZ];
                int icc;
 
-               icc = min(uio_resid(uio), IBUFSIZ);
+               icc = MIN(uio_resid(uio), IBUFSIZ);
                icc = q_to_b(qp, (u_char *)ibuf, icc);
                if (icc <= 0) {
                        if (first)
@@ -2186,8 +2218,8 @@ slowcase:
                        tty_pgsignal(tp, SIGTSTP, 1);
                        tty_lock(tp);
                        if (first) {
-                               error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
-                                                "ttybg3", 0);
+                               error = ttysleep(tp, &ttread, TTIPRI | PCATCH,
+                                                "ttybg3", hz);
                                if (error)
                                        break;
                                goto loop;
@@ -2366,7 +2398,7 @@ loop:
                 * leftover from last time.
                 */
                if (cc == 0) {
-                       cc = min(uio_resid(uio), OBUFSIZ);
+                       cc = MIN(uio_resid(uio), OBUFSIZ);
                        cp = obuf;
                        error = uiomove(cp, cc, uio);
                        if (error) {