diff options
author | jhb <jhb@FreeBSD.org> | 2002-04-16 17:09:22 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2002-04-16 17:09:22 +0000 |
commit | 6cbba0bb0370167bd9f9a0d6ef843373f6b8f1c0 (patch) | |
tree | 0f54ccd7b3f0f7afd39d3813614ad4daa4b3e70b /sys/kern/tty_pty.c | |
parent | d9a4c30c37718c0f14402f6af58255a45ccf9617 (diff) | |
download | FreeBSD-src-6cbba0bb0370167bd9f9a0d6ef843373f6b8f1c0.zip FreeBSD-src-6cbba0bb0370167bd9f9a0d6ef843373f6b8f1c0.tar.gz |
- Lock proctree_lock instead of pgrpsess_lock.
- Use temporary variables to hold a pointer to a pgrp while we dink with it
while not holding either the associated proc lock or proctree_lock. It
is in theory possible that p->p_pgrp could change out from under us.
Diffstat (limited to 'sys/kern/tty_pty.c')
-rw-r--r-- | sys/kern/tty_pty.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index 9bc2360..7d6e736 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -234,25 +234,27 @@ ptsread(dev, uio, flag) struct proc *p = td->td_proc; register struct tty *tp = dev->si_tty; register struct pt_ioctl *pti = dev->si_drv1; + struct pgrp *pg; int error = 0; again: if (pti->pt_flags & PF_REMOTE) { while (isbackground(p, tp)) { - PGRPSESS_SLOCK(); + sx_slock(&proctree_lock); PROC_LOCK(p); if (SIGISMEMBER(p->p_sigignore, SIGTTIN) || SIGISMEMBER(p->p_sigmask, SIGTTIN) || p->p_pgrp->pg_jobc == 0 || p->p_flag & P_PPWAIT) { PROC_UNLOCK(p); - PGRPSESS_SUNLOCK(); + sx_sunlock(&proctree_lock); return (EIO); } + pg = p->p_pgrp; PROC_UNLOCK(p); - PGRP_LOCK(p->p_pgrp); - PGRPSESS_SUNLOCK(); - pgsignal(p->p_pgrp, SIGTTIN, 1); - PGRP_UNLOCK(p->p_pgrp); + PGRP_LOCK(pg); + sx_sunlock(&proctree_lock); + pgsignal(pg, SIGTTIN, 1); + PGRP_UNLOCK(pg); error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ptsbg", 0); if (error) |