home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / kern / tty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-07  |  40.6 KB  |  1,893 lines

  1. /*-
  2.  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
  3.  * Copyright (c) 1991 The Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *    This product includes software developed by the University of
  17.  *    California, Berkeley and its contributors.
  18.  * 4. Neither the name of the University nor the names of its contributors
  19.  *    may be used to endorse or promote products derived from this software
  20.  *    without specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  *    @(#)tty.c    7.44 (Berkeley) 5/28/91
  35.  */
  36.  
  37. #include "param.h"
  38. #include "systm.h"
  39. #include "ioctl.h"
  40. #define TTYDEFCHARS
  41. #include "tty.h"
  42. #undef TTYDEFCHARS
  43. #include "proc.h"
  44. #include "file.h"
  45. #include "conf.h"
  46. #include "dkstat.h"
  47. #include "uio.h"
  48. #include "kernel.h"
  49. #include "vnode.h"
  50. #include "syslog.h"
  51.  
  52. #include "vm/vm.h"
  53.  
  54. static int proc_compare __P((struct proc *p1, struct proc *p2));
  55.  
  56. /* symbolic sleep message strings */
  57. char ttyin[] = "ttyin";
  58. char ttyout[] = "ttyout";
  59. char ttopen[] = "ttyopn";
  60. char ttclos[] = "ttycls";
  61. char ttybg[] = "ttybg";
  62. char ttybuf[] = "ttybuf";
  63.  
  64. /*
  65.  * Table giving parity for characters and indicating
  66.  * character classes to tty driver. The 8th bit
  67.  * indicates parity, the 7th bit indicates the character
  68.  * is an alphameric or underscore (for ALTWERASE), and the 
  69.  * low 6 bits indicate delay type.  If the low 6 bits are 0
  70.  * then the character needs no special processing on output;
  71.  * classes other than 0 might be translated or (not currently)
  72.  * require delays.
  73.  */
  74. #define    PARITY(c)    (partab[c] & 0x80)
  75. #define    ISALPHA(c)    (partab[(c)&TTY_CHARMASK] & 0x40)
  76. #define    CCLASSMASK    0x3f
  77. #define    CCLASS(c)    (partab[c] & CCLASSMASK)
  78.  
  79. #define    E    0x00    /* even parity */
  80. #define    O    0x80    /* odd parity */
  81. #define    ALPHA    0x40    /* alpha or underscore */
  82.  
  83. #define    NO    ORDINARY
  84. #define    NA    ORDINARY|ALPHA
  85. #define    CC    CONTROL
  86. #define    BS    BACKSPACE
  87. #define    NL    NEWLINE
  88. #define    TB    TAB
  89. #define    VT    VTAB
  90. #define    CR    RETURN
  91.  
  92. char partab[] = {
  93.     E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC,    /* nul - bel */
  94.     O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
  95.     O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
  96.     E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
  97.     O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
  98.     E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
  99.     E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
  100.     O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
  101.     O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
  102.     E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
  103.     E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
  104.     O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
  105.     E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
  106.     O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
  107.     O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
  108.     E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
  109.     /*
  110.      * "meta" chars; should be settable per charset.
  111.      * For now, treat all as normal characters.
  112.      */
  113.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  114.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  115.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  116.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  117.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  118.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  119.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  120.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  121.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  122.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  123.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  124.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  125.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  126.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  127.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  128.     NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
  129. };
  130. #undef    NO
  131. #undef    NA
  132. #undef    CC
  133. #undef    BS
  134. #undef    NL
  135. #undef    TB
  136. #undef    VT
  137. #undef    CR
  138.  
  139. extern struct tty *constty;        /* temporary virtual console */
  140.  
  141. /*
  142.  * Is 'c' a line delimiter ("break" character)?
  143.  */
  144. #define ttbreakc(c) ((c) == '\n' || ((c) == cc[VEOF] || \
  145.     (c) == cc[VEOL] || (c) == cc[VEOL2]) && (c) != _POSIX_VDISABLE)
  146.  
  147. ttychars(tp)
  148.     struct tty *tp;
  149. {
  150.  
  151.     bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
  152. }
  153.  
  154. /*
  155.  * Flush tty after output has drained.
  156.  */
  157. ttywflush(tp)
  158.     struct tty *tp;
  159. {
  160.     int error;
  161.  
  162.     if ((error = ttywait(tp)) == 0)
  163.         ttyflush(tp, FREAD);
  164.     return (error);
  165. }
  166.  
  167. /*
  168.  * Wait for output to drain.
  169.  */
  170. ttywait(tp)
  171.     register struct tty *tp;
  172. {
  173.     int error = 0, s = spltty();
  174.  
  175.     while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) &&
  176.         (tp->t_state&TS_CARR_ON || tp->t_cflag&CLOCAL) && 
  177.         tp->t_oproc) {
  178.         (*tp->t_oproc)(tp);
  179.         tp->t_state |= TS_ASLEEP;
  180.         if (error = ttysleep(tp, (caddr_t)&tp->t_outq, 
  181.             TTOPRI | PCATCH, ttyout, 0))
  182.             break;
  183.     }
  184.     splx(s);
  185.     return (error);
  186. }
  187.  
  188. #define    flushq(qq) { \
  189.     register struct clist *q = qq; \
  190.     if (q->c_cc) \
  191.         ndflush(q, q->c_cc); \
  192. }
  193.  
  194. /*
  195.  * Flush TTY read and/or write queues,
  196.  * notifying anyone waiting.
  197.  */
  198. ttyflush(tp, rw)
  199.     register struct tty *tp;
  200. {
  201.     register s;
  202.  
  203.     s = spltty();
  204.     if (rw & FREAD) {
  205.         flushq(&tp->t_canq);
  206.         flushq(&tp->t_rawq);
  207.         tp->t_rocount = 0;
  208.         tp->t_rocol = 0;
  209.         tp->t_state &= ~TS_LOCAL;
  210.         ttwakeup(tp);
  211.     }
  212.     if (rw & FWRITE) {
  213.         tp->t_state &= ~TS_TTSTOP;
  214.         (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
  215.         flushq(&tp->t_outq);
  216.         wakeup((caddr_t)&tp->t_outq);
  217.         if (tp->t_wsel) {
  218.             selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
  219.             tp->t_wsel = 0;
  220.             tp->t_state &= ~TS_WCOLL;
  221.         }
  222.     }
  223.     splx(s);
  224. }
  225.  
  226. /*
  227.  * Send stop character on input overflow.
  228.  */
  229. ttyblock(tp)
  230.     register struct tty *tp;
  231. {
  232.     register x;
  233.  
  234.     x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
  235.     if (tp->t_rawq.c_cc > TTYHOG) {
  236.         ttyflush(tp, FREAD|FWRITE);
  237.         tp->t_state &= ~TS_TBLOCK;
  238.     }
  239.     /*
  240.      * Block further input iff:
  241.      * Current input > threshold AND input is available to user program
  242.      */
  243.     if (x >= TTYHOG/2 && (tp->t_state & TS_TBLOCK) == 0 &&
  244.         ((tp->t_lflag&ICANON) == 0) || (tp->t_canq.c_cc > 0) &&
  245.         tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
  246.         if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
  247.             tp->t_state |= TS_TBLOCK;
  248.             ttstart(tp);
  249.         }
  250.     }
  251. }
  252.  
  253. ttstart(tp)
  254.     struct tty *tp;
  255. {
  256.  
  257.     if (tp->t_oproc)        /* kludge for pty */
  258.         (*tp->t_oproc)(tp);
  259. }
  260.  
  261. ttrstrt(tp)                /* XXX */
  262.     struct tty *tp;
  263. {
  264.  
  265. #ifdef DIAGNOSTIC
  266.     if (tp == 0)
  267.         panic("ttrstrt");
  268. #endif
  269.     tp->t_state &= ~TS_TIMEOUT;
  270.     ttstart(tp);
  271. }
  272.  
  273.  
  274. /*
  275.  * Common code for ioctls on tty devices.
  276.  * Called after line-discipline-specific ioctl
  277.  * has been called to do discipline-specific functions
  278.  * and/or reject any of these ioctl commands.
  279.  */
  280. /*ARGSUSED*/
  281. ttioctl(tp, com, data, flag)
  282.     register struct tty *tp;
  283.     caddr_t data;
  284. {
  285.     register struct proc *p = curproc;        /* XXX */
  286.     extern int nldisp;
  287.     int s, error;
  288.  
  289.     /*
  290.      * If the ioctl involves modification,
  291.      * hang if in the background.
  292.      */
  293.     switch (com) {
  294.  
  295.     case TIOCSETD: 
  296.     case TIOCFLUSH:
  297.     /*case TIOCSPGRP:*/
  298.     case TIOCSTI:
  299.     case TIOCSWINSZ:
  300.     case TIOCSETA:
  301.     case TIOCSETAW:
  302.     case TIOCSETAF:
  303. #ifdef COMPAT_43
  304.     case TIOCSETP:
  305.     case TIOCSETN:
  306.     case TIOCSETC:
  307.     case TIOCSLTC:
  308.     case TIOCLBIS:
  309.     case TIOCLBIC:
  310.     case TIOCLSET:
  311.     case OTIOCSETD:
  312. #endif
  313.         while (isbackground(curproc, tp) && 
  314.            p->p_pgrp->pg_jobc && (p->p_flag&SPPWAIT) == 0 &&
  315.            (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
  316.            (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
  317.             pgsignal(p->p_pgrp, SIGTTOU, 1);
  318.             if (error = ttysleep(tp, (caddr_t)&lbolt, 
  319.                 TTOPRI | PCATCH, ttybg, 0)) 
  320.                 return (error);
  321.         }
  322.         break;
  323.     }
  324.  
  325.     /*
  326.      * Process the ioctl.
  327.      */
  328.     switch (com) {
  329.  
  330.     /* get discipline number */
  331.     case TIOCGETD:
  332.         *(int *)data = tp->t_line;
  333.         break;
  334.  
  335.     /* set line discipline */
  336.     case TIOCSETD: {
  337.         register int t = *(int *)data;
  338.         dev_t dev = tp->t_dev;
  339.  
  340.         if ((unsigned)t >= nldisp)
  341.             return (ENXIO);
  342.         if (t != tp->t_line) {
  343.             s = spltty();
  344.             (*linesw[tp->t_line].l_close)(tp, flag);
  345.             error = (*linesw[t].l_open)(dev, tp);
  346.             if (error) {
  347.                 (void)(*linesw[tp->t_line].l_open)(dev, tp);
  348.                 splx(s);
  349.                 return (error);
  350.             }
  351.             tp->t_line = t;
  352.             splx(s);
  353.         }
  354.         break;
  355.     }
  356.  
  357.     /* prevent more opens on channel */
  358.     case TIOCEXCL:
  359.         tp->t_state |= TS_XCLUDE;
  360.         break;
  361.  
  362.     case TIOCNXCL:
  363.         tp->t_state &= ~TS_XCLUDE;
  364.         break;
  365.  
  366.     case TIOCHPCL:
  367.         tp->t_cflag |= HUPCL;
  368.         break;
  369.  
  370.     case TIOCFLUSH: {
  371.         register int flags = *(int *)data;
  372.  
  373.         if (flags == 0)
  374.             flags = FREAD|FWRITE;
  375.         else
  376.             flags &= FREAD|FWRITE;
  377.         ttyflush(tp, flags);
  378.         break;
  379.     }
  380.  
  381.     case FIOASYNC:
  382.         if (*(int *)data)
  383.             tp->t_state |= TS_ASYNC;
  384.         else
  385.             tp->t_state &= ~TS_ASYNC;
  386.         break;
  387.  
  388.     case FIONBIO:
  389.         break;    /* XXX remove */
  390.  
  391.     /* return number of characters immediately available */
  392.     case FIONREAD:
  393.         *(off_t *)data = ttnread(tp);
  394.         break;
  395.  
  396.     case TIOCOUTQ:
  397.         *(int *)data = tp->t_outq.c_cc;
  398.         break;
  399.  
  400.     case TIOCSTOP:
  401.         s = spltty();
  402.         if ((tp->t_state&TS_TTSTOP) == 0) {
  403.             tp->t_state |= TS_TTSTOP;
  404.             (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
  405.         }
  406.         splx(s);
  407.         break;
  408.  
  409.     case TIOCSTART:
  410.         s = spltty();
  411.         if ((tp->t_state&TS_TTSTOP) || (tp->t_lflag&FLUSHO)) {
  412.             tp->t_state &= ~TS_TTSTOP;
  413.             tp->t_lflag &= ~FLUSHO;
  414.             ttstart(tp);
  415.         }
  416.         splx(s);
  417.         break;
  418.  
  419.     /*
  420.      * Simulate typing of a character at the terminal.
  421.      */
  422.     case TIOCSTI:
  423.         if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
  424.             return (EPERM);
  425.         if (p->p_ucred->cr_uid && !isctty(p, tp))
  426.             return (EACCES);
  427.         (*linesw[tp->t_line].l_rint)(*(char *)data, tp);
  428.         break;
  429.  
  430.     case TIOCGETA: {
  431.         struct termios *t = (struct termios *)data;
  432.  
  433.         bcopy(&tp->t_termios, t, sizeof(struct termios));
  434.         break;
  435.     }
  436.  
  437.     case TIOCSETA:
  438.     case TIOCSETAW:
  439.     case TIOCSETAF: {
  440.         register struct termios *t = (struct termios *)data;
  441.  
  442.         s = spltty();
  443.         if (com == TIOCSETAW || com == TIOCSETAF) {
  444.             if (error = ttywait(tp)) {
  445.                 splx(s);
  446.                 return (error);
  447.             }
  448.             if (com == TIOCSETAF)
  449.                 ttyflush(tp, FREAD);
  450.         }
  451.         if ((t->c_cflag&CIGNORE) == 0) {
  452.             /*
  453.              * set device hardware
  454.              */
  455.             if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
  456.                 splx(s);
  457.                 return (error);
  458.             } else {
  459.                 if ((tp->t_state&TS_CARR_ON) == 0 &&
  460.                     (tp->t_cflag&CLOCAL) &&
  461.                     (t->c_cflag&CLOCAL) == 0) {
  462.                     tp->t_state &= ~TS_ISOPEN;
  463.                     tp->t_state |= TS_WOPEN;
  464.                     ttwakeup(tp);
  465.                 }
  466.                 tp->t_cflag = t->c_cflag;
  467.                 tp->t_ispeed = t->c_ispeed;
  468.                 tp->t_ospeed = t->c_ospeed;
  469.             }
  470.             ttsetwater(tp);
  471.         }
  472.         if (com != TIOCSETAF) {
  473.             if ((t->c_lflag&ICANON) != (tp->t_lflag&ICANON))
  474.                 if (t->c_lflag&ICANON) {    
  475.                     tp->t_lflag |= PENDIN;
  476.                     ttwakeup(tp);
  477.                 }
  478.                 else {
  479.                     struct clist tq;
  480.  
  481.                     catq(&tp->t_rawq, &tp->t_canq);
  482.                     tq = tp->t_rawq;
  483.                     tp->t_rawq = tp->t_canq;
  484.                     tp->t_canq = tq;
  485.                 }
  486.         }
  487.         tp->t_iflag = t->c_iflag;
  488.         tp->t_oflag = t->c_oflag;
  489.         /*
  490.          * Make the EXTPROC bit read only.
  491.          */
  492.         if (tp->t_lflag&EXTPROC)
  493.             t->c_lflag |= EXTPROC;
  494.         else
  495.             t->c_lflag &= ~EXTPROC;
  496.         tp->t_lflag = t->c_lflag;
  497.         bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
  498.         splx(s);
  499.         break;
  500.     }
  501.  
  502.     /*
  503.      * Set controlling terminal.
  504.      * Session ctty vnode pointer set in vnode layer.
  505.      */
  506.     case TIOCSCTTY:
  507.         if (!SESS_LEADER(p) || 
  508.            (p->p_session->s_ttyvp || tp->t_session) &&
  509.            (tp->t_session != p->p_session))
  510.             return (EPERM);
  511.         tp->t_session = p->p_session;
  512.         tp->t_pgrp = p->p_pgrp;
  513.         p->p_session->s_ttyp = tp;
  514.         p->p_flag |= SCTTY;
  515.         break;
  516.         
  517.     /*
  518.      * Set terminal process group.
  519.      */
  520.     case TIOCSPGRP: {
  521.         register struct pgrp *pgrp = pgfind(*(int *)data);
  522.  
  523.         if (!isctty(p, tp))
  524.             return (ENOTTY);
  525.         else if (pgrp == NULL || pgrp->pg_session != p->p_session)
  526.             return (EPERM);
  527.         tp->t_pgrp = pgrp;
  528.         break;
  529.     }
  530.  
  531.     case TIOCGPGRP:
  532.         if (!isctty(p, tp))
  533.             return (ENOTTY);
  534.         *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
  535.         break;
  536.  
  537.     case TIOCSWINSZ:
  538.         if (bcmp((caddr_t)&tp->t_winsize, data,
  539.             sizeof (struct winsize))) {
  540.             tp->t_winsize = *(struct winsize *)data;
  541.             pgsignal(tp->t_pgrp, SIGWINCH, 1);
  542.         }
  543.         break;
  544.  
  545.     case TIOCGWINSZ:
  546.         *(struct winsize *)data = tp->t_winsize;
  547.         break;
  548.  
  549.     case TIOCCONS:
  550.         if (*(int *)data) {
  551.             if (constty && constty != tp &&
  552.                 (constty->t_state & (TS_CARR_ON|TS_ISOPEN)) ==
  553.                 (TS_CARR_ON|TS_ISOPEN))
  554.                 return (EBUSY);
  555. #ifndef    UCONSOLE
  556.             if (error = suser(p->p_ucred, &p->p_acflag))
  557.                 return (error);
  558. #endif
  559.             constty = tp;
  560.         } else if (tp == constty)
  561.             constty = NULL;
  562.         break;
  563.  
  564.     case TIOCDRAIN:
  565.         if (error = ttywait(tp))
  566.             return (error);
  567.         break;
  568.  
  569.     default:
  570. #ifdef COMPAT_43
  571.         return (ttcompat(tp, com, data, flag));
  572. #else
  573.         return (-1);
  574. #endif
  575.     }
  576.     return (0);
  577. }
  578.  
  579. ttnread(tp)
  580.     struct tty *tp;
  581. {
  582.     int nread = 0;
  583.  
  584.     if (tp->t_lflag & PENDIN)
  585.         ttypend(tp);
  586.     nread = tp->t_canq.c_cc;
  587.     if ((tp->t_lflag & ICANON) == 0)
  588.         nread += tp->t_rawq.c_cc;
  589.     return (nread);
  590. }
  591.  
  592. ttselect(dev, rw)
  593.     dev_t dev;
  594.     int rw;
  595. {
  596.     register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
  597.     int nread;
  598.     int s = spltty();
  599.  
  600.     switch (rw) {
  601.  
  602.     case FREAD:
  603.         nread = ttnread(tp);
  604.         if (nread > 0 || 
  605.            ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0))
  606.             goto win;
  607.         if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
  608.             tp->t_state |= TS_RCOLL;
  609.         else
  610.             tp->t_rsel = curproc;
  611.         break;
  612.  
  613.     case FWRITE:
  614.         if (tp->t_outq.c_cc <= tp->t_lowat)
  615.             goto win;
  616.         if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
  617.             tp->t_state |= TS_WCOLL;
  618.         else
  619.             tp->t_wsel = curproc;
  620.         break;
  621.     }
  622.     splx(s);
  623.     return (0);
  624. win:
  625.     splx(s);
  626.     return (1);
  627. }
  628.  
  629. /*
  630.  * Initial open of tty, or (re)entry to standard tty line discipline.
  631.  */
  632. ttyopen(dev, tp)
  633.     dev_t dev;
  634.     register struct tty *tp;
  635. {
  636.  
  637.     tp->t_dev = dev;
  638.  
  639.     tp->t_state &= ~TS_WOPEN;
  640.     if ((tp->t_state & TS_ISOPEN) == 0) {
  641.         tp->t_state |= TS_ISOPEN;
  642.         bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize));
  643.     }
  644.     return (0);
  645. }
  646.  
  647. /*
  648.  * "close" a line discipline
  649.  */
  650. ttylclose(tp, flag)
  651.     struct tty *tp;
  652.     int flag;
  653. {
  654.  
  655.     if (flag&IO_NDELAY)
  656.         ttyflush(tp, FREAD|FWRITE);
  657.     else
  658.         ttywflush(tp);
  659. }
  660.  
  661. /*
  662.  * Handle close() on a tty line: flush and set to initial state,
  663.  * bumping generation number so that pending read/write calls
  664.  * can detect recycling of the tty.
  665.  */
  666. ttyclose(tp)
  667.     register struct tty *tp;
  668. {
  669.     if (constty == tp)
  670.         constty = NULL;
  671.     ttyflush(tp, FREAD|FWRITE);
  672.     tp->t_session = NULL;
  673.     tp->t_pgrp = NULL;
  674.     tp->t_state = 0;
  675.     tp->t_gen++;
  676.     return (0);
  677. }
  678.  
  679. /*
  680.  * Handle modem control transition on a tty.
  681.  * Flag indicates new state of carrier.
  682.  * Returns 0 if the line should be turned off, otherwise 1.
  683.  */
  684. ttymodem(tp, flag)
  685.     register struct tty *tp;
  686. {
  687.  
  688.     if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag&MDMBUF)) {
  689.         /*
  690.          * MDMBUF: do flow control according to carrier flag
  691.          */
  692.         if (flag) {
  693.             tp->t_state &= ~TS_TTSTOP;
  694.             ttstart(tp);
  695.         } else if ((tp->t_state&TS_TTSTOP) == 0) {
  696.             tp->t_state |= TS_TTSTOP;
  697.             (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
  698.         }
  699.     } else if (flag == 0) {
  700.         /*
  701.          * Lost carrier.
  702.          */
  703.         tp->t_state &= ~TS_CARR_ON;
  704.         if (tp->t_state&TS_ISOPEN && (tp->t_cflag&CLOCAL) == 0) {
  705.             if (tp->t_session && tp->t_session->s_leader)
  706.                 psignal(tp->t_session->s_leader, SIGHUP);
  707.             ttyflush(tp, FREAD|FWRITE);
  708.             return (0);
  709.         }
  710.     } else {
  711.         /*
  712.          * Carrier now on.
  713.          */
  714.         tp->t_state |= TS_CARR_ON;
  715.         ttwakeup(tp);
  716.     }
  717.     return (1);
  718. }
  719.  
  720. /*
  721.  * Default modem control routine (for other line disciplines).
  722.  * Return argument flag, to turn off device on carrier drop.
  723.  */
  724. nullmodem(tp, flag)
  725.     register struct tty *tp;
  726.     int flag;
  727. {
  728.     
  729.     if (flag)
  730.         tp->t_state |= TS_CARR_ON;
  731.     else {
  732.         tp->t_state &= ~TS_CARR_ON;
  733.         if ((tp->t_cflag&CLOCAL) == 0) {
  734.             if (tp->t_session && tp->t_session->s_leader)
  735.                 psignal(tp->t_session->s_leader, SIGHUP);
  736.             return (0);
  737.         }
  738.     }
  739.     return (1);
  740. }
  741.  
  742. /*
  743.  * reinput pending characters after state switch
  744.  * call at spltty().
  745.  */
  746. ttypend(tp)
  747.     register struct tty *tp;
  748. {
  749.     struct clist tq;
  750.     register c;
  751.  
  752.     tp->t_lflag &= ~PENDIN;
  753.     tp->t_state |= TS_TYPEN;
  754.     tq = tp->t_rawq;
  755.     tp->t_rawq.c_cc = 0;
  756.     tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
  757.     while ((c = getc(&tq)) >= 0)
  758.         ttyinput(c, tp);
  759.     tp->t_state &= ~TS_TYPEN;
  760. }
  761.  
  762. /*
  763.  * Process input of a single character received on a tty.
  764.  */
  765. ttyinput(c, tp)
  766.     register c;
  767.     register struct tty *tp;
  768. {
  769.     register int iflag = tp->t_iflag;
  770.     register int lflag = tp->t_lflag;
  771.     register u_char *cc = tp->t_cc;
  772.     int i, err;
  773.  
  774.     /*
  775.      * If input is pending take it first.
  776.      */
  777.     if (lflag&PENDIN)
  778.         ttypend(tp);
  779.     /*
  780.      * Gather stats.
  781.      */
  782.     tk_nin++;
  783.     if (lflag&ICANON) {
  784.         tk_cancc++;
  785.         tp->t_cancc++;
  786.     } else {
  787.         tk_rawcc++;
  788.         tp->t_rawcc++;
  789.     }
  790.     /*
  791.      * Handle exceptional conditions (break, parity, framing).
  792.      */
  793.     if (err = (c&TTY_ERRORMASK)) {
  794.         c &= ~TTY_ERRORMASK;
  795.         if (err&TTY_FE && !c) {        /* break */
  796.             if (iflag&IGNBRK)
  797.                 goto endcase;
  798.             else if (iflag&BRKINT && lflag&ISIG && 
  799.                 (cc[VINTR] != _POSIX_VDISABLE))
  800.                 c = cc[VINTR];
  801.             else if (iflag&PARMRK)
  802.                 goto parmrk;
  803.         } else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) {
  804.             if (iflag&IGNPAR)
  805.                 goto endcase;
  806.             else if (iflag&PARMRK) {
  807. parmrk:
  808.                 putc(0377|TTY_QUOTE, &tp->t_rawq);
  809.                 putc(0|TTY_QUOTE, &tp->t_rawq);
  810.                 putc(c|TTY_QUOTE, &tp->t_rawq);
  811.                 goto endcase;
  812.             } else
  813.                 c = 0;
  814.         }
  815.     }
  816.     /*
  817.      * In tandem mode, check high water mark.
  818.      */
  819.     if (iflag&IXOFF)
  820.         ttyblock(tp);
  821.     if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP))
  822.         c &= ~0x80;
  823.     if ((tp->t_lflag&EXTPROC) == 0) {
  824.         /*
  825.          * Check for literal nexting very first
  826.          */
  827.         if (tp->t_state&TS_LNCH) {
  828.             c |= TTY_QUOTE;
  829.             tp->t_state &= ~TS_LNCH;
  830.         }
  831.         /*
  832.          * Scan for special characters.  This code
  833.          * is really just a big case statement with
  834.          * non-constant cases.  The bottom of the
  835.          * case statement is labeled ``endcase'', so goto
  836.          * it after a case match, or similar.
  837.          */
  838.  
  839.         /*
  840.          * Control chars which aren't controlled
  841.          * by ICANON, ISIG, or IXON.
  842.          */
  843.         if (lflag&IEXTEN) {
  844.             if (CCEQ(cc[VLNEXT], c)) {
  845.                 if (lflag&ECHO) {
  846.                     if (lflag&ECHOE)
  847.                         ttyoutstr("^\b", tp);
  848.                     else
  849.                         ttyecho(c, tp);
  850.                 }
  851.                 tp->t_state |= TS_LNCH;
  852.                 goto endcase;
  853.             }
  854.             if (CCEQ(cc[VDISCARD], c)) {
  855.                 if (lflag&FLUSHO)
  856.                     tp->t_lflag &= ~FLUSHO;
  857.                 else {
  858.                     ttyflush(tp, FWRITE);
  859.                     ttyecho(c, tp);
  860.                     if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
  861.                         ttyretype(tp);
  862.                     tp->t_lflag |= FLUSHO;
  863.                 }
  864.                 goto startoutput;
  865.             }
  866.         }
  867.         /*
  868.          * Signals.
  869.          */
  870.         if (lflag&ISIG) {
  871.             if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
  872.                 if ((lflag&NOFLSH) == 0)
  873.                     ttyflush(tp, FREAD|FWRITE);
  874.                 ttyecho(c, tp);
  875.                 pgsignal(tp->t_pgrp,
  876.                     CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
  877.                 goto endcase;
  878.             }
  879.             if (CCEQ(cc[VSUSP], c)) {
  880.                 if ((lflag&NOFLSH) == 0)
  881.                     ttyflush(tp, FREAD);
  882.                 ttyecho(c, tp);
  883.                 pgsignal(tp->t_pgrp, SIGTSTP, 1);
  884.                 goto endcase;
  885.             }
  886.         }
  887.         /*
  888.          * Handle start/stop characters.
  889.          */
  890.         if (iflag&IXON) {
  891.             if (CCEQ(cc[VSTOP], c)) {
  892.                 if ((tp->t_state&TS_TTSTOP) == 0) {
  893.                     tp->t_state |= TS_TTSTOP;
  894.                     (*cdevsw[major(tp->t_dev)].d_stop)(tp,
  895.                        0);
  896.                     return;
  897.                 }
  898.                 if (!CCEQ(cc[VSTART], c))
  899.                     return;
  900.                 /* 
  901.                  * if VSTART == VSTOP then toggle 
  902.                  */
  903.                 goto endcase;
  904.             }
  905.             if (CCEQ(cc[VSTART], c))
  906.                 goto restartoutput;
  907.         }
  908.         /*
  909.          * IGNCR, ICRNL, & INLCR
  910.          */
  911.         if (c == '\r') {
  912.             if (iflag&IGNCR)
  913.                 goto endcase;
  914.             else if (iflag&ICRNL)
  915.                 c = '\n';
  916.         } else if (c == '\n' && iflag&INLCR)
  917.             c = '\r';
  918.     }
  919.     if ((tp->t_lflag&EXTPROC) == 0 && lflag&ICANON) {
  920.         /*
  921.          * From here on down canonical mode character
  922.          * processing takes place.
  923.          */
  924.         /*
  925.          * erase (^H / ^?)
  926.          */
  927.         if (CCEQ(cc[VERASE], c)) {
  928.             if (tp->t_rawq.c_cc)
  929.                 ttyrub(unputc(&tp->t_rawq), tp);
  930.             goto endcase;
  931.         }
  932.         /*
  933.          * kill (^U)
  934.          */
  935.         if (CCEQ(cc[VKILL], c)) {
  936.             if (lflag&ECHOKE && tp->t_rawq.c_cc == tp->t_rocount &&
  937.                 (lflag&ECHOPRT) == 0) {
  938.                 while (tp->t_rawq.c_cc)
  939.                     ttyrub(unputc(&tp->t_rawq), tp);
  940.             } else {
  941.                 ttyecho(c, tp);
  942.                 if (lflag&ECHOK || lflag&ECHOKE)
  943.                     ttyecho('\n', tp);
  944.                 while (getc(&tp->t_rawq) > 0)
  945.                     ;
  946.                 tp->t_rocount = 0;
  947.             }
  948.             tp->t_state &= ~TS_LOCAL;
  949.             goto endcase;
  950.         }
  951.         /*
  952.          * word erase (^W)
  953.          */
  954.         if (CCEQ(cc[VWERASE], c)) {    
  955.             int ctype;
  956.             int alt = lflag&ALTWERASE;
  957.  
  958.             /* 
  959.              * erase whitespace 
  960.              */
  961.             while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
  962.                 ttyrub(c, tp);
  963.             if (c == -1)
  964.                 goto endcase;
  965.             /*
  966.              * erase last char of word and remember the
  967.              * next chars type (for ALTWERASE)
  968.              */
  969.             ttyrub(c, tp);
  970.             c = unputc(&tp->t_rawq);
  971.             if (c == -1)
  972.                 goto endcase;
  973.             ctype = ISALPHA(c);
  974.             /*
  975.              * erase rest of word
  976.              */
  977.             do {
  978.                 ttyrub(c, tp);
  979.                 c = unputc(&tp->t_rawq);
  980.                 if (c == -1)
  981.                     goto endcase;
  982.             } while (c != ' ' && c != '\t' && 
  983.                 (alt == 0 || ISALPHA(c) == ctype));
  984.             (void) putc(c, &tp->t_rawq);
  985.             goto endcase;
  986.         }
  987.         /*
  988.          * reprint line (^R)
  989.          */
  990.         if (CCEQ(cc[VREPRINT], c)) {
  991.             ttyretype(tp);
  992.             goto endcase;
  993.         }
  994.         /*
  995.          * ^T - kernel info and generate SIGINFO
  996.          */
  997.         if (CCEQ(cc[VSTATUS], c)) {
  998.             pgsignal(tp->t_pgrp, SIGINFO, 1);
  999.             if ((lflag&NOKERNINFO) == 0)
  1000.                 ttyinfo(tp);
  1001.             goto endcase;
  1002.         }
  1003.     }
  1004.     /*
  1005.      * Check for input buffer overflow
  1006.      */
  1007.     if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
  1008.         if (iflag&IMAXBEL) {
  1009.             if (tp->t_outq.c_cc < tp->t_hiwat)
  1010.                 (void) ttyoutput(CTRL('g'), tp);
  1011.         } else
  1012.             ttyflush(tp, FREAD | FWRITE);
  1013.         goto endcase;
  1014.     }
  1015.     /*
  1016.      * Put data char in q for user and
  1017.      * wakeup on seeing a line delimiter.
  1018.      */
  1019.     if (putc(c, &tp->t_rawq) >= 0) {
  1020.         if ((lflag&ICANON) == 0) {
  1021.             ttwakeup(tp);
  1022.             ttyecho(c, tp);
  1023.             goto endcase;
  1024.         }
  1025.         if (ttbreakc(c)) {
  1026.             tp->t_rocount = 0;
  1027.             catq(&tp->t_rawq, &tp->t_canq);
  1028.             ttwakeup(tp);
  1029.         } else if (tp->t_rocount++ == 0)
  1030.             tp->t_rocol = tp->t_col;
  1031.         if (tp->t_state&TS_ERASE) {
  1032.             /*
  1033.              * end of prterase \.../
  1034.              */
  1035.             tp->t_state &= ~TS_ERASE;
  1036.             (void) ttyoutput('/', tp);
  1037.         }
  1038.         i = tp->t_col;
  1039.         ttyecho(c, tp);
  1040.         if (CCEQ(cc[VEOF], c) && lflag&ECHO) {
  1041.             /*
  1042.              * Place the cursor over the '^' of the ^D.
  1043.              */
  1044.             i = MIN(2, tp->t_col - i);
  1045.             while (i > 0) {
  1046.                 (void) ttyoutput('\b', tp);
  1047.                 i--;
  1048.             }
  1049.         }
  1050.     }
  1051. endcase:
  1052.     /*
  1053.      * IXANY means allow any character to restart output.
  1054.      */
  1055.     if ((tp->t_state&TS_TTSTOP) && (iflag&IXANY) == 0 && 
  1056.         cc[VSTART] != cc[VSTOP])
  1057.         return;
  1058. restartoutput:
  1059.     tp->t_state &= ~TS_TTSTOP;
  1060.     tp->t_lflag &= ~FLUSHO;
  1061. startoutput:
  1062.     ttstart(tp);
  1063. }
  1064.  
  1065. /*
  1066.  * Output a single character on a tty, doing output processing
  1067.  * as needed (expanding tabs, newline processing, etc.).
  1068.  * Returns < 0 if putc succeeds, otherwise returns char to resend.
  1069.  * Must be recursive.
  1070.  */
  1071. ttyoutput(c, tp)
  1072.     register c;
  1073.     register struct tty *tp;
  1074. {
  1075.     register int col;
  1076.     register long oflag = tp->t_oflag;
  1077.     
  1078.     if ((oflag&OPOST) == 0) {
  1079.         if (tp->t_lflag&FLUSHO) 
  1080.             return (-1);
  1081.         if (putc(c, &tp->t_outq))
  1082.             return (c);
  1083.         tk_nout++;
  1084.         tp->t_outcc++;
  1085.         return (-1);
  1086.     }
  1087.     c &= TTY_CHARMASK;
  1088.     /*
  1089.      * Do tab expansion if OXTABS is set.
  1090.      * Special case if we have external processing, we don't
  1091.      * do the tab expansion because we'll probably get it
  1092.      * wrong.  If tab expansion needs to be done, let it
  1093.      * happen externally.
  1094.      */
  1095.     if (c == '\t' && oflag&OXTABS && (tp->t_lflag&EXTPROC) == 0) {
  1096.         register int s;
  1097.  
  1098.         c = 8 - (tp->t_col&7);
  1099.         if ((tp->t_lflag&FLUSHO) == 0) {
  1100.             s = spltty();        /* don't interrupt tabs */
  1101.             c -= b_to_q("        ", c, &tp->t_outq);
  1102.             tk_nout += c;
  1103.             tp->t_outcc += c;
  1104.             splx(s);
  1105.         }
  1106.         tp->t_col += c;
  1107.         return (c ? -1 : '\t');
  1108.     }
  1109.     if (c == CEOT && oflag&ONOEOT)
  1110.         return (-1);
  1111.     tk_nout++;
  1112.     tp->t_outcc++;
  1113.     /*
  1114.      * Newline translation: if ONLCR is set,
  1115.      * translate newline into "\r\n".
  1116.      */
  1117.     if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0)
  1118.         return (c);
  1119.     if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_outq))
  1120.         return (c);
  1121.  
  1122.     col = tp->t_col;
  1123.     switch (CCLASS(c)) {
  1124.  
  1125.     case ORDINARY:
  1126.         col++;
  1127.  
  1128.     case CONTROL:
  1129.         break;
  1130.  
  1131.     case BACKSPACE:
  1132.         if (col > 0)
  1133.             col--;
  1134.         break;
  1135.  
  1136.     case NEWLINE:
  1137.         col = 0;
  1138.         break;
  1139.  
  1140.     case TAB:
  1141.         col = (col + 8) &~ 0x7;
  1142.         break;
  1143.  
  1144.     case RETURN:
  1145.         col = 0;
  1146.     }
  1147.     tp->t_col = col;
  1148.     return (-1);
  1149. }
  1150.  
  1151. /*
  1152.  * Process a read call on a tty device.
  1153.  */
  1154. ttread(tp, uio, flag)
  1155.     register struct tty *tp;
  1156.     struct uio *uio;
  1157. {
  1158.     register struct clist *qp;
  1159.     register int c;
  1160.     register long lflag;
  1161.     register u_char *cc = tp->t_cc;
  1162.     register struct proc *p = curproc;
  1163.     int s, first, error = 0;
  1164.  
  1165. loop:
  1166.     lflag = tp->t_lflag;
  1167.     s = spltty();
  1168.     /*
  1169.      * take pending input first 
  1170.      */
  1171.     if (lflag&PENDIN)
  1172.         ttypend(tp);
  1173.     splx(s);
  1174.  
  1175.     /*
  1176.      * Hang process if it's in the background.
  1177.      */
  1178.     if (isbackground(p, tp)) {
  1179.         if ((p->p_sigignore & sigmask(SIGTTIN)) ||
  1180.            (p->p_sigmask & sigmask(SIGTTIN)) ||
  1181.             p->p_flag&SPPWAIT || p->p_pgrp->pg_jobc == 0)
  1182.             return (EIO);
  1183.         pgsignal(p->p_pgrp, SIGTTIN, 1);
  1184.         if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH, 
  1185.             ttybg, 0)) 
  1186.             return (error);
  1187.         goto loop;
  1188.     }
  1189.  
  1190.     /*
  1191.      * If canonical, use the canonical queue,
  1192.      * else use the raw queue.
  1193.      *
  1194.      * (should get rid of clists...)
  1195.      */
  1196.     qp = lflag&ICANON ? &tp->t_canq : &tp->t_rawq;
  1197.  
  1198.     /*
  1199.      * If there is no input, sleep on rawq
  1200.      * awaiting hardware receipt and notification.
  1201.      * If we have data, we don't need to check for carrier.
  1202.      */
  1203.     s = spltty();
  1204.     if (qp->c_cc <= 0) {
  1205.         int carrier;
  1206.  
  1207.         carrier = (tp->t_state&TS_CARR_ON) || (tp->t_cflag&CLOCAL);
  1208.         if (!carrier && tp->t_state&TS_ISOPEN) {
  1209.             splx(s);
  1210.             return (0);    /* EOF */
  1211.         }
  1212.         if (flag & IO_NDELAY) {
  1213.             splx(s);
  1214.             return (EWOULDBLOCK);
  1215.         }
  1216.         error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
  1217.             carrier ? ttyin : ttopen, 0);
  1218.         splx(s);
  1219.         if (error)
  1220.             return (error);
  1221.         goto loop;
  1222.     }
  1223.     splx(s);
  1224.  
  1225.     /*
  1226.      * Input present, check for input mapping and processing.
  1227.      */
  1228.     first = 1;
  1229.     while ((c = getc(qp)) >= 0) {
  1230.         /*
  1231.          * delayed suspend (^Y)
  1232.          */
  1233.         if (CCEQ(cc[VDSUSP], c) && lflag&ISIG) {
  1234.             pgsignal(tp->t_pgrp, SIGTSTP, 1);
  1235.             if (first) {
  1236.                 if (error = ttysleep(tp, (caddr_t)&lbolt,
  1237.                     TTIPRI | PCATCH, ttybg, 0))
  1238.                     break;
  1239.                 goto loop;
  1240.             }
  1241.             break;
  1242.         }
  1243.         /*
  1244.          * Interpret EOF only in canonical mode.
  1245.          */
  1246.         if (CCEQ(cc[VEOF], c) && lflag&ICANON)
  1247.             break;
  1248.         /*
  1249.          * Give user character.
  1250.          */
  1251.          error = ureadc(c, uio);
  1252.         if (error)
  1253.             break;
  1254.          if (uio->uio_resid == 0)
  1255.             break;
  1256.         /*
  1257.          * In canonical mode check for a "break character"
  1258.          * marking the end of a "line of input".
  1259.          */
  1260.         if (lflag&ICANON && ttbreakc(c))
  1261.             break;
  1262.         first = 0;
  1263.     }
  1264.     /*
  1265.      * Look to unblock output now that (presumably)
  1266.      * the input queue has gone down.
  1267.      */
  1268.     if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
  1269.         if (cc[VSTART] != _POSIX_VDISABLE &&
  1270.             putc(cc[VSTART], &tp->t_outq) == 0) {
  1271.             tp->t_state &= ~TS_TBLOCK;
  1272.             ttstart(tp);
  1273.         }
  1274.     }
  1275.     return (error);
  1276. }
  1277.  
  1278. /*
  1279.  * Check the output queue on tp for space for a kernel message
  1280.  * (from uprintf/tprintf).  Allow some space over the normal
  1281.  * hiwater mark so we don't lose messages due to normal flow
  1282.  * control, but don't let the tty run amok.
  1283.  * Sleeps here are not interruptible, but we return prematurely
  1284.  * if new signals come in.
  1285.  */
  1286. ttycheckoutq(tp, wait)
  1287.     register struct tty *tp;
  1288.     int wait;
  1289. {
  1290.     int hiwat, s, oldsig;
  1291.     extern int wakeup();
  1292.  
  1293.     hiwat = tp->t_hiwat;
  1294.     s = spltty();
  1295.     oldsig = curproc->p_sig;
  1296.     if (tp->t_outq.c_cc > hiwat + 200)
  1297.         while (tp->t_outq.c_cc > hiwat) {
  1298.             ttstart(tp);
  1299.             if (wait == 0 || curproc->p_sig != oldsig) {
  1300.                 splx(s);
  1301.                 return (0);
  1302.             }
  1303.             timeout(wakeup, (caddr_t)&tp->t_outq, hz);
  1304.             tp->t_state |= TS_ASLEEP;
  1305.             sleep((caddr_t)&tp->t_outq, PZERO - 1);
  1306.         }
  1307.     splx(s);
  1308.     return (1);
  1309. }
  1310.  
  1311. /*
  1312.  * Process a write call on a tty device.
  1313.  */
  1314. ttwrite(tp, uio, flag)
  1315.     register struct tty *tp;
  1316.     register struct uio *uio;
  1317. {
  1318.     register char *cp;
  1319.     register int cc = 0, ce;
  1320.     register struct proc *p = curproc;
  1321.     int i, hiwat, cnt, error, s;
  1322.     char obuf[OBUFSIZ];
  1323.  
  1324.     hiwat = tp->t_hiwat;
  1325.     cnt = uio->uio_resid;
  1326.     error = 0;
  1327. loop:
  1328.     s = spltty();
  1329.     if ((tp->t_state&TS_CARR_ON) == 0 && (tp->t_cflag&CLOCAL) == 0) {
  1330.         if (tp->t_state&TS_ISOPEN) {
  1331.             splx(s);
  1332.             return (EIO);
  1333.         } else if (flag & IO_NDELAY) {
  1334.             splx(s);
  1335.             error = EWOULDBLOCK;
  1336.             goto out;
  1337.         } else {
  1338.             /*
  1339.              * sleep awaiting carrier
  1340.              */
  1341.             error = ttysleep(tp, (caddr_t)&tp->t_rawq, 
  1342.                     TTIPRI | PCATCH,ttopen, 0);
  1343.             splx(s);
  1344.             if (error)
  1345.                 goto out;
  1346.             goto loop;
  1347.         }
  1348.     }
  1349.     splx(s);
  1350.     /*
  1351.      * Hang the process if it's in the background.
  1352.      */
  1353.     if (isbackground(p, tp) && 
  1354.         tp->t_lflag&TOSTOP && (p->p_flag&SPPWAIT) == 0 &&
  1355.         (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
  1356.         (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
  1357.          p->p_pgrp->pg_jobc) {
  1358.         pgsignal(p->p_pgrp, SIGTTOU, 1);
  1359.         if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH, 
  1360.             ttybg, 0))
  1361.             goto out;
  1362.         goto loop;
  1363.     }
  1364.     /*
  1365.      * Process the user's data in at most OBUFSIZ
  1366.      * chunks.  Perform any output translation.
  1367.      * Keep track of high water mark, sleep on overflow
  1368.      * awaiting device aid in acquiring new space.
  1369.      */
  1370.     while (uio->uio_resid > 0 || cc > 0) {
  1371.         if (tp->t_lflag&FLUSHO) {
  1372.             uio->uio_resid = 0;
  1373.             return (0);
  1374.         }
  1375.         if (tp->t_outq.c_cc > hiwat)
  1376.             goto ovhiwat;
  1377.         /*
  1378.          * Grab a hunk of data from the user,
  1379.          * unless we have some leftover from last time.
  1380.          */
  1381.         if (cc == 0) {
  1382.             cc = min(uio->uio_resid, OBUFSIZ);
  1383.             cp = obuf;
  1384.             error = uiomove(cp, cc, uio);
  1385.             if (error) {
  1386.                 cc = 0;
  1387.                 break;
  1388.             }
  1389.         }
  1390.         /*
  1391.          * If nothing fancy need be done, grab those characters we
  1392.          * can handle without any of ttyoutput's processing and
  1393.          * just transfer them to the output q.  For those chars
  1394.          * which require special processing (as indicated by the
  1395.          * bits in partab), call ttyoutput.  After processing
  1396.          * a hunk of data, look for FLUSHO so ^O's will take effect
  1397.          * immediately.
  1398.          */
  1399.         while (cc > 0) {
  1400.             if ((tp->t_oflag&OPOST) == 0)
  1401.                 ce = cc;
  1402.             else {
  1403.                 ce = cc - scanc((unsigned)cc, (u_char *)cp,
  1404.                    (u_char *)partab, CCLASSMASK);
  1405.                 /*
  1406.                  * If ce is zero, then we're processing
  1407.                  * a special character through ttyoutput.
  1408.                  */
  1409.                 if (ce == 0) {
  1410.                     tp->t_rocount = 0;
  1411.                     if (ttyoutput(*cp, tp) >= 0) {
  1412.                         /* no c-lists, wait a bit */
  1413.                         ttstart(tp);
  1414.                         if (error = ttysleep(tp, 
  1415.                         (caddr_t)&lbolt,
  1416.                          TTOPRI | PCATCH, ttybuf, 0))
  1417.                             break;
  1418.                         goto loop;
  1419.                     }
  1420.                     cp++, cc--;
  1421.                     if ((tp->t_lflag&FLUSHO) ||
  1422.                         tp->t_outq.c_cc > hiwat)
  1423.                         goto ovhiwat;
  1424.                     continue;
  1425.                 }
  1426.             }
  1427.             /*
  1428.              * A bunch of normal characters have been found,
  1429.              * transfer them en masse to the output queue and
  1430.              * continue processing at the top of the loop.
  1431.              * If there are any further characters in this
  1432.              * <= OBUFSIZ chunk, the first should be a character
  1433.              * requiring special handling by ttyoutput.
  1434.              */
  1435.             tp->t_rocount = 0;
  1436.             i = b_to_q(cp, ce, &tp->t_outq);
  1437.             ce -= i;
  1438.             tp->t_col += ce;
  1439.             cp += ce, cc -= ce, tk_nout += ce;
  1440.             tp->t_outcc += ce;
  1441.             if (i > 0) {
  1442.                 /* out of c-lists, wait a bit */
  1443.                 ttstart(tp);
  1444.                 if (error = ttysleep(tp, (caddr_t)&lbolt,
  1445.                         TTOPRI | PCATCH, ttybuf, 0))
  1446.                     break;
  1447.                 goto loop;
  1448.             }
  1449.             if (tp->t_lflag&FLUSHO || tp->t_outq.c_cc > hiwat)
  1450.                 break;
  1451.         }
  1452.         ttstart(tp);
  1453.     }
  1454. out:
  1455.     /*
  1456.      * If cc is nonzero, we leave the uio structure inconsistent,
  1457.      * as the offset and iov pointers have moved forward,
  1458.      * but it doesn't matter (the call will either return short
  1459.      * or restart with a new uio).
  1460.      */
  1461.     uio->uio_resid += cc;
  1462.     return (error);
  1463.  
  1464. ovhiwat:
  1465.     ttstart(tp);
  1466.     s = spltty();
  1467.     /*
  1468.      * This can only occur if FLUSHO is set in t_lflag,
  1469.      * or if ttstart/oproc is synchronous (or very fast).
  1470.      */
  1471.     if (tp->t_outq.c_cc <= hiwat) {
  1472.         splx(s);
  1473.         goto loop;
  1474.     }
  1475.     if (flag & IO_NDELAY) {
  1476.         splx(s);
  1477.         uio->uio_resid += cc;
  1478.         if (uio->uio_resid == cnt)
  1479.             return (EWOULDBLOCK);
  1480.         return (0);
  1481.     }
  1482.     tp->t_state |= TS_ASLEEP;
  1483.     error = ttysleep(tp, (caddr_t)&tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
  1484.     splx(s);
  1485.     if (error)
  1486.         goto out;
  1487.     goto loop;
  1488. }
  1489.  
  1490. /*
  1491.  * Rubout one character from the rawq of tp
  1492.  * as cleanly as possible.
  1493.  */
  1494. ttyrub(c, tp)
  1495.     register c;
  1496.     register struct tty *tp;
  1497. {
  1498.     register char *cp;
  1499.     register int savecol;
  1500.     int s;
  1501.     char *nextc();
  1502.  
  1503.     if ((tp->t_lflag&ECHO) == 0 || (tp->t_lflag&EXTPROC))
  1504.         return;
  1505.     tp->t_lflag &= ~FLUSHO;    
  1506.     if (tp->t_lflag&ECHOE) {
  1507.         if (tp->t_rocount == 0) {
  1508.             /*
  1509.              * Screwed by ttwrite; retype
  1510.              */
  1511.             ttyretype(tp);
  1512.             return;
  1513.         }
  1514.         if (c == ('\t'|TTY_QUOTE) || c == ('\n'|TTY_QUOTE))
  1515.             ttyrubo(tp, 2);
  1516.         else switch (CCLASS(c &= TTY_CHARMASK)) {
  1517.  
  1518.         case ORDINARY:
  1519.             ttyrubo(tp, 1);
  1520.             break;
  1521.  
  1522.         case VTAB:
  1523.         case BACKSPACE:
  1524.         case CONTROL:
  1525.         case RETURN:
  1526.         case NEWLINE:
  1527.             if (tp->t_lflag&ECHOCTL)
  1528.                 ttyrubo(tp, 2);
  1529.             break;
  1530.  
  1531.         case TAB: {
  1532.             int c;
  1533.  
  1534.             if (tp->t_rocount < tp->t_rawq.c_cc) {
  1535.                 ttyretype(tp);
  1536.                 return;
  1537.             }
  1538.             s = spltty();
  1539.             savecol = tp->t_col;
  1540.             tp->t_state |= TS_CNTTB;
  1541.             tp->t_lflag |= FLUSHO;
  1542.             tp->t_col = tp->t_rocol;
  1543.             cp = tp->t_rawq.c_cf;
  1544.             if (cp)
  1545.                 c = *cp;    /* XXX FIX NEXTC */
  1546.             for (; cp; cp = nextc(&tp->t_rawq, cp, &c))
  1547.                 ttyecho(c, tp);
  1548.             tp->t_lflag &= ~FLUSHO;
  1549.             tp->t_state &= ~TS_CNTTB;
  1550.             splx(s);
  1551.             /*
  1552.              * savecol will now be length of the tab
  1553.              */
  1554.             savecol -= tp->t_col;
  1555.             tp->t_col += savecol;
  1556.             if (savecol > 8)
  1557.                 savecol = 8;        /* overflow screw */
  1558.             while (--savecol >= 0)
  1559.                 (void) ttyoutput('\b', tp);
  1560.             break;
  1561.         }
  1562.  
  1563.         default:
  1564.             /* XXX */
  1565.             printf("ttyrub: would panic c = %d, val = %d\n",
  1566.                 c, CCLASS(c));
  1567.             /*panic("ttyrub");*/
  1568.         }
  1569.     } else if (tp->t_lflag&ECHOPRT) {
  1570.         if ((tp->t_state&TS_ERASE) == 0) {
  1571.             (void) ttyoutput('\\', tp);
  1572.             tp->t_state |= TS_ERASE;
  1573.         }
  1574.         ttyecho(c, tp);
  1575.     } else
  1576.         ttyecho(tp->t_cc[VERASE], tp);
  1577.     tp->t_rocount--;
  1578. }
  1579.  
  1580. /*
  1581.  * Crt back over cnt chars perhaps
  1582.  * erasing them.
  1583.  */
  1584. ttyrubo(tp, cnt)
  1585.     register struct tty *tp;
  1586.     int cnt;
  1587. {
  1588.  
  1589.     while (--cnt >= 0)
  1590.         ttyoutstr("\b \b", tp);
  1591. }
  1592.  
  1593. /*
  1594.  * Reprint the rawq line.
  1595.  * We assume c_cc has already been checked.
  1596.  */
  1597. ttyretype(tp)
  1598.     register struct tty *tp;
  1599. {
  1600.     register char *cp;
  1601.     char *nextc();
  1602.     int s, c;
  1603.  
  1604.     if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
  1605.         ttyecho(tp->t_cc[VREPRINT], tp);
  1606.     (void) ttyoutput('\n', tp);
  1607.     s = spltty();
  1608.     /*** XXX *** FIX *** NEXTC IS BROKEN - DOESN'T CHECK QUOTE
  1609.       BIT OF FIRST CHAR ****/
  1610.     for (cp = tp->t_canq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_canq, cp, &c)) {
  1611.         ttyecho(c, tp);
  1612.     }
  1613.     for (cp = tp->t_rawq.c_cf, c=(cp?*cp:0); cp; cp = nextc(&tp->t_rawq, cp, &c)) {
  1614.         ttyecho(c, tp);
  1615.     }
  1616.     tp->t_state &= ~TS_ERASE;
  1617.     splx(s);
  1618.     tp->t_rocount = tp->t_rawq.c_cc;
  1619.     tp->t_rocol = 0;
  1620. }
  1621.  
  1622. /*
  1623.  * Echo a typed character to the terminal.
  1624.  */
  1625. ttyecho(c, tp)
  1626.     register c;
  1627.     register struct tty *tp;
  1628. {
  1629.     if ((tp->t_state&TS_CNTTB) == 0)
  1630.         tp->t_lflag &= ~FLUSHO;
  1631.     if (((tp->t_lflag&ECHO) == 0 &&
  1632.         ((tp->t_lflag&ECHONL) == 0 || c == '\n')) || (tp->t_lflag&EXTPROC))
  1633.         return;
  1634.     if (tp->t_lflag&ECHOCTL) {
  1635.         if ((c&TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' ||
  1636.             c == 0177) {
  1637.             (void) ttyoutput('^', tp);
  1638.             c &= TTY_CHARMASK;
  1639.             if (c == 0177)
  1640.                 c = '?';
  1641.             else
  1642.                 c += 'A' - 1;
  1643.         }
  1644.     }
  1645.     (void) ttyoutput(c, tp);
  1646. }
  1647.  
  1648. /*
  1649.  * send string cp to tp
  1650.  */
  1651. ttyoutstr(cp, tp)
  1652.     register char *cp;
  1653.     register struct tty *tp;
  1654. {
  1655.     register char c;
  1656.  
  1657.     while (c = *cp++)
  1658.         (void) ttyoutput(c, tp);
  1659. }
  1660.  
  1661. /*
  1662.  * Wake up any readers on a tty.
  1663.  */
  1664. ttwakeup(tp)
  1665.     register struct tty *tp;
  1666. {
  1667.  
  1668.     if (tp->t_rsel) {
  1669.         selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
  1670.         tp->t_state &= ~TS_RCOLL;
  1671.         tp->t_rsel = 0;
  1672.     }
  1673.     if (tp->t_state & TS_ASYNC)
  1674.         pgsignal(tp->t_pgrp, SIGIO, 1); 
  1675.     wakeup((caddr_t)&tp->t_rawq);
  1676. }
  1677.  
  1678. /*
  1679.  * Look up a code for a specified speed in a conversion table;
  1680.  * used by drivers to map software speed values to hardware parameters.
  1681.  */
  1682. ttspeedtab(speed, table)
  1683.     register struct speedtab *table;
  1684. {
  1685.  
  1686.     for ( ; table->sp_speed != -1; table++)
  1687.         if (table->sp_speed == speed)
  1688.             return (table->sp_code);
  1689.     return (-1);
  1690. }
  1691.  
  1692. /*
  1693.  * set tty hi and low water marks
  1694.  *
  1695.  * Try to arrange the dynamics so there's about one second
  1696.  * from hi to low water.
  1697.  * 
  1698.  */
  1699. ttsetwater(tp)
  1700.     struct tty *tp;
  1701. {
  1702.     register cps = tp->t_ospeed / 10;
  1703.     register x;
  1704.  
  1705. #define clamp(x, h, l) ((x)>h ? h : ((x)<l) ? l : (x))
  1706.     tp->t_lowat = x = clamp(cps/2, TTMAXLOWAT, TTMINLOWAT);
  1707.     x += cps;
  1708.     x = clamp(x, TTMAXHIWAT, TTMINHIWAT);
  1709.     tp->t_hiwat = roundup(x, CBSIZE);
  1710. #undef clamp
  1711. }
  1712.  
  1713. /*
  1714.  * Report on state of foreground process group.
  1715.  */
  1716. ttyinfo(tp)
  1717.     register struct tty *tp;
  1718. {
  1719.     register struct proc *p, *pick;
  1720.     struct timeval utime, stime;
  1721.     int tmp;
  1722.  
  1723.     if (ttycheckoutq(tp,0) == 0) 
  1724.         return;
  1725.  
  1726.     /* Print load average. */
  1727.     tmp = (averunnable[0] * 100 + FSCALE / 2) >> FSHIFT;
  1728.     ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
  1729.  
  1730.     if (tp->t_session == NULL)
  1731.         ttyprintf(tp, "not a controlling terminal\n");
  1732.     else if (tp->t_pgrp == NULL)
  1733.         ttyprintf(tp, "no foreground process group\n");
  1734.     else if ((p = tp->t_pgrp->pg_mem) == NULL)
  1735.         ttyprintf(tp, "empty foreground process group\n");
  1736.     else {
  1737.         /* Pick interesting process. */
  1738.         for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
  1739.             if (proc_compare(pick, p))
  1740.                 pick = p;
  1741.  
  1742.         ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
  1743.             pick->p_stat == SRUN ? "running" :
  1744.             pick->p_wmesg ? pick->p_wmesg : "iowait");
  1745.  
  1746.         /*
  1747.          * Lock out clock if process is running; get user/system
  1748.          * cpu time.
  1749.          */
  1750.         if (curproc == pick)
  1751.             tmp = splclock();
  1752.         utime = pick->p_utime;
  1753.         stime = pick->p_stime;
  1754.         if (curproc == pick)
  1755.             splx(tmp);
  1756.  
  1757.         /* Print user time. */
  1758.         ttyprintf(tp, "%d.%02du ",
  1759.             utime.tv_sec, (utime.tv_usec + 5000) / 10000);
  1760.  
  1761.         /* Print system time. */
  1762.         ttyprintf(tp, "%d.%02ds ",
  1763.             stime.tv_sec, (stime.tv_usec + 5000) / 10000);
  1764.  
  1765. #define    pgtok(a)    (((a) * NBPG) / 1024)
  1766.         /* Print percentage cpu, resident set size. */
  1767.         tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT;
  1768.         ttyprintf(tp, "%d%% %dk\n",
  1769.            tmp / 100, pgtok(pick->p_vmspace->vm_rssize));
  1770.     }
  1771.     tp->t_rocount = 0;    /* so pending input will be retyped if BS */
  1772. }
  1773.  
  1774. /*
  1775.  * Returns 1 if p2 is "better" than p1
  1776.  *
  1777.  * The algorithm for picking the "interesting" process is thus:
  1778.  *
  1779.  *    1) (Only foreground processes are eligable - implied)
  1780.  *    2) Runnable processes are favored over anything
  1781.  *       else.  The runner with the highest cpu
  1782.  *       utilization is picked (p_cpu).  Ties are
  1783.  *       broken by picking the highest pid.
  1784.  *    3  Next, the sleeper with the shortest sleep
  1785.  *       time is favored.  With ties, we pick out
  1786.  *       just "short-term" sleepers (SSINTR == 0).
  1787.  *       Further ties are broken by picking the highest
  1788.  *       pid.
  1789.  *
  1790.  */
  1791. #define isrun(p)    (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
  1792. #define TESTAB(a, b)    ((a)<<1 | (b))
  1793. #define ONLYA   2
  1794. #define ONLYB   1
  1795. #define BOTH    3
  1796.  
  1797. static int
  1798. proc_compare(p1, p2)
  1799.     register struct proc *p1, *p2;
  1800. {
  1801.  
  1802.     if (p1 == NULL)
  1803.         return (1);
  1804.     /*
  1805.      * see if at least one of them is runnable
  1806.      */
  1807.     switch (TESTAB(isrun(p1), isrun(p2))) {
  1808.     case ONLYA:
  1809.         return (0);
  1810.     case ONLYB:
  1811.         return (1);
  1812.     case BOTH:
  1813.         /*
  1814.          * tie - favor one with highest recent cpu utilization
  1815.          */
  1816.         if (p2->p_cpu > p1->p_cpu)
  1817.             return (1);
  1818.         if (p1->p_cpu > p2->p_cpu)
  1819.             return (0);
  1820.         return (p2->p_pid > p1->p_pid);    /* tie - return highest pid */
  1821.     }
  1822.     /*
  1823.       * weed out zombies
  1824.      */
  1825.     switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
  1826.     case ONLYA:
  1827.         return (1);
  1828.     case ONLYB:
  1829.         return (0);
  1830.     case BOTH:
  1831.         return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
  1832.     }
  1833.     /* 
  1834.      * pick the one with the smallest sleep time
  1835.      */
  1836.     if (p2->p_slptime > p1->p_slptime)
  1837.         return (0);
  1838.     if (p1->p_slptime > p2->p_slptime)
  1839.         return (1);
  1840.     /*
  1841.      * favor one sleeping in a non-interruptible sleep
  1842.      */
  1843.     if (p1->p_flag&SSINTR && (p2->p_flag&SSINTR) == 0)
  1844.         return (1);
  1845.     if (p2->p_flag&SSINTR && (p1->p_flag&SSINTR) == 0)
  1846.         return (0);
  1847.     return (p2->p_pid > p1->p_pid);        /* tie - return highest pid */
  1848. }
  1849.  
  1850. /*
  1851.  * Output char to tty; console putchar style.
  1852.  */
  1853. tputchar(c, tp)
  1854.     int c;
  1855.     struct tty *tp;
  1856. {
  1857.     register s = spltty();
  1858.  
  1859.     if ((tp->t_state & (TS_CARR_ON|TS_ISOPEN)) == (TS_CARR_ON|TS_ISOPEN)) {
  1860.         if (c == '\n')
  1861.             (void) ttyoutput('\r', tp);
  1862.         (void) ttyoutput(c, tp);
  1863.         ttstart(tp);
  1864.         splx(s);
  1865.         return (0);
  1866.     }
  1867.     splx(s);
  1868.     return (-1);
  1869. }
  1870.  
  1871. /*
  1872.  * Sleep on chan, returning ERESTART if tty changed
  1873.  * while we napped and returning any errors (e.g. EINTR/ETIMEDOUT)
  1874.  * reported by tsleep.  If the tty is revoked, restarting a pending
  1875.  * call will redo validation done at the start of the call.
  1876.  */
  1877. ttysleep(tp, chan, pri, wmesg, timo)
  1878.     struct tty *tp;
  1879.     caddr_t chan;
  1880.     int pri;
  1881.     char *wmesg;
  1882.     int timo;
  1883. {
  1884.     int error;
  1885.     short gen = tp->t_gen;
  1886.  
  1887.     if (error = tsleep(chan, pri, wmesg, timo))
  1888.         return (error);
  1889.     if (tp->t_gen != gen)
  1890.         return (ERESTART);
  1891.     return (0);
  1892. }
  1893.