tty.c (93719) | tty.c (94860) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)tty.c 8.8 (Berkeley) 1/21/94 | 1/*- 2 * Copyright (c) 1982, 1986, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)tty.c 8.8 (Berkeley) 1/21/94 |
39 * $FreeBSD: head/sys/kern/tty.c 93719 2002-04-03 10:56:59Z ru $ | 39 * $FreeBSD: head/sys/kern/tty.c 94860 2002-04-16 17:09:22Z jhb $ |
40 */ 41 42/*- 43 * TODO: 44 * o Fix races for sending the start char in ttyflush(). 45 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect(). 46 * With luck, there will be MIN chars before select() returns(). 47 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it. --- 678 unchanged lines hidden (view full) --- 726ttioctl(tp, cmd, data, flag) 727 register struct tty *tp; 728 u_long cmd; 729 int flag; 730 void *data; 731{ 732 register struct proc *p; 733 struct thread *td; | 40 */ 41 42/*- 43 * TODO: 44 * o Fix races for sending the start char in ttyflush(). 45 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect(). 46 * With luck, there will be MIN chars before select() returns(). 47 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it. --- 678 unchanged lines hidden (view full) --- 726ttioctl(tp, cmd, data, flag) 727 register struct tty *tp; 728 u_long cmd; 729 int flag; 730 void *data; 731{ 732 register struct proc *p; 733 struct thread *td; |
734 struct pgrp *pgrp; |
|
734 int s, error; 735 736 td = curthread; /* XXX */ 737 p = td->td_proc; 738 739 /* If the ioctl involves modification, hang if in the background. */ 740 switch (cmd) { 741 case TIOCCBRK: --- 23 unchanged lines hidden (view full) --- 765 case TIOCLBIS: 766 case TIOCLSET: 767 case TIOCSETC: 768 case OTIOCSETD: 769 case TIOCSETN: 770 case TIOCSETP: 771 case TIOCSLTC: 772#endif | 735 int s, error; 736 737 td = curthread; /* XXX */ 738 p = td->td_proc; 739 740 /* If the ioctl involves modification, hang if in the background. */ 741 switch (cmd) { 742 case TIOCCBRK: --- 23 unchanged lines hidden (view full) --- 766 case TIOCLBIS: 767 case TIOCLSET: 768 case TIOCSETC: 769 case OTIOCSETD: 770 case TIOCSETN: 771 case TIOCSETP: 772 case TIOCSLTC: 773#endif |
773 PGRPSESS_SLOCK(); | 774 sx_slock(&proctree_lock); |
774 PROC_LOCK(p); 775 while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) && 776 !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 777 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { | 775 PROC_LOCK(p); 776 while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) && 777 !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 778 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { |
778 if (p->p_pgrp->pg_jobc == 0) { 779 PROC_UNLOCK(p); 780 PGRPSESS_SUNLOCK(); | 779 pgrp = p->p_pgrp; 780 PROC_UNLOCK(p); 781 if (pgrp->pg_jobc == 0) { 782 sx_sunlock(&proctree_lock); |
781 return (EIO); 782 } | 783 return (EIO); 784 } |
783 PROC_UNLOCK(p); 784 PGRP_LOCK(p->p_pgrp); 785 PGRPSESS_SUNLOCK(); 786 pgsignal(p->p_pgrp, SIGTTOU, 1); 787 PGRP_UNLOCK(p->p_pgrp); | 785 PGRP_LOCK(pgrp); 786 sx_sunlock(&proctree_lock); 787 pgsignal(pgrp, SIGTTOU, 1); 788 PGRP_UNLOCK(pgrp); |
788 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1", 789 0); 790 if (error) 791 return (error); | 789 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1", 790 0); 791 if (error) 792 return (error); |
792 PGRPSESS_SLOCK(); | 793 sx_slock(&proctree_lock); |
793 PROC_LOCK(p); 794 } 795 PROC_UNLOCK(p); | 794 PROC_LOCK(p); 795 } 796 PROC_UNLOCK(p); |
796 PGRPSESS_SUNLOCK(); | 797 sx_sunlock(&proctree_lock); |
797 break; 798 } 799 800 switch (cmd) { /* Process the ioctl. */ 801 case FIOASYNC: /* set/clear async i/o */ 802 s = spltty(); 803 if (*(int *)data) 804 SET(tp->t_state, TS_ASYNC); --- 243 unchanged lines hidden (view full) --- 1048 if (!ISSET(tp->t_state, TS_TTSTOP)) { 1049 SET(tp->t_state, TS_TTSTOP); 1050 (*tp->t_stop)(tp, 0); 1051 } 1052 splx(s); 1053 break; 1054 case TIOCSCTTY: /* become controlling tty */ 1055 /* Session ctty vnode pointer set in vnode layer. */ | 798 break; 799 } 800 801 switch (cmd) { /* Process the ioctl. */ 802 case FIOASYNC: /* set/clear async i/o */ 803 s = spltty(); 804 if (*(int *)data) 805 SET(tp->t_state, TS_ASYNC); --- 243 unchanged lines hidden (view full) --- 1049 if (!ISSET(tp->t_state, TS_TTSTOP)) { 1050 SET(tp->t_state, TS_TTSTOP); 1051 (*tp->t_stop)(tp, 0); 1052 } 1053 splx(s); 1054 break; 1055 case TIOCSCTTY: /* become controlling tty */ 1056 /* Session ctty vnode pointer set in vnode layer. */ |
1056 PGRPSESS_SLOCK(); | 1057 sx_slock(&proctree_lock); |
1057 if (!SESS_LEADER(p) || 1058 ((p->p_session->s_ttyvp || tp->t_session) && 1059 (tp->t_session != p->p_session))) { | 1058 if (!SESS_LEADER(p) || 1059 ((p->p_session->s_ttyvp || tp->t_session) && 1060 (tp->t_session != p->p_session))) { |
1060 PGRPSESS_SUNLOCK(); | 1061 sx_sunlock(&proctree_lock); |
1061 return (EPERM); 1062 } 1063 tp->t_session = p->p_session; 1064 tp->t_pgrp = p->p_pgrp; 1065 SESS_LOCK(p->p_session); 1066 p->p_session->s_ttyp = tp; 1067 SESS_UNLOCK(p->p_session); 1068 PROC_LOCK(p); 1069 p->p_flag |= P_CONTROLT; 1070 PROC_UNLOCK(p); | 1062 return (EPERM); 1063 } 1064 tp->t_session = p->p_session; 1065 tp->t_pgrp = p->p_pgrp; 1066 SESS_LOCK(p->p_session); 1067 p->p_session->s_ttyp = tp; 1068 SESS_UNLOCK(p->p_session); 1069 PROC_LOCK(p); 1070 p->p_flag |= P_CONTROLT; 1071 PROC_UNLOCK(p); |
1071 PGRPSESS_SUNLOCK(); | 1072 sx_sunlock(&proctree_lock); |
1072 break; 1073 case TIOCSPGRP: { /* set pgrp of tty */ | 1073 break; 1074 case TIOCSPGRP: { /* set pgrp of tty */ |
1074 register struct pgrp *pgrp; 1075 1076 PGRPSESS_SLOCK(); | 1075 sx_slock(&proctree_lock); |
1077 pgrp = pgfind(*(int *)data); 1078 if (!isctty(p, tp)) { 1079 if (pgrp != NULL) 1080 PGRP_UNLOCK(pgrp); | 1076 pgrp = pgfind(*(int *)data); 1077 if (!isctty(p, tp)) { 1078 if (pgrp != NULL) 1079 PGRP_UNLOCK(pgrp); |
1081 PGRPSESS_SUNLOCK(); | 1080 sx_sunlock(&proctree_lock); |
1082 return (ENOTTY); 1083 } 1084 if (pgrp == NULL) { | 1081 return (ENOTTY); 1082 } 1083 if (pgrp == NULL) { |
1085 PGRPSESS_SUNLOCK(); | 1084 sx_sunlock(&proctree_lock); |
1086 return (EPERM); 1087 } 1088 PGRP_UNLOCK(pgrp); 1089 if (pgrp->pg_session != p->p_session) { | 1085 return (EPERM); 1086 } 1087 PGRP_UNLOCK(pgrp); 1088 if (pgrp->pg_session != p->p_session) { |
1090 PGRPSESS_SUNLOCK(); | 1089 sx_sunlock(&proctree_lock); |
1091 return (EPERM); 1092 } | 1090 return (EPERM); 1091 } |
1093 PGRPSESS_SUNLOCK(); | 1092 sx_sunlock(&proctree_lock); |
1094 tp->t_pgrp = pgrp; 1095 break; 1096 } 1097 case TIOCSTAT: /* simulate control-T */ 1098 s = spltty(); 1099 ttyinfo(tp); 1100 splx(s); 1101 break; --- 420 unchanged lines hidden (view full) --- 1522 * Lost carrier. 1523 */ 1524 CLR(tp->t_state, TS_CARR_ON); 1525 if (ISSET(tp->t_state, TS_ISOPEN) && 1526 !ISSET(tp->t_cflag, CLOCAL)) { 1527 SET(tp->t_state, TS_ZOMBIE); 1528 CLR(tp->t_state, TS_CONNECTED); 1529 if (tp->t_session) { | 1093 tp->t_pgrp = pgrp; 1094 break; 1095 } 1096 case TIOCSTAT: /* simulate control-T */ 1097 s = spltty(); 1098 ttyinfo(tp); 1099 splx(s); 1100 break; --- 420 unchanged lines hidden (view full) --- 1521 * Lost carrier. 1522 */ 1523 CLR(tp->t_state, TS_CARR_ON); 1524 if (ISSET(tp->t_state, TS_ISOPEN) && 1525 !ISSET(tp->t_cflag, CLOCAL)) { 1526 SET(tp->t_state, TS_ZOMBIE); 1527 CLR(tp->t_state, TS_CONNECTED); 1528 if (tp->t_session) { |
1530 PGRPSESS_SLOCK(); | 1529 sx_slock(&proctree_lock); |
1531 if (tp->t_session->s_leader) { 1532 struct proc *p; 1533 1534 p = tp->t_session->s_leader; 1535 PROC_LOCK(p); 1536 psignal(p, SIGHUP); 1537 PROC_UNLOCK(p); 1538 } | 1530 if (tp->t_session->s_leader) { 1531 struct proc *p; 1532 1533 p = tp->t_session->s_leader; 1534 PROC_LOCK(p); 1535 psignal(p, SIGHUP); 1536 PROC_UNLOCK(p); 1537 } |
1539 PGRPSESS_SUNLOCK(); | 1538 sx_sunlock(&proctree_lock); |
1540 } 1541 ttyflush(tp, FREAD | FWRITE); 1542 return (0); 1543 } 1544 } else { 1545 /* 1546 * Carrier now on. 1547 */ --- 48 unchanged lines hidden (view full) --- 1596 register int c; 1597 register tcflag_t lflag; 1598 register cc_t *cc = tp->t_cc; 1599 register struct proc *p = curproc; 1600 int s, first, error = 0; 1601 int has_stime = 0, last_cc = 0; 1602 long slp = 0; /* XXX this should be renamed `timo'. */ 1603 struct timeval stime; | 1539 } 1540 ttyflush(tp, FREAD | FWRITE); 1541 return (0); 1542 } 1543 } else { 1544 /* 1545 * Carrier now on. 1546 */ --- 48 unchanged lines hidden (view full) --- 1595 register int c; 1596 register tcflag_t lflag; 1597 register cc_t *cc = tp->t_cc; 1598 register struct proc *p = curproc; 1599 int s, first, error = 0; 1600 int has_stime = 0, last_cc = 0; 1601 long slp = 0; /* XXX this should be renamed `timo'. */ 1602 struct timeval stime; |
1603 struct pgrp *pg; |
|
1604 1605loop: 1606 s = spltty(); 1607 lflag = tp->t_lflag; 1608 /* 1609 * take pending input first 1610 */ 1611 if (ISSET(lflag, PENDIN)) { 1612 ttypend(tp); 1613 splx(s); /* reduce latency */ 1614 s = spltty(); 1615 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */ 1616 } 1617 1618 /* 1619 * Hang process if it's in the background. 1620 */ 1621 if (isbackground(p, tp)) { 1622 splx(s); | 1604 1605loop: 1606 s = spltty(); 1607 lflag = tp->t_lflag; 1608 /* 1609 * take pending input first 1610 */ 1611 if (ISSET(lflag, PENDIN)) { 1612 ttypend(tp); 1613 splx(s); /* reduce latency */ 1614 s = spltty(); 1615 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */ 1616 } 1617 1618 /* 1619 * Hang process if it's in the background. 1620 */ 1621 if (isbackground(p, tp)) { 1622 splx(s); |
1623 PGRPSESS_SLOCK(); | 1623 sx_slock(&proctree_lock); |
1624 PROC_LOCK(p); 1625 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) || 1626 SIGISMEMBER(p->p_sigmask, SIGTTIN) || 1627 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) { 1628 PROC_UNLOCK(p); | 1624 PROC_LOCK(p); 1625 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) || 1626 SIGISMEMBER(p->p_sigmask, SIGTTIN) || 1627 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) { 1628 PROC_UNLOCK(p); |
1629 PGRPSESS_SUNLOCK(); | 1629 sx_sunlock(&proctree_lock); |
1630 return (EIO); 1631 } | 1630 return (EIO); 1631 } |
1632 pg = p->p_pgrp; |
|
1632 PROC_UNLOCK(p); | 1633 PROC_UNLOCK(p); |
1633 PGRP_LOCK(p->p_pgrp); 1634 PGRPSESS_SUNLOCK(); 1635 pgsignal(p->p_pgrp, SIGTTIN, 1); 1636 PGRP_UNLOCK(p->p_pgrp); | 1634 PGRP_LOCK(pg); 1635 sx_sunlock(&proctree_lock); 1636 pgsignal(pg, SIGTTIN, 1); 1637 PGRP_UNLOCK(pg); |
1637 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0); 1638 if (error) 1639 return (error); 1640 goto loop; 1641 } 1642 1643 if (ISSET(tp->t_state, TS_ZOMBIE)) { 1644 splx(s); --- 289 unchanged lines hidden (view full) --- 1934 goto out; 1935 goto loop; 1936 } 1937 splx(s); 1938 /* 1939 * Hang the process if it's in the background. 1940 */ 1941 p = curproc; | 1638 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0); 1639 if (error) 1640 return (error); 1641 goto loop; 1642 } 1643 1644 if (ISSET(tp->t_state, TS_ZOMBIE)) { 1645 splx(s); --- 289 unchanged lines hidden (view full) --- 1935 goto out; 1936 goto loop; 1937 } 1938 splx(s); 1939 /* 1940 * Hang the process if it's in the background. 1941 */ 1942 p = curproc; |
1942 PGRPSESS_SLOCK(); | 1943 sx_slock(&proctree_lock); |
1943 PROC_LOCK(p); 1944 if (isbackground(p, tp) && 1945 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) && 1946 !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 1947 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { 1948 if (p->p_pgrp->pg_jobc == 0) { 1949 PROC_UNLOCK(p); | 1944 PROC_LOCK(p); 1945 if (isbackground(p, tp) && 1946 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) && 1947 !SIGISMEMBER(p->p_sigignore, SIGTTOU) && 1948 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) { 1949 if (p->p_pgrp->pg_jobc == 0) { 1950 PROC_UNLOCK(p); |
1950 PGRPSESS_SUNLOCK(); | 1951 sx_sunlock(&proctree_lock); |
1951 error = EIO; 1952 goto out; 1953 } 1954 PROC_UNLOCK(p); 1955 PGRP_LOCK(p->p_pgrp); | 1952 error = EIO; 1953 goto out; 1954 } 1955 PROC_UNLOCK(p); 1956 PGRP_LOCK(p->p_pgrp); |
1956 PGRPSESS_SUNLOCK(); | 1957 sx_sunlock(&proctree_lock); |
1957 pgsignal(p->p_pgrp, SIGTTOU, 1); 1958 PGRP_UNLOCK(p->p_pgrp); 1959 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0); 1960 if (error) 1961 goto out; 1962 goto loop; 1963 } else { 1964 PROC_UNLOCK(p); | 1958 pgsignal(p->p_pgrp, SIGTTOU, 1); 1959 PGRP_UNLOCK(p->p_pgrp); 1960 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0); 1961 if (error) 1962 goto out; 1963 goto loop; 1964 } else { 1965 PROC_UNLOCK(p); |
1965 PGRPSESS_SUNLOCK(); | 1966 sx_sunlock(&proctree_lock); |
1966 } 1967 /* 1968 * Process the user's data in at most OBUFSIZ chunks. Perform any 1969 * output translation. Keep track of high water mark, sleep on 1970 * overflow awaiting device aid in acquiring new space. 1971 */ 1972 while (uio->uio_resid > 0 || cc > 0) { 1973 if (ISSET(tp->t_lflag, FLUSHO)) { --- 722 unchanged lines hidden --- | 1967 } 1968 /* 1969 * Process the user's data in at most OBUFSIZ chunks. Perform any 1970 * output translation. Keep track of high water mark, sleep on 1971 * overflow awaiting device aid in acquiring new space. 1972 */ 1973 while (uio->uio_resid > 0 || cc > 0) { 1974 if (ISSET(tp->t_lflag, FLUSHO)) { --- 722 unchanged lines hidden --- |