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