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