diff options
Diffstat (limited to 'usr/src/uts/common/os/strsubr.c')
-rw-r--r-- | usr/src/uts/common/os/strsubr.c | 74 |
1 files changed, 24 insertions, 50 deletions
diff --git a/usr/src/uts/common/os/strsubr.c b/usr/src/uts/common/os/strsubr.c index 57a918a3f0..ae99e5198a 100644 --- a/usr/src/uts/common/os/strsubr.c +++ b/usr/src/uts/common/os/strsubr.c @@ -3107,13 +3107,18 @@ straccess(struct stdata *stp, enum jcaccess mode) proc_t *p = ttoproc(t); sess_t *sp; + ASSERT(mutex_owned(&stp->sd_lock)); + if (stp->sd_sidp == NULL || stp->sd_vnode->v_type == VFIFO) return (0); - mutex_enter(&p->p_lock); - sp = p->p_sessp; + mutex_enter(&p->p_lock); /* protects p_pgidp */ for (;;) { + mutex_enter(&p->p_splock); /* protects p->p_sessp */ + sp = p->p_sessp; + mutex_enter(&sp->s_lock); /* protects sp->* */ + /* * If this is not the calling process's controlling terminal * or if the calling process is already in the foreground @@ -3121,6 +3126,8 @@ straccess(struct stdata *stp, enum jcaccess mode) */ if (sp->s_dev != stp->sd_vnode->v_rdev || p->p_pgidp == stp->sd_pgidp) { + mutex_exit(&sp->s_lock); + mutex_exit(&p->p_splock); mutex_exit(&p->p_lock); return (0); } @@ -3131,10 +3138,15 @@ straccess(struct stdata *stp, enum jcaccess mode) if (sp->s_vp == NULL) { if (!cantsend(p, t, SIGHUP)) sigtoproc(p, t, SIGHUP); + mutex_exit(&sp->s_lock); + mutex_exit(&p->p_splock); mutex_exit(&p->p_lock); return (EIO); } + mutex_exit(&sp->s_lock); + mutex_exit(&p->p_splock); + if (mode == JCGETP) { mutex_exit(&p->p_lock); return (0); @@ -3146,7 +3158,9 @@ straccess(struct stdata *stp, enum jcaccess mode) return (EIO); } mutex_exit(&p->p_lock); + mutex_exit(&stp->sd_lock); pgsignal(p->p_pgidp, SIGTTIN); + mutex_enter(&stp->sd_lock); mutex_enter(&p->p_lock); } else { /* mode == JCWRITE or JCSETP */ if ((mode == JCWRITE && !(stp->sd_flag & STRTOSTOP)) || @@ -3159,7 +3173,9 @@ straccess(struct stdata *stp, enum jcaccess mode) return (EIO); } mutex_exit(&p->p_lock); + mutex_exit(&stp->sd_lock); pgsignal(p->p_pgidp, SIGTTOU); + mutex_enter(&stp->sd_lock); mutex_enter(&p->p_lock); } @@ -3174,10 +3190,15 @@ straccess(struct stdata *stp, enum jcaccess mode) * We can't get here if the signal is ignored or * if the current thread is blocking the signal. */ + mutex_exit(&stp->sd_lock); if (!cv_wait_sig_swap(&lbolt_cv, &p->p_lock)) { mutex_exit(&p->p_lock); + mutex_enter(&stp->sd_lock); return (EINTR); } + mutex_exit(&p->p_lock); + mutex_enter(&stp->sd_lock); + mutex_enter(&p->p_lock); } } @@ -4001,59 +4022,12 @@ strsignal(stdata_t *stp, int sig, int32_t band) void strhup(stdata_t *stp) { + ASSERT(mutex_owned(&stp->sd_lock)); pollwakeup(&stp->sd_pollist, POLLHUP); - mutex_enter(&stp->sd_lock); if (stp->sd_sigflags & S_HANGUP) strsendsig(stp->sd_siglist, S_HANGUP, 0, 0); - mutex_exit(&stp->sd_lock); -} - -void -stralloctty(stdata_t *stp) -{ - proc_t *p = curproc; - sess_t *sp = p->p_sessp; - - mutex_enter(&stp->sd_lock); - /* - * No need to hold the session lock or do a TTY_HOLD() because - * this is the only thread that can be the session leader and not - * have a controlling tty. - */ - if ((stp->sd_flag & - (STRHUP|STRDERR|STWRERR|STPLEX|STRISTTY)) == STRISTTY && - stp->sd_sidp == NULL && /* not allocated as ctty */ - sp->s_sidp == p->p_pidp && /* session leader */ - sp->s_flag != SESS_CLOSE && /* session is not closing */ - sp->s_vp == NULL) { /* without ctty */ - ASSERT(stp->sd_pgidp == NULL); - alloctty(p, makectty(stp->sd_vnode)); - - mutex_enter(&pidlock); - stp->sd_sidp = sp->s_sidp; - stp->sd_pgidp = sp->s_sidp; - PID_HOLD(stp->sd_pgidp); - PID_HOLD(stp->sd_sidp); - mutex_exit(&pidlock); - } - mutex_exit(&stp->sd_lock); } -void -strfreectty(stdata_t *stp) -{ - mutex_enter(&stp->sd_lock); - pgsignal(stp->sd_pgidp, SIGHUP); - mutex_enter(&pidlock); - PID_RELE(stp->sd_pgidp); - PID_RELE(stp->sd_sidp); - stp->sd_pgidp = NULL; - stp->sd_sidp = NULL; - mutex_exit(&pidlock); - mutex_exit(&stp->sd_lock); - if (!(stp->sd_flag & STRHUP)) - strhup(stp); -} /* * Backenable the first queue upstream from `q' with a service procedure. */ |