• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /macosx-10.10.1/xnu-2782.1.97/bsd/kern/

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 __private_extern__ 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;
971 ttysetpgrphup(struct tty *tp)
973 TTY_LOCK_OWNED(tp); /* debug assert */
974 SET(tp->t_state, TS_PGRPHUP);
981 ttyclrpgrphup(struct tty *tp)
983 TTY_LOCK_OWNED(tp); /* debug assert */
984 CLR(tp->t_state, TS_PGRPHUP);
1005 ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, proc_t p)
1009 tty_lock(tp);
1010 retval = ttioctl_locked(tp, cmd, data, flag, p);
1011 tty_unlock(tp);
1022 * Parameters: tp Tty on which ioctl() is being called
1059 * *tp->t_param:? TIOCSETA* underlying function
1064 * tp at the time of the call. The lock remains held on return.
1075 ttioctl_locked(struct tty *tp, u_long cmd, caddr_t data, int flag, proc_t p)
1083 TTY_LOCK_OWNED(tp); /* debug assert */
1113 while (isbackground(p, tp) &&
1123 tty_unlock(tp);
1126 tty_lock(tp);
1132 tty_lock(tp);
1150 SET(tp->t_state, TS_ASYNC);
1152 CLR(tp->t_state, TS_ASYNC);
1157 *(int *)data = ttnread(tp);
1160 SET(tp->t_state, TS_XCLUDE);
1169 ttyflush(tp, flags);
1181 if (constty && constty != tp &&
1188 constty = tp;
1189 } else if (tp == constty) {
1196 (*cdevsw[major(tp->t_dev)].d_ioctl)
1197 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, p);
1202 error = ttywait(tp);
1208 termios64to32((struct user_termios *)&tp->t_termios, (struct termios32 *)data);
1210 bcopy(&tp->t_termios, data, sizeof(struct termios));
1215 bcopy(&tp->t_termios, data, sizeof(struct termios));
1217 termios32to64((struct termios32 *)&tp->t_termios, (struct user_termios *)data);
1221 *(int *)data = tp->t_line;
1224 *(struct winsize *)data = tp->t_winsize;
1227 if (!isctty(p, tp)) {
1231 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
1235 SET(tp->t_cflag, HUPCL);
1239 CLR(tp->t_state, TS_XCLUDE);
1242 *(int *)data = tp->t_outq.c_cc;
1276 error = ttywait(tp);
1281 ttyflush(tp, FREAD);
1287 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1291 !ISSET(tp->t_cflag, CLOCAL)) {
1298 CLR(tp->t_state, TS_ZOMBIE);
1300 wakeup(TSA_CARR_ON(tp));
1301 ttwakeup(tp);
1302 ttwwakeup(tp);
1304 if ((ISSET(tp->t_state, TS_CARR_ON) ||
1306 !ISSET(tp->t_state, TS_ZOMBIE))
1307 SET(tp->t_state, TS_CONNECTED);
1309 CLR(tp->t_state, TS_CONNECTED);
1310 tp->t_cflag = t->c_cflag;
1311 tp->t_ispeed = t->c_ispeed;
1312 tp->t_ospeed = t->c_ospeed;
1313 ttsetwater(tp);
1315 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
1318 SET(tp->t_lflag, PENDIN);
1326 if (tp->t_rawq.c_cs && tp->t_canq.c_cs) {
1329 catq(&tp->t_rawq, &tp->t_canq);
1330 tq = tp->t_rawq;
1331 tp->t_rawq = tp->t_canq;
1332 tp->t_canq = tq;
1334 CLR(tp->t_lflag, PENDIN);
1336 ttwakeup(tp);
1338 tp->t_iflag = t->c_iflag;
1339 tp->t_oflag = t->c_oflag;
1343 if (ISSET(tp->t_lflag, EXTPROC))
1347 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1348 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1349 t->c_cc[VTIME] != tp->t_cc[VTIME])
1350 ttwakeup(tp);
1351 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1356 dev_t device = tp->t_dev;
1366 if (t != tp->t_line) {
1367 (*linesw[tp->t_line].l_close)(tp, flag);
1368 error = (*linesw[t].l_open)(device, tp);
1371 (void)(*linesw[tp->t_line].l_open)(device, tp);
1374 tp->t_line = t;
1379 if (ISSET(tp->t_state, TS_TTSTOP) ||
1380 ISSET(tp->t_lflag, FLUSHO)) {
1381 CLR(tp->t_lflag, FLUSHO);
1382 CLR(tp->t_state, TS_TTSTOP);
1383 ttstart(tp);
1391 if (suser(kauth_cred_get(), NULL) && !isctty(p, tp)) {
1395 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1398 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1399 SET(tp->t_state, TS_TTSTOP);
1400 ttystop(tp, 0);
1404 ttyunblock(tp);
1407 ttyblock(tp);
1414 ((sessp->s_ttyvp || tp->t_session) &&
1415 (tp->t_session != sessp))) {
1417 tty_unlock(tp);
1422 tty_lock(tp);
1427 oldsessp = tp->t_session;
1428 oldpg = tp->t_pgrp;
1431 /* do not drop refs on sessp and pg as tp holds them */
1432 tp->t_session = sessp;
1434 tp->t_pgrp = pg;
1438 ttyhold(tp);
1439 sessp->s_ttyp = tp;
1443 tty_unlock(tp);
1451 tty_lock(tp);
1458 if (!isctty_sp(p, tp, sessp)) {
1471 tty_unlock(tp);
1475 tty_lock(tp);
1484 if (ISSET(tp->t_state, TS_PGRPHUP)) {
1489 oldpg = tp->t_pgrp;
1490 tp->t_pgrp = pgrp;
1494 tty_unlock(tp);
1499 tty_lock(tp);
1503 ttyinfo_locked(tp);
1506 if (bcmp((caddr_t)&tp->t_winsize, data,
1508 tp->t_winsize = *(struct winsize *)data;
1510 tty_unlock(tp);
1511 tty_pgsignal(tp, SIGWINCH, 1);
1512 tty_lock(tp);
1520 tp->t_timeout = *(int *)data * hz;
1521 wakeup(TSA_OCOMPLETE(tp));
1522 wakeup(TSA_OLOWAT(tp));
1525 *(int *)data = tp->t_timeout / hz;
1528 error = ttcompat(tp, cmd, data, flag, p);
1539 * Locks: Assumes tp is locked on entry, remains locked on exit
1542 ttyselect(struct tty *tp, int rw, void *wql, proc_t p)
1546 if (tp == NULL)
1549 TTY_LOCK_OWNED(tp); /* debug assert */
1553 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1557 retval = ttnread(tp);
1562 selrecord(p, &tp->t_rsel, wql);
1565 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1569 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
1570 ISSET(tp->t_state, TS_CONNECTED)) {
1571 retval = tp->t_hiwat - tp->t_outq.c_cc;
1575 selrecord(p, &tp->t_wsel, wql);
1592 struct tty *tp = cdevsw[major(dev)].d_ttys[minor(dev)];
1594 tty_lock(tp);
1595 rv = ttyselect(tp, rw, wql, p);
1596 tty_unlock(tp);
1603 * Locks: Assumes tp is locked on entry, remains locked on exit
1606 ttnread(struct tty *tp)
1610 TTY_LOCK_OWNED(tp); /* debug assert */
1612 if (ISSET(tp->t_lflag, PENDIN))
1613 ttypend(tp);
1614 nread = tp->t_canq.c_cc;
1615 if (!ISSET(tp->t_lflag, ICANON)) {
1616 nread += tp->t_rawq.c_cc;
1617 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1629 * Parameters: tp Tty on which to wait for output to drain
1640 * Locks: Assumes tp is locked on entry, remains locked on exit
1643 ttywait(struct tty *tp)
1647 TTY_LOCK_OWNED(tp); /* debug assert */
1650 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1651 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1652 (*tp->t_oproc)(tp);
1653 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1654 ISSET(tp->t_state, TS_CONNECTED)) {
1655 SET(tp->t_state, TS_SO_OCOMPLETE);
1656 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1658 tp->t_timeout);
1667 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1678 ttystop(struct tty *tp, int rw)
1680 TTY_LOCK_OWNED(tp); /* debug assert */
1682 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1691 ttywflush(struct tty *tp)
1695 TTY_LOCK_OWNED(tp); /* debug assert */
1697 if ((error = ttywait(tp)) == 0)
1698 ttyflush(tp, FREAD);
1708 ttyflush(struct tty *tp, int rw)
1710 TTY_LOCK_OWNED(tp); /* debug assert */
1716 FLUSHQ(&tp->t_outq);
1717 CLR(tp->t_state, TS_TTSTOP);
1719 ttystop(tp, rw);
1721 FLUSHQ(&tp->t_canq);
1722 FLUSHQ(&tp->t_rawq);
1723 CLR(tp->t_lflag, PENDIN);
1724 tp->t_rocount = 0;
1725 tp->t_rocol = 0;
1726 CLR(tp->t_state, TS_LOCAL);
1727 ttwakeup(tp);
1728 if (ISSET(tp->t_state, TS_TBLOCK)) {
1730 FLUSHQ(&tp->t_outq);
1731 ttyunblock(tp);
1740 CLR(tp->t_state, TS_TBLOCK);
1743 if (ISSET(tp->t_iflag, IXOFF)) {
1753 SET(tp->t_state, TS_SO_OCOMPLETE);
1754 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1759 CLR(tp->t_state, TS_TBLOCK);
1766 FLUSHQ(&tp->t_outq);
1767 ttwwakeup(tp);
1776 * Notes: No assertion; tp is not in scope.
1793 ttyblock(struct tty *tp)
1795 TTY_LOCK_OWNED(tp); /* debug assert */
1797 SET(tp->t_state, TS_TBLOCK);
1798 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1799 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1800 CLR(tp->t_state, TS_TBLOCK); /* try again later */
1801 ttstart(tp);
1813 ttyunblock(struct tty *tp)
1815 TTY_LOCK_OWNED(tp); /* debug assert */
1817 CLR(tp->t_state, TS_TBLOCK);
1818 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1819 putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1820 SET(tp->t_state, TS_TBLOCK); /* try again later */
1821 ttstart(tp);
1830 * Parameters: tp tty on which to start output
1842 ttstart(struct tty *tp)
1844 TTY_LOCK_OWNED(tp); /* debug assert */
1846 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1847 (*tp->t_oproc)(tp);
1861 ttylclose(struct tty *tp, int flag)
1863 TTY_LOCK_OWNED(tp); /* debug assert */
1865 if ( (flag & FNONBLOCK) || ttywflush(tp))
1866 ttyflush(tp, FREAD | FWRITE);
1882 ttymodem(struct tty *tp, int flag)
1886 TTY_LOCK_OWNED(tp); /* debug assert */
1888 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1895 CLR(tp->t_state, TS_CAR_OFLOW);
1896 CLR(tp->t_state, TS_TTSTOP);
1897 ttstart(tp);
1898 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1899 SET(tp->t_state, TS_CAR_OFLOW);
1900 SET(tp->t_state, TS_TTSTOP);
1901 ttystop(tp, 0);
1907 CLR(tp->t_state, TS_CARR_ON);
1908 if (ISSET(tp->t_state, TS_ISOPEN) &&
1909 !ISSET(tp->t_cflag, CLOCAL)) {
1910 SET(tp->t_state, TS_ZOMBIE);
1911 CLR(tp->t_state, TS_CONNECTED);
1912 if (tp->t_session && tp->t_session->s_leader)
1913 psignal(tp->t_session->s_leader, SIGHUP);
1914 ttyflush(tp, FREAD | FWRITE);
1922 SET(tp->t_state, TS_CARR_ON);
1923 if (!ISSET(tp->t_state, TS_ZOMBIE))
1924 SET(tp->t_state, TS_CONNECTED);
1925 wakeup(TSA_CARR_ON(tp));
1926 ttwakeup(tp);
1927 ttwwakeup(tp);
1942 ttypend(struct tty *tp)
1947 TTY_LOCK_OWNED(tp); /* debug assert */
1949 CLR(tp->t_lflag, PENDIN);
1950 SET(tp->t_state, TS_TYPEN);
1951 tq = tp->t_rawq;
1952 tp->t_rawq.c_cc = 0;
1953 tp->t_rawq.c_cf = tp->t_rawq.c_cl = NULL;
1955 ttyinput(c, tp);
1956 CLR(tp->t_state, TS_TYPEN);
1968 ttread(struct tty *tp, struct uio *uio, int flag)
1973 cc_t *cc = tp->t_cc;
1981 TTY_LOCK_OWNED(tp); /* debug assert */
1986 lflag = tp->t_lflag;
1991 ttypend(tp);
1992 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
1998 if (isbackground(p, tp)) {
2012 tty_unlock(tp);
2014 tty_lock(tp);
2019 tty_unlock(tp);
2022 tty_lock(tp);
2034 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2045 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
2151 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
2152 ISSET(tp->t_state, TS_CONNECTED) ?
2217 tty_unlock(tp);
2218 tty_pgsignal(tp, SIGTSTP, 1);
2219 tty_lock(tp);
2221 error = ttysleep(tp, &ttread, TTIPRI | PCATCH,
2257 if (ISSET(tp->t_state, TS_TBLOCK) &&
2258 tp->t_rawq.c_cc + tp->t_canq.c_cc <= I_LOW_WATER)
2259 ttyunblock(tp);
2267 * Check the output queue on tp for space for a kernel message (from uprintf
2278 ttycheckoutq(struct tty *tp, int wait)
2284 TTY_LOCK_OWNED(tp); /* debug assert */
2288 hiwat = tp->t_hiwat;
2290 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
2291 while (tp->t_outq.c_cc > hiwat) {
2292 ttstart(tp);
2293 if (tp->t_outq.c_cc <= hiwat)
2298 SET(tp->t_state, TS_SO_OLOWAT);
2299 ttysleep(tp, TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
2313 ttwrite(struct tty *tp, struct uio *uio, int flag)
2324 TTY_LOCK_OWNED(tp); /* debug assert */
2327 hiwat = tp->t_hiwat;
2332 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2337 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2342 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
2352 if (isbackground(p, tp) &&
2353 ISSET(tp->t_lflag, TOSTOP) && (p->p_lflag & P_LPPWAIT) == 0 &&
2364 tty_unlock(tp);
2366 tty_lock(tp);
2371 tty_unlock(tp);
2374 tty_lock(tp);
2390 if (ISSET(tp->t_lflag, FLUSHO)) {
2394 if (tp->t_outq.c_cc > hiwat)
2419 if (!ISSET(tp->t_oflag, OPOST))
2429 tp->t_rocount = 0;
2430 if (ttyoutput(*cp, tp) >= 0) {
2436 if (ISSET(tp->t_lflag, FLUSHO) ||
2437 tp->t_outq.c_cc > hiwat)
2450 tp->t_rocount = 0;
2451 i = b_to_q((u_char *)cp, ce, &tp->t_outq);
2453 tp->t_column += ce;
2455 tp->t_outcc += ce;
2460 if (ISSET(tp->t_lflag, FLUSHO) ||
2461 tp->t_outq.c_cc > hiwat)
2464 ttstart(tp);
2483 hiwat = tp->t_outq.c_cc - 1;
2486 ttstart(tp);
2491 if (tp->t_outq.c_cc <= hiwat) {
2498 SET(tp->t_state, TS_SO_OLOWAT);
2499 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
2500 tp->t_timeout);
2510 * Rubout one character from the rawq of tp
2516 ttyrub(int c, struct tty *tp)
2522 TTY_LOCK_OWNED(tp); /* debug assert */
2524 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2526 CLR(tp->t_lflag, FLUSHO);
2527 if (ISSET(tp->t_lflag, ECHOE)) {
2528 if (tp->t_rocount == 0) {
2532 ttyretype(tp);
2536 ttyrubo(tp, 2);
2541 if(!(ISSET(tp->t_iflag, IUTF8) && CCONT(c))) {
2542 ttyrubo(tp, 1);
2550 if (ISSET(tp->t_lflag, ECHOCTL))
2551 ttyrubo(tp, 2);
2554 if (tp->t_rocount < tp->t_rawq.c_cc) {
2555 ttyretype(tp);
2558 savecol = tp->t_column;
2559 SET(tp->t_state, TS_CNTTB);
2560 SET(tp->t_lflag, FLUSHO);
2561 tp->t_column = tp->t_rocol;
2562 for (cp = firstc(&tp->t_rawq, &tabc); cp;
2563 cp = nextc(&tp->t_rawq, cp, &tabc))
2564 ttyecho(tabc, tp);
2565 CLR(tp->t_lflag, FLUSHO);
2566 CLR(tp->t_state, TS_CNTTB);
2569 savecol -= tp->t_column;
2570 tp->t_column += savecol;
2574 (void)ttyoutput('\b', tp);
2584 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2585 if (!ISSET(tp->t_state, TS_ERASE)) {
2586 SET(tp->t_state, TS_ERASE);
2587 (void)ttyoutput('\\', tp);
2589 ttyecho(c, tp);
2591 ttyecho(tp->t_cc[VERASE], tp);
2592 --tp->t_rocount;
2602 ttyrubo(struct tty *tp, int count)
2604 TTY_LOCK_OWNED(tp); /* debug assert */
2607 (void)ttyoutput('\b', tp);
2608 (void)ttyoutput(' ', tp);
2609 (void)ttyoutput('\b', tp);
2622 ttyretype(struct tty *tp)
2627 TTY_LOCK_OWNED(tp); /* debug assert */
2630 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2631 ttyecho(tp->t_cc[VREPRINT], tp);
2633 (void)ttyoutput('\n', tp);
2640 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
2641 ttyecho(c, tp);
2642 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
2643 ttyecho(c, tp);
2644 CLR(tp->t_state, TS_ERASE);
2646 tp->t_rocount = tp->t_rawq.c_cc;
2647 tp->t_rocol = 0;
2657 ttyecho(int c, struct tty *tp)
2659 TTY_LOCK_OWNED(tp); /* debug assert */
2661 if (!ISSET(tp->t_state, TS_CNTTB))
2662 CLR(tp->t_lflag, FLUSHO);
2663 if ((!ISSET(tp->t_lflag, ECHO) &&
2664 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2665 ISSET(tp->t_lflag, EXTPROC))
2667 if (ISSET(tp->t_lflag, ECHOCTL) &&
2670 (void)ttyoutput('^', tp);
2677 (void)ttyoutput(c, tp);
2687 ttwakeup(struct tty *tp)
2689 TTY_LOCK_OWNED(tp); /* debug assert */
2691 selwakeup(&tp->t_rsel);
2692 KNOTE(&tp->t_rsel.si_note, 1);
2693 if (ISSET(tp->t_state, TS_ASYNC)) {
2702 tty_unlock(tp);
2703 tty_pgsignal(tp, SIGIO, 1);
2704 tty_lock(tp);
2706 wakeup(TSA_HUP_OR_INPUT(tp));
2718 ttwwakeup(struct tty *tp)
2720 TTY_LOCK_OWNED(tp); /* debug assert */
2722 if (tp->t_outq.c_cc <= tp->t_lowat) {
2723 selwakeup(&tp->t_wsel);
2724 KNOTE(&tp->t_wsel.si_note, 1);
2726 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2727 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2728 CLR(tp->t_state, TS_SO_OCOMPLETE);
2729 wakeup(TSA_OCOMPLETE(tp));
2731 if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2732 tp->t_outq.c_cc <= tp->t_lowat) {
2733 CLR(tp->t_state, TS_SO_OLOWAT);
2734 wakeup(TSA_OLOWAT(tp));
2765 ttsetwater(struct tty *tp)
2770 TTY_LOCK_OWNED(tp); /* debug assert */
2774 cps = tp->t_ospeed / 10;
2775 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2778 tp->t_hiwat = roundup(x, CBSIZE);
2798 ttyinfo_locked(struct tty *tp)
2813 TTY_LOCK_OWNED(tp); /* debug assert */
2815 if (ttycheckoutq(tp,0) == 0)
2820 ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
2823 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
2826 if (tp->t_session == NULL) {
2827 ttyprintf(tp, "not a controlling terminal\n");
2828 tp->t_rocount = 0;
2831 if (tp->t_pgrp == NULL) {
2832 ttyprintf(tp, "no foreground process group\n");
2833 tp->t_rocount = 0;
2838 if ((p = tp->t_pgrp->pg_members.lh_first) == NULL) {
2839 ttyprintf(tp, "empty foreground process group\n");
2840 tp->t_rocount = 0;
2861 tty_unlock(tp);
2863 tty_lock(tp);
2873 ttyprintf(tp, "foreground process without thread\n");
2874 tp->t_rocount = 0;
2903 ttyprintf(tp, " cmd: %s %d %s %ld.%02du %ld.%02ds\n",
2909 tp->t_rocount = 0;
2933 * tty_lock(tp) for p2's tty, for which p2 is the foreground
2997 tputchar(int c, struct tty *tp)
2999 TTY_LOCK_OWNED(tp); /* debug assert */
3001 if (!ISSET(tp->t_state, TS_CONNECTED)) {
3005 (void)ttyoutput('\r', tp);
3006 (void)ttyoutput(c, tp);
3007 ttstart(tp);
3018 * Parameters: tp Tty going to sleep
3042 ttysleep(struct tty *tp, void *chan, int pri, const char *wmesg, int timo)
3047 TTY_LOCK_OWNED(tp);
3049 gen = tp->t_gen;
3051 error = msleep0(chan, &tp->t_lock, pri, wmesg, timo, (int (*)(int))0);
3054 return (tp->t_gen == gen ? 0 : ERESTART);
3072 struct tty *tp;
3074 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO);
3075 if (tp != NULL) {
3077 clalloc(&tp->t_rawq, TTYCLSIZE, 1);
3078 clalloc(&tp->t_canq, TTYCLSIZE, 1);
3080 clalloc(&tp->t_outq, TTYCLSIZE, 0);
3081 lck_mtx_init(&tp->t_lock, tty_lck_grp, tty_lck_attr);
3082 klist_init(&tp->t_rsel.si_note);
3083 klist_init(&tp->t_wsel.si_note);
3084 tp->t_refcnt = 1;
3086 return (tp);
3093 ttyhold(struct tty *tp)
3095 TTY_LOCK_OWNED(tp);
3096 tp->t_refcnt++;
3104 ttyfree(struct tty *tp)
3106 TTY_LOCK_NOTOWNED(tp);
3108 tty_lock(tp);
3109 if (--tp->t_refcnt == 0) {
3110 tty_unlock(tp);
3111 ttydeallocate(tp);
3112 } else if (tp->t_refcnt < 0) {
3113 panic("%s: freeing free tty %p", __func__, tp);
3115 tty_unlock(tp);
3125 ttydeallocate(struct tty *tp)
3127 TTY_LOCK_NOTOWNED(tp); /* debug assert */
3130 if (!(SLIST_EMPTY(&tp->t_rsel.si_note) && SLIST_EMPTY(&tp->t_wsel.si_note))) {
3135 clfree(&tp->t_rawq);
3136 clfree(&tp->t_canq);
3137 clfree(&tp->t_outq);
3138 lck_mtx_destroy(&tp->t_lock, tty_lck_grp);
3139 FREE(tp, M_TTYS);
3147 isbackground(proc_t p, struct tty *tp)
3149 TTY_LOCK_OWNED(tp);
3151 return (tp->t_session != NULL && p->p_pgrp != NULL && (p->p_pgrp != tp->t_pgrp) && isctty_sp(p, tp, p->p_pgrp->pg_session));
3155 isctty(proc_t p, struct tty *tp)
3161 retval = (sessp == tp->t_session && p->p_flag & P_CONTROLT);
3167 isctty_sp(proc_t p, struct tty *tp, struct session *sessp)
3169 return(sessp == tp->t_session && p->p_flag & P_CONTROLT);