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