Deleted Added
full compact
tty.c (9823) tty.c (9824)
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 * $Id: tty.c,v 1.61 1995/07/31 18:29:28 bde Exp $
39 * $Id: tty.c,v 1.62 1995/07/31 19:17:11 bde Exp $
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.

--- 719 unchanged lines hidden (view full) ---

767 else
768 flags &= FREAD | FWRITE;
769 ttyflush(tp, flags);
770 break;
771 }
772 case TIOCCONS: /* become virtual console */
773 if (*(int *)data) {
774 if (constty && constty != tp &&
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.

--- 719 unchanged lines hidden (view full) ---

767 else
768 flags &= FREAD | FWRITE;
769 ttyflush(tp, flags);
770 break;
771 }
772 case TIOCCONS: /* become virtual console */
773 if (*(int *)data) {
774 if (constty && constty != tp &&
775 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
776 (TS_CARR_ON | TS_ISOPEN))
775 ISSET(constty->t_state, TS_CONNECTED))
777 return (EBUSY);
778#ifndef UCONSOLE
779 if (error = suser(p->p_ucred, &p->p_acflag))
780 return (error);
781#endif
782 constty = tp;
783 } else if (tp == constty)
784 constty = NULL;

--- 52 unchanged lines hidden (view full) ---

837 }
838 if (!ISSET(t->c_cflag, CIGNORE)) {
839 /*
840 * Set device hardware.
841 */
842 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
843 splx(s);
844 return (error);
776 return (EBUSY);
777#ifndef UCONSOLE
778 if (error = suser(p->p_ucred, &p->p_acflag))
779 return (error);
780#endif
781 constty = tp;
782 } else if (tp == constty)
783 constty = NULL;

--- 52 unchanged lines hidden (view full) ---

