Deleted Added
full compact
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 ---