45a723292efd0502062cfe968d3ff48ea0695b67
[dragonfly.git] / sys / kern / tty.c
1 /*-
2  * (MPSAFE)
3  *
4  * Copyright (c) 1982, 1986, 1990, 1991, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  * (c) UNIX System Laboratories, Inc.
7  * All or some portions of this file are derived from material licensed
8  * to the University of California by American Telephone and Telegraph
9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10  * the permission of UNIX System Laboratories, Inc.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *      This product includes software developed by the University of
23  *      California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  *      @(#)tty.c       8.8 (Berkeley) 1/21/94
41  * $FreeBSD: src/sys/kern/tty.c,v 1.129.2.5 2002/03/11 01:32:31 dd Exp $
42  */
43
44 /*
45  * MPSAFE NOTE:
46  * Almost all functions in this file are acquiring the tty token due to their
47  * access and modifications of the 'tp' (struct tty) objects.
48  */
49
50 /*-
51  * TODO:
52  *      o Fix races for sending the start char in ttyflush().
53  *      o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
54  *        With luck, there will be MIN chars before select() returns().
55  *      o Handle CLOCAL consistently for ptys.  Perhaps disallow setting it.
56  *      o Don't allow input in TS_ZOMBIE case.  It would be visible through
57  *        FIONREAD.
58  *      o Do the new sio locking stuff here and use it to avoid special
59  *        case for EXTPROC?
60  *      o Lock PENDIN too?
61  *      o Move EXTPROC and/or PENDIN to t_state?
62  *      o Wrap most of ttioctl in spltty/splx.
63  *      o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
64  *      o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
65  *      o Don't allow certain termios flags to affect disciplines other
66  *        than TTYDISC.  Cancel their effects before switch disciplines
67  *        and ignore them if they are set while we are in another
68  *        discipline.
69  *      o Now that historical speed conversions are handled here, don't
70  *        do them in drivers.
71  *      o Check for TS_CARR_ON being set while everything is closed and not
72  *        waiting for carrier.  TS_CARR_ON isn't cleared if nothing is open,
73  *        so it would live until the next open even if carrier drops.
74  *      o Restore TS_WOPEN since it is useful in pstat.  It must be cleared
75  *        only when _all_ openers leave open().
76  */
77
78 #include "opt_compat.h"
79 #include "opt_uconsole.h"
80
81 #include <sys/param.h>
82 #include <sys/systm.h>
83 #include <sys/filio.h>
84 #if defined(COMPAT_43)
85 #include <sys/ioctl_compat.h>
86 #endif
87 #include <sys/proc.h>
88 #include <sys/priv.h>
89 #define TTYDEFCHARS
90 #include <sys/tty.h>
91 #include <sys/clist.h>
92 #undef  TTYDEFCHARS
93 #include <sys/fcntl.h>
94 #include <sys/conf.h>
95 #include <sys/dkstat.h>
96 #include <sys/kernel.h>
97 #include <sys/vnode.h>
98 #include <sys/signalvar.h>
99 #include <sys/signal2.h>
100 #include <sys/resourcevar.h>
101 #include <sys/malloc.h>
102 #include <sys/filedesc.h>
103 #include <sys/sysctl.h>
104 #include <sys/thread2.h>
105
106 #include <vm/vm.h>
107 #include <sys/lock.h>
108 #include <vm/pmap.h>
109 #include <vm/vm_map.h>
110 #include <vm/vm_extern.h>
111
112 MALLOC_DEFINE(M_TTYS, "ttys", "tty data structures");
113
114 static int      proc_compare (struct proc *p1, struct proc *p2);
115 static int      ttnread (struct tty *tp);
116 static void     ttyecho (int c, struct tty *tp);
117 static int      ttyoutput (int c, struct tty *tp);
118 static void     ttypend (struct tty *tp);
119 static void     ttyretype (struct tty *tp);
120 static void     ttyrub (int c, struct tty *tp);
121 static void     ttyrubo (struct tty *tp, int cnt);
122 static void     ttyunblock (struct tty *tp);
123 static int      ttywflush (struct tty *tp);
124 static int      filt_ttyread (struct knote *kn, long hint);
125 static void     filt_ttyrdetach (struct knote *kn);
126 static int      filt_ttywrite (struct knote *kn, long hint);
127 static void     filt_ttywdetach (struct knote *kn);
128
129 /*
130  * Table with character classes and parity. The 8th bit indicates parity,
131  * the 7th bit indicates the character is an alphameric or underscore (for
132  * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
133  * are 0 then the character needs no special processing on output; classes
134  * other than 0 might be translated or (not currently) require delays.
135  */
136 #define E       0x00    /* Even parity. */
137 #define O       0x80    /* Odd parity. */
138 #define PARITY(c)       (char_type[c] & O)
139
140 #define ALPHA   0x40    /* Alpha or underscore. */
141 #define ISALPHA(c)      (char_type[(c) & TTY_CHARMASK] & ALPHA)
142
143 #define CCLASSMASK      0x3f
144 #define CCLASS(c)       (char_type[c] & CCLASSMASK)
145
146 #define BS      BACKSPACE
147 #define CC      CONTROL
148 #define CR      RETURN
149 #define NA      ORDINARY | ALPHA
150 #define NL      NEWLINE
151 #define NO      ORDINARY
152 #define TB      TAB
153 #define VT      VTAB
154
155 static u_char const char_type[] = {
156         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
157         O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
158         O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
159         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
160         O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
161         E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
162         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
163         O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
164         O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
165         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
166         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
167         O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
168         E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
169         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
170         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
171         E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
172         /*
173          * Meta chars; should be settable per character set;
174          * for now, treat them all as normal characters.
175          */
176         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
177         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
178         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
179         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
180         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
181         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
182         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
183         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
184         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
185         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
186         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
187         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
188         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
189         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
190         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
191         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
192 };
193 #undef  BS
194 #undef  CC
195 #undef  CR
196 #undef  NA
197 #undef  NL
198 #undef  NO
199 #undef  TB
200 #undef  VT
201
202 /* Macros to clear/set/test flags. */
203 #define SET(t, f)       (t) |= (f)
204 #define CLR(t, f)       (t) &= ~(f)
205 #define ISSET(t, f)     ((t) & (f))
206
207 #undef MAX_INPUT                /* XXX wrong in <sys/syslimits.h> */
208 #define MAX_INPUT       TTYHOG  /* XXX limit is usually larger for !ICANON */
209
210 uint64_t tk_nin;
211 SYSCTL_OPAQUE(_kern, OID_AUTO, tk_nin, CTLFLAG_RD, &tk_nin, sizeof(tk_nin),
212     "LU", "TTY input statistic");
213 uint64_t tk_nout;
214 SYSCTL_OPAQUE(_kern, OID_AUTO, tk_nout, CTLFLAG_RD, &tk_nout, sizeof(tk_nout),
215     "LU", "TTY output statistic");
216 uint64_t tk_rawcc;
217
218 /*
219  * list of struct tty where pstat(8) can pick it up with sysctl
220  */
221 static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list);
222
223 /*
224  * Initial open of tty, or (re)entry to standard tty line discipline.
225  */
226 int
227 ttyopen(cdev_t device, struct tty *tp)
228 {
229         crit_enter();
230         lwkt_gettoken(&tty_token);
231         tp->t_dev = device;
232         if (!ISSET(tp->t_state, TS_ISOPEN)) {
233                 SET(tp->t_state, TS_ISOPEN);
234                 if (ISSET(tp->t_cflag, CLOCAL)) {
235                         SET(tp->t_state, TS_CONNECTED);
236                 }
237                 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
238         }
239         ttsetwater(tp);
240         lwkt_reltoken(&tty_token);
241         crit_exit();
242         return (0);
243 }
244
245 /*
246  * Handle close() on a tty line: flush and set to initial state,
247  * bumping generation number so that pending read/write calls
248  * can detect recycling of the tty.
249  *
250  * XXX our caller should have done `spltty(); l_close(); ttyclose();'
251  * and l_close() should have flushed, but we repeat the spltty() and
252  * the flush in case there are buggy callers.
253  */
254 int
255 ttyclose(struct tty *tp)
256 {
257         crit_enter();
258         lwkt_gettoken(&tty_token);
259         funsetown(&tp->t_sigio);
260         if (constty == tp)
261                 constty = NULL;
262
263         ttyflush(tp, FREAD | FWRITE);
264         clist_free_cblocks(&tp->t_canq);
265         clist_free_cblocks(&tp->t_outq);
266         clist_free_cblocks(&tp->t_rawq);
267
268         tp->t_gen++;
269         tp->t_line = TTYDISC;
270         ttyclearsession(tp);
271         tp->t_state &= TS_REGISTERED;   /* clear all bits except */
272         lwkt_reltoken(&tty_token);
273         crit_exit();
274         return (0);
275 }
276
277 /*
278  * Disassociate the tty from its session.  Traditionally this has only been
279  * a half-close, meaning that the session was still allowed to point at the
280  * tty (resulting in the tty in the ps command showing something like 'p0-'),
281  * even though the tty is no longer pointing at the session.
282  *
283  * The half close seems to be useful only for 'ps' output but there is as
284  * yet no reason to remove the feature.  The full-close code is currently
285  * #if 0'd out.  See also sess_rele() in kern/kern_proc.c.
286  */
287 void
288 ttyclearsession(struct tty *tp)
289 {
290         struct session *sp;
291         struct pgrp *opgrp;
292
293         lwkt_gettoken(&tty_token);
294         opgrp = tp->t_pgrp;
295         tp->t_pgrp = NULL;
296         if (opgrp) {
297                 pgrel(opgrp);
298                 opgrp = NULL;
299         }
300
301         if ((sp = tp->t_session) != NULL) {
302                 tp->t_session = NULL;
303 #ifdef TTY_DO_FULL_CLOSE
304                 /* FULL CLOSE (not yet) */
305                 if (sp->s_ttyp == tp) {
306                         sp->s_ttyp = NULL;
307                         ttyunhold(tp);
308                 } else {
309                         kprintf("ttyclearsession: warning: sp->s_ttyp != tp "
310                                 "%p/%p\n", sp->s_ttyp, tp);
311                 }
312 #endif
313         }
314         lwkt_reltoken(&tty_token);
315 }
316
317 /*
318  * Release the tty vnode association for a session.  This is the 
319  * 'other half' of the close.  Because multiple opens of /dev/tty
320  * only generate a single open to the actual tty, the file modes
321  * are locked to FREAD|FWRITE.
322  *
323  * If dorevoke is non-zero, the session is also revoked.  We have to
324  * close the vnode if VCTTYISOPEN is set.
325  */
326 void
327 ttyclosesession(struct session *sp, int dorevoke)
328 {
329         struct vnode *vp;
330
331         lwkt_gettoken(&tty_token);
332 retry:
333         /*
334          * There may not be a controlling terminal or it may have been closed
335          * out from under us.
336          */
337         if ((vp = sp->s_ttyvp) == NULL) {
338                 lwkt_reltoken(&tty_token);
339                 return;
340         }
341
342         /*
343          * We need a lock if we have to close or revoke.
344          */
345         if ((vp->v_flag & VCTTYISOPEN) || dorevoke) {
346                 vhold(vp);
347                 if (vn_lock(vp, LK_EXCLUSIVE|LK_RETRY)) {
348                         vdrop(vp);
349                         goto retry;
350                 }
351
352                 /*
353                  * Retry if the vnode was ripped out from under us
354                  */
355                 if (vp != sp->s_ttyvp) {
356                         vn_unlock(vp);
357                         vdrop(vp);
358                         goto retry;
359                 }
360
361                 /*
362                  * Close and revoke as needed
363                  */
364                 sp->s_ttyvp = NULL;
365                 if (vp->v_flag & VCTTYISOPEN) {
366                         vclrflags(vp, VCTTYISOPEN);
367                         VOP_CLOSE(vp, FREAD|FWRITE);
368                 }
369                 vn_unlock(vp);
370                 if (dorevoke)
371                         vrevoke(vp, proc0.p_ucred);
372                 vdrop(vp);
373         } else {
374                 sp->s_ttyvp = NULL;
375         }
376         vrele(vp);
377         lwkt_reltoken(&tty_token);
378 }
379
380 #define FLUSHQ(q) {                                                     \
381         if ((q)->c_cc)                                                  \
382                 ndflush(q, (q)->c_cc);                                  \
383 }
384
385 /* Is 'c' a line delimiter ("break" character)? */
386 #define TTBREAKC(c, lflag)                                                      \
387         ((c) == '\n' || (((c) == cc[VEOF] ||                            \
388           (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) &&   \
389          (c) != _POSIX_VDISABLE))
390
391 /*
392  * Process input of a single character received on a tty.
393  */
394 int
395 ttyinput(int c, struct tty *tp)
396 {
397         tcflag_t iflag, lflag;
398         cc_t *cc;
399         int i, err;
400
401         lwkt_gettoken(&tty_token);
402         /*
403          * If input is pending take it first.
404          */
405         lflag = tp->t_lflag;
406         if (ISSET(lflag, PENDIN))
407                 ttypend(tp);
408         /*
409          * Gather stats.
410          */
411         if (ISSET(lflag, ICANON))
412                 ++tp->t_cancc;
413         else
414                 ++tp->t_rawcc;
415         ++tk_nin;
416
417         /*
418          * Block further input iff:
419          * current input > threshold AND input is available to user program
420          * AND input flow control is enabled and not yet invoked.
421          * The 3 is slop for PARMRK.
422          */
423         iflag = tp->t_iflag;
424         if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 &&
425             (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
426             (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
427             !ISSET(tp->t_state, TS_TBLOCK))
428                 ttyblock(tp);
429
430         /* Handle exceptional conditions (break, parity, framing). */
431         cc = tp->t_cc;
432         err = (ISSET(c, TTY_ERRORMASK));
433         if (err) {
434                 CLR(c, TTY_ERRORMASK);
435                 if (ISSET(err, TTY_BI)) {
436                         if (ISSET(iflag, IGNBRK)) {
437                                 lwkt_reltoken(&tty_token);
438                                 return (0);
439                         }
440                         if (ISSET(iflag, BRKINT)) {
441                                 ttyflush(tp, FREAD | FWRITE);
442                                 pgsignal(tp->t_pgrp, SIGINT, 1);
443                                 goto endcase;
444                         }
445                         if (ISSET(iflag, PARMRK))
446                                 goto parmrk;
447                 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
448                         || ISSET(err, TTY_FE)) {
449                         if (ISSET(iflag, IGNPAR)) {
450                                 lwkt_reltoken(&tty_token);
451                                 return (0);
452                         }
453                         else if (ISSET(iflag, PARMRK)) {
454 parmrk:
455                                 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
456                                     MAX_INPUT - 3)
457                                         goto input_overflow;
458                                 clist_putc(0377 | TTY_QUOTE, &tp->t_rawq);
459                                 clist_putc(0 | TTY_QUOTE, &tp->t_rawq);
460                                 clist_putc(c | TTY_QUOTE, &tp->t_rawq);
461                                 goto endcase;
462                         } else
463                                 c = 0;
464                 }
465         }
466
467         if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
468                 CLR(c, 0x80);
469         if (!ISSET(lflag, EXTPROC)) {
470                 /*
471                  * Check for literal nexting very first
472                  */
473                 if (ISSET(tp->t_state, TS_LNCH)) {
474                         SET(c, TTY_QUOTE);
475                         CLR(tp->t_state, TS_LNCH);
476                 }
477                 /*
478                  * Scan for special characters.  This code
479                  * is really just a big case statement with
480                  * non-constant cases.  The bottom of the
481                  * case statement is labeled ``endcase'', so goto
482                  * it after a case match, or similar.
483                  */
484
485                 /*
486                  * Control chars which aren't controlled
487                  * by ICANON, ISIG, or IXON.
488                  */
489                 if (ISSET(lflag, IEXTEN)) {
490                         if (CCEQ(cc[VLNEXT], c)) {
491                                 if (ISSET(lflag, ECHO)) {
492                                         if (ISSET(lflag, ECHOE)) {
493                                                 (void)ttyoutput('^', tp);
494                                                 (void)ttyoutput('\b', tp);
495                                         } else
496                                                 ttyecho(c, tp);
497                                 }
498                                 SET(tp->t_state, TS_LNCH);
499                                 goto endcase;
500                         }
501                         if (CCEQ(cc[VDISCARD], c)) {
502                                 if (ISSET(lflag, FLUSHO))
503                                         CLR(tp->t_lflag, FLUSHO);
504                                 else {
505                                         ttyflush(tp, FWRITE);
506                                         ttyecho(c, tp);
507                                         if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
508                                                 ttyretype(tp);
509                                         SET(tp->t_lflag, FLUSHO);
510                                 }
511                                 goto startoutput;
512                         }
513                 }
514                 /*
515                  * Signals.
516                  */
517                 if (ISSET(lflag, ISIG)) {
518                         if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
519                                 if (!ISSET(lflag, NOFLSH))
520                                         ttyflush(tp, FREAD | FWRITE);
521                                 ttyecho(c, tp);
522                                 pgsignal(tp->t_pgrp,
523                                     CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
524                                 goto endcase;
525                         }
526                         if (CCEQ(cc[VSUSP], c)) {
527                                 if (!ISSET(lflag, NOFLSH))
528                                         ttyflush(tp, FREAD);
529                                 ttyecho(c, tp);
530                                 pgsignal(tp->t_pgrp, SIGTSTP, 1);
531                                 goto endcase;
532                         }
533                 }
534                 /*
535                  * Handle start/stop characters.
536                  */
537                 if (ISSET(iflag, IXON)) {
538                         if (CCEQ(cc[VSTOP], c)) {
539                                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
540                                         SET(tp->t_state, TS_TTSTOP);
541                                         (*tp->t_stop)(tp, 0);
542                                         lwkt_reltoken(&tty_token);
543                                         return (0);
544                                 }
545                                 if (!CCEQ(cc[VSTART], c)) {
546                                         lwkt_reltoken(&tty_token);
547                                         return (0);
548                                 }
549                                 /*
550                                  * if VSTART == VSTOP then toggle
551                                  */
552                                 goto endcase;
553                         }
554                         if (CCEQ(cc[VSTART], c))
555                                 goto restartoutput;
556                 }
557                 /*
558                  * IGNCR, ICRNL, & INLCR
559                  */
560                 if (c == '\r') {
561                         if (ISSET(iflag, IGNCR)) {
562                                 lwkt_reltoken(&tty_token);
563                                 return (0);
564                         }
565                         else if (ISSET(iflag, ICRNL))
566                                 c = '\n';
567                 } else if (c == '\n' && ISSET(iflag, INLCR))
568                         c = '\r';
569         }
570         if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
571                 /*
572                  * From here on down canonical mode character
573                  * processing takes place.
574                  */
575                 /*
576                  * erase or erase2 (^H / ^?)
577                  */
578                 if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c) ) {
579                         if (tp->t_rawq.c_cc)
580                                 ttyrub(clist_unputc(&tp->t_rawq), tp);
581                         goto endcase;
582                 }
583                 /*
584                  * kill (^U)
585                  */
586                 if (CCEQ(cc[VKILL], c)) {
587                         if (ISSET(lflag, ECHOKE) &&
588                             tp->t_rawq.c_cc == tp->t_rocount &&
589                             !ISSET(lflag, ECHOPRT))
590                                 while (tp->t_rawq.c_cc)
591                                         ttyrub(clist_unputc(&tp->t_rawq), tp);
592                         else {
593                                 ttyecho(c, tp);
594                                 if (ISSET(lflag, ECHOK) ||
595                                     ISSET(lflag, ECHOKE))
596                                         ttyecho('\n', tp);
597                                 FLUSHQ(&tp->t_rawq);
598                                 tp->t_rocount = 0;
599                         }
600                         CLR(tp->t_state, TS_LOCAL);
601                         goto endcase;
602                 }
603                 /*
604                  * word erase (^W)
605                  */
606                 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
607                         int ctype;
608
609                         /*
610                          * erase whitespace
611                          */
612                         while ((c = clist_unputc(&tp->t_rawq)) == ' ' || c == '\t')
613                                 ttyrub(c, tp);
614                         if (c == -1)
615                                 goto endcase;
616                         /*
617                          * erase last char of word and remember the
618                          * next chars type (for ALTWERASE)
619                          */
620                         ttyrub(c, tp);
621                         c = clist_unputc(&tp->t_rawq);
622                         if (c == -1)
623                                 goto endcase;
624                         if (c == ' ' || c == '\t') {
625                                 clist_putc(c, &tp->t_rawq);
626                                 goto endcase;
627                         }
628                         ctype = ISALPHA(c);
629                         /*
630                          * erase rest of word
631                          */
632                         do {
633                                 ttyrub(c, tp);
634                                 c = clist_unputc(&tp->t_rawq);
635                                 if (c == -1)
636                                         goto endcase;
637                         } while (c != ' ' && c != '\t' &&
638                             (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
639                         clist_putc(c, &tp->t_rawq);
640                         goto endcase;
641                 }
642                 /*
643                  * reprint line (^R)
644                  */
645                 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
646                         ttyretype(tp);
647                         goto endcase;
648                 }
649                 /*
650                  * ^T - kernel info and generate SIGINFO
651                  */
652                 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
653                         if (ISSET(lflag, ISIG))
654                                 pgsignal(tp->t_pgrp, SIGINFO, 1);
655                         if (!ISSET(lflag, NOKERNINFO))
656                                 ttyinfo(tp);
657                         goto endcase;
658                 }
659                 if (CCEQ(cc[VCHECKPT], c) && ISSET(lflag, IEXTEN)) {
660                         if (ISSET(lflag, ISIG))
661                                 pgsignal(tp->t_pgrp, SIGCKPT, 1);
662                         goto endcase;
663                 }
664         }
665         /*
666          * Check for input buffer overflow
667          */
668         if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
669 input_overflow:
670                 if (ISSET(iflag, IMAXBEL)) {
671                         if (tp->t_outq.c_cc < tp->t_ohiwat)
672                                 (void)ttyoutput(CTRL('g'), tp);
673                 }
674                 goto endcase;
675         }
676
677         if (   c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
678              && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
679                 clist_putc(0377 | TTY_QUOTE, &tp->t_rawq);
680
681         /*
682          * Put data char in q for user and
683          * wakeup on seeing a line delimiter.
684          */
685         if (clist_putc(c, &tp->t_rawq) >= 0) {
686                 if (!ISSET(lflag, ICANON)) {
687                         ttwakeup(tp);
688                         ttyecho(c, tp);
689                         goto endcase;
690                 }
691                 if (TTBREAKC(c, lflag)) {
692                         tp->t_rocount = 0;
693                         catq(&tp->t_rawq, &tp->t_canq);
694                         ttwakeup(tp);
695                 } else if (tp->t_rocount++ == 0)
696                         tp->t_rocol = tp->t_column;
697                 if (ISSET(tp->t_state, TS_ERASE)) {
698                         /*
699                          * end of prterase \.../
700                          */
701                         CLR(tp->t_state, TS_ERASE);
702                         (void)ttyoutput('/', tp);
703                 }
704                 i = tp->t_column;
705                 ttyecho(c, tp);
706                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
707                         /*
708                          * Place the cursor over the '^' of the ^D.
709                          */
710                         i = imin(2, tp->t_column - i);
711                         while (i > 0) {
712                                 (void)ttyoutput('\b', tp);
713                                 i--;
714                         }
715                 }
716         }
717 endcase:
718         /*
719          * IXANY means allow any character to restart output.
720          */
721         if (ISSET(tp->t_state, TS_TTSTOP) &&
722             !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) {
723                 lwkt_reltoken(&tty_token);
724                 return (0);
725         }
726 restartoutput:
727         CLR(tp->t_lflag, FLUSHO);
728         CLR(tp->t_state, TS_TTSTOP);
729 startoutput:
730         lwkt_reltoken(&tty_token);
731         return (ttstart(tp));
732 }
733
734 /*
735  * Output a single character on a tty, doing output processing
736  * as needed (expanding tabs, newline processing, etc.).
737  * Returns < 0 if succeeds, otherwise returns char to resend.
738  * Must be recursive.
739  */
740 static int
741 ttyoutput(int c, struct tty *tp)
742 {
743         tcflag_t oflag;
744         int col;
745
746         lwkt_gettoken(&tty_token);
747         oflag = tp->t_oflag;
748         if (!ISSET(oflag, OPOST)) {
749                 if (ISSET(tp->t_lflag, FLUSHO)) {
750                         lwkt_reltoken(&tty_token);
751                         return (-1);
752                 }
753                 if (clist_putc(c, &tp->t_outq)) {
754                         lwkt_reltoken(&tty_token);
755                         return (c);
756                 }
757                 tk_nout++;
758                 tp->t_outcc++;
759                 lwkt_reltoken(&tty_token);
760                 return (-1);
761         }
762         /*
763          * Do tab expansion if OXTABS is set.  Special case if we external
764          * processing, we don't do the tab expansion because we'll probably
765          * get it wrong.  If tab expansion needs to be done, let it happen
766          * externally.
767          */
768         CLR(c, ~TTY_CHARMASK);
769         if (c == '\t' &&
770             ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
771                 c = 8 - (tp->t_column & 7);
772                 if (!ISSET(tp->t_lflag, FLUSHO)) {
773                         crit_enter();           /* Don't interrupt tabs. */
774                         c -= b_to_q("        ", c, &tp->t_outq);
775                         tk_nout += c;
776                         tp->t_outcc += c;
777                         crit_exit();
778                 }
779                 tp->t_column += c;
780                 lwkt_reltoken(&tty_token);
781                 return (c ? -1 : '\t');
782         }
783         if (c == CEOT && ISSET(oflag, ONOEOT)) {
784                 lwkt_reltoken(&tty_token);
785                 return (-1);
786         }
787
788         /*
789          * Newline translation: if ONLCR is set,
790          * translate newline into "\r\n".
791          */
792         if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
793                 tk_nout++;
794                 tp->t_outcc++;
795                 if (!ISSET(tp->t_lflag, FLUSHO) && clist_putc('\r', &tp->t_outq)) {
796                         lwkt_reltoken(&tty_token);
797                         return (c);
798                 }
799         }
800         /* If OCRNL is set, translate "\r" into "\n". */
801         else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
802                 c = '\n';
803         /* If ONOCR is set, don't transmit CRs when on column 0. */
804         else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0) {
805                 lwkt_reltoken(&tty_token);
806                 return (-1);
807         }
808
809         tk_nout++;
810         tp->t_outcc++;
811         if (!ISSET(tp->t_lflag, FLUSHO) && clist_putc(c, &tp->t_outq)) {
812                 lwkt_reltoken(&tty_token);
813                 return (c);
814         }
815
816         col = tp->t_column;
817         switch (CCLASS(c)) {
818         case BACKSPACE:
819                 if (col > 0)
820                         --col;
821                 break;
822         case CONTROL:
823                 break;
824         case NEWLINE:
825                 if (ISSET(tp->t_oflag, ONLCR | ONLRET))
826                         col = 0;
827                 break;
828         case RETURN:
829                 col = 0;
830                 break;
831         case ORDINARY:
832                 ++col;
833                 break;
834         case TAB:
835                 col = (col + 8) & ~7;
836                 break;
837         }
838         tp->t_column = col;
839         lwkt_reltoken(&tty_token);
840         return (-1);
841 }
842
843 /*
844  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
845  * has been called to do discipline-specific functions and/or reject any
846  * of these ioctl commands.
847  */
848 /* ARGSUSED */
849 int
850 ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
851 {
852         struct thread *td = curthread;
853         struct lwp *lp = td->td_lwp;
854         struct proc *p = td->td_proc;
855         struct pgrp *opgrp;
856         struct tty *otp;
857         int error;
858
859         KKASSERT(p);
860         lwkt_gettoken(&tty_token);
861         lwkt_gettoken(&proc_token);
862         lwkt_gettoken(&p->p_token);
863
864         /* If the ioctl involves modification, hang if in the background. */
865         switch (cmd) {
866         case  TIOCCBRK:
867         case  TIOCCONS:
868         case  TIOCDRAIN:
869         case  TIOCEXCL:
870         case  TIOCFLUSH:
871 #ifdef TIOCHPCL
872         case  TIOCHPCL:
873 #endif
874         case  TIOCNXCL:
875         case  TIOCSBRK:
876         case  TIOCSCTTY:
877         case  TIOCSDRAINWAIT:
878         case  TIOCSETA:
879         case  TIOCSETAF:
880         case  TIOCSETAW:
881         case  TIOCSETD:
882         case  TIOCSPGRP:
883         case  TIOCSTART:
884         case  TIOCSTAT:
885         case  TIOCSTI:
886         case  TIOCSTOP:
887         case  TIOCSWINSZ:
888 #if defined(COMPAT_43)
889         case  TIOCLBIC:
890         case  TIOCLBIS:
891         case  TIOCLSET:
892         case  TIOCSETC:
893         case OTIOCSETD:
894         case  TIOCSETN:
895         case  TIOCSETP:
896         case  TIOCSLTC:
897 #endif
898                 while (isbackground(p, tp) && !(p->p_flags & P_PPWAIT) &&
899                     !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
900                     !SIGISMEMBER(lp->lwp_sigmask, SIGTTOU)) {
901                         if (p->p_pgrp->pg_jobc == 0) {
902                                 lwkt_reltoken(&p->p_token);
903                                 lwkt_reltoken(&proc_token);
904                                 lwkt_reltoken(&tty_token);
905                                 return (EIO);
906                         }
907                         pgsignal(p->p_pgrp, SIGTTOU, 1);
908                         error = ttysleep(tp, &lbolt, PCATCH, "ttybg1",
909                                          0);
910                         if (error) {
911                                 lwkt_reltoken(&p->p_token);
912                                 lwkt_reltoken(&proc_token);
913                                 lwkt_reltoken(&tty_token);
914                                 return (error);
915                         }
916                 }
917                 break;
918         }
919
920         switch (cmd) {                  /* Process the ioctl. */
921         case FIOASYNC:                  /* set/clear async i/o */
922                 crit_enter();
923                 if (*(int *)data)
924                         SET(tp->t_state, TS_ASYNC);
925                 else
926                         CLR(tp->t_state, TS_ASYNC);
927                 crit_exit();
928                 break;
929         case FIONREAD:                  /* get # bytes to read */
930                 crit_enter();
931                 *(int *)data = ttnread(tp);
932                 crit_exit();
933                 break;
934
935         case FIOSETOWN:
936                 /*
937                  * Policy -- Don't allow FIOSETOWN on someone else's 
938                  *           controlling tty
939                  */
940                 if (tp->t_session != NULL && !isctty(p, tp)) {
941                         lwkt_reltoken(&p->p_token);
942                         lwkt_reltoken(&proc_token);
943                         lwkt_reltoken(&tty_token);
944                         return (ENOTTY);
945                 }
946
947                 error = fsetown(*(int *)data, &tp->t_sigio);
948                 if (error) {
949                         lwkt_reltoken(&p->p_token);
950                         lwkt_reltoken(&proc_token);
951                         lwkt_reltoken(&tty_token);
952                         return (error);
953                 }
954                 break;
955         case FIOGETOWN:
956                 if (tp->t_session != NULL && !isctty(p, tp)) {
957                         lwkt_reltoken(&p->p_token);
958                         lwkt_reltoken(&proc_token);
959                         lwkt_reltoken(&tty_token);
960                         return (ENOTTY);
961                 }
962                 *(int *)data = fgetown(&tp->t_sigio);
963                 break;
964
965         case TIOCEXCL:                  /* set exclusive use of tty */
966                 crit_enter();
967                 SET(tp->t_state, TS_XCLUDE);
968                 crit_exit();
969                 break;
970         case TIOCFLUSH: {               /* flush buffers */
971                 int flags = *(int *)data;
972
973                 if (flags == 0)
974                         flags = FREAD | FWRITE;
975                 else
976                         flags &= FREAD | FWRITE;
977                 ttyflush(tp, flags);
978                 break;
979         }
980         case TIOCCONS:                  /* become virtual console */
981                 if (*(int *)data) {
982                         if (constty && constty != tp &&
983                             ISSET(constty->t_state, TS_CONNECTED)) {
984                                 lwkt_reltoken(&p->p_token);
985                                 lwkt_reltoken(&proc_token);
986                                 lwkt_reltoken(&tty_token);
987                                 return (EBUSY);
988                         }
989 #ifndef UCONSOLE
990                         if ((error = priv_check(td, PRIV_ROOT)) != 0) {
991                                 lwkt_reltoken(&p->p_token);
992                                 lwkt_reltoken(&proc_token);
993                                 lwkt_reltoken(&tty_token);
994                                 return (error);
995                         }
996 #endif
997                         constty = tp;
998                 } else if (tp == constty)
999                         constty = NULL;
1000                 break;
1001         case TIOCDRAIN:                 /* wait till output drained */
1002                 error = ttywait(tp);
1003                 if (error) {
1004                         lwkt_reltoken(&p->p_token);
1005                         lwkt_reltoken(&proc_token);
1006                         lwkt_reltoken(&tty_token);
1007                         return (error);
1008                 }
1009                 break;
1010         case TIOCGETA: {                /* get termios struct */
1011                 struct termios *t = (struct termios *)data;
1012
1013                 bcopy(&tp->t_termios, t, sizeof(struct termios));
1014                 break;
1015         }
1016         case TIOCGETD:                  /* get line discipline */
1017                 *(int *)data = tp->t_line;
1018                 break;
1019         case TIOCGWINSZ:                /* get window size */
1020                 *(struct winsize *)data = tp->t_winsize;
1021                 break;
1022         case TIOCGPGRP:                 /* get pgrp of tty */
1023                 if (!isctty(p, tp)) {
1024                         lwkt_reltoken(&p->p_token);
1025                         lwkt_reltoken(&proc_token);
1026                         lwkt_reltoken(&tty_token);
1027                         return (ENOTTY);
1028                 }
1029                 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
1030                 break;
1031         case TIOCGSID:                  /* get sid of tty */
1032                 if (!isctty(p, tp)) {
1033                         lwkt_reltoken(&p->p_token);
1034                         lwkt_reltoken(&proc_token);
1035                         lwkt_reltoken(&tty_token);
1036                         return (ENOTTY);
1037                 }
1038                 *(int *)data = tp->t_session->s_sid;
1039                 break;
1040 #ifdef TIOCHPCL
1041         case TIOCHPCL:                  /* hang up on last close */
1042                 crit_enter();
1043                 SET(tp->t_cflag, HUPCL);
1044                 crit_exit();
1045                 break;
1046 #endif
1047         case TIOCNXCL:                  /* reset exclusive use of tty */
1048                 crit_enter();
1049                 CLR(tp->t_state, TS_XCLUDE);
1050                 crit_exit();
1051                 break;
1052         case TIOCOUTQ:                  /* output queue size */
1053                 *(int *)data = tp->t_outq.c_cc;
1054                 break;
1055         case TIOCSETA:                  /* set termios struct */
1056         case TIOCSETAW:                 /* drain output, set */
1057         case TIOCSETAF: {               /* drn out, fls in, set */
1058                 struct termios *t = (struct termios *)data;
1059
1060                 if (t->c_ispeed == 0)
1061                         t->c_ispeed = t->c_ospeed;
1062                 if (t->c_ispeed == 0)
1063                         t->c_ispeed = tp->t_ospeed;
1064                 if (t->c_ispeed == 0) {
1065                         lwkt_reltoken(&p->p_token);
1066                         lwkt_reltoken(&proc_token);
1067                         lwkt_reltoken(&tty_token);
1068                         return (EINVAL);
1069                 }
1070                 crit_enter();
1071                 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
1072                         error = ttywait(tp);
1073                         if (error) {
1074                                 crit_exit();
1075                                 lwkt_reltoken(&p->p_token);
1076                                 lwkt_reltoken(&proc_token);
1077                                 lwkt_reltoken(&tty_token);
1078                                 return (error);
1079                         }
1080                         if (cmd == TIOCSETAF)
1081                                 ttyflush(tp, FREAD);
1082                 }
1083                 if (!ISSET(t->c_cflag, CIGNORE)) {
1084                         /*
1085                          * Set device hardware.
1086                          */
1087                         if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1088                                 crit_exit();
1089                                 lwkt_reltoken(&p->p_token);
1090                                 lwkt_reltoken(&proc_token);
1091                                 lwkt_reltoken(&tty_token);
1092                                 return (error);
1093                         }
1094                         if (ISSET(t->c_cflag, CLOCAL) &&
1095                             !ISSET(tp->t_cflag, CLOCAL)) {
1096                                 /*
1097                                  * XXX disconnections would be too hard to
1098                                  * get rid of without this kludge.  The only
1099                                  * way to get rid of controlling terminals
1100                                  * is to exit from the session leader.
1101                                  */
1102                                 CLR(tp->t_state, TS_ZOMBIE);
1103
1104                                 wakeup(TSA_CARR_ON(tp));
1105                                 ttwakeup(tp);
1106                                 ttwwakeup(tp);
1107                         }
1108                         if ((ISSET(tp->t_state, TS_CARR_ON) ||
1109                              ISSET(t->c_cflag, CLOCAL)) &&
1110                             !ISSET(tp->t_state, TS_ZOMBIE))
1111                                 SET(tp->t_state, TS_CONNECTED);
1112                         else
1113                                 CLR(tp->t_state, TS_CONNECTED);
1114                         tp->t_cflag = t->c_cflag;
1115                         tp->t_ispeed = t->c_ispeed;
1116                         if (t->c_ospeed != 0)
1117                                 tp->t_ospeed = t->c_ospeed;
1118                         ttsetwater(tp);
1119                 }
1120                 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
1121                     cmd != TIOCSETAF) {
1122                         if (ISSET(t->c_lflag, ICANON))
1123                                 SET(tp->t_lflag, PENDIN);
1124                         else {
1125                                 /*
1126                                  * XXX we really shouldn't allow toggling
1127                                  * ICANON while we're in a non-termios line
1128                                  * discipline.  Now we have to worry about
1129                                  * panicing for a null queue.
1130                                  */
1131                                 if (tp->t_canq.c_cbreserved > 0 &&
1132                                     tp->t_rawq.c_cbreserved > 0) {
1133                                         catq(&tp->t_rawq, &tp->t_canq);
1134                                         /*
1135                                          * XXX the queue limits may be
1136                                          * different, so the old queue
1137                                          * swapping method no longer works.
1138                                          */
1139                                         catq(&tp->t_canq, &tp->t_rawq);
1140                                 }
1141                                 CLR(tp->t_lflag, PENDIN);
1142                         }
1143                         ttwakeup(tp);
1144                 }
1145                 tp->t_iflag = t->c_iflag;
1146                 tp->t_oflag = t->c_oflag;
1147                 /*
1148                  * Make the EXTPROC bit read only.
1149                  */
1150                 if (ISSET(tp->t_lflag, EXTPROC))
1151                         SET(t->c_lflag, EXTPROC);
1152                 else
1153                         CLR(t->c_lflag, EXTPROC);
1154                 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1155                 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1156                     t->c_cc[VTIME] != tp->t_cc[VTIME])
1157                         ttwakeup(tp);
1158                 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1159                 crit_exit();
1160                 break;
1161         }
1162         case TIOCSETD: {                /* set line discipline */
1163                 int t = *(int *)data;
1164                 cdev_t device = tp->t_dev;
1165
1166                 if ((u_int)t >= nlinesw) {
1167                         lwkt_reltoken(&p->p_token);
1168                         lwkt_reltoken(&proc_token);
1169                         lwkt_reltoken(&tty_token);
1170                         return (ENXIO);
1171                 }
1172                 if (t != tp->t_line) {
1173                         crit_enter();
1174                         (*linesw[tp->t_line].l_close)(tp, flag);
1175                         error = (*linesw[t].l_open)(device, tp);
1176                         if (error) {
1177                                 (void)(*linesw[tp->t_line].l_open)(device, tp);
1178                                 crit_exit();
1179                                 lwkt_reltoken(&p->p_token);
1180                                 lwkt_reltoken(&proc_token);
1181                                 lwkt_reltoken(&tty_token);
1182                                 return (error);
1183                         }
1184                         tp->t_line = t;
1185                         crit_exit();
1186                 }
1187                 break;
1188         }
1189         case TIOCSTART:                 /* start output, like ^Q */
1190                 crit_enter();
1191                 if (ISSET(tp->t_state, TS_TTSTOP) ||
1192                     ISSET(tp->t_lflag, FLUSHO)) {
1193                         CLR(tp->t_lflag, FLUSHO);
1194                         CLR(tp->t_state, TS_TTSTOP);
1195                         ttstart(tp);
1196                 }
1197                 crit_exit();
1198                 break;
1199         case TIOCSTI:                   /* simulate terminal input */
1200                 if ((flag & FREAD) == 0 && priv_check(td, PRIV_ROOT)) {
1201                         lwkt_reltoken(&p->p_token);
1202                         lwkt_reltoken(&proc_token);
1203                         lwkt_reltoken(&tty_token);
1204                         return (EPERM);
1205                 }
1206                 if (!isctty(p, tp) && priv_check(td, PRIV_ROOT)) {
1207                         lwkt_reltoken(&p->p_token);
1208                         lwkt_reltoken(&proc_token);
1209                         lwkt_reltoken(&tty_token);
1210                         return (EACCES);
1211                 }
1212                 crit_enter();
1213                 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1214                 crit_exit();
1215                 break;
1216         case TIOCSTOP:                  /* stop output, like ^S */
1217                 crit_enter();
1218                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1219                         SET(tp->t_state, TS_TTSTOP);
1220                         (*tp->t_stop)(tp, 0);
1221                 }
1222                 crit_exit();
1223                 break;
1224         case TIOCSCTTY:                 /* become controlling tty */
1225                 /* Session ctty vnode pointer set in vnode layer. */
1226                 if (!SESS_LEADER(p) ||
1227                     ((p->p_session->s_ttyvp || tp->t_session) &&
1228                     (tp->t_session != p->p_session))) {
1229                         lwkt_reltoken(&p->p_token);
1230                         lwkt_reltoken(&proc_token);
1231                         lwkt_reltoken(&tty_token);
1232                         return (EPERM);
1233                 }
1234                 ttyhold(tp);
1235                 tp->t_session = p->p_session;
1236                 opgrp = tp->t_pgrp;
1237                 pgref(p->p_pgrp);
1238                 tp->t_pgrp = p->p_pgrp;
1239                 otp = p->p_session->s_ttyp;
1240                 p->p_session->s_ttyp = tp;
1241                 p->p_flags |= P_CONTROLT;
1242                 if (otp)
1243                         ttyunhold(otp);
1244                 if (opgrp) {
1245                         pgrel(opgrp);
1246                         opgrp = NULL;
1247                 }
1248                 break;
1249         case TIOCSPGRP: {               /* set pgrp of tty */
1250                 pid_t pgid = *(int *)data;
1251
1252                 if (!isctty(p, tp)) {
1253                         lwkt_reltoken(&p->p_token);
1254                         lwkt_reltoken(&proc_token);
1255                         lwkt_reltoken(&tty_token);
1256                         return (ENOTTY);
1257                 }
1258                 else if (pgid < 1 || pgid > PID_MAX) {
1259                         lwkt_reltoken(&p->p_token);
1260                         lwkt_reltoken(&proc_token);
1261                         lwkt_reltoken(&tty_token);
1262                         return (EINVAL);
1263                 } else {
1264                         struct pgrp *pgrp = pgfind(pgid);
1265                         if (pgrp == NULL || pgrp->pg_session != p->p_session) {
1266                                 if (pgrp)
1267                                         pgrel(pgrp);
1268                                 lwkt_reltoken(&p->p_token);
1269                                 lwkt_reltoken(&proc_token);
1270                                 lwkt_reltoken(&tty_token);
1271                                 return (EPERM);
1272                         }
1273                         opgrp = tp->t_pgrp;
1274                         tp->t_pgrp = pgrp;
1275                         if (opgrp) {
1276                                 pgrel(opgrp);
1277                                 opgrp = NULL;
1278                         }
1279                 }
1280                 break;
1281         }
1282         case TIOCSTAT:                  /* simulate control-T */
1283                 crit_enter();
1284                 ttyinfo(tp);
1285                 crit_exit();
1286                 break;
1287         case TIOCSWINSZ:                /* set window size */
1288                 if (bcmp((caddr_t)&tp->t_winsize, data,
1289                     sizeof (struct winsize))) {
1290                         tp->t_winsize = *(struct winsize *)data;
1291                         pgsignal(tp->t_pgrp, SIGWINCH, 1);
1292                 }
1293                 break;
1294         case TIOCSDRAINWAIT:
1295                 error = priv_check(td, PRIV_ROOT);
1296                 if (error) {
1297                         lwkt_reltoken(&p->p_token);
1298                         lwkt_reltoken(&proc_token);
1299                         lwkt_reltoken(&tty_token);
1300                         return (error);
1301                 }
1302                 tp->t_timeout = *(int *)data * hz;
1303                 wakeup(TSA_OCOMPLETE(tp));
1304                 wakeup(TSA_OLOWAT(tp));
1305                 break;
1306         case TIOCGDRAINWAIT:
1307                 *(int *)data = tp->t_timeout / hz;
1308                 break;
1309         default:
1310                 lwkt_reltoken(&p->p_token);
1311                 lwkt_reltoken(&proc_token);
1312                 lwkt_reltoken(&tty_token);
1313 #if defined(COMPAT_43)
1314                 return (ttcompat(tp, cmd, data, flag));
1315 #else
1316                 return (ENOIOCTL);
1317 #endif
1318         }
1319         lwkt_reltoken(&p->p_token);
1320         lwkt_reltoken(&proc_token);
1321         lwkt_reltoken(&tty_token);
1322         return (0);
1323 }
1324
1325 static struct filterops ttyread_filtops =
1326         { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_ttyrdetach, filt_ttyread };
1327 static struct filterops ttywrite_filtops =
1328         { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_ttywdetach, filt_ttywrite };
1329
1330 int
1331 ttykqfilter(struct dev_kqfilter_args *ap)
1332 {
1333         cdev_t dev = ap->a_head.a_dev;
1334         struct knote *kn = ap->a_kn;
1335         struct tty *tp = dev->si_tty;
1336         struct klist *klist;
1337
1338         ap->a_result = 0;
1339
1340         lwkt_gettoken(&tty_token);
1341         switch (kn->kn_filter) {
1342         case EVFILT_READ:
1343                 klist = &tp->t_rkq.ki_note;
1344                 kn->kn_fop = &ttyread_filtops;
1345                 break;
1346         case EVFILT_WRITE:
1347                 klist = &tp->t_wkq.ki_note;
1348                 kn->kn_fop = &ttywrite_filtops;
1349                 break;
1350         default:
1351                 ap->a_result = EOPNOTSUPP;
1352                 lwkt_reltoken(&tty_token);
1353                 return (0);
1354         }
1355         lwkt_reltoken(&tty_token);
1356         kn->kn_hook = (caddr_t)dev;
1357         knote_insert(klist, kn);
1358
1359         return (0);
1360 }
1361
1362 static void
1363 filt_ttyrdetach(struct knote *kn)
1364 {
1365         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1366
1367         lwkt_gettoken(&tty_token);
1368         knote_remove(&tp->t_rkq.ki_note, kn);
1369         lwkt_reltoken(&tty_token);
1370 }
1371
1372 static int
1373 filt_ttyread(struct knote *kn, long hint)
1374 {
1375         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1376
1377         lwkt_gettoken(&tty_token);
1378         kn->kn_data = ttnread(tp);
1379         if (ISSET(tp->t_state, TS_ZOMBIE)) {
1380                 kn->kn_flags |= (EV_EOF | EV_NODATA);
1381                 lwkt_reltoken(&tty_token);
1382                 return (1);
1383         }
1384         lwkt_reltoken(&tty_token);
1385         return (kn->kn_data > 0);
1386 }
1387
1388 static void
1389 filt_ttywdetach(struct knote *kn)
1390 {
1391         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1392
1393         lwkt_gettoken(&tty_token);
1394         knote_remove(&tp->t_wkq.ki_note, kn);
1395         lwkt_reltoken(&tty_token);
1396 }
1397
1398 static int
1399 filt_ttywrite(struct knote *kn, long hint)
1400 {
1401         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1402         int ret;
1403
1404         lwkt_gettoken(&tty_token);
1405         kn->kn_data = tp->t_outq.c_cc;
1406         if (ISSET(tp->t_state, TS_ZOMBIE)) {
1407                 lwkt_reltoken(&tty_token);
1408                 return (1);
1409         }
1410         ret = (kn->kn_data <= tp->t_olowat &&
1411             ISSET(tp->t_state, TS_CONNECTED));
1412         lwkt_reltoken(&tty_token);
1413         return ret;
1414 }
1415
1416 /*
1417  * Must be called while in a critical section.
1418  * NOTE: tty_token must be held.
1419  */
1420 static int
1421 ttnread(struct tty *tp)
1422 {
1423         int nread;
1424
1425         ASSERT_LWKT_TOKEN_HELD(&tty_token);
1426         if (ISSET(tp->t_lflag, PENDIN))
1427                 ttypend(tp);
1428         nread = tp->t_canq.c_cc;
1429         if (!ISSET(tp->t_lflag, ICANON)) {
1430                 nread += tp->t_rawq.c_cc;
1431                 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1432                         nread = 0;
1433         }
1434         return (nread);
1435 }
1436
1437 /*
1438  * Wait for output to drain.
1439  */
1440 int
1441 ttywait(struct tty *tp)
1442 {
1443         int error;
1444
1445         error = 0;
1446         crit_enter();
1447         lwkt_gettoken(&tty_token);
1448         while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1449                ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1450                 (*tp->t_oproc)(tp);
1451                 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1452                     ISSET(tp->t_state, TS_CONNECTED)) {
1453                         SET(tp->t_state, TS_SO_OCOMPLETE);
1454                         error = ttysleep(tp, TSA_OCOMPLETE(tp),
1455                                          PCATCH, "ttywai",
1456                                          tp->t_timeout);
1457                         if (error) {
1458                                 if (error == EWOULDBLOCK)
1459                                         error = EIO;
1460                                 break;
1461                         }
1462                 } else
1463                         break;
1464         }
1465         if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1466                 error = EIO;
1467         lwkt_reltoken(&tty_token);
1468         crit_exit();
1469         return (error);
1470 }
1471
1472 /*
1473  * Flush if successfully wait.
1474  */
1475 static int
1476 ttywflush(struct tty *tp)
1477 {
1478         int error;
1479
1480         if ((error = ttywait(tp)) == 0)
1481                 ttyflush(tp, FREAD);
1482         return (error);
1483 }
1484
1485 /*
1486  * Flush tty read and/or write queues, notifying anyone waiting.
1487  */
1488 void
1489 ttyflush(struct tty *tp, int rw)
1490 {
1491         crit_enter();
1492         lwkt_gettoken(&tty_token);
1493 #if 0
1494 again:
1495 #endif
1496         if (rw & FWRITE) {
1497                 FLUSHQ(&tp->t_outq);
1498                 CLR(tp->t_state, TS_TTSTOP);
1499         }
1500         (*tp->t_stop)(tp, rw);
1501         if (rw & FREAD) {
1502                 FLUSHQ(&tp->t_canq);
1503                 FLUSHQ(&tp->t_rawq);
1504                 CLR(tp->t_lflag, PENDIN);
1505                 tp->t_rocount = 0;
1506                 tp->t_rocol = 0;
1507                 CLR(tp->t_state, TS_LOCAL);
1508                 ttwakeup(tp);
1509                 if (ISSET(tp->t_state, TS_TBLOCK)) {
1510                         if (rw & FWRITE)
1511                                 FLUSHQ(&tp->t_outq);
1512                         ttyunblock(tp);
1513
1514                         /*
1515                          * Don't let leave any state that might clobber the
1516                          * next line discipline (although we should do more
1517                          * to send the START char).  Not clearing the state
1518                          * may have caused the "putc to a clist with no
1519                          * reserved cblocks" panic/kprintf.
1520                          */
1521                         CLR(tp->t_state, TS_TBLOCK);
1522
1523 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1524                         if (ISSET(tp->t_iflag, IXOFF)) {
1525                                 /*
1526                                  * XXX wait a bit in the hope that the stop
1527                                  * character (if any) will go out.  Waiting
1528                                  * isn't good since it allows races.  This
1529                                  * will be fixed when the stop character is
1530                                  * put in a special queue.  Don't bother with
1531                                  * the checks in ttywait() since the timeout
1532                                  * will save us.
1533                                  */
1534                                 SET(tp->t_state, TS_SO_OCOMPLETE);
1535                                 ttysleep(tp, TSA_OCOMPLETE(tp), 0,
1536                                          "ttyfls", hz / 10);
1537                                 /*
1538                                  * Don't try sending the stop character again.
1539                                  */
1540                                 CLR(tp->t_state, TS_TBLOCK);
1541                                 goto again;
1542                         }
1543 #endif
1544                 }
1545         }
1546         if (rw & FWRITE) {
1547                 FLUSHQ(&tp->t_outq);
1548                 ttwwakeup(tp);
1549         }
1550         lwkt_reltoken(&tty_token);
1551         crit_exit();
1552 }
1553
1554 /*
1555  * Copy in the default termios characters.
1556  */
1557 void
1558 termioschars(struct termios *t)
1559 {
1560         lwkt_gettoken(&tty_token);
1561         bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1562         lwkt_reltoken(&tty_token);
1563 }
1564
1565 /*
1566  * Old interface.
1567  */
1568 void
1569 ttychars(struct tty *tp)
1570 {
1571         lwkt_gettoken(&tty_token);
1572         termioschars(&tp->t_termios);
1573         lwkt_reltoken(&tty_token);
1574 }
1575
1576 /*
1577  * Handle input high water.  Send stop character for the IXOFF case.  Turn
1578  * on our input flow control bit and propagate the changes to the driver.
1579  * XXX the stop character should be put in a special high priority queue.
1580  */
1581 void
1582 ttyblock(struct tty *tp)
1583 {
1584         lwkt_gettoken(&tty_token);
1585         SET(tp->t_state, TS_TBLOCK);
1586         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1587             clist_putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1588                 CLR(tp->t_state, TS_TBLOCK);    /* try again later */
1589         ttstart(tp);
1590         lwkt_reltoken(&tty_token);
1591 }
1592
1593 /*
1594  * Handle input low water.  Send start character for the IXOFF case.  Turn
1595  * off our input flow control bit and propagate the changes to the driver.
1596  * XXX the start character should be put in a special high priority queue.
1597  */
1598 static void
1599 ttyunblock(struct tty *tp)
1600 {
1601         lwkt_gettoken(&tty_token);
1602         CLR(tp->t_state, TS_TBLOCK);
1603         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1604             clist_putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1605                 SET(tp->t_state, TS_TBLOCK);    /* try again later */
1606         ttstart(tp);
1607         lwkt_reltoken(&tty_token);
1608 }
1609
1610 #ifdef notyet
1611 /* Not used by any current (i386) drivers. */
1612 /*
1613  * Restart after an inter-char delay.
1614  */
1615 void
1616 ttrstrt(void *tp_arg)
1617 {
1618         struct tty *tp;
1619
1620         KASSERT(tp_arg != NULL, ("ttrstrt"));
1621
1622         tp = tp_arg;
1623         crit_enter();
1624         lwkt_gettoken(&tty_token);
1625         CLR(tp->t_state, TS_TIMEOUT);
1626         ttstart(tp);
1627         lwkt_reltoken(&tty_token);
1628         crit_exit();
1629 }
1630 #endif
1631
1632 int
1633 ttstart(struct tty *tp)
1634 {
1635         lwkt_gettoken(&tty_token);
1636         if (tp->t_oproc != NULL)        /* XXX: Kludge for pty. */
1637                 (*tp->t_oproc)(tp);
1638         lwkt_reltoken(&tty_token);
1639         return (0);
1640 }
1641
1642 /*
1643  * "close" a line discipline
1644  */
1645 int
1646 ttylclose(struct tty *tp, int flag)
1647 {
1648         lwkt_gettoken(&tty_token);
1649         if (flag & FNONBLOCK || ttywflush(tp))
1650                 ttyflush(tp, FREAD | FWRITE);
1651         lwkt_reltoken(&tty_token);
1652         return (0);
1653 }
1654
1655 void
1656 ttyhold(struct tty *tp)
1657 {
1658         ++tp->t_refs;
1659 }
1660
1661 void
1662 ttyunhold(struct tty *tp)
1663 {
1664         if (tp->t_unhold)
1665                 tp->t_unhold(tp);
1666         else
1667                 --tp->t_refs;
1668 }
1669
1670 /*
1671  * Handle modem control transition on a tty.
1672  * Flag indicates new state of carrier.
1673  * Returns 0 if the line should be turned off, otherwise 1.
1674  */
1675 int
1676 ttymodem(struct tty *tp, int flag)
1677 {
1678         lwkt_gettoken(&tty_token);
1679         if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1680                 /*
1681                  * MDMBUF: do flow control according to carrier flag
1682                  * XXX TS_CAR_OFLOW doesn't do anything yet.  TS_TTSTOP
1683                  * works if IXON and IXANY are clear.
1684                  */
1685                 if (flag) {
1686                         CLR(tp->t_state, TS_CAR_OFLOW);
1687                         CLR(tp->t_state, TS_TTSTOP);
1688                         ttstart(tp);
1689                 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1690                         SET(tp->t_state, TS_CAR_OFLOW);
1691                         SET(tp->t_state, TS_TTSTOP);
1692                         (*tp->t_stop)(tp, 0);
1693                 }
1694         } else if (flag == 0) {
1695                 /*
1696                  * Lost carrier.
1697                  */
1698                 CLR(tp->t_state, TS_CARR_ON);
1699                 if (ISSET(tp->t_state, TS_ISOPEN) &&
1700                     !ISSET(tp->t_cflag, CLOCAL)) {
1701                         SET(tp->t_state, TS_ZOMBIE);
1702                         CLR(tp->t_state, TS_CONNECTED);
1703                         if (tp->t_session && tp->t_session->s_leader)
1704                                 ksignal(tp->t_session->s_leader, SIGHUP);
1705                         ttyflush(tp, FREAD | FWRITE);
1706                         lwkt_reltoken(&tty_token);
1707                         return (0);
1708                 }
1709         } else {
1710                 /*
1711                  * Carrier now on.
1712                  */
1713                 SET(tp->t_state, TS_CARR_ON);
1714                 if (!ISSET(tp->t_state, TS_ZOMBIE))
1715                         SET(tp->t_state, TS_CONNECTED);
1716                 wakeup(TSA_CARR_ON(tp));
1717                 ttwakeup(tp);
1718                 ttwwakeup(tp);
1719         }
1720         lwkt_reltoken(&tty_token);
1721         return (1);
1722 }
1723
1724 /*
1725  * Reinput pending characters after state switch
1726  * call from a critical section.
1727  */
1728 static void
1729 ttypend(struct tty *tp)
1730 {
1731         struct clist tq;
1732         int c;
1733
1734         lwkt_gettoken(&tty_token);
1735         CLR(tp->t_lflag, PENDIN);
1736         SET(tp->t_state, TS_TYPEN);
1737         /*
1738          * XXX this assumes too much about clist internals.  It may even
1739          * fail if the cblock slush pool is empty.  We can't allocate more
1740          * cblocks here because we are called from an interrupt handler
1741          * and clist_alloc_cblocks() can wait.
1742          */
1743         tq = tp->t_rawq;
1744         bzero(&tp->t_rawq, sizeof tp->t_rawq);
1745         tp->t_rawq.c_cbmax = tq.c_cbmax;
1746         tp->t_rawq.c_cbreserved = tq.c_cbreserved;
1747         while ((c = clist_getc(&tq)) >= 0)
1748                 ttyinput(c, tp);
1749         CLR(tp->t_state, TS_TYPEN);
1750         lwkt_reltoken(&tty_token);
1751 }
1752
1753 /*
1754  * Process a read call on a tty device.
1755  */
1756 int
1757 ttread(struct tty *tp, struct uio *uio, int flag)
1758 {
1759         struct clist *qp;
1760         int c;
1761         tcflag_t lflag;
1762         cc_t *cc = tp->t_cc;
1763         struct proc *pp;
1764         struct lwp *lp;
1765         int first, error = 0;
1766         int has_stime = 0, last_cc = 0;
1767         long slp = 0;           /* XXX this should be renamed `timo'. */
1768         struct timeval stime;
1769
1770         lp = curthread->td_lwp;
1771         stime.tv_sec = 0;       /* fix compiler warnings */
1772         stime.tv_usec = 0;
1773
1774         lwkt_gettoken(&tty_token);
1775 loop:
1776         crit_enter();
1777         lflag = tp->t_lflag;
1778         /*
1779          * take pending input first
1780          */
1781         if (ISSET(lflag, PENDIN)) {
1782                 ttypend(tp);
1783                 splz();         /* reduce latency */
1784                 lflag = tp->t_lflag;    /* XXX ttypend() clobbers it */
1785         }
1786
1787         /*
1788          * Hang process if it's in the background.
1789          */
1790         lwkt_gettoken(&proc_token);
1791         if ((pp = curproc) && isbackground(pp, tp)) {
1792                 crit_exit();
1793                 if (SIGISMEMBER(pp->p_sigignore, SIGTTIN) ||
1794                     SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
1795                     (pp->p_flags & P_PPWAIT) || pp->p_pgrp->pg_jobc == 0) {
1796                         lwkt_reltoken(&proc_token);
1797                         lwkt_reltoken(&tty_token);
1798                         return (EIO);
1799                 }
1800                 pgsignal(pp->p_pgrp, SIGTTIN, 1);
1801                 error = ttysleep(tp, &lbolt, PCATCH, "ttybg2", 0);
1802                 if (error) {
1803                         lwkt_reltoken(&proc_token);
1804                         lwkt_reltoken(&tty_token);
1805                         return (error);
1806                 }
1807                 lwkt_reltoken(&proc_token);
1808                 goto loop;
1809         }
1810         lwkt_reltoken(&proc_token);
1811
1812         if (ISSET(tp->t_state, TS_ZOMBIE)) {
1813                 crit_exit();
1814                 lwkt_reltoken(&tty_token);
1815                 return (0);     /* EOF */
1816         }
1817
1818         /*
1819          * If canonical, use the canonical queue,
1820          * else use the raw queue.
1821          *
1822          * (should get rid of clists...)
1823          */
1824         qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1825
1826         if (flag & IO_NDELAY) {
1827                 if (qp->c_cc > 0)
1828                         goto read;
1829                 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1830                         crit_exit();
1831                         lwkt_reltoken(&tty_token);
1832                         return (0);
1833                 }
1834                 crit_exit();
1835                 lwkt_reltoken(&tty_token);
1836                 return (EWOULDBLOCK);
1837         }
1838         if (!ISSET(lflag, ICANON)) {
1839                 int m = cc[VMIN];
1840                 long t = cc[VTIME];
1841                 struct timeval timecopy;
1842
1843                 /*
1844                  * Check each of the four combinations.
1845                  * (m > 0 && t == 0) is the normal read case.
1846                  * It should be fairly efficient, so we check that and its
1847                  * companion case (m == 0 && t == 0) first.
1848                  * For the other two cases, we compute the target sleep time
1849                  * into slp.
1850                  */
1851                 if (t == 0) {
1852                         if (qp->c_cc < m)
1853                                 goto sleep;
1854                         if (qp->c_cc > 0)
1855                                 goto read;
1856
1857                         /* m, t and qp->c_cc are all 0.  0 is enough input. */
1858                         crit_exit();
1859                         lwkt_reltoken(&tty_token);
1860                         return (0);
1861                 }
1862                 t *= 100000;            /* time in us */
1863 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1864                          ((t1).tv_usec - (t2).tv_usec))
1865                 if (m > 0) {
1866                         if (qp->c_cc <= 0)
1867                                 goto sleep;
1868                         if (qp->c_cc >= m)
1869                                 goto read;
1870                         getmicrotime(&timecopy);
1871                         if (has_stime == 0) {
1872                                 /* first character, start timer */
1873                                 has_stime = 1;
1874                                 stime = timecopy;
1875                                 slp = t;
1876                         } else if (qp->c_cc > last_cc) {
1877                                 /* got a character, restart timer */
1878                                 stime = timecopy;
1879                                 slp = t;
1880                         } else {
1881                                 /* nothing, check expiration */
1882                                 slp = t - diff(timecopy, stime);
1883                                 if (slp <= 0)
1884                                         goto read;
1885                         }
1886                         last_cc = qp->c_cc;
1887                 } else {        /* m == 0 */
1888                         if (qp->c_cc > 0)
1889                                 goto read;
1890                         getmicrotime(&timecopy);
1891                         if (has_stime == 0) {
1892                                 has_stime = 1;
1893                                 stime = timecopy;
1894                                 slp = t;
1895                         } else {
1896                                 slp = t - diff(timecopy, stime);
1897                                 if (slp <= 0) {
1898                                         /* Timed out, but 0 is enough input. */
1899                                         crit_exit();
1900                                         lwkt_reltoken(&tty_token);
1901                                         return (0);
1902                                 }
1903                         }
1904                 }
1905 #undef diff
1906                 /*
1907                  * Rounding down may make us wake up just short
1908                  * of the target, so we round up.
1909                  * The formula is ceiling(slp * hz/1000000).
1910                  * 32-bit arithmetic is enough for hz < 169.
1911                  * XXX see tvtohz() for how to avoid overflow if hz
1912                  * is large (divide by `tick' and/or arrange to
1913                  * use tvtohz() if hz is large).
1914                  */
1915                 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1916                 goto sleep;
1917         }
1918         if (qp->c_cc <= 0) {
1919 sleep:
1920                 /*
1921                  * There is no input, or not enough input and we can block.
1922                  */
1923                 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), PCATCH,
1924                                  ISSET(tp->t_state, TS_CONNECTED) ?
1925                                  "ttyin" : "ttyhup", (int)slp);
1926                 crit_exit();
1927                 if (error == EWOULDBLOCK)
1928                         error = 0;
1929                 else if (error) {
1930                         lwkt_reltoken(&tty_token);
1931                         return (error);
1932                 }
1933                 /*
1934                  * XXX what happens if another process eats some input
1935                  * while we are asleep (not just here)?  It would be
1936                  * safest to detect changes and reset our state variables
1937                  * (has_stime and last_cc).
1938                  */
1939                 slp = 0;
1940                 goto loop;
1941         }
1942 read:
1943         crit_exit();
1944         /*
1945          * Input present, check for input mapping and processing.
1946          */
1947         first = 1;
1948         if (ISSET(lflag, ICANON | ISIG))
1949                 goto slowcase;
1950         for (;;) {
1951                 char ibuf[IBUFSIZ];
1952                 int icc;
1953
1954                 icc = (int)szmin(uio->uio_resid, IBUFSIZ);
1955                 icc = q_to_b(qp, ibuf, icc);
1956                 if (icc <= 0) {
1957                         if (first)
1958                                 goto loop;
1959                         break;
1960                 }
1961                 error = uiomove(ibuf, (size_t)icc, uio);
1962                 /*
1963                  * XXX if there was an error then we should ungetc() the
1964                  * unmoved chars and reduce icc here.
1965                  */
1966                 if (error)
1967                         break;
1968                 if (uio->uio_resid == 0)
1969                         break;
1970                 first = 0;
1971         }
1972         goto out;
1973 slowcase:
1974         for (;;) {
1975                 c = clist_getc(qp);
1976                 if (c < 0) {
1977                         if (first)
1978                                 goto loop;
1979                         break;
1980                 }
1981                 /*
1982                  * delayed suspend (^Y)
1983                  */
1984                 if (CCEQ(cc[VDSUSP], c) &&
1985                     ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1986                         pgsignal(tp->t_pgrp, SIGTSTP, 1);
1987                         if (first) {
1988                                 error = ttysleep(tp, &lbolt, PCATCH,
1989                                                  "ttybg3", 0);
1990                                 if (error)
1991                                         break;
1992                                 goto loop;
1993                         }
1994                         break;
1995                 }
1996                 /*
1997                  * Interpret EOF only in canonical mode.
1998                  */
1999                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
2000                         break;
2001                 /*
2002                  * Give user character.
2003                  */
2004                 error = ureadc(c, uio);
2005                 if (error)
2006                         /* XXX should ungetc(c, qp). */
2007                         break;
2008                 if (uio->uio_resid == 0)
2009                         break;
2010                 /*
2011                  * In canonical mode check for a "break character"
2012                  * marking the end of a "line of input".
2013                  */
2014                 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
2015                         break;
2016                 first = 0;
2017         }
2018
2019 out:
2020         /*
2021          * Look to unblock input now that (presumably)
2022          * the input queue has gone down.
2023          */
2024         crit_enter();
2025         if (ISSET(tp->t_state, TS_TBLOCK) &&
2026             tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
2027                 ttyunblock(tp);
2028         crit_exit();
2029
2030         lwkt_reltoken(&tty_token);
2031         return (error);
2032 }
2033
2034 /*
2035  * Check the output queue on tp for space for a kernel message (from uprintf
2036  * or tprintf).  Allow some space over the normal hiwater mark so we don't
2037  * lose messages due to normal flow control, but don't let the tty run amok.
2038  * Sleeps here are not interruptible, but we return prematurely if new signals
2039  * arrive.
2040  */
2041 int
2042 ttycheckoutq(struct tty *tp, int wait)
2043 {
2044         struct lwp *lp = curthread->td_lwp;
2045         int hiwat;
2046         sigset_t oldset, newset;
2047
2048         lwkt_gettoken(&tty_token);
2049         hiwat = tp->t_ohiwat;
2050         SIGEMPTYSET(oldset);
2051         SIGEMPTYSET(newset);
2052         crit_enter();
2053         if (wait)
2054                 oldset = lwp_sigpend(lp);
2055         if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) {
2056                 while (tp->t_outq.c_cc > hiwat) {
2057                         ttstart(tp);
2058                         if (tp->t_outq.c_cc <= hiwat)
2059                                 break;
2060                         if (wait)
2061                                 newset = lwp_sigpend(lp);
2062                         if (!wait || SIGSETNEQ(oldset, newset)) {
2063                                 crit_exit();
2064                                 lwkt_reltoken(&tty_token);
2065                                 return (0);
2066                         }
2067                         SET(tp->t_state, TS_SO_OLOWAT);
2068                         tsleep(TSA_OLOWAT(tp), 0, "ttoutq", hz);
2069                 }
2070         }
2071         crit_exit();
2072         lwkt_reltoken(&tty_token);
2073         return (1);
2074 }
2075
2076 /*
2077  * Process a write call on a tty device.
2078  */
2079 int
2080 ttwrite(struct tty *tp, struct uio *uio, int flag)
2081 {
2082         char *cp = NULL;
2083         int cc, ce;
2084         struct proc *pp;
2085         struct lwp *lp;
2086         int i, hiwat, error;
2087         size_t cnt;
2088
2089         char obuf[OBUFSIZ];
2090
2091         lwkt_gettoken(&tty_token);
2092         lp = curthread->td_lwp;
2093         hiwat = tp->t_ohiwat;
2094         cnt = uio->uio_resid;
2095         error = 0;
2096         cc = 0;
2097 loop:
2098         crit_enter();
2099         if (ISSET(tp->t_state, TS_ZOMBIE)) {
2100                 crit_exit();
2101                 if (uio->uio_resid == cnt)
2102                         error = EIO;
2103                 goto out;
2104         }
2105         if (!ISSET(tp->t_state, TS_CONNECTED)) {
2106                 if (flag & IO_NDELAY) {
2107                         crit_exit();
2108                         error = EWOULDBLOCK;
2109                         goto out;
2110                 }
2111                 error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ttydcd", 0);
2112                 crit_exit();
2113                 if (error)
2114                         goto out;
2115                 goto loop;
2116         }
2117         crit_exit();
2118
2119         /*
2120          * Hang the process if it's in the background.
2121          */
2122         lwkt_gettoken(&proc_token);
2123         if ((pp = curproc) && isbackground(pp, tp) &&
2124             ISSET(tp->t_lflag, TOSTOP) && !(pp->p_flags & P_PPWAIT) &&
2125             !SIGISMEMBER(pp->p_sigignore, SIGTTOU) &&
2126             !SIGISMEMBER(lp->lwp_sigmask, SIGTTOU)) {
2127                 if (pp->p_pgrp->pg_jobc == 0) {
2128                         error = EIO;
2129                         lwkt_reltoken(&proc_token);
2130                         goto out;
2131                 }
2132                 pgsignal(pp->p_pgrp, SIGTTOU, 1);
2133                 lwkt_reltoken(&proc_token);
2134                 error = ttysleep(tp, &lbolt, PCATCH, "ttybg4", 0);
2135                 if (error)
2136                         goto out;
2137                 goto loop;
2138         }
2139         lwkt_reltoken(&proc_token);
2140         /*
2141          * Process the user's data in at most OBUFSIZ chunks.  Perform any
2142          * output translation.  Keep track of high water mark, sleep on
2143          * overflow awaiting device aid in acquiring new space.
2144          */
2145         while (uio->uio_resid > 0 || cc > 0) {
2146                 if (ISSET(tp->t_lflag, FLUSHO)) {
2147                         uio->uio_resid = 0;
2148                         lwkt_reltoken(&tty_token);
2149                         return (0);
2150                 }
2151                 if (tp->t_outq.c_cc > hiwat)
2152                         goto ovhiwat;
2153                 /*
2154                  * Grab a hunk of data from the user, unless we have some
2155                  * leftover from last time.
2156                  */
2157                 if (cc == 0) {
2158                         cc = szmin(uio->uio_resid, OBUFSIZ);
2159                         cp = obuf;
2160                         error = uiomove(cp, (size_t)cc, uio);
2161                         if (error) {
2162                                 cc = 0;
2163                                 break;
2164                         }
2165                 }
2166                 /*
2167                  * If nothing fancy need be done, grab those characters we
2168                  * can handle without any of ttyoutput's processing and
2169                  * just transfer them to the output q.  For those chars
2170                  * which require special processing (as indicated by the
2171                  * bits in char_type), call ttyoutput.  After processing
2172                  * a hunk of data, look for FLUSHO so ^O's will take effect
2173                  * immediately.
2174                  */
2175                 while (cc > 0) {
2176                         if (!ISSET(tp->t_oflag, OPOST))
2177                                 ce = cc;
2178                         else {
2179                                 ce = cc - scanc((u_int)cc, (u_char *)cp,
2180                                                 char_type, CCLASSMASK);
2181                                 /*
2182                                  * If ce is zero, then we're processing
2183                                  * a special character through ttyoutput.
2184                                  */
2185                                 if (ce == 0) {
2186                                         tp->t_rocount = 0;
2187                                         if (ttyoutput(*cp, tp) >= 0) {
2188                                                 /* No Clists, wait a bit. */
2189                                                 ttstart(tp);
2190                                                 if (flag & IO_NDELAY) {
2191                                                         error = EWOULDBLOCK;
2192                                                         goto out;
2193                                                 }
2194                                                 error = ttysleep(tp, &lbolt,
2195                                                                  PCATCH,
2196                                                                  "ttybf1", 0);
2197                                                 if (error)
2198                                                         goto out;
2199                                                 goto loop;
2200                                         }
2201                                         cp++;
2202                                         cc--;
2203                                         if (ISSET(tp->t_lflag, FLUSHO) ||
2204                                             tp->t_outq.c_cc > hiwat)
2205                                                 goto ovhiwat;
2206                                         continue;
2207                                 }
2208                         }
2209                         /*
2210                          * A bunch of normal characters have been found.
2211                          * Transfer them en masse to the output queue and
2212                          * continue processing at the top of the loop.
2213                          * If there are any further characters in this
2214                          * <= OBUFSIZ chunk, the first should be a character
2215                          * requiring special handling by ttyoutput.
2216                          */
2217                         tp->t_rocount = 0;
2218                         i = b_to_q(cp, ce, &tp->t_outq);
2219                         ce -= i;
2220                         tp->t_column += ce;
2221                         cp += ce, cc -= ce, tk_nout += ce;
2222                         tp->t_outcc += ce;
2223                         if (i > 0) {
2224                                 /* No Clists, wait a bit. */
2225                                 ttstart(tp);
2226                                 if (flag & IO_NDELAY) {
2227                                         error = EWOULDBLOCK;
2228                                         goto out;
2229                                 }
2230                                 error = ttysleep(tp, &lbolt, PCATCH,
2231                                                  "ttybf2", 0);
2232                                 if (error)
2233                                         goto out;
2234                                 goto loop;
2235                         }
2236                         if (ISSET(tp->t_lflag, FLUSHO) ||
2237                             tp->t_outq.c_cc > hiwat)
2238                                 break;
2239                 }
2240                 ttstart(tp);
2241         }
2242 out:
2243         /*
2244          * If cc is nonzero, we leave the uio structure inconsistent, as the
2245          * offset and iov pointers have moved forward, but it doesn't matter
2246          * (the call will either return short or restart with a new uio).
2247          */
2248         uio->uio_resid += cc;
2249         lwkt_reltoken(&tty_token);
2250         return (error);
2251
2252 ovhiwat:
2253         ttstart(tp);
2254         crit_enter();
2255         /*
2256          * This can only occur if FLUSHO is set in t_lflag,
2257          * or if ttstart/oproc is synchronous (or very fast).
2258          */
2259         if (tp->t_outq.c_cc <= hiwat) {
2260                 crit_exit();
2261                 goto loop;
2262         }
2263         if (flag & IO_NDELAY) {
2264                 crit_exit();
2265                 uio->uio_resid += cc;
2266                 lwkt_reltoken(&tty_token);
2267                 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
2268         }
2269         SET(tp->t_state, TS_SO_OLOWAT);
2270         error = ttysleep(tp, TSA_OLOWAT(tp), PCATCH, "ttywri", tp->t_timeout);
2271         crit_exit();
2272         if (error == EWOULDBLOCK)
2273                 error = EIO;
2274         if (error)
2275                 goto out;
2276         goto loop;
2277 }
2278
2279 /*
2280  * Rubout one character from the rawq of tp
2281  * as cleanly as possible.
2282  * NOTE: Must be called with tty_token held
2283  */
2284 static void
2285 ttyrub(int c, struct tty *tp)
2286 {
2287         char *cp;
2288         int savecol;
2289         int tabc;
2290
2291         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2292         if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2293                 return;
2294         CLR(tp->t_lflag, FLUSHO);
2295         if (ISSET(tp->t_lflag, ECHOE)) {
2296                 if (tp->t_rocount == 0) {
2297                         /*
2298                          * Screwed by ttwrite; retype
2299                          */
2300                         ttyretype(tp);
2301                         return;
2302                 }
2303                 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
2304                         ttyrubo(tp, 2);
2305                 else {
2306                         CLR(c, ~TTY_CHARMASK);
2307                         switch (CCLASS(c)) {
2308                         case ORDINARY:
2309                                 ttyrubo(tp, 1);
2310                                 break;
2311                         case BACKSPACE:
2312                         case CONTROL:
2313                         case NEWLINE:
2314                         case RETURN:
2315                         case VTAB:
2316                                 if (ISSET(tp->t_lflag, ECHOCTL))
2317                                         ttyrubo(tp, 2);
2318                                 break;
2319                         case TAB:
2320                                 if (tp->t_rocount < tp->t_rawq.c_cc) {
2321                                         ttyretype(tp);
2322                                         return;
2323                                 }
2324                                 crit_enter();
2325                                 savecol = tp->t_column;
2326                                 SET(tp->t_state, TS_CNTTB);
2327                                 SET(tp->t_lflag, FLUSHO);
2328                                 tp->t_column = tp->t_rocol;
2329                                 cp = tp->t_rawq.c_cf;
2330                                 if (cp)
2331                                         tabc = *cp;     /* XXX FIX NEXTC */
2332                                 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
2333                                         ttyecho(tabc, tp);
2334                                 CLR(tp->t_lflag, FLUSHO);
2335                                 CLR(tp->t_state, TS_CNTTB);
2336                                 crit_exit();
2337
2338                                 /* savecol will now be length of the tab. */
2339                                 savecol -= tp->t_column;
2340                                 tp->t_column += savecol;
2341                                 if (savecol > 8)
2342                                         savecol = 8;    /* overflow screw */
2343                                 while (--savecol >= 0)
2344                                         (void)ttyoutput('\b', tp);
2345                                 break;
2346                         default:                        /* XXX */
2347 #define PANICSTR        "ttyrub: would panic c = %d, val = %d\n"
2348                                 (void)kprintf(PANICSTR, c, CCLASS(c));
2349 #ifdef notdef
2350                                 panic(PANICSTR, c, CCLASS(c));
2351 #endif
2352                         }
2353                 }
2354         } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2355                 if (!ISSET(tp->t_state, TS_ERASE)) {
2356                         SET(tp->t_state, TS_ERASE);
2357                         (void)ttyoutput('\\', tp);
2358                 }
2359                 ttyecho(c, tp);
2360         } else {
2361                 ttyecho(tp->t_cc[VERASE], tp);
2362                 /*
2363                  * This code may be executed not only when an ERASE key
2364                  * is pressed, but also when ^U (KILL) or ^W (WERASE) are.
2365                  * So, I didn't think it was worthwhile to pass the extra
2366                  * information (which would need an extra parameter,
2367                  * changing every call) needed to distinguish the ERASE2
2368                  * case from the ERASE.
2369                  */
2370         }
2371         --tp->t_rocount;
2372 }
2373
2374 /*
2375  * Back over cnt characters, erasing them.
2376  * NOTE: Must be called with tty_token held
2377  */
2378 static void
2379 ttyrubo(struct tty *tp, int cnt)
2380 {
2381         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2382         while (cnt-- > 0) {
2383                 (void)ttyoutput('\b', tp);
2384                 (void)ttyoutput(' ', tp);
2385                 (void)ttyoutput('\b', tp);
2386         }
2387 }
2388
2389 /*
2390  * ttyretype --
2391  *      Reprint the rawq line.  Note, it is assumed that c_cc has already
2392  *      been checked.
2393  * NOTE: Must be called with tty_token held
2394  */
2395 static void
2396 ttyretype(struct tty *tp)
2397 {
2398         char *cp;
2399         int c;
2400
2401         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2402         /* Echo the reprint character. */
2403         if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2404                 ttyecho(tp->t_cc[VREPRINT], tp);
2405
2406         (void)ttyoutput('\n', tp);
2407
2408         /*
2409          * XXX
2410          * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2411          * BIT OF FIRST CHAR.
2412          */
2413         crit_enter();
2414         for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
2415             cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
2416                 ttyecho(c, tp);
2417         for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
2418             cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
2419                 ttyecho(c, tp);
2420         CLR(tp->t_state, TS_ERASE);
2421         crit_exit();
2422
2423         tp->t_rocount = tp->t_rawq.c_cc;
2424         tp->t_rocol = 0;
2425 }
2426
2427 /*
2428  * Echo a typed character to the terminal.
2429  * NOTE: Must be called with tty_token held
2430  */
2431 static void
2432 ttyecho(int c, struct tty *tp)
2433 {
2434         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2435
2436         if (!ISSET(tp->t_state, TS_CNTTB))
2437                 CLR(tp->t_lflag, FLUSHO);
2438         if ((!ISSET(tp->t_lflag, ECHO) &&
2439              (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2440             ISSET(tp->t_lflag, EXTPROC))
2441                 return;
2442         if (ISSET(tp->t_lflag, ECHOCTL) &&
2443             ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2444             ISSET(c, TTY_CHARMASK) == 0177)) {
2445                 (void)ttyoutput('^', tp);
2446                 CLR(c, ~TTY_CHARMASK);
2447                 if (c == 0177)
2448                         c = '?';
2449                 else
2450                         c += 'A' - 1;
2451         }
2452         (void)ttyoutput(c, tp);
2453 }
2454
2455 /*
2456  * Wake up any readers on a tty.
2457  */
2458 void
2459 ttwakeup(struct tty *tp)
2460 {
2461         lwkt_gettoken(&tty_token);
2462         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2463                 pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
2464         wakeup(TSA_HUP_OR_INPUT(tp));
2465         KNOTE(&tp->t_rkq.ki_note, 0);
2466         lwkt_reltoken(&tty_token);
2467 }
2468
2469 /*
2470  * Wake up any writers on a tty.
2471  */
2472 void
2473 ttwwakeup(struct tty *tp)
2474 {
2475         lwkt_gettoken(&tty_token);
2476         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2477                 pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
2478         if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2479             TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2480                 CLR(tp->t_state, TS_SO_OCOMPLETE);
2481                 wakeup(TSA_OCOMPLETE(tp));
2482         }
2483         if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2484             tp->t_outq.c_cc <= tp->t_olowat) {
2485                 CLR(tp->t_state, TS_SO_OLOWAT);
2486                 wakeup(TSA_OLOWAT(tp));
2487         }
2488         KNOTE(&tp->t_wkq.ki_note, 0);
2489         lwkt_reltoken(&tty_token);
2490 }
2491
2492 /*
2493  * Look up a code for a specified speed in a conversion table;
2494  * used by drivers to map software speed values to hardware parameters.
2495  * No requirements
2496  */
2497 int
2498 ttspeedtab(int speed, struct speedtab *table)
2499 {
2500
2501         for ( ; table->sp_speed != -1; table++)
2502                 if (table->sp_speed == speed)
2503                         return (table->sp_code);
2504         return (-1);
2505 }
2506
2507 /*
2508  * Set input and output watermarks and buffer sizes.  For input, the
2509  * high watermark is about one second's worth of input above empty, the
2510  * low watermark is slightly below high water, and the buffer size is a
2511  * driver-dependent amount above high water.  For output, the watermarks
2512  * are near the ends of the buffer, with about 1 second's worth of input
2513  * between them.  All this only applies to the standard line discipline.
2514  */
2515 void
2516 ttsetwater(struct tty *tp)
2517 {
2518         int cps, ttmaxhiwat, x;
2519
2520         lwkt_gettoken(&tty_token);
2521         /* Input. */
2522         clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
2523         switch (tp->t_ispeedwat) {
2524         case (speed_t)-1:
2525                 cps = tp->t_ispeed / 10;
2526                 break;
2527         case 0:
2528                 /*
2529                  * This case is for old drivers that don't know about
2530                  * t_ispeedwat.  Arrange for them to get the old buffer
2531                  * sizes and watermarks.
2532                  */
2533                 cps = TTYHOG - 2 * 256;
2534                 tp->t_ififosize = 2 * 2048;
2535                 break;
2536         default:
2537                 cps = tp->t_ispeedwat / 10;
2538                 break;
2539         }
2540         tp->t_ihiwat = cps;
2541         tp->t_ilowat = 7 * cps / 8;
2542         x = cps + tp->t_ififosize;
2543         clist_alloc_cblocks(&tp->t_rawq, x, x);
2544
2545         /* Output. */
2546         switch (tp->t_ospeedwat) {
2547         case (speed_t)-1:
2548                 cps = tp->t_ospeed / 10;
2549                 ttmaxhiwat = 2 * TTMAXHIWAT;
2550                 break;
2551         case 0:
2552                 cps = tp->t_ospeed / 10;
2553                 ttmaxhiwat = TTMAXHIWAT;
2554                 break;
2555         default:
2556                 cps = tp->t_ospeedwat / 10;
2557                 ttmaxhiwat = 8 * TTMAXHIWAT;
2558                 break;
2559         }
2560 #define CLAMP(x, h, l)  ((x) > h ? h : ((x) < l) ? l : (x))
2561         tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2562         x += cps;
2563         x = CLAMP(x, ttmaxhiwat, TTMINHIWAT);   /* XXX clamps are too magic */
2564         tp->t_ohiwat = roundup(x, CBSIZE);      /* XXX for compat */
2565         x = imax(tp->t_ohiwat, TTMAXHIWAT);     /* XXX for compat/safety */
2566         x += OBUFSIZ + 100;
2567         clist_alloc_cblocks(&tp->t_outq, x, x);
2568 #undef  CLAMP
2569         lwkt_reltoken(&tty_token);
2570 }
2571
2572 /*
2573  * Report on state of foreground process group.
2574  */
2575 void
2576 ttyinfo(struct tty *tp)
2577 {
2578         struct pgrp *pgrp;
2579         struct proc *p, *pick;
2580         struct lwp *lp;
2581         struct rusage ru;
2582         char buf[64];
2583         const char *str;
2584         struct vmspace *vm;
2585         long vmsz;
2586         int pctcpu;
2587         int tmp;
2588
2589         if (ttycheckoutq(tp,0) == 0)
2590                 return;
2591
2592         lwkt_gettoken(&tty_token);
2593         lwkt_gettoken(&proc_token);
2594         /*
2595          * We always print the load average, then figure out what else to
2596          * print based on the state of the current process group.
2597          */
2598         tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2599         ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2600
2601         if (tp->t_session == NULL) {
2602                 ttyprintf(tp, "not a controlling terminal\n");
2603                 goto done2;
2604         }
2605         if ((pgrp = tp->t_pgrp) == NULL) {
2606                 ttyprintf(tp, "no foreground process group\n");
2607                 goto done2;
2608         }
2609
2610         /*
2611          * Pick an interesting process.  Note that certain elements,
2612          * in particular the wmesg, require a critical section for
2613          * safe access (YYY and we are still not MP safe).
2614          *
2615          * NOTE: lwp_wmesg is lwp_thread->td_wmesg.
2616          */
2617         pgref(pgrp);
2618         lwkt_gettoken(&pgrp->pg_token);
2619
2620         pick = NULL;
2621         for (p = LIST_FIRST(&pgrp->pg_members);
2622              p != NULL;
2623              p = LIST_NEXT(p, p_pglist)) {
2624                 if (proc_compare(pick, p))
2625                         pick = p;
2626         }
2627         if (pick == NULL) {
2628                 ttyprintf(tp, "empty foreground process group\n");
2629                 goto done1;
2630         }
2631
2632         /*
2633          * Pick an interesting LWP (XXX)
2634          */
2635         PHOLD(pick);
2636         lp = FIRST_LWP_IN_PROC(pick);
2637         if (lp == NULL) {
2638                 PRELE(pick);
2639                 ttyprintf(tp, "foreground process without lwp\n");
2640                 goto done1;
2641         }
2642
2643         /*
2644          * Figure out what wait/process-state message, and command
2645          * buffer to present
2646          */
2647         /*
2648          * XXX lwp This is a horrible mixture.  We need to rework this
2649          * as soon as lwps have their own runnable status.
2650          */
2651         LWPHOLD(lp);
2652         if (pick->p_flags & P_WEXIT)
2653                 str = "exiting";
2654         else if (lp->lwp_stat == LSRUN)
2655                 str = "running";
2656         else if (pick->p_stat == SIDL)
2657                 str = "spawning";
2658         else if (lp->lwp_wmesg) /* lwp_thread must not be NULL */
2659                                 str = lp->lwp_wmesg;
2660         else
2661                 str = "iowait";
2662
2663         ksnprintf(buf, sizeof(buf), "cmd: %s %d [%s]",
2664                   pick->p_comm, pick->p_pid, str);
2665
2666         /*
2667          * Calculate cpu usage, percent cpu, and cmsz.  Note that
2668          * 'pick' becomes invalid the moment we exit the critical
2669          * section.
2670          */
2671         if (lp->lwp_thread && (pick->p_flags & P_SWAPPEDOUT) == 0)
2672                 calcru_proc(pick, &ru);
2673
2674         pctcpu = (lp->lwp_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
2675
2676         LWPRELE(lp);
2677
2678         if (pick->p_stat == SIDL || pick->p_stat == SZOMB) {
2679                 vmsz = 0;
2680         } else if ((vm = pick->p_vmspace) == NULL) {
2681                 vmsz = 0;
2682         } else {
2683                 vmspace_hold(vm);
2684                 vmsz = pgtok(vmspace_resident_count(vm));
2685                 vmspace_drop(vm);
2686         }
2687         PRELE(pick);
2688
2689         /*
2690          * Dump the output
2691          */
2692         ttyprintf(tp, " %s ",
2693                   buf);
2694         ttyprintf(tp, "%ld.%02ldu ",
2695                   ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 10000);
2696         ttyprintf(tp, "%ld.%02lds ",
2697                   ru.ru_stime.tv_sec, ru.ru_stime.tv_usec / 10000);
2698         ttyprintf(tp, "%d%% %ldk\n",
2699                   pctcpu / 100, vmsz);
2700
2701 done1:
2702         lwkt_reltoken(&pgrp->pg_token);
2703         pgrel(pgrp);
2704 done2:
2705         tp->t_rocount = 0;      /* so pending input will be retyped if BS */
2706         lwkt_reltoken(&proc_token);
2707         lwkt_reltoken(&tty_token);
2708 }
2709
2710 /*
2711  * Returns 1 if p2 is "better" than p1
2712  *
2713  * The algorithm for picking the "interesting" process is thus:
2714  *
2715  *      1) Only foreground processes are eligible - implied.
2716  *      2) Runnable processes are favored over anything else.  The runner
2717  *         with the highest cpu utilization is picked (p_cpticks).  Ties are
2718  *         broken by picking the highest pid.
2719  *      3) The sleeper with the shortest sleep time is next.  With ties,
2720  *         we pick out just "short-term" sleepers (LWP_SINTR == 0).
2721  *      4) Further ties are broken by picking the highest pid.
2722  *
2723  * NOTE: must be called with proc_token held.
2724  */
2725 #define ISRUN(lp)       ((lp)->lwp_stat == LSRUN)
2726 #define TESTAB(a, b)    ((a)<<1 | (b))
2727 #define ONLYA   2
2728 #define ONLYB   1
2729 #define BOTH    3
2730
2731 static int
2732 proc_compare(struct proc *p1, struct proc *p2)
2733 {
2734         struct lwp *lp1, *lp2;
2735         int res;
2736
2737         ASSERT_LWKT_TOKEN_HELD(&proc_token);
2738
2739         if (p1 == NULL)
2740                 return (1);
2741         if (lwkt_trytoken(&p1->p_token) == 0)
2742                 return (1);
2743         if (lwkt_trytoken(&p2->p_token) == 0) {
2744                 lwkt_reltoken(&p1->p_token);
2745                 return (0);
2746         }
2747
2748         /*
2749          * weed out zombies
2750          */
2751         switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
2752         case ONLYA:
2753                 res = 1;
2754                 goto done;
2755         case ONLYB:
2756                 res = 0;
2757                 goto done;
2758         case BOTH:
2759                 res = (p2->p_pid > p1->p_pid);  /* tie - return highest pid */
2760                 goto done;
2761         default:
2762                 break;
2763         }
2764
2765         /* XXX choose the best lwp? */
2766         lp1 = FIRST_LWP_IN_PROC(p1);
2767         lp2 = FIRST_LWP_IN_PROC(p2);
2768
2769         /*
2770          * Favor one with LWPs verses one that has none (is exiting).
2771          */
2772         if (lp1 == NULL) {
2773                 res = 1;
2774                 goto done;
2775         }
2776         if (lp2 == NULL) {
2777                 res = 0;
2778                 goto done;
2779         }
2780
2781         /*
2782          * see if at least one of them is runnable
2783          */
2784         switch (TESTAB(ISRUN(lp1), ISRUN(lp2))) {
2785         case ONLYA:
2786                 res = 0;
2787                 goto done;
2788         case ONLYB:
2789                 res = 1;
2790                 goto done;
2791         case BOTH:
2792                 /*
2793                  * tie - favor one with highest recent cpu utilization
2794                  */
2795                 if (lp2->lwp_cpticks > lp1->lwp_cpticks)
2796                         res = 1;
2797                 else if (lp1->lwp_cpticks > lp2->lwp_cpticks)
2798                         res = 0;
2799                 else
2800                         res = (p2->p_pid > p1->p_pid); /* tie - ret highest */
2801                 goto done;
2802         default:
2803                 break;
2804         }
2805
2806         /*
2807          * Pick the one with the smallest sleep time
2808          */
2809         if (lp2->lwp_slptime > lp1->lwp_slptime) {
2810                 res = 0;
2811                 goto done;
2812         }
2813         if (lp1->lwp_slptime > lp2->lwp_slptime) {
2814                 res = 1;
2815                 goto done;
2816         }
2817
2818         /*
2819          * Favor one sleeping in a non-interruptible sleep
2820          */
2821         if ((lp1->lwp_flags & LWP_SINTR) && (lp2->lwp_flags & LWP_SINTR) == 0)
2822                 res = 1;
2823         else
2824         if ((lp2->lwp_flags & LWP_SINTR) && (lp1->lwp_flags & LWP_SINTR) == 0)
2825                 res = 0;
2826         else
2827                 res = (p2->p_pid > p1->p_pid);  /* tie - return highest pid */
2828         /* fall through */
2829
2830 done:
2831         lwkt_reltoken(&p2->p_token);
2832         lwkt_reltoken(&p1->p_token);
2833         return (res);
2834 }
2835
2836 /*
2837  * Output char to tty; console putchar style.
2838  */
2839 int
2840 tputchar(int c, struct tty *tp)
2841 {
2842         crit_enter();
2843         lwkt_gettoken(&tty_token);
2844         if (!ISSET(tp->t_state, TS_CONNECTED)) {
2845                 lwkt_reltoken(&tty_token);
2846                 crit_exit();
2847                 return (-1);
2848         }
2849         if (c == '\n')
2850                 (void)ttyoutput('\r', tp);
2851         (void)ttyoutput(c, tp);
2852         ttstart(tp);
2853         lwkt_reltoken(&tty_token);
2854         crit_exit();
2855         return (0);
2856 }
2857
2858 /*
2859  * Sleep on chan, returning ERESTART if tty changed while we napped and
2860  * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep.  If
2861  * the tty is revoked, restarting a pending call will redo validation done
2862  * at the start of the call.
2863  */
2864 int
2865 ttysleep(struct tty *tp, void *chan, int slpflags, char *wmesg, int timo)
2866 {
2867         int error;
2868         int gen;
2869
2870         gen = tp->t_gen;
2871         error = tsleep(chan, slpflags, wmesg, timo);
2872         if (error)
2873                 return (error);
2874         return (tp->t_gen == gen ? 0 : ERESTART);
2875 }
2876
2877 /*
2878  * Revoke a tty.
2879  *
2880  * We bump the gen to force any ttysleep()'s to return with ERESTART
2881  * and flush the tty.  The related fp's should already have been
2882  * replaced so the tty will close when the last references on the
2883  * original fp's go away.
2884  */
2885 int
2886 ttyrevoke(struct dev_revoke_args *ap)
2887 {
2888         struct tty *tp;
2889
2890         lwkt_gettoken(&tty_token);
2891         tp = ap->a_head.a_dev->si_tty;
2892         tp->t_gen++;
2893         ttyflush(tp, FREAD | FWRITE);
2894         wakeup(TSA_CARR_ON(tp));
2895         ttwakeup(tp);
2896         ttwwakeup(tp);
2897         lwkt_reltoken(&tty_token);
2898         return (0);
2899 }
2900
2901 /*
2902  * Allocate a tty struct.  Clists in the struct will be allocated by
2903  * ttyopen().
2904  */
2905 struct tty *
2906 ttymalloc(struct tty *tp)
2907 {
2908
2909         if (tp) {
2910                 return(tp);
2911         }
2912         tp = kmalloc(sizeof *tp, M_TTYS, M_WAITOK|M_ZERO);
2913         ttyregister(tp);
2914         return (tp);
2915 }
2916
2917 void
2918 ttyunregister(struct tty *tp)
2919 {
2920         lwkt_gettoken(&tty_token);
2921         KKASSERT(ISSET(tp->t_state, TS_REGISTERED));
2922         CLR(tp->t_state, TS_REGISTERED);
2923         TAILQ_REMOVE(&tty_list, tp, t_list);
2924         lwkt_reltoken(&tty_token);
2925 }
2926
2927 void
2928 ttyregister(struct tty *tp)
2929 {
2930         lwkt_gettoken(&tty_token);
2931         KKASSERT(!ISSET(tp->t_state, TS_REGISTERED));
2932         SET(tp->t_state, TS_REGISTERED);
2933         TAILQ_INSERT_HEAD(&tty_list, tp, t_list);
2934         lwkt_reltoken(&tty_token);
2935 }
2936
2937 static int
2938 sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
2939 {
2940         int error;
2941         struct tty *tp;
2942         struct tty t;
2943         struct tty marker;
2944
2945         bzero(&marker, sizeof(marker));
2946         marker.t_state = TS_MARKER;
2947         error = 0;
2948
2949         lwkt_gettoken(&tty_token);
2950
2951         TAILQ_INSERT_HEAD(&tty_list, &marker, t_list);
2952         while ((tp = TAILQ_NEXT(&marker, t_list)) != NULL) {
2953                 TAILQ_REMOVE(&tty_list, &marker, t_list);
2954                 TAILQ_INSERT_AFTER(&tty_list, tp, &marker, t_list);
2955                 if (tp->t_state & TS_MARKER)
2956                         continue;
2957                 t = *tp;
2958                 if (t.t_dev)
2959                         t.t_dev = (cdev_t)(uintptr_t)dev2udev(t.t_dev);
2960                 error = SYSCTL_OUT(req, (caddr_t)&t, sizeof(t));
2961                 if (error)
2962                         break;
2963         }
2964         TAILQ_REMOVE(&tty_list, &marker, t_list);
2965         lwkt_reltoken(&tty_token);
2966         return (error);
2967 }
2968
2969 SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
2970         0, 0, sysctl_kern_ttys, "S,tty", "All struct ttys");
2971
2972 void
2973 nottystop(struct tty *tp, int rw)
2974 {
2975         return;
2976 }
2977
2978 int
2979 ttyread(struct dev_read_args *ap)
2980 {
2981         struct tty *tp;
2982         int ret;
2983
2984         tp = ap->a_head.a_dev->si_tty;
2985         if (tp == NULL)
2986                 return (ENODEV);
2987         lwkt_gettoken(&tty_token);
2988         ret = ((*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag));
2989         lwkt_reltoken(&tty_token);
2990
2991         return ret;
2992 }
2993
2994 int
2995 ttywrite(struct dev_write_args *ap)
2996 {
2997         struct tty *tp;
2998         int ret;
2999
3000         tp = ap->a_head.a_dev->si_tty;
3001         if (tp == NULL)
3002                 return (ENODEV);
3003         lwkt_gettoken(&tty_token);
3004         ret = ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
3005         lwkt_reltoken(&tty_token);
3006
3007         return ret;
3008 }