836 }
837 if (!ISSET(t->c_cflag, CIGNORE)) {
838 /*
839 * Set device hardware.
840 */
841 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
842 splx(s);
843 return (error);
845 } else {
846 if (!ISSET(tp->t_state, TS_CARR_ON) &&
847 ISSET(tp->t_cflag, CLOCAL) &&
848 !ISSET(t->c_cflag, CLOCAL)) {
849#if 0
850 CLR(tp->t_state, TS_ISOPEN);
851#endif
852 ttwakeup(tp);
853 }
844 }
845 if (ISSET(t->c_cflag, CLOCAL) &&
846 !ISSET(tp->t_cflag, CLOCAL)) {
847 /*
848 * XXX disconnections would be too hard to
849 * get rid of without this kludge. The only
850 * way to get rid of controlling terminals
851 * is to exit from the session leader.
852 */
853 CLR(tp->t_state, TS_ZOMBIE);
854
855 wakeup(TSA_CARR_ON(tp));
856 ttwakeup(tp);
854 ttwwakeup(tp);
857 ttwwakeup(tp);
855 tp->t_cflag = t->c_cflag;
856 tp->t_ispeed = t->c_ispeed;
857 tp->t_ospeed = t->c_ospeed;
858 }
858 }
859 if ((ISSET(tp->t_state, TS_CARR_ON) ||
860 ISSET(t->c_cflag, CLOCAL)) &&
861 !ISSET(tp->t_state, TS_ZOMBIE))
862 SET(tp->t_state, TS_CONNECTED);
863 else
864 CLR(tp->t_state, TS_CONNECTED);
865 tp->t_cflag = t->c_cflag;
866 tp->t_ispeed = t->c_ispeed;
867 tp->t_ospeed = t->c_ospeed;
859 ttsetwater(tp);
860 }
861 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
862 cmd != TIOCSETAF) {
863 if (ISSET(t->c_lflag, ICANON))
864 SET(tp->t_lflag, PENDIN);
865 else {
866 /*

--- 146 unchanged lines hidden (view full) ---

1013 int s;
1014
1015 if (tp == NULL)
1016 return (ENXIO);
1017
1018 s = spltty();
1019 switch (rw) {
1020 case FREAD:
868 ttsetwater(tp);
869 }
870 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
871 cmd != TIOCSETAF) {
872 if (ISSET(t->c_lflag, ICANON))
873 SET(tp->t_lflag, PENDIN);
874 else {
875 /*

--- 146 unchanged lines hidden (view full) ---

1022 int s;
1023
1024 if (tp == NULL)
1025 return (ENXIO);
1026
1027 s = spltty();
1028 switch (rw) {
1029 case FREAD:
1021 if (ttnread(tp) > 0 || (!ISSET(tp->t_cflag, CLOCAL) &&
1022 !ISSET(tp->t_state, TS_CARR_ON)))
1030 if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
1023 goto win;
1024 selrecord(p, &tp->t_rsel);
1025 break;
1026 case FWRITE:
1031 goto win;
1032 selrecord(p, &tp->t_rsel);
1033 break;
1034 case FWRITE:
1027 if (tp->t_outq.c_cc <= tp->t_lowat) {
1035 if ((tp->t_outq.c_cc <= tp->t_lowat &&
1036 ISSET(tp->t_state, TS_CONNECTED))
1037 || ISSET(tp->t_state, TS_ZOMBIE)) {
1028win: splx(s);
1029 return (1);
1030 }
1031 selrecord(p, &tp->t_wsel);
1032 break;
1033 }
1034 splx(s);
1035 return (0);

--- 39 unchanged lines hidden (view full) ---

1075ttywait(tp)
1076 register struct tty *tp;
1077{
1078 int error, s;
1079
1080 error = 0;
1081 s = spltty();
1082 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1038win: splx(s);
1039 return (1);
1040 }
1041 selrecord(p, &tp->t_wsel);
1042 break;
1043 }
1044 splx(s);
1045 return (0);

--- 39 unchanged lines hidden (view full) ---

1085ttywait(tp)
1086 register struct tty *tp;
1087{
1088 int error, s;
1089
1090 error = 0;
1091 s = spltty();
1092 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1083 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
1084 && tp->t_oproc) {
1093 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1085 (*tp->t_oproc)(tp);
1086 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1094 (*tp->t_oproc)(tp);
1095 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1087 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))) {
1096 ISSET(tp->t_state, TS_CONNECTED)) {
1088 SET(tp->t_state, TS_SO_OCOMPLETE);
1089 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1090 TTOPRI | PCATCH, "ttywai",
1091 tp->t_timeout);
1092 if (error) {
1093 if (error == EWOULDBLOCK)
1094 error = EIO;
1095 break;

--- 205 unchanged lines hidden (view full) ---

1301 }
1302 } else if (flag == 0) {
1303 /*
1304 * Lost carrier.
1305 */
1306 CLR(tp->t_state, TS_CARR_ON);
1307 if (ISSET(tp->t_state, TS_ISOPEN) &&
1308 !ISSET(tp->t_cflag, CLOCAL)) {
1097 SET(tp->t_state, TS_SO_OCOMPLETE);
1098 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1099 TTOPRI | PCATCH, "ttywai",
1100 tp->t_timeout);
1101 if (error) {
1102 if (error == EWOULDBLOCK)
1103 error = EIO;
1104 break;

--- 205 unchanged lines hidden (view full) ---

1310 }
1311 } else if (flag == 0) {
1312 /*
1313 * Lost carrier.
1314 */
1315 CLR(tp->t_state, TS_CARR_ON);
1316 if (ISSET(tp->t_state, TS_ISOPEN) &&
1317 !ISSET(tp->t_cflag, CLOCAL)) {
1318 SET(tp->t_state, TS_ZOMBIE);
1319 CLR(tp->t_state, TS_CONNECTED);
1309 if (tp->t_session && tp->t_session->s_leader)
1310 psignal(tp->t_session->s_leader, SIGHUP);
1311 ttyflush(tp, FREAD | FWRITE);
1312 return (0);
1313 }
1314 } else {
1315 /*
1316 * Carrier now on.
1317 */
1318 SET(tp->t_state, TS_CARR_ON);
1320 if (tp->t_session && tp->t_session->s_leader)
1321 psignal(tp->t_session->s_leader, SIGHUP);
1322 ttyflush(tp, FREAD | FWRITE);
1323 return (0);
1324 }
1325 } else {
1326 /*
1327 * Carrier now on.
1328 */
1329 SET(tp->t_state, TS_CARR_ON);
1330 if (!ISSET(tp->t_state, TS_ZOMBIE))
1331 SET(tp->t_state, TS_CONNECTED);
1332 wakeup(TSA_CARR_ON(tp));
1319 ttwakeup(tp);
1320 ttwwakeup(tp);
1321 }
1322 return (1);
1323}
1324
1325/*
1326 * Reinput pending characters after state switch

--- 32 unchanged lines hidden (view full) ---

1359 struct uio *uio;
1360 int flag;
1361{
1362 register struct clist *qp;
1363 register int c;
1364 register tcflag_t lflag;
1365 register cc_t *cc = tp->t_cc;
1366 register struct proc *p = curproc;
1333 ttwakeup(tp);
1334 ttwwakeup(tp);
1335 }
1336 return (1);
1337}
1338
1339/*
1340 * Reinput pending characters after state switch

--- 32 unchanged lines hidden (view full) ---

1373 struct uio *uio;
1374 int flag;
1375{
1376 register struct clist *qp;
1377 register int c;
1378 register tcflag_t lflag;
1379 register cc_t *cc = tp->t_cc;
1380 register struct proc *p = curproc;
1367 int s, first, error = 0, carrier;
1381 int s, first, error = 0;
1368 int has_stime = 0, last_cc = 0;
1369 long slp = 0; /* XXX this should be renamed `timo'. */
1370
1371loop:
1372 s = spltty();
1373 lflag = tp->t_lflag;
1374 /*
1375 * take pending input first

--- 16 unchanged lines hidden (view full) ---

1392 return (EIO);
1393 pgsignal(p->p_pgrp, SIGTTIN, 1);
1394 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1395 if (error)
1396 return (error);
1397 goto loop;
1398 }
1399
1382 int has_stime = 0, last_cc = 0;
1383 long slp = 0; /* XXX this should be renamed `timo'. */
1384
1385loop:
1386 s = spltty();
1387 lflag = tp->t_lflag;
1388 /*
1389 * take pending input first

--- 16 unchanged lines hidden (view full) ---

1406 return (EIO);
1407 pgsignal(p->p_pgrp, SIGTTIN, 1);
1408 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1409 if (error)
1410 return (error);
1411 goto loop;
1412 }
1413
1414 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1415 splx(s);
1416 return (0); /* EOF */
1417 }
1418
1400 /*
1401 * If canonical, use the canonical queue,
1402 * else use the raw queue.
1403 *
1404 * (should get rid of clists...)
1405 */
1406 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1407
1408 if (flag & IO_NDELAY) {
1409 if (qp->c_cc > 0)
1410 goto read;
1419 /*
1420 * If canonical, use the canonical queue,
1421 * else use the raw queue.
1422 *
1423 * (should get rid of clists...)
1424 */
1425 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1426
1427 if (flag & IO_NDELAY) {
1428 if (qp->c_cc > 0)
1429 goto read;
1411 carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1412 ISSET(tp->t_cflag, CLOCAL);
1413 if ((!carrier && ISSET(tp->t_state, TS_ISOPEN)) ||
1414 !ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1430 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1415 splx(s);
1416 return (0);
1417 }
1418 splx(s);
1419 return (EWOULDBLOCK);
1420 }
1421 if (!ISSET(lflag, ICANON)) {
1422 int m = cc[VMIN];

--- 73 unchanged lines hidden (view full) ---

1496 * 32-bit arithmetic is enough for hz < 169.
1497 * XXX see hzto() for how to avoid overflow if hz
1498 * is large (divide by `tick' and/or arrange to
1499 * use hzto() if hz is large).
1500 */
1501 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1502 goto sleep;
1503 }
1431 splx(s);
1432 return (0);
1433 }
1434 splx(s);
1435 return (EWOULDBLOCK);
1436 }
1437 if (!ISSET(lflag, ICANON)) {
1438 int m = cc[VMIN];

--- 73 unchanged lines hidden (view full) ---

1512 * 32-bit arithmetic is enough for hz < 169.
1513 * XXX see hzto() for how to avoid overflow if hz
1514 * is large (divide by `tick' and/or arrange to
1515 * use hzto() if hz is large).
1516 */
1517 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1518 goto sleep;
1519 }
1504
1505 /*
1506 * If there is no input, sleep on rawq
1507 * awaiting hardware receipt and notification.
1508 * If we have data, we don't need to check for carrier.
1509 */
1510 if (qp->c_cc <= 0) {
1511sleep:
1520 if (qp->c_cc <= 0) {
1521sleep:
1512 carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1513 ISSET(tp->t_cflag, CLOCAL);
1514 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1515 splx(s);
1516 return (0); /* EOF */
1517 }
1518 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
1519 carrier ?
1522 /*
1523 * There is no input, or not enough input and we can block.
1524 */
1525 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
1526 ISSET(tp->t_state, TS_CONNECTED) ?
1520 "ttyin" : "ttyhup", (int)slp);
1521 splx(s);
1522 if (error == EWOULDBLOCK)
1523 error = 0;
1524 else if (error)
1525 return (error);
1526 /*
1527 * XXX what happens if another process eats some input

--- 157 unchanged lines hidden (view full) ---

1685 char obuf[OBUFSIZ];
1686
1687 hiwat = tp->t_hiwat;
1688 cnt = uio->uio_resid;
1689 error = 0;
1690 cc = 0;
1691loop:
1692 s = spltty();
1527 "ttyin" : "ttyhup", (int)slp);
1528 splx(s);
1529 if (error == EWOULDBLOCK)
1530 error = 0;
1531 else if (error)
1532 return (error);
1533 /*
1534 * XXX what happens if another process eats some input

--- 157 unchanged lines hidden (view full) ---

1692 char obuf[OBUFSIZ];
1693
1694 hiwat = tp->t_hiwat;
1695 cnt = uio->uio_resid;
1696 error = 0;
1697 cc = 0;
1698loop:
1699 s = spltty();
1693 if (!ISSET(tp->t_state, TS_CARR_ON) &&
1694 !ISSET(tp->t_cflag, CLOCAL)) {
1695 if (ISSET(tp->t_state, TS_ISOPEN)) {
1700 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1701 splx(s);
1702 if (uio->uio_resid == cnt)
1703 error = EIO;
1704 goto out;
1705 }
1706 if (!ISSET(tp->t_state, TS_CONNECTED)) {
1707 if (flag & IO_NDELAY) {
1696 splx(s);
1708 splx(s);
1697 return (EIO);
1698 } else if (flag & IO_NDELAY) {
1699 splx(s);
1700 error = EWOULDBLOCK;
1701 goto out;
1709 error = EWOULDBLOCK;
1710 goto out;
1702 } else {
1703 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
1704 "ttydcd", 0);
1705 splx(s);
1706 if (error)
1707 goto out;
1708 goto loop;
1709 }
1711 }
1712 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
1713 "ttydcd", 0);
1714 splx(s);
1715 if (error)
1716 goto out;
1717 goto loop;
1710 }
1711 splx(s);
1712 /*
1713 * Hang the process if it's in the background.
1714 */
1715 p = curproc;
1716 if (isbackground(p, tp) &&
1717 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&

--- 317 unchanged lines hidden (view full) ---

2035/*
2036 * Wake up any readers on a tty.
2037 */
2038void
2039ttwakeup(tp)
2040 register struct tty *tp;
2041{
2042
1718 }
1719 splx(s);
1720 /*
1721 * Hang the process if it's in the background.
1722 */
1723 p = curproc;
1724 if (isbackground(p, tp) &&
1725 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&

--- 317 unchanged lines hidden (view full) ---

2043/*
2044 * Wake up any readers on a tty.
2045 */
2046void
2047ttwakeup(tp)
2048 register struct tty *tp;
2049{
2050
2043 selwakeup(&tp->t_rsel);
2051 if (tp->t_rsel.si_pid != 0)
2052 selwakeup(&tp->t_rsel);
2044 if (ISSET(tp->t_state, TS_ASYNC))
2045 pgsignal(tp->t_pgrp, SIGIO, 1);
2053 if (ISSET(tp->t_state, TS_ASYNC))
2054 pgsignal(tp->t_pgrp, SIGIO, 1);
2046 wakeup(TSA_CARR_ON(tp));
2055 wakeup(TSA_HUP_OR_INPUT(tp));
2047}
2048
2049/*
2050 * Wake up any writers on a tty.
2051 */
2052void
2053ttwwakeup(tp)
2054 register struct tty *tp;

--- 190 unchanged lines hidden (view full) ---

2245int
2246tputchar(c, tp)
2247 int c;
2248 struct tty *tp;
2249{
2250 register int s;
2251
2252 s = spltty();
2056}
2057
2058/*
2059 * Wake up any writers on a tty.
2060 */
2061void
2062ttwwakeup(tp)
2063 register struct tty *tp;

--- 190 unchanged lines hidden (view full) ---

2254int
2255tputchar(c, tp)
2256 int c;
2257 struct tty *tp;
2258{
2259 register int s;
2260
2261 s = spltty();
2253 if (ISSET(tp->t_state,
2254 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
2262 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2255 splx(s);
2256 return (-1);
2257 }
2258 if (c == '\n')
2259 (void)ttyoutput('\r', tp);
2260 (void)ttyoutput(c, tp);
2261 ttstart(tp);
2262 splx(s);

--- 56 unchanged lines hidden ---
2263 splx(s);
2264 return (-1);
2265 }
2266 if (c == '\n')
2267 (void)ttyoutput('\r', tp);
2268 (void)ttyoutput(c, tp);
2269 ttstart(tp);
2270 splx(s);

--- 56 unchanged lines hidden ---