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 --- |