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 $
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))
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);
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 }
854 ttwwakeup(tp);
855 tp->t_cflag = t->c_cflag;
856 tp->t_ispeed = t->c_ispeed;
857 tp->t_ospeed = t->c_ospeed;
858 }
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:
1021 if (ttnread(tp) > 0 || (!ISSET(tp->t_cflag, CLOCAL) &&
1022 !ISSET(tp->t_state, TS_CARR_ON)))
1023 goto win;
1024 selrecord(p, &tp->t_rsel);
1025 break;
1026 case FWRITE:
1027 if (tp->t_outq.c_cc <= tp->t_lowat) {
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)) &&
1083 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
1084 && tp->t_oproc) {
1085 (*tp->t_oproc)(tp);
1086 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))) {
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)) {
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);
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;
1367 int s, first, error = 0, carrier;
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
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;
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) {
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 }
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:
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 ?
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();
1693 if (!ISSET(tp->t_state, TS_CARR_ON) &&
1694 !ISSET(tp->t_cflag, CLOCAL)) {
1695 if (ISSET(tp->t_state, TS_ISOPEN)) {
1696 splx(s);
1697 return (EIO);
1698 } else if (flag & IO_NDELAY) {
1699 splx(s);
1700 error = EWOULDBLOCK;
1701 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 }
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
2043 selwakeup(&tp->t_rsel);
2044 if (ISSET(tp->t_state, TS_ASYNC))
2045 pgsignal(tp->t_pgrp, SIGIO, 1);
2046 wakeup(TSA_CARR_ON(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();
2253 if (ISSET(tp->t_state,
2254 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
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 ---
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 $
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))
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);
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 }
854 ttwwakeup(tp);
855 tp->t_cflag = t->c_cflag;
856 tp->t_ispeed = t->c_ispeed;
857 tp->t_ospeed = t->c_ospeed;
858 }
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:
1021 if (ttnread(tp) > 0 || (!ISSET(tp->t_cflag, CLOCAL) &&
1022 !ISSET(tp->t_state, TS_CARR_ON)))
1023 goto win;
1024 selrecord(p, &tp->t_rsel);
1025 break;
1026 case FWRITE:
1027 if (tp->t_outq.c_cc <= tp->t_lowat) {
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)) &&
1083 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
1084 && tp->t_oproc) {
1085 (*tp->t_oproc)(tp);
1086 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))) {
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)) {
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);
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;
1367 int s, first, error = 0, carrier;
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
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;
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) {
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 }
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:
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 ?
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();
1693 if (!ISSET(tp->t_state, TS_CARR_ON) &&
1694 !ISSET(tp->t_cflag, CLOCAL)) {
1695 if (ISSET(tp->t_state, TS_ISOPEN)) {
1696 splx(s);
1697 return (EIO);
1698 } else if (flag & IO_NDELAY) {
1699 splx(s);
1700 error = EWOULDBLOCK;
1701 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 }
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
2043 selwakeup(&tp->t_rsel);
2044 if (ISSET(tp->t_state, TS_ASYNC))
2045 pgsignal(tp->t_pgrp, SIGIO, 1);
2046 wakeup(TSA_CARR_ON(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();
2253 if (ISSET(tp->t_state,
2254 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
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 ---