Index: tty.c =================================================================== RCS file: /usr/store/mlaier/fcvs/src/sys/kern/tty.c,v retrieving revision 1.249 diff -u -r1.249 tty.c --- tty.c 13 Apr 2005 13:56:17 -0000 1.249 +++ tty.c 9 May 2005 00:34:55 -0000 @@ -329,8 +329,10 @@ tp->t_gen++; tp->t_line = TTYDISC; tp->t_hotchar = 0; + sx_xlock(&proctree_lock); tp->t_pgrp = NULL; tp->t_session = NULL; + sx_xunlock(&proctree_lock); tp->t_state = 0; knlist_clear(&tp->t_rsel.si_note, 0); knlist_clear(&tp->t_wsel.si_note, 0); @@ -401,11 +403,13 @@ return (0); if (ISSET(iflag, BRKINT)) { ttyflush(tp, FREAD | FWRITE); + sx_slock(&proctree_lock); if (tp->t_pgrp != NULL) { PGRP_LOCK(tp->t_pgrp); pgsignal(tp->t_pgrp, SIGINT, 1); PGRP_UNLOCK(tp->t_pgrp); } + sx_sunlock(&proctree_lock); goto endcase; } if (ISSET(iflag, PARMRK)) @@ -483,23 +487,27 @@ if (!ISSET(lflag, NOFLSH)) ttyflush(tp, FREAD | FWRITE); ttyecho(c, tp); + sx_slock(&proctree_lock); if (tp->t_pgrp != NULL) { PGRP_LOCK(tp->t_pgrp); pgsignal(tp->t_pgrp, CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1); PGRP_UNLOCK(tp->t_pgrp); } + sx_sunlock(&proctree_lock); goto endcase; } if (CCEQ(cc[VSUSP], c)) { if (!ISSET(lflag, NOFLSH)) ttyflush(tp, FREAD); ttyecho(c, tp); + sx_slock(&proctree_lock); if (tp->t_pgrp != NULL) { PGRP_LOCK(tp->t_pgrp); pgsignal(tp->t_pgrp, SIGTSTP, 1); PGRP_UNLOCK(tp->t_pgrp); } + sx_sunlock(&proctree_lock); goto endcase; } } @@ -617,11 +625,13 @@ * ^T - kernel info and generate SIGINFO */ if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) { + sx_slock(&proctree_lock); if (ISSET(lflag, ISIG) && tp->t_pgrp != NULL) { PGRP_LOCK(tp->t_pgrp); pgsignal(tp->t_pgrp, SIGINFO, 1); PGRP_UNLOCK(tp->t_pgrp); } + sx_sunlock(&proctree_lock); if (!ISSET(lflag, NOKERNINFO)) ttyinfo(tp); goto endcase; @@ -1013,7 +1023,9 @@ case TIOCGPGRP: /* get pgrp of tty */ if (!isctty(p, tp)) return (ENOTTY); + sx_slock(&proctree_lock); *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID; + sx_sunlock(&proctree_lock); break; #ifdef TIOCHPCL case TIOCHPCL: /* hang up on last close */ @@ -1193,11 +1205,11 @@ break; case TIOCSCTTY: /* become controlling tty */ /* Session ctty vnode pointer set in vnode layer. */ - sx_slock(&proctree_lock); + sx_xlock(&proctree_lock); /* XXX: protect t_pgrp */ if (!SESS_LEADER(p) || ((p->p_session->s_ttyvp || tp->t_session) && (tp->t_session != p->p_session))) { - sx_sunlock(&proctree_lock); + sx_xunlock(&proctree_lock); return (EPERM); } tp->t_session = p->p_session; @@ -1209,28 +1221,28 @@ PROC_LOCK(p); p->p_flag |= P_CONTROLT; PROC_UNLOCK(p); - sx_sunlock(&proctree_lock); + sx_xunlock(&proctree_lock); break; case TIOCSPGRP: { /* set pgrp of tty */ - sx_slock(&proctree_lock); + sx_xlock(&proctree_lock); /* XXX: protect t_pgrp */ pgrp = pgfind(*(int *)data); if (!isctty(p, tp)) { if (pgrp != NULL) PGRP_UNLOCK(pgrp); - sx_sunlock(&proctree_lock); + sx_xunlock(&proctree_lock); return (ENOTTY); } if (pgrp == NULL) { - sx_sunlock(&proctree_lock); + sx_xunlock(&proctree_lock); return (EPERM); } PGRP_UNLOCK(pgrp); if (pgrp->pg_session != p->p_session) { - sx_sunlock(&proctree_lock); + sx_xunlock(&proctree_lock); return (EPERM); } - sx_sunlock(&proctree_lock); tp->t_pgrp = pgrp; + sx_xunlock(&proctree_lock); break; } case TIOCSTAT: /* simulate control-T */ @@ -1242,11 +1254,13 @@ if (bcmp((caddr_t)&tp->t_winsize, data, sizeof (struct winsize))) { tp->t_winsize = *(struct winsize *)data; + sx_slock(&proctree_lock); if (tp->t_pgrp != NULL) { PGRP_LOCK(tp->t_pgrp); pgsignal(tp->t_pgrp, SIGWINCH, 1); PGRP_UNLOCK(tp->t_pgrp); } + sx_sunlock(&proctree_lock); } break; case TIOCSDRAINWAIT: @@ -1937,11 +1951,13 @@ */ if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) { + sx_slock(&proctree_lock); if (tp->t_pgrp != NULL) { PGRP_LOCK(tp->t_pgrp); pgsignal(tp->t_pgrp, SIGTSTP, 1); PGRP_UNLOCK(tp->t_pgrp); } + sx_sunlock(&proctree_lock); if (first) { error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg3", 0); @@ -2551,17 +2567,19 @@ * On return following a ttyprintf(), we set tp->t_rocount to 0 so * that pending input will be retyped on BS. */ + sx_slock(&proctree_lock); if (tp->t_session == NULL) { + sx_sunlock(&proctree_lock); ttyprintf(tp, "not a controlling terminal\n"); tp->t_rocount = 0; return; } if (tp->t_pgrp == NULL) { + sx_sunlock(&proctree_lock); ttyprintf(tp, "no foreground process group\n"); tp->t_rocount = 0; return; } - sx_slock(&proctree_lock); if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL) { sx_sunlock(&proctree_lock); ttyprintf(tp, "empty foreground process group\n"); @@ -3041,10 +3059,12 @@ XT_COPY(state); XT_COPY(flags); XT_COPY(timeout); + sx_slock(&proctree_lock); if (tp->t_pgrp != NULL) xt.xt_pgid = tp->t_pgrp->pg_id; if (tp->t_session != NULL) xt.xt_sid = tp->t_session->s_sid; + sx_sunlock(&proctree_lock); XT_COPY(termios); XT_COPY(winsize); XT_COPY(column);