diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 673707f7387f..bc2b8810c4a7 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -300,52 +300,47 @@ exit1(struct thread *td, int rv) sx_xlock(&proctree_lock); if (SESS_LEADER(p)) { - struct session *sp; - - sp = p->p_session; + struct session *sp = p->p_session; + struct tty *tp; + /* + * s_ttyp is not zero'd; we use this to indicate that + * the session once had a controlling terminal. (for + * logging and informational purposes) + */ SESS_LOCK(sp); ttyvp = sp->s_ttyvp; + tp = sp->s_ttyp; sp->s_ttyvp = NULL; + sp->s_leader = NULL; SESS_UNLOCK(sp); - if (ttyvp != NULL && ttyvp->v_type != VBAD) { - /* - * Controlling process. - * Signal foreground pgrp and revoke access to - * controlling terminal. - * - * There is no need to drain the terminal here, - * because this will be done on revocation. - */ - if (sp->s_ttyp != NULL) { - struct tty *tp = sp->s_ttyp; + /* + * Signal foreground pgrp and revoke access to + * controlling terminal if it has not been revoked + * already. + * + * Because the TTY may have been revoked in the mean + * time and could already have a new session associated + * with it, make sure we don't send a SIGHUP to a + * foreground process group that does not belong to this + * session. + */ - tty_lock(tp); + if (tp != NULL) { + tty_lock(tp); + if (tp->t_session == sp) tty_signal_pgrp(tp, SIGHUP); - tty_unlock(tp); - - /* - * The tty could have been revoked - * if we blocked. - */ - if (ttyvp->v_type != VBAD) { - sx_xunlock(&proctree_lock); - VOP_LOCK(ttyvp, LK_EXCLUSIVE); - VOP_REVOKE(ttyvp, REVOKEALL); - VOP_UNLOCK(ttyvp, 0); - sx_xlock(&proctree_lock); - } - } - /* - * s_ttyp is not zero'd; we use this to indicate that - * the session once had a controlling terminal. - * (for logging and informational purposes) - */ + tty_unlock(tp); + } + + if (ttyvp != NULL && ttyvp->v_type != VBAD) { + sx_xunlock(&proctree_lock); + VOP_LOCK(ttyvp, LK_EXCLUSIVE); + VOP_REVOKE(ttyvp, REVOKEALL); + VOP_UNLOCK(ttyvp, 0); + sx_xlock(&proctree_lock); } - SESS_LOCK(p->p_session); - sp->s_leader = NULL; - SESS_UNLOCK(p->p_session); } fixjobc(p, p->p_pgrp, 0); sx_xunlock(&proctree_lock); diff --git a/sys/kern/tty.c b/sys/kern/tty.c index bf800be0e44c..2603cac5182f 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1486,7 +1486,7 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td) return (0); } - if (p->p_session->s_ttyvp != NULL || + if (p->p_session->s_ttyp != NULL || (tp->t_session != NULL && tp->t_session->s_ttyvp != NULL && tp->t_session->s_ttyvp->v_type != VBAD)) { /*