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.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 && |
775 ISSET(constty->t_state, TS_CONNECTED)) |
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); |
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); |
857 ttwwakeup(tp); |
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; |
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: |
1030 if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE)) |
1031 goto win; 1032 selrecord(p, &tp->t_rsel); 1033 break; 1034 case FWRITE: |
1035 if ((tp->t_outq.c_cc <= tp->t_lowat && 1036 ISSET(tp->t_state, TS_CONNECTED)) 1037 || ISSET(tp->t_state, TS_ZOMBIE)) { |
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)) && |
1093 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) { |
1094 (*tp->t_oproc)(tp); 1095 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) && |
1096 ISSET(tp->t_state, TS_CONNECTED)) { |
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); |
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)); |
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; |
1381 int s, first, error = 0; |
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 |
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; |
1430 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) { |
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 } |
1520 if (qp->c_cc <= 0) { 1521sleep: |
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) ? |
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(); |
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) { |
1708 splx(s); |
1709 error = EWOULDBLOCK; 1710 goto out; |
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; |
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 |
2051 if (tp->t_rsel.si_pid != 0) 2052 selwakeup(&tp->t_rsel); |
2053 if (ISSET(tp->t_state, TS_ASYNC)) 2054 pgsignal(tp->t_pgrp, SIGIO, 1); |
2055 wakeup(TSA_HUP_OR_INPUT(tp)); |
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(); |
2262 if (!ISSET(tp->t_state, TS_CONNECTED)) { |
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 --- |