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