Lines Matching refs:tp
87 * of in drivers and fix drivers that write to tp->t_termios.
122 #define TTY_LOCK_OWNED(tp) do {lck_mtx_assert(&tp->t_lock, LCK_MTX_ASSERT_OWNED); } while (0)
123 #define TTY_LOCK_NOTOWNED(tp) do {lck_mtx_assert(&tp->t_lock, LCK_MTX_ASSERT_NOTOWNED); } while (0)
125 #define TTY_LOCK_OWNED(tp)
126 #define TTY_LOCK_NOTOWNED(tp)
133 static int ttnread(struct tty *tp);
134 static void ttyecho(int c, struct tty *tp);
135 static int ttyoutput(int c, struct tty *tp);
136 static void ttypend(struct tty *tp);
137 static void ttyretype(struct tty *tp);
138 static void ttyrub(int c, struct tty *tp);
139 static void ttyrubo(struct tty *tp, int count);
140 static void ttystop(struct tty *tp, int rw);
141 static void ttyunblock(struct tty *tp);
142 static int ttywflush(struct tty *tp);
145 static void ttyhold(struct tty *tp);
146 static void ttydeallocate(struct tty *tp);
148 static int isctty(proc_t p, struct tty *tp);
149 static int isctty_sp(proc_t p, struct tty *tp, struct session *sessp);
301 * Parameters: tp The tty we want to lock
305 * Locks: On return, tp is locked
308 tty_lock(struct tty *tp)
310 TTY_LOCK_NOTOWNED(tp); /* debug assert */
311 lck_mtx_lock(&tp->t_lock);
320 * Parameters: tp The tty we want to unlock
324 * Locks: On return, tp is unlocked
327 tty_unlock(struct tty *tp)
329 TTY_LOCK_OWNED(tp); /* debug assert */
330 lck_mtx_unlock(&tp->t_lock);
342 ttyopen(dev_t device, struct tty *tp)
349 TTY_LOCK_OWNED(tp); /* debug assert */
351 tp->t_dev = device;
353 if (!ISSET(tp->t_state, TS_ISOPEN)) {
354 SET(tp->t_state, TS_ISOPEN);
355 if (ISSET(tp->t_cflag, CLOCAL)) {
356 SET(tp->t_state, TS_CONNECTED); }
357 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
369 tp->t_session == NULL ) { /* and tty not controlling */
373 ttyhold(tp);
374 sessp->s_ttyp = tp;
378 oldpg = tp->t_pgrp;
379 oldsess = tp->t_session;
382 tp->t_session = sessp;
383 tp->t_pgrp = pg;
387 tty_unlock(tp);
394 tty_lock(tp);
401 tty_unlock(tp);
406 tty_lock(tp);
427 ttyclose(struct tty *tp)
432 TTY_LOCK_OWNED(tp); /* debug assert */
434 if (constty == tp) {
442 (*cdevsw[major(tp->t_dev)].d_ioctl)
443 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, current_proc());
446 ttyflush(tp, FREAD | FWRITE);
448 tp->t_gen++;
449 tp->t_line = TTYDISC;
451 oldpg = tp->t_pgrp;
452 oldsessp = tp->t_session;
453 tp->t_pgrp = NULL;
454 tp->t_session = NULL;
460 tty_unlock(tp);
465 tty_lock(tp);
466 tp->t_state = 0;
467 selthreadclear(&tp->t_wsel);
468 selthreadclear(&tp->t_rsel);
489 * tp The tty on which it was received
496 ttyinput(int c, struct tty *tp)
503 TTY_LOCK_OWNED(tp); /* debug assert */
508 lflag = tp->t_lflag;
510 ttypend(tp);
516 ++tp->t_cancc;
519 ++tp->t_rawcc;
529 iflag = tp->t_iflag;
530 if (tp->t_rawq.c_cc + tp->t_canq.c_cc > I_HIGH_WATER - 3 &&
531 (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
532 (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
533 !ISSET(tp->t_state, TS_TBLOCK))
534 ttyblock(tp);
537 cc = tp->t_cc;
546 ttyflush(tp, FREAD | FWRITE);
548 tty_unlock(tp);
549 tty_pgsignal(tp, SIGINT, 1);
550 tty_lock(tp);
562 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
565 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
566 (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
567 (void)putc(c | TTY_QUOTE, &tp->t_rawq);
574 if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
580 if (ISSET(tp->t_state, TS_LNCH)) {
582 CLR(tp->t_state, TS_LNCH);
600 (void)ttyoutput('^', tp);
601 (void)ttyoutput('\b', tp);
603 ttyecho(c, tp);
605 SET(tp->t_state, TS_LNCH);
610 CLR(tp->t_lflag, FLUSHO);
612 ttyflush(tp, FWRITE);
613 ttyecho(c, tp);
614 if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
615 ttyretype(tp);
616 SET(tp->t_lflag, FLUSHO);
627 ttyflush(tp, FREAD | FWRITE);
628 ttyecho(c, tp);
638 tty_unlock(tp);
639 tty_pgsignal(tp,
641 tty_lock(tp);
646 ttyflush(tp, FREAD);
647 ttyecho(c, tp);
649 tty_unlock(tp);
650 tty_pgsignal(tp, SIGTSTP, 1);
651 tty_lock(tp);
660 if (!ISSET(tp->t_state, TS_TTSTOP)) {
661 SET(tp->t_state, TS_TTSTOP);
662 ttystop(tp, 0);
688 if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
697 if (tp->t_rawq.c_cc) {
700 ttyrub((c = unputc(&tp->t_rawq)), tp);
701 } while(tp->t_rawq.c_cc && CCONT(c));
703 ttyrub(unputc(&tp->t_rawq), tp);
713 tp->t_rawq.c_cc == tp->t_rocount &&
715 while (tp->t_rawq.c_cc)
716 ttyrub(unputc(&tp->t_rawq), tp);
718 ttyecho(c, tp);
721 ttyecho('\n', tp);
722 FLUSHQ(&tp->t_rawq);
723 tp->t_rocount = 0;
725 CLR(tp->t_state, TS_LOCAL);
737 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
738 ttyrub(c, tp);
745 ttyrub(c, tp);
746 c = unputc(&tp->t_rawq);
750 (void)putc(c, &tp->t_rawq);
758 ttyrub(c, tp);
759 c = unputc(&tp->t_rawq);
764 (void)putc(c, &tp->t_rawq);
771 ttyretype(tp);
780 tty_unlock(tp);
781 tty_pgsignal(tp, SIGINFO, 1);
782 tty_lock(tp);
785 ttyinfo_locked(tp);
792 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
795 if (tp->t_outq.c_cc < tp->t_hiwat)
796 (void)ttyoutput(CTRL('g'), tp);
803 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
809 if (putc(c, &tp->t_rawq) >= 0) {
811 ttwakeup(tp);
812 ttyecho(c, tp);
816 tp->t_rocount = 0;
817 catq(&tp->t_rawq, &tp->t_canq);
818 ttwakeup(tp);
819 } else if (tp->t_rocount++ == 0)
820 tp->t_rocol = tp->t_column;
821 if (ISSET(tp->t_state, TS_ERASE)) {
825 CLR(tp->t_state, TS_ERASE);
826 (void)ttyoutput('/', tp);
828 i = tp->t_column;
829 ttyecho(c, tp);
834 i = min(2, tp->t_column - i);
836 (void)ttyoutput('\b', tp);
846 if (ISSET(tp->t_state, TS_TTSTOP) &&
852 CLR(tp->t_lflag, FLUSHO);
853 CLR(tp->t_state, TS_TTSTOP);
857 retval = ttstart(tp);
871 * tp The tty on which to output on the tty
876 * Locks: Assumes tp is locked on entry, remains locked on exit
881 ttyoutput(int c, struct tty *tp)
886 TTY_LOCK_OWNED(tp); /* debug assert */
888 oflag = tp->t_oflag;
890 if (ISSET(tp->t_lflag, FLUSHO))
892 if (putc(c, &tp->t_outq))
895 tp->t_outcc++;
906 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
907 col = c = 8 - (tp->t_column & 7);
908 if (!ISSET(tp->t_lflag, FLUSHO)) {
909 c -= b_to_q((const u_char *)" ", c, &tp->t_outq);
911 tp->t_outcc += c;
913 tp->t_column += c;
923 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
925 tp->t_outcc++;
926 if (putc('\r', &tp->t_outq))
930 else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
933 else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0)
936 tp->t_outcc++;
937 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
940 col = tp->t_column;
959 tp->t_column = col;
982 ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, proc_t p)
986 tty_lock(tp);
987 retval = ttioctl_locked(tp, cmd, data, flag, p);
988 tty_unlock(tp);
999 * Parameters: tp Tty on which ioctl() is being called
1036 * *tp->t_param:? TIOCSETA* underlying function
1041 * tp at the time of the call. The lock remains held on return.
1052 ttioctl_locked(struct tty *tp, u_long cmd, caddr_t data, int flag, proc_t p)
1060 TTY_LOCK_OWNED(tp); /* debug assert */
1090 while (isbackground(p, tp) &&
1100 tty_unlock(tp);
1103 tty_lock(tp);
1109 tty_lock(tp);
1127 SET(tp->t_state, TS_ASYNC);
1129 CLR(tp->t_state, TS_ASYNC);
1134 *(int *)data = ttnread(tp);
1137 SET(tp->t_state, TS_XCLUDE);
1146 ttyflush(tp, flags);
1158 if (constty && constty != tp &&
1165 constty = tp;
1166 } else if (tp == constty) {
1173 (*cdevsw[major(tp->t_dev)].d_ioctl)
1174 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, p);
1179 error = ttywait(tp);
1185 termios64to32((struct user_termios *)&tp->t_termios, (struct termios32 *)data);
1187 bcopy(&tp->t_termios, data, sizeof(struct termios));
1192 bcopy(&tp->t_termios, data, sizeof(struct termios));
1194 termios32to64((struct termios32 *)&tp->t_termios, (struct user_termios *)data);
1198 *(int *)data = tp->t_line;
1201 *(struct winsize *)data = tp->t_winsize;
1204 if (!isctty(p, tp)) {
1208 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
1212 SET(tp->t_cflag, HUPCL);
1216 CLR(tp->t_state, TS_XCLUDE);
1219 *(int *)data = tp->t_outq.c_cc;
1253 error = ttywait(tp);
1258 ttyflush(tp, FREAD);
1264 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1268 !ISSET(tp->t_cflag, CLOCAL)) {
1275 CLR(tp->t_state, TS_ZOMBIE);
1277 wakeup(TSA_CARR_ON(tp));
1278 ttwakeup(tp);
1279 ttwwakeup(tp);
1281 if ((ISSET(tp->t_state, TS_CARR_ON) ||
1283 !ISSET(tp->t_state, TS_ZOMBIE))
1284 SET(tp->t_state, TS_CONNECTED);
1286 CLR(tp->t_state, TS_CONNECTED);
1287 tp->t_cflag = t->c_cflag;
1288 tp->t_ispeed = t->c_ispeed;
1289 tp->t_ospeed = t->c_ospeed;
1290 ttsetwater(tp);
1292 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
1295 SET(tp->t_lflag, PENDIN);
1303 if (tp->t_rawq.c_cs && tp->t_canq.c_cs) {
1306 catq(&tp->t_rawq, &tp->t_canq);
1307 tq = tp->t_rawq;
1308 tp->t_rawq = tp->t_canq;
1309 tp->t_canq = tq;
1311 CLR(tp->t_lflag, PENDIN);
1313 ttwakeup(tp);
1315 tp->t_iflag = t->c_iflag;
1316 tp->t_oflag = t->c_oflag;
1320 if (ISSET(tp->t_lflag, EXTPROC))
1324 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1325 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1326 t->c_cc[VTIME] != tp->t_cc[VTIME])
1327 ttwakeup(tp);
1328 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1333 dev_t device = tp->t_dev;
1343 if (t != tp->t_line) {
1344 (*linesw[tp->t_line].l_close)(tp, flag);
1345 error = (*linesw[t].l_open)(device, tp);
1348 (void)(*linesw[tp->t_line].l_open)(device, tp);
1351 tp->t_line = t;
1356 if (ISSET(tp->t_state, TS_TTSTOP) ||
1357 ISSET(tp->t_lflag, FLUSHO)) {
1358 CLR(tp->t_lflag, FLUSHO);
1359 CLR(tp->t_state, TS_TTSTOP);
1360 ttstart(tp);
1368 if (suser(kauth_cred_get(), NULL) && !isctty(p, tp)) {
1372 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1375 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1376 SET(tp->t_state, TS_TTSTOP);
1377 ttystop(tp, 0);
1381 ttyunblock(tp);
1384 ttyblock(tp);
1391 ((sessp->s_ttyvp || tp->t_session) &&
1392 (tp->t_session != sessp))) {
1394 tty_unlock(tp);
1399 tty_lock(tp);
1404 oldsessp = tp->t_session;
1405 oldpg = tp->t_pgrp;
1408 /* do not drop refs on sessp and pg as tp holds them */
1409 tp->t_session = sessp;
1411 tp->t_pgrp = pg;
1415 ttyhold(tp);
1416 sessp->s_ttyp = tp;
1420 tty_unlock(tp);
1428 tty_lock(tp);
1435 if (!isctty_sp(p, tp, sessp)) {
1448 tty_unlock(tp);
1452 tty_lock(tp);
1457 oldpg = tp->t_pgrp;
1458 tp->t_pgrp = pgrp;
1462 tty_unlock(tp);
1467 tty_lock(tp);
1471 ttyinfo_locked(tp);
1474 if (bcmp((caddr_t)&tp->t_winsize, data,
1476 tp->t_winsize = *(struct winsize *)data;
1478 tty_unlock(tp);
1479 tty_pgsignal(tp, SIGWINCH, 1);
1480 tty_lock(tp);
1488 tp->t_timeout = *(int *)data * hz;
1489 wakeup(TSA_OCOMPLETE(tp));
1490 wakeup(TSA_OLOWAT(tp));
1493 *(int *)data = tp->t_timeout / hz;
1496 error = ttcompat(tp, cmd, data, flag, p);
1507 * Locks: Assumes tp is locked on entry, remains locked on exit
1510 ttyselect(struct tty *tp, int rw, void *wql, proc_t p)
1514 if (tp == NULL)
1517 TTY_LOCK_OWNED(tp); /* debug assert */
1521 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1525 retval = ttnread(tp);
1530 selrecord(p, &tp->t_rsel, wql);
1533 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1537 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
1538 ISSET(tp->t_state, TS_CONNECTED)) {
1539 retval = tp->t_hiwat - tp->t_outq.c_cc;
1543 selrecord(p, &tp->t_wsel, wql);
1560 struct tty *tp = cdevsw[major(dev)].d_ttys[minor(dev)];
1562 tty_lock(tp);
1563 rv = ttyselect(tp, rw, wql, p);
1564 tty_unlock(tp);
1571 * Locks: Assumes tp is locked on entry, remains locked on exit
1574 ttnread(struct tty *tp)
1578 TTY_LOCK_OWNED(tp); /* debug assert */
1580 if (ISSET(tp->t_lflag, PENDIN))
1581 ttypend(tp);
1582 nread = tp->t_canq.c_cc;
1583 if (!ISSET(tp->t_lflag, ICANON)) {
1584 nread += tp->t_rawq.c_cc;
1585 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1597 * Parameters: tp Tty on which to wait for output to drain
1608 * Locks: Assumes tp is locked on entry, remains locked on exit
1611 ttywait(struct tty *tp)
1615 TTY_LOCK_OWNED(tp); /* debug assert */
1618 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1619 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1620 (*tp->t_oproc)(tp);
1621 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1622 ISSET(tp->t_state, TS_CONNECTED)) {
1623 SET(tp->t_state, TS_SO_OCOMPLETE);
1624 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1626 tp->t_timeout);
1635 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1646 ttystop(struct tty *tp, int rw)
1648 TTY_LOCK_OWNED(tp); /* debug assert */
1650 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1659 ttywflush(struct tty *tp)
1663 TTY_LOCK_OWNED(tp); /* debug assert */
1665 if ((error = ttywait(tp)) == 0)
1666 ttyflush(tp, FREAD);
1676 ttyflush(struct tty *tp, int rw)
1678 TTY_LOCK_OWNED(tp); /* debug assert */
1684 FLUSHQ(&tp->t_outq);
1685 CLR(tp->t_state, TS_TTSTOP);
1687 ttystop(tp, rw);
1689 FLUSHQ(&tp->t_canq);
1690 FLUSHQ(&tp->t_rawq);
1691 CLR(tp->t_lflag, PENDIN);
1692 tp->t_rocount = 0;
1693 tp->t_rocol = 0;
1694 CLR(tp->t_state, TS_LOCAL);
1695 ttwakeup(tp);
1696 if (ISSET(tp->t_state, TS_TBLOCK)) {
1698 FLUSHQ(&tp->t_outq);
1699 ttyunblock(tp);
1708 CLR(tp->t_state, TS_TBLOCK);
1711 if (ISSET(tp->t_iflag, IXOFF)) {
1721 SET(tp->t_state, TS_SO_OCOMPLETE);
1722 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1727 CLR(tp->t_state, TS_TBLOCK);
1734 FLUSHQ(&tp->t_outq);
1735 ttwwakeup(tp);
1744 * Notes: No assertion; tp is not in scope.
1761 ttyblock(struct tty *tp)
1763 TTY_LOCK_OWNED(tp); /* debug assert */
1765 SET(tp->t_state, TS_TBLOCK);
1766 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1767 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1768 CLR(tp->t_state, TS_TBLOCK); /* try again later */
1769 ttstart(tp);
1781 ttyunblock(struct tty *tp)
1783 TTY_LOCK_OWNED(tp); /* debug assert */
1785 CLR(tp->t_state, TS_TBLOCK);
1786 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1787 putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1788 SET(tp->t_state, TS_TBLOCK); /* try again later */
1789 ttstart(tp);
1798 * Parameters: tp tty on which to start output
1810 ttstart(struct tty *tp)
1812 TTY_LOCK_OWNED(tp); /* debug assert */
1814 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1815 (*tp->t_oproc)(tp);
1829 ttylclose(struct tty *tp, int flag)
1831 TTY_LOCK_OWNED(tp); /* debug assert */
1833 if ( (flag & FNONBLOCK) || ttywflush(tp))
1834 ttyflush(tp, FREAD | FWRITE);
1850 ttymodem(struct tty *tp, int flag)
1854 TTY_LOCK_OWNED(tp); /* debug assert */
1856 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1863 CLR(tp->t_state, TS_CAR_OFLOW);
1864 CLR(tp->t_state, TS_TTSTOP);
1865 ttstart(tp);
1866 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1867 SET(tp->t_state, TS_CAR_OFLOW);
1868 SET(tp->t_state, TS_TTSTOP);
1869 ttystop(tp, 0);
1875 CLR(tp->t_state, TS_CARR_ON);
1876 if (ISSET(tp->t_state, TS_ISOPEN) &&
1877 !ISSET(tp->t_cflag, CLOCAL)) {
1878 SET(tp->t_state, TS_ZOMBIE);
1879 CLR(tp->t_state, TS_CONNECTED);
1880 if (tp->t_session && tp->t_session->s_leader)
1881 psignal(tp->t_session->s_leader, SIGHUP);
1882 ttyflush(tp, FREAD | FWRITE);
1890 SET(tp->t_state, TS_CARR_ON);
1891 if (!ISSET(tp->t_state, TS_ZOMBIE))
1892 SET(tp->t_state, TS_CONNECTED);
1893 wakeup(TSA_CARR_ON(tp));
1894 ttwakeup(tp);
1895 ttwwakeup(tp);
1910 ttypend(struct tty *tp)
1915 TTY_LOCK_OWNED(tp); /* debug assert */
1917 CLR(tp->t_lflag, PENDIN);
1918 SET(tp->t_state, TS_TYPEN);
1919 tq = tp->t_rawq;
1920 tp->t_rawq.c_cc = 0;
1921 tp->t_rawq.c_cf = tp->t_rawq.c_cl = NULL;
1923 ttyinput(c, tp);
1924 CLR(tp->t_state, TS_TYPEN);
1936 ttread(struct tty *tp, struct uio *uio, int flag)
1941 cc_t *cc = tp->t_cc;
1949 TTY_LOCK_OWNED(tp); /* debug assert */
1954 lflag = tp->t_lflag;
1959 ttypend(tp);
1960 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
1966 if (isbackground(p, tp)) {
1980 tty_unlock(tp);
1982 tty_lock(tp);
1987 tty_unlock(tp);
1990 tty_lock(tp);
2002 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2013 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
2119 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
2120 ISSET(tp->t_state, TS_CONNECTED) ?
2185 tty_unlock(tp);
2186 tty_pgsignal(tp, SIGTSTP, 1);
2187 tty_lock(tp);
2189 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
2225 if (ISSET(tp->t_state, TS_TBLOCK) &&
2226 tp->t_rawq.c_cc + tp->t_canq.c_cc <= I_LOW_WATER)
2227 ttyunblock(tp);
2235 * Check the output queue on tp for space for a kernel message (from uprintf
2246 ttycheckoutq(struct tty *tp, int wait)
2252 TTY_LOCK_OWNED(tp); /* debug assert */
2256 hiwat = tp->t_hiwat;
2258 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
2259 while (tp->t_outq.c_cc > hiwat) {
2260 ttstart(tp);
2261 if (tp->t_outq.c_cc <= hiwat)
2266 SET(tp->t_state, TS_SO_OLOWAT);
2267 ttysleep(tp, TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
2281 ttwrite(struct tty *tp, struct uio *uio, int flag)
2292 TTY_LOCK_OWNED(tp); /* debug assert */
2295 hiwat = tp->t_hiwat;
2300 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2305 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2310 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
2320 if (isbackground(p, tp) &&
2321 ISSET(tp->t_lflag, TOSTOP) && (p->p_lflag & P_LPPWAIT) == 0 &&
2332 tty_unlock(tp);
2334 tty_lock(tp);
2339 tty_unlock(tp);
2342 tty_lock(tp);
2358 if (ISSET(tp->t_lflag, FLUSHO)) {
2362 if (tp->t_outq.c_cc > hiwat)
2387 if (!ISSET(tp->t_oflag, OPOST))
2397 tp->t_rocount = 0;
2398 if (ttyoutput(*cp, tp) >= 0) {
2404 if (ISSET(tp->t_lflag, FLUSHO) ||
2405 tp->t_outq.c_cc > hiwat)
2418 tp->t_rocount = 0;
2419 i = b_to_q((u_char *)cp, ce, &tp->t_outq);
2421 tp->t_column += ce;
2423 tp->t_outcc += ce;
2428 if (ISSET(tp->t_lflag, FLUSHO) ||
2429 tp->t_outq.c_cc > hiwat)
2432 ttstart(tp);
2451 hiwat = tp->t_outq.c_cc - 1;
2454 ttstart(tp);
2459 if (tp->t_outq.c_cc <= hiwat) {
2466 SET(tp->t_state, TS_SO_OLOWAT);
2467 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
2468 tp->t_timeout);
2478 * Rubout one character from the rawq of tp
2484 ttyrub(int c, struct tty *tp)
2490 TTY_LOCK_OWNED(tp); /* debug assert */
2492 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2494 CLR(tp->t_lflag, FLUSHO);
2495 if (ISSET(tp->t_lflag, ECHOE)) {
2496 if (tp->t_rocount == 0) {
2500 ttyretype(tp);
2504 ttyrubo(tp, 2);
2509 if(!(ISSET(tp->t_iflag, IUTF8) && CCONT(c))) {
2510 ttyrubo(tp, 1);
2518 if (ISSET(tp->t_lflag, ECHOCTL))
2519 ttyrubo(tp, 2);
2522 if (tp->t_rocount < tp->t_rawq.c_cc) {
2523 ttyretype(tp);
2526 savecol = tp->t_column;
2527 SET(tp->t_state, TS_CNTTB);
2528 SET(tp->t_lflag, FLUSHO);
2529 tp->t_column = tp->t_rocol;
2530 for (cp = firstc(&tp->t_rawq, &tabc); cp;
2531 cp = nextc(&tp->t_rawq, cp, &tabc))
2532 ttyecho(tabc, tp);
2533 CLR(tp->t_lflag, FLUSHO);
2534 CLR(tp->t_state, TS_CNTTB);
2537 savecol -= tp->t_column;
2538 tp->t_column += savecol;
2542 (void)ttyoutput('\b', tp);
2552 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2553 if (!ISSET(tp->t_state, TS_ERASE)) {
2554 SET(tp->t_state, TS_ERASE);
2555 (void)ttyoutput('\\', tp);
2557 ttyecho(c, tp);
2559 ttyecho(tp->t_cc[VERASE], tp);
2560 --tp->t_rocount;
2570 ttyrubo(struct tty *tp, int count)
2572 TTY_LOCK_OWNED(tp); /* debug assert */
2575 (void)ttyoutput('\b', tp);
2576 (void)ttyoutput(' ', tp);
2577 (void)ttyoutput('\b', tp);
2590 ttyretype(struct tty *tp)
2595 TTY_LOCK_OWNED(tp); /* debug assert */
2598 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2599 ttyecho(tp->t_cc[VREPRINT], tp);
2601 (void)ttyoutput('\n', tp);
2608 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
2609 ttyecho(c, tp);
2610 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
2611 ttyecho(c, tp);
2612 CLR(tp->t_state, TS_ERASE);
2614 tp->t_rocount = tp->t_rawq.c_cc;
2615 tp->t_rocol = 0;
2625 ttyecho(int c, struct tty *tp)
2627 TTY_LOCK_OWNED(tp); /* debug assert */
2629 if (!ISSET(tp->t_state, TS_CNTTB))
2630 CLR(tp->t_lflag, FLUSHO);
2631 if ((!ISSET(tp->t_lflag, ECHO) &&
2632 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2633 ISSET(tp->t_lflag, EXTPROC))
2635 if (ISSET(tp->t_lflag, ECHOCTL) &&
2638 (void)ttyoutput('^', tp);
2645 (void)ttyoutput(c, tp);
2655 ttwakeup(struct tty *tp)
2657 TTY_LOCK_OWNED(tp); /* debug assert */
2659 selwakeup(&tp->t_rsel);
2660 KNOTE(&tp->t_rsel.si_note, 1);
2661 if (ISSET(tp->t_state, TS_ASYNC)) {
2670 tty_unlock(tp);
2671 tty_pgsignal(tp, SIGIO, 1);
2672 tty_lock(tp);
2674 wakeup(TSA_HUP_OR_INPUT(tp));
2686 ttwwakeup(struct tty *tp)
2688 TTY_LOCK_OWNED(tp); /* debug assert */
2690 if (tp->t_outq.c_cc <= tp->t_lowat) {
2691 selwakeup(&tp->t_wsel);
2692 KNOTE(&tp->t_wsel.si_note, 1);
2694 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2695 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2696 CLR(tp->t_state, TS_SO_OCOMPLETE);
2697 wakeup(TSA_OCOMPLETE(tp));
2699 if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2700 tp->t_outq.c_cc <= tp->t_lowat) {
2701 CLR(tp->t_state, TS_SO_OLOWAT);
2702 wakeup(TSA_OLOWAT(tp));
2733 ttsetwater(struct tty *tp)
2738 TTY_LOCK_OWNED(tp); /* debug assert */
2742 cps = tp->t_ospeed / 10;
2743 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2746 tp->t_hiwat = roundup(x, CBSIZE);
2766 ttyinfo_locked(struct tty *tp)
2781 TTY_LOCK_OWNED(tp); /* debug assert */
2783 if (ttycheckoutq(tp,0) == 0)
2788 ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
2791 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
2794 if (tp->t_session == NULL) {
2795 ttyprintf(tp, "not a controlling terminal\n");
2796 tp->t_rocount = 0;
2799 if (tp->t_pgrp == NULL) {
2800 ttyprintf(tp, "no foreground process group\n");
2801 tp->t_rocount = 0;
2806 if ((p = tp->t_pgrp->pg_members.lh_first) == NULL) {
2807 ttyprintf(tp, "empty foreground process group\n");
2808 tp->t_rocount = 0;
2829 tty_unlock(tp);
2831 tty_lock(tp);
2841 ttyprintf(tp, "foreground process without thread\n");
2842 tp->t_rocount = 0;
2871 ttyprintf(tp, " cmd: %s %d %s %ld.%02du %ld.%02ds\n",
2877 tp->t_rocount = 0;
2901 * tty_lock(tp) for p2's tty, for which p2 is the foreground
2965 tputchar(int c, struct tty *tp)
2967 TTY_LOCK_OWNED(tp); /* debug assert */
2969 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2973 (void)ttyoutput('\r', tp);
2974 (void)ttyoutput(c, tp);
2975 ttstart(tp);
2986 * Parameters: tp Tty going to sleep
3010 ttysleep(struct tty *tp, void *chan, int pri, const char *wmesg, int timo)
3015 TTY_LOCK_OWNED(tp);
3017 gen = tp->t_gen;
3019 error = msleep0(chan, &tp->t_lock, pri, wmesg, timo, (int (*)(int))0);
3022 return (tp->t_gen == gen ? 0 : ERESTART);
3040 struct tty *tp;
3042 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO);
3043 if (tp != NULL) {
3045 clalloc(&tp->t_rawq, TTYCLSIZE, 1);
3046 clalloc(&tp->t_canq, TTYCLSIZE, 1);
3048 clalloc(&tp->t_outq, TTYCLSIZE, 0);
3049 lck_mtx_init(&tp->t_lock, tty_lck_grp, tty_lck_attr);
3050 klist_init(&tp->t_rsel.si_note);
3051 klist_init(&tp->t_wsel.si_note);
3052 tp->t_refcnt = 1;
3054 return (tp);
3061 ttyhold(struct tty *tp)
3063 TTY_LOCK_OWNED(tp);
3064 tp->t_refcnt++;
3072 ttyfree(struct tty *tp)
3074 TTY_LOCK_NOTOWNED(tp);
3076 tty_lock(tp);
3077 if (--tp->t_refcnt == 0) {
3078 tty_unlock(tp);
3079 ttydeallocate(tp);
3080 } else if (tp->t_refcnt < 0) {
3081 panic("%s: freeing free tty %p", __func__, tp);
3083 tty_unlock(tp);
3093 ttydeallocate(struct tty *tp)
3095 TTY_LOCK_NOTOWNED(tp); /* debug assert */
3098 if (!(SLIST_EMPTY(&tp->t_rsel.si_note) && SLIST_EMPTY(&tp->t_wsel.si_note))) {
3103 clfree(&tp->t_rawq);
3104 clfree(&tp->t_canq);
3105 clfree(&tp->t_outq);
3106 lck_mtx_destroy(&tp->t_lock, tty_lck_grp);
3107 FREE(tp, M_TTYS);
3115 isbackground(proc_t p, struct tty *tp)
3117 TTY_LOCK_OWNED(tp);
3119 return (tp->t_session != NULL && p->p_pgrp != NULL && (p->p_pgrp != tp->t_pgrp) && isctty_sp(p, tp, p->p_pgrp->pg_session));
3123 isctty(proc_t p, struct tty *tp)
3129 retval = (sessp == tp->t_session && p->p_flag & P_CONTROLT);
3135 isctty_sp(proc_t p, struct tty *tp, struct session *sessp)
3137 return(sessp == tp->t_session && p->p_flag & P_CONTROLT);