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