]> git.saurik.com Git - apple/xnu.git/blame_incremental - bsd/kern/tty.c
xnu-4903.241.1.tar.gz
[apple/xnu.git] / bsd / kern / tty.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1997-2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*-
29 * Copyright (c) 1982, 1986, 1990, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
31 * (c) UNIX System Laboratories, Inc.
32 * All or some portions of this file are derived from material licensed
33 * to the University of California by American Telephone and Telegraph
34 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
35 * the permission of UNIX System Laboratories, Inc.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by the University of
48 * California, Berkeley and its contributors.
49 * 4. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 *
65 * @(#)tty.c 8.8 (Berkeley) 1/21/94
66 */
67/*-
68 * TODO:
69 * o Fix races for sending the start char in ttyflush().
70 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
71 * With luck, there will be MIN chars before select() returns().
72 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it.
73 * o Don't allow input in TS_ZOMBIE case. It would be visible through
74 * FIONREAD.
75 * o Do the new sio locking stuff here and use it to avoid special
76 * case for EXTPROC?
77 * o Lock PENDIN too?
78 * o Move EXTPROC and/or PENDIN to t_state?
79 * o Wrap most of ttioctl in spltty/splx.
80 * o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
81 * o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
82 * o Don't allow certain termios flags to affect disciplines other
83 * than TTYDISC. Cancel their effects before switch disciplines
84 * and ignore them if they are set while we are in another
85 * discipline.
86 * o Handle c_ispeed = 0 to c_ispeed = c_ospeed conversion here instead
87 * of in drivers and fix drivers that write to tp->t_termios.
88 * o Check for TS_CARR_ON being set while everything is closed and not
89 * waiting for carrier. TS_CARR_ON isn't cleared if nothing is open,
90 * so it would live until the next open even if carrier drops.
91 * o Restore TS_WOPEN since it is useful in pstat. It must be cleared
92 * only when _all_ openers leave open().
93 */
94#include <sys/param.h>
95#define TTYDEFCHARS 1
96#include <sys/systm.h>
97#undef TTYDEFCHARS
98#include <sys/ioctl.h>
99#include <sys/proc_internal.h>
100#include <sys/kauth.h>
101#include <sys/file_internal.h>
102#include <sys/conf.h>
103#include <sys/dkstat.h>
104#include <sys/uio_internal.h>
105#include <sys/kernel.h>
106#include <sys/vnode.h>
107#include <sys/syslog.h>
108#include <sys/user.h>
109#include <sys/signalvar.h>
110#include <sys/signalvar.h>
111#include <sys/malloc.h>
112
113#include <dev/kmreg_com.h>
114#include <machine/cons.h>
115#include <sys/resource.h> /* averunnable */
116#include <kern/waitq.h>
117#include <libkern/section_keywords.h>
118
119static lck_grp_t *tty_lck_grp;
120static lck_grp_attr_t *tty_lck_grp_attr;
121static lck_attr_t *tty_lck_attr;
122
123__private_extern__ int ttnread(struct tty *tp);
124static void ttyecho(int c, struct tty *tp);
125static int ttyoutput(int c, struct tty *tp);
126static void ttypend(struct tty *tp);
127static void ttyretype(struct tty *tp);
128static void ttyrub(int c, struct tty *tp);
129static void ttyrubo(struct tty *tp, int count);
130static void ttystop(struct tty *tp, int rw);
131static void ttyunblock(struct tty *tp);
132static int ttywflush(struct tty *tp);
133static int proc_compare(proc_t p1, proc_t p2);
134
135void ttyhold(struct tty *tp);
136static void ttydeallocate(struct tty *tp);
137
138static int isctty(proc_t p, struct tty *tp);
139static int isctty_sp(proc_t p, struct tty *tp, struct session *sessp);
140
141/*
142 * Table with character classes and parity. The 8th bit indicates parity,
143 * the 7th bit indicates the character is an alphameric or underscore (for
144 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
145 * are 0 then the character needs no special processing on output; classes
146 * other than 0 might be translated or (not currently) require delays.
147 */
148#define E 0x00 /* Even parity. */
149#define O 0x80 /* Odd parity. */
150#define PARITY(c) (char_type[c] & O)
151
152#define ALPHA 0x40 /* Alpha or underscore. */
153#define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
154
155#define CCLASSMASK 0x3f
156#define CCLASS(c) (char_type[c] & CCLASSMASK)
157/* 0b10xxxxxx is the mask for UTF-8 continuations */
158#define CCONT(c) ((c & 0xc0) == 0x80)
159
160#define BS BACKSPACE
161#define CC CONTROL
162#define CR RETURN
163#define NA ORDINARY | ALPHA
164#define NL NEWLINE
165#define NO ORDINARY
166#define TB TAB
167#define VT VTAB
168
169static u_char const char_type[] = {
170 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
171 O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
172 O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
173 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
174 O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
175 E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
176 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
177 O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
178 O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
179 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
180 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
181 O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
182 E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
183 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
184 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
185 E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
186 /*
187 * Meta chars; should be settable per character set;
188 * for now, treat them all as normal characters.
189 */
190 NA, NA, NA, NA, NA, NA, NA, NA,
191 NA, NA, NA, NA, NA, NA, NA, NA,
192 NA, NA, NA, NA, NA, NA, NA, NA,
193 NA, NA, NA, NA, NA, NA, NA, NA,
194 NA, NA, NA, NA, NA, NA, NA, NA,
195 NA, NA, NA, NA, NA, NA, NA, NA,
196 NA, NA, NA, NA, NA, NA, NA, NA,
197 NA, NA, NA, NA, NA, NA, NA, NA,
198 NA, NA, NA, NA, NA, NA, NA, NA,
199 NA, NA, NA, NA, NA, NA, NA, NA,
200 NA, NA, NA, NA, NA, NA, NA, NA,
201 NA, NA, NA, NA, NA, NA, NA, NA,
202 NA, NA, NA, NA, NA, NA, NA, NA,
203 NA, NA, NA, NA, NA, NA, NA, NA,
204 NA, NA, NA, NA, NA, NA, NA, NA,
205 NA, NA, NA, NA, NA, NA, NA, NA,
206};
207#undef BS
208#undef CC
209#undef CR
210#undef NA
211#undef NL
212#undef NO
213#undef TB
214#undef VT
215
216/* Macros to clear/set/test flags. */
217#define SET(t, f) (t) |= (f)
218#define CLR(t, f) (t) &= ~(f)
219#define ISSET(t, f) ((t) & (f))
220
221/*
222 * Input control starts when we would not be able to fit the maximum
223 * contents of the ping-pong buffers and finishes when we would be able
224 * to fit that much plus 1/8 more.
225 */
226#define I_HIGH_WATER (TTYHOG - 2 * 256) /* XXX */
227#define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
228
229static void
230termios32to64(struct termios32 *in, struct user_termios *out)
231{
232 out->c_iflag = (user_tcflag_t)in->c_iflag;
233 out->c_oflag = (user_tcflag_t)in->c_oflag;
234 out->c_cflag = (user_tcflag_t)in->c_cflag;
235 out->c_lflag = (user_tcflag_t)in->c_lflag;
236
237 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
238 bcopy(in->c_cc, out->c_cc, sizeof(in->c_cc));
239
240 out->c_ispeed = (user_speed_t)in->c_ispeed;
241 out->c_ospeed = (user_speed_t)in->c_ospeed;
242}
243
244static void
245termios64to32(struct user_termios *in, struct termios32 *out)
246{
247 out->c_iflag = (tcflag_t)in->c_iflag;
248 out->c_oflag = (tcflag_t)in->c_oflag;
249 out->c_cflag = (tcflag_t)in->c_cflag;
250 out->c_lflag = (tcflag_t)in->c_lflag;
251
252 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
253 bcopy(in->c_cc, out->c_cc, sizeof(in->c_cc));
254
255 out->c_ispeed = (speed_t)in->c_ispeed;
256 out->c_ospeed = (speed_t)in->c_ospeed;
257}
258
259
260/*
261 * tty_init
262 *
263 * Initialize the tty line discipline subsystem.
264 *
265 * Parameters: void
266 *
267 * Returns: void
268 *
269 * Locks: No ttys can be allocated and no tty locks can be used
270 * until after this function is called
271 *
272 * Notes: The intent of this is to set up a log group attribute,
273 * lock group, and loc atribute for subsequent per-tty locks.
274 * This function is called early in bsd_init(), prior to the
275 * console device initialization.
276 */
277void
278tty_init(void)
279{
280 tty_lck_grp_attr = lck_grp_attr_alloc_init();
281 tty_lck_grp = lck_grp_alloc_init("tty", tty_lck_grp_attr);
282 tty_lck_attr = lck_attr_alloc_init();
283}
284
285
286/*
287 * tty_lock
288 *
289 * Lock the requested tty structure.
290 *
291 * Parameters: tp The tty we want to lock
292 *
293 * Returns: void
294 *
295 * Locks: On return, tp is locked
296 */
297void
298tty_lock(struct tty *tp)
299{
300 TTY_LOCK_NOTOWNED(tp); /* debug assert */
301 lck_mtx_lock(&tp->t_lock);
302}
303
304
305/*
306 * tty_unlock
307 *
308 * Unlock the requested tty structure.
309 *
310 * Parameters: tp The tty we want to unlock
311 *
312 * Returns: void
313 *
314 * Locks: On return, tp is unlocked
315 */
316void
317tty_unlock(struct tty *tp)
318{
319 TTY_LOCK_OWNED(tp); /* debug assert */
320 lck_mtx_unlock(&tp->t_lock);
321}
322
323/*
324 * ttyopen (LDISC)
325 *
326 * Initial open of tty, or (re)entry to standard tty line discipline.
327 *
328 * Locks: Assumes tty_lock() is held prior to calling.
329 */
330int
331ttyopen(dev_t device, struct tty *tp)
332{
333 TTY_LOCK_OWNED(tp); /* debug assert */
334
335 tp->t_dev = device;
336
337 if (!ISSET(tp->t_state, TS_ISOPEN)) {
338 SET(tp->t_state, TS_ISOPEN);
339 if (ISSET(tp->t_cflag, CLOCAL)) {
340 SET(tp->t_state, TS_CONNECTED); }
341 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
342 }
343
344 return (0);
345}
346
347/*
348 * ttyclose
349 *
350 * Handle close() on a tty line: flush and set to initial state,
351 * bumping generation number so that pending read/write calls
352 * can detect recycling of the tty.
353 * XXX our caller should have done `spltty(); l_close(); ttyclose();'
354 * and l_close() should have flushed, but we repeat the spltty() and
355 * the flush in case there are buggy callers.
356 *
357 * Locks: Assumes tty_lock() is held prior to calling.
358 */
359int
360ttyclose(struct tty *tp)
361{
362 struct pgrp * oldpg;
363 struct session * oldsessp;
364 struct knote *kn;
365
366 TTY_LOCK_OWNED(tp); /* debug assert */
367
368 if (constty == tp) {
369 constty = NULL;
370
371
372 /*
373 * Closing current console tty; disable printing of console
374 * messages at bottom-level driver.
375 */
376 (*cdevsw[major(tp->t_dev)].d_ioctl)
377 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, current_proc());
378 }
379
380 ttyflush(tp, FREAD | FWRITE);
381
382 tp->t_gen++;
383 tp->t_line = TTYDISC;
384 proc_list_lock();
385 oldpg = tp->t_pgrp;
386 oldsessp = tp->t_session;
387 tp->t_pgrp = NULL;
388 tp->t_session = NULL;
389 if (oldsessp != SESSION_NULL)
390 oldsessp->s_ttypgrpid = NO_PID;
391 proc_list_unlock();
392 /* drop the reference on prev session and pgrp */
393 /* SAFE: All callers drop the lock on return */
394 tty_unlock(tp);
395 if (oldsessp != SESSION_NULL)
396 session_rele(oldsessp);
397 if (oldpg != PGRP_NULL)
398 pg_rele(oldpg);
399 tty_lock(tp);
400 tp->t_state = 0;
401 SLIST_FOREACH(kn, &tp->t_wsel.si_note, kn_selnext) {
402 KNOTE_DETACH(&tp->t_wsel.si_note, kn);
403 }
404 selthreadclear(&tp->t_wsel);
405 SLIST_FOREACH(kn, &tp->t_rsel.si_note, kn_selnext) {
406 KNOTE_DETACH(&tp->t_rsel.si_note, kn);
407 }
408 selthreadclear(&tp->t_rsel);
409
410 return (0);
411}
412
413#define FLUSHQ(q) { \
414 if ((q)->c_cc) \
415 ndflush(q, (q)->c_cc); \
416}
417
418/* Is 'c' a line delimiter ("break" character)? */
419#define TTBREAKC(c, lflag) \
420 ((c) == '\n' || (((c) == cc[VEOF] || \
421 (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \
422 (c) != _POSIX_VDISABLE))
423
424/*
425 * ttyinput (LDISC)
426 *
427 * Process input of a single character received on a tty.
428 *
429 * Parameters: c The character received
430 * tp The tty on which it was received
431 *
432 * Returns: .
433 *
434 * Locks: Assumes tty_lock() is held prior to calling.
435 */
436int
437ttyinput(int c, struct tty *tp)
438{
439 tcflag_t iflag, lflag;
440 cc_t *cc;
441 int i, err;
442 int retval = 0; /* default return value */
443
444 TTY_LOCK_OWNED(tp); /* debug assert */
445
446 /*
447 * If input is pending take it first.
448 */
449 lflag = tp->t_lflag;
450 if (ISSET(lflag, PENDIN))
451 ttypend(tp);
452 /*
453 * Gather stats.
454 */
455 if (ISSET(lflag, ICANON)) {
456 ++tk_cancc;
457 ++tp->t_cancc;
458 } else {
459 ++tk_rawcc;
460 ++tp->t_rawcc;
461 }
462 ++tk_nin;
463
464 /*
465 * Block further input iff:
466 * current input > threshold AND input is available to user program
467 * AND input flow control is enabled and not yet invoked.
468 * The 3 is slop for PARMRK.
469 */
470 iflag = tp->t_iflag;
471 if (tp->t_rawq.c_cc + tp->t_canq.c_cc > I_HIGH_WATER - 3 &&
472 (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
473 (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
474 !ISSET(tp->t_state, TS_TBLOCK))
475 ttyblock(tp);
476
477 /* Handle exceptional conditions (break, parity, framing). */
478 cc = tp->t_cc;
479 err = (ISSET(c, TTY_ERRORMASK));
480 if (err) {
481 CLR(c, TTY_ERRORMASK);
482 if (ISSET(err, TTY_BI)) {
483 if (ISSET(iflag, IGNBRK)) {
484 goto out;
485 }
486 if (ISSET(iflag, BRKINT)) {
487 ttyflush(tp, FREAD | FWRITE);
488 /* SAFE: All callers drop the lock on return */
489 tty_unlock(tp);
490 tty_pgsignal(tp, SIGINT, 1);
491 tty_lock(tp);
492 goto endcase;
493 }
494 if (ISSET(iflag, PARMRK))
495 goto parmrk;
496 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
497 || ISSET(err, TTY_FE)) {
498 if (ISSET(iflag, IGNPAR)) {
499 goto out;
500 }
501 else if (ISSET(iflag, PARMRK)) {
502parmrk:
503 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
504 MAX_INPUT - 3)
505 goto input_overflow;
506 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
507 (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
508 (void)putc(c | TTY_QUOTE, &tp->t_rawq);
509 goto endcase;
510 } else
511 c = 0;
512 }
513 }
514
515 if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
516 CLR(c, 0x80);
517 if (!ISSET(lflag, EXTPROC)) {
518 /*
519 * Check for literal nexting very first
520 */
521 if (ISSET(tp->t_state, TS_LNCH)) {
522 SET(c, TTY_QUOTE);
523 CLR(tp->t_state, TS_LNCH);
524 }
525 /*
526 * Scan for special characters. This code
527 * is really just a big case statement with
528 * non-constant cases. The bottom of the
529 * case statement is labeled ``endcase'', so goto
530 * it after a case match, or similar.
531 */
532
533 /*
534 * Control chars which aren't controlled
535 * by ICANON, ISIG, or IXON.
536 */
537 if (ISSET(lflag, IEXTEN)) {
538 if (CCEQ(cc[VLNEXT], c)) {
539 if (ISSET(lflag, ECHO)) {
540 if (ISSET(lflag, ECHOE)) {
541 (void)ttyoutput('^', tp);
542 (void)ttyoutput('\b', tp);
543 } else
544 ttyecho(c, tp);
545 }
546 SET(tp->t_state, TS_LNCH);
547 goto endcase;
548 }
549 if (CCEQ(cc[VDISCARD], c)) {
550 if (ISSET(lflag, FLUSHO))
551 CLR(tp->t_lflag, FLUSHO);
552 else {
553 ttyflush(tp, FWRITE);
554 ttyecho(c, tp);
555 if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
556 ttyretype(tp);
557 SET(tp->t_lflag, FLUSHO);
558 }
559 goto startoutput;
560 }
561 }
562 /*
563 * Signals.
564 */
565 if (ISSET(lflag, ISIG)) {
566 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
567 if (!ISSET(lflag, NOFLSH))
568 ttyflush(tp, FREAD | FWRITE);
569 ttyecho(c, tp);
570 /*
571 * SAFE: All callers drop the lock on return;
572 * SAFE: if we lose a threaded race on change
573 * SAFE: of the interrupt character, we could
574 * SAFE: have lost that race anyway due to the
575 * SAFE: scheduler executing threads in
576 * SAFE: priority order rather than "last
577 * SAFE: active thread" order (FEATURE).
578 */
579 tty_unlock(tp);
580 tty_pgsignal(tp,
581 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
582 tty_lock(tp);
583 goto endcase;
584 }
585 if (CCEQ(cc[VSUSP], c)) {
586 if (!ISSET(lflag, NOFLSH))
587 ttyflush(tp, FREAD);
588 ttyecho(c, tp);
589 /* SAFE: All callers drop the lock on return */
590 tty_unlock(tp);
591 tty_pgsignal(tp, SIGTSTP, 1);
592 tty_lock(tp);
593 goto endcase;
594 }
595 }
596 /*
597 * Handle start/stop characters.
598 */
599 if (ISSET(iflag, IXON)) {
600 if (CCEQ(cc[VSTOP], c)) {
601 if (!ISSET(tp->t_state, TS_TTSTOP)) {
602 SET(tp->t_state, TS_TTSTOP);
603 ttystop(tp, 0);
604 goto out;
605 }
606 if (!CCEQ(cc[VSTART], c)) {
607 goto out;
608 }
609 /*
610 * if VSTART == VSTOP then toggle
611 */
612 goto endcase;
613 }
614 if (CCEQ(cc[VSTART], c))
615 goto restartoutput;
616 }
617 /*
618 * IGNCR, ICRNL, & INLCR
619 */
620 if (c == '\r') {
621 if (ISSET(iflag, IGNCR)) {
622 goto out;
623 }
624 else if (ISSET(iflag, ICRNL))
625 c = '\n';
626 } else if (c == '\n' && ISSET(iflag, INLCR))
627 c = '\r';
628 }
629 if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
630 /*
631 * From here on down canonical mode character
632 * processing takes place.
633 */
634 /*
635 * erase (^H / ^?)
636 */
637 if (CCEQ(cc[VERASE], c)) {
638 if (tp->t_rawq.c_cc) {
639 if (ISSET(iflag, IUTF8)) {
640 do {
641 ttyrub((c = unputc(&tp->t_rawq)), tp);
642 } while(tp->t_rawq.c_cc && CCONT(c));
643 } else {
644 ttyrub(unputc(&tp->t_rawq), tp);
645 }
646 }
647 goto endcase;
648 }
649 /*
650 * kill (^U)
651 */
652 if (CCEQ(cc[VKILL], c)) {
653 if (ISSET(lflag, ECHOKE) &&
654 tp->t_rawq.c_cc == tp->t_rocount &&
655 !ISSET(lflag, ECHOPRT))
656 while (tp->t_rawq.c_cc)
657 ttyrub(unputc(&tp->t_rawq), tp);
658 else {
659 ttyecho(c, tp);
660 if (ISSET(lflag, ECHOK) ||
661 ISSET(lflag, ECHOKE))
662 ttyecho('\n', tp);
663 FLUSHQ(&tp->t_rawq);
664 tp->t_rocount = 0;
665 }
666 CLR(tp->t_state, TS_LOCAL);
667 goto endcase;
668 }
669 /*
670 * word erase (^W)
671 */
672 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
673 int ctype;
674
675 /*
676 * erase whitespace
677 */
678 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
679 ttyrub(c, tp);
680 if (c == -1)
681 goto endcase;
682 /*
683 * erase last char of word and remember the
684 * next chars type (for ALTWERASE)
685 */
686 ttyrub(c, tp);
687 c = unputc(&tp->t_rawq);
688 if (c == -1)
689 goto endcase;
690 if (c == ' ' || c == '\t') {
691 (void)putc(c, &tp->t_rawq);
692 goto endcase;
693 }
694 ctype = ISALPHA(c);
695 /*
696 * erase rest of word
697 */
698 do {
699 ttyrub(c, tp);
700 c = unputc(&tp->t_rawq);
701 if (c == -1)
702 goto endcase;
703 } while (c != ' ' && c != '\t' &&
704 (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
705 (void)putc(c, &tp->t_rawq);
706 goto endcase;
707 }
708 /*
709 * reprint line (^R)
710 */
711 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
712 ttyretype(tp);
713 goto endcase;
714 }
715 /*
716 * ^T - kernel info and generate SIGINFO
717 */
718 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
719 if (ISSET(lflag, ISIG)) {
720 /* SAFE: All callers drop the lock on return */
721 tty_unlock(tp);
722 tty_pgsignal(tp, SIGINFO, 1);
723 tty_lock(tp);
724 }
725 if (!ISSET(lflag, NOKERNINFO))
726 ttyinfo_locked(tp);
727 goto endcase;
728 }
729 }
730 /*
731 * Check for input buffer overflow
732 */
733 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
734input_overflow:
735 if (ISSET(iflag, IMAXBEL)) {
736 if (tp->t_outq.c_cc < tp->t_hiwat)
737 (void)ttyoutput(CTRL('g'), tp);
738 }
739 goto endcase;
740 }
741
742 if ( c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
743 && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
744 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
745
746 /*
747 * Put data char in q for user and
748 * wakeup on seeing a line delimiter.
749 */
750 if (putc(c, &tp->t_rawq) >= 0) {
751 if (!ISSET(lflag, ICANON)) {
752 ttwakeup(tp);
753 ttyecho(c, tp);
754 goto endcase;
755 }
756 if (TTBREAKC(c, lflag)) {
757 tp->t_rocount = 0;
758 catq(&tp->t_rawq, &tp->t_canq);
759 ttwakeup(tp);
760 } else if (tp->t_rocount++ == 0)
761 tp->t_rocol = tp->t_column;
762 if (ISSET(tp->t_state, TS_ERASE)) {
763 /*
764 * end of prterase \.../
765 */
766 CLR(tp->t_state, TS_ERASE);
767 (void)ttyoutput('/', tp);
768 }
769 i = tp->t_column;
770 ttyecho(c, tp);
771 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
772 /*
773 * Place the cursor over the '^' of the ^D.
774 */
775 i = min(2, tp->t_column - i);
776 while (i > 0) {
777 (void)ttyoutput('\b', tp);
778 i--;
779 }
780 }
781 }
782
783endcase:
784 /*
785 * IXANY means allow any character to restart output.
786 */
787 if (ISSET(tp->t_state, TS_TTSTOP) &&
788 !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) {
789 goto out;
790 }
791
792restartoutput:
793 CLR(tp->t_lflag, FLUSHO);
794 CLR(tp->t_state, TS_TTSTOP);
795
796startoutput:
797 /* Start the output */
798 retval = ttstart(tp);
799
800out:
801 return (retval);
802}
803
804
805/*
806 * ttyoutput
807 *
808 * Output a single character on a tty, doing output processing
809 * as needed (expanding tabs, newline processing, etc.).
810 *
811 * Parameters: c The character to output
812 * tp The tty on which to output on the tty
813 *
814 * Returns: < 0 Success
815 * >= 0 Character to resend (failure)
816 *
817 * Locks: Assumes tp is locked on entry, remains locked on exit
818 *
819 * Notes: Must be recursive.
820 */
821static int
822ttyoutput(int c, struct tty *tp)
823{
824 tcflag_t oflag;
825 int col;
826
827 TTY_LOCK_OWNED(tp); /* debug assert */
828
829 oflag = tp->t_oflag;
830 if (!ISSET(oflag, OPOST)) {
831 if (ISSET(tp->t_lflag, FLUSHO))
832 return (-1);
833 if (putc(c, &tp->t_outq))
834 return (c);
835 tk_nout++;
836 tp->t_outcc++;
837 return (-1);
838 }
839 /*
840 * Do tab expansion if OXTABS is set. Special case if we external
841 * processing, we don't do the tab expansion because we'll probably
842 * get it wrong. If tab expansion needs to be done, let it happen
843 * externally.
844 */
845 CLR(c, ~TTY_CHARMASK);
846 if (c == '\t' &&
847 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
848 col = c = 8 - (tp->t_column & 7);
849 if (!ISSET(tp->t_lflag, FLUSHO)) {
850 c -= b_to_q((const u_char *)" ", c, &tp->t_outq);
851 tk_nout += c;
852 tp->t_outcc += c;
853 }
854 tp->t_column += c;
855 return (c == col ? -1 : '\t');
856 }
857 if (c == CEOT && ISSET(oflag, ONOEOT))
858 return (-1);
859
860 /*
861 * Newline translation: if ONLCR is set,
862 * translate newline into "\r\n".
863 */
864 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
865 tk_nout++;
866 tp->t_outcc++;
867 if (putc('\r', &tp->t_outq))
868 return (c);
869 }
870 /* If OCRNL is set, translate "\r" into "\n". */
871 else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
872 c = '\n';
873 /* If ONOCR is set, don't transmit CRs when on column 0. */
874 else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0)
875 return (-1);
876 tk_nout++;
877 tp->t_outcc++;
878 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
879 return (c);
880
881 col = tp->t_column;
882 switch (CCLASS(c)) {
883 case BACKSPACE:
884 if (col > 0)
885 --col;
886 break;
887 case CONTROL:
888 break;
889 case NEWLINE:
890 case RETURN:
891 col = 0;
892 break;
893 case ORDINARY:
894 ++col;
895 break;
896 case TAB:
897 col = (col + 8) & ~7;
898 break;
899 }
900 tp->t_column = col;
901 return (-1);
902}
903
904/*
905 * Sets the tty state to not allow any more changes of foreground process
906 * group. This is required to be done so that a subsequent revoke on a vnode
907 * is able to always successfully complete.
908 *
909 * Locks : Assumes tty_lock held on entry
910 */
911void
912ttysetpgrphup(struct tty *tp)
913{
914 TTY_LOCK_OWNED(tp); /* debug assert */
915 SET(tp->t_state, TS_PGRPHUP);
916 /*
917 * Also wake up sleeping readers which may or may not belong to the
918 * current foreground process group.
919 *
920 * This forces any non-fg readers (which entered read when
921 * that process group was in the fg) to return with EIO (if they're
922 * catching SIGTTIN or with SIGTTIN). The ones which do belong to the fg
923 * process group will promptly go back to sleep and get a SIGHUP shortly
924 * This would normally happen as part of the close in revoke but if
925 * there is a sleeping reader from a non-fg process group we never get
926 * to the close because the sleeping reader holds an iocount on the
927 * vnode of the terminal which is going to get revoked->reclaimed.
928 */
929 wakeup(TSA_HUP_OR_INPUT(tp));
930}
931
932/*
933 * Locks : Assumes tty lock held on entry
934 */
935void
936ttyclrpgrphup(struct tty *tp)
937{
938 TTY_LOCK_OWNED(tp); /* debug assert */
939 CLR(tp->t_state, TS_PGRPHUP);
940}
941
942/*
943 * ttioctl
944 *
945 * Identical to ttioctl_locked, only the lock is not held
946 *
947 * Parameters: <See ttioctl_locked()>
948 *
949 * Returns: <See ttioctl_locked()>
950 *
951 * Locks: This function assumes the tty_lock() is not held on entry;
952 * it takes the lock, and releases it before returning.
953 *
954 * Notes: This is supported to ensure the line discipline interfaces
955 * all have the same locking semantics.
956 *
957 * This function is called from
958 */
959int
960ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, proc_t p)
961{
962 int retval;
963
964 tty_lock(tp);
965 retval = ttioctl_locked(tp, cmd, data, flag, p);
966 tty_unlock(tp);
967
968 return (retval);
969}
970
971
972/*
973 * ttioctl_locked
974 *
975 * Ioctls for all tty devices.
976 *
977 * Parameters: tp Tty on which ioctl() is being called
978 * cmd ioctl() command parameter
979 * data ioctl() data argument (if any)
980 * flag fileglob open modes from fcntl.h;
981 * if called internally, this is usually
982 * set to 0, rather than something useful
983 * p Process context for the call; if the
984 * call is proxied to a worker thread,
985 * this will not be the current process!!!
986 *
987 * Returns: 0 Success
988 * EIO I/O error (no process group, job
989 * control, etc.)
990 * EINTR Interrupted by signal
991 * EBUSY Attempt to become the console while
992 * the console is busy
993 * ENOTTY TIOCGPGRP on a non-controlling tty
994 * EINVAL Invalid baud rate
995 * ENXIO TIOCSETD of invalid line discipline
996 * EPERM TIOCSTI, not root, not open for read
997 * EACCES TIOCSTI, not root, not your controlling
998 * tty
999 * EPERM TIOCSCTTY failed
1000 * ENOTTY/EINVAL/EPERM TIOCSPGRP failed
1001 * EPERM TIOCSDRAINWAIT as non-root user
1002 * suser:EPERM Console control denied
1003 * ttywait:EIO t_timeout too small/expired
1004 * ttywait:ERESTART Upper layer must redrive the call;
1005 * this is usually done by the Libc
1006 * stub in user space
1007 * ttywait:EINTR Interrupted (usually a signal)
1008 * ttcompat:EINVAL
1009 * ttcompat:ENOTTY
1010 * ttcompat:EIOCTL
1011 * ttcompat:ENOTTY TIOCGSID, if no session or session
1012 * leader
1013 * ttcompat:ENOTTY All unrecognized ioctls
1014 * *tp->t_param:? TIOCSETA* underlying function
1015 * *linesw[t].l_open:? TIOCSETD line discipline open failure
1016 *
1017 *
1018 * Locks: This function assumes that the tty_lock() is held for the
1019 * tp at the time of the call. The lock remains held on return.
1020 *
1021 * Notes: This function is called after line-discipline specific ioctl
1022 * has been called to do discipline-specific functions and/or
1023 * reject any of these ioctl() commands.
1024 *
1025 * This function calls ttcompat(), which can re-call ttioctl()
1026 * to a depth of one (FORTRAN style mutual recursion); at some
1027 * point, we should just in-line ttcompat() here.
1028 */
1029int
1030ttioctl_locked(struct tty *tp, u_long cmd, caddr_t data, int flag, proc_t p)
1031{
1032 int error = 0;
1033 int bogusData = 1;
1034 struct uthread *ut;
1035 struct pgrp *pg, *oldpg;
1036 struct session *sessp, *oldsessp;
1037 struct tty *oldtp;
1038
1039 TTY_LOCK_OWNED(tp); /* debug assert */
1040
1041 ut = (struct uthread *)get_bsdthread_info(current_thread());
1042 /* If the ioctl involves modification, signal if in the background. */
1043 switch (cmd) {
1044 case TIOCIXON:
1045 case TIOCIXOFF:
1046 case TIOCDRAIN:
1047 case TIOCFLUSH:
1048 case TIOCSTOP:
1049 case TIOCSTART:
1050 case TIOCSETA_32:
1051 case TIOCSETA_64:
1052 case TIOCSETD:
1053 case TIOCSETAF_32:
1054 case TIOCSETAF_64:
1055 case TIOCSETAW_32:
1056 case TIOCSETAW_64:
1057 case TIOCSPGRP:
1058 case TIOCSTAT:
1059 case TIOCSTI:
1060 case TIOCSWINSZ:
1061 case TIOCLBIC:
1062 case TIOCLBIS:
1063 case TIOCLSET:
1064 case TIOCSETC:
1065 case OTIOCSETD:
1066 case TIOCSETN:
1067 case TIOCSETP:
1068 case TIOCSLTC:
1069 while (isbackground(p, tp) &&
1070 (p->p_lflag & P_LPPWAIT) == 0 &&
1071 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
1072 (ut->uu_sigmask & sigmask(SIGTTOU)) == 0) {
1073 pg = proc_pgrp(p);
1074 if (pg == PGRP_NULL) {
1075 error = EIO;
1076 goto out;
1077 }
1078 /* SAFE: All callers drop the lock on return */
1079 tty_unlock(tp);
1080 if (pg->pg_jobc == 0) {
1081 pg_rele(pg);
1082 tty_lock(tp);
1083 error = EIO;
1084 goto out;
1085 }
1086 pgsignal(pg, SIGTTOU, 1);
1087 pg_rele(pg);
1088 tty_lock(tp);
1089
1090
1091 /*
1092 * We signalled ourself, so we need to act as if we
1093 * have been "interrupted" from a "sleep" to act on
1094 * the signal. If it's a signal that stops the
1095 * process, that's handled in the signal sending code.
1096 */
1097 error = EINTR;
1098 goto out;
1099 }
1100 break;
1101 }
1102
1103 switch (cmd) { /* Process the ioctl. */
1104 case FIOASYNC: /* set/clear async i/o */
1105 if (*(int *)data)
1106 SET(tp->t_state, TS_ASYNC);
1107 else
1108 CLR(tp->t_state, TS_ASYNC);
1109 break;
1110 case FIONBIO: /* set/clear non-blocking i/o */
1111 break; /* XXX: delete. */
1112 case FIONREAD: /* get # bytes to read */
1113 *(int *)data = ttnread(tp);
1114 break;
1115 case TIOCEXCL: /* set exclusive use of tty */
1116 SET(tp->t_state, TS_XCLUDE);
1117 break;
1118 case TIOCFLUSH: { /* flush buffers */
1119 int flags = *(int *)data;
1120
1121 if (flags == 0)
1122 flags = FREAD | FWRITE;
1123 else
1124 flags &= FREAD | FWRITE;
1125 ttyflush(tp, flags);
1126 break;
1127 }
1128 case TIOCSCONS: {
1129 /* Set current console device to this line */
1130 data = (caddr_t) &bogusData;
1131
1132 /* No break - Fall through to BSD code */
1133 }
1134 case TIOCCONS: { /* become virtual console */
1135 if (*(int *)data) {
1136 if (constty && constty != tp &&
1137 ISSET(constty->t_state, TS_CONNECTED)) {
1138 error = EBUSY;
1139 goto out;
1140 }
1141 if ( (error = suser(kauth_cred_get(), &p->p_acflag)) )
1142 goto out;
1143 constty = tp;
1144 } else if (tp == constty) {
1145 constty = NULL;
1146 }
1147 if (constty) {
1148 (*cdevsw[major(constty->t_dev)].d_ioctl)
1149 (constty->t_dev, KMIOCDISABLCONS, NULL, 0, p);
1150 } else {
1151 (*cdevsw[major(tp->t_dev)].d_ioctl)
1152 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, p);
1153 }
1154 break;
1155 }
1156 case TIOCDRAIN: /* wait till output drained */
1157 error = ttywait(tp);
1158 if (error)
1159 goto out;
1160 break;
1161 case TIOCGETA_32: /* get termios struct */
1162#ifdef __LP64__
1163 termios64to32((struct user_termios *)&tp->t_termios, (struct termios32 *)data);
1164#else
1165 bcopy(&tp->t_termios, data, sizeof(struct termios));
1166#endif
1167 break;
1168 case TIOCGETA_64: /* get termios struct */
1169#ifdef __LP64__
1170 bcopy(&tp->t_termios, data, sizeof(struct termios));
1171#else
1172 termios32to64((struct termios32 *)&tp->t_termios, (struct user_termios *)data);
1173#endif
1174 break;
1175 case TIOCGETD: /* get line discipline */
1176 *(int *)data = tp->t_line;
1177 break;
1178 case TIOCGWINSZ: /* get window size */
1179 *(struct winsize *)data = tp->t_winsize;
1180 break;
1181 case TIOCGPGRP: /* get pgrp of tty */
1182 if (!isctty(p, tp)) {
1183 error = ENOTTY;
1184 goto out;
1185 }
1186 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
1187 break;
1188#ifdef TIOCHPCL
1189 case TIOCHPCL: /* hang up on last close */
1190 SET(tp->t_cflag, HUPCL);
1191 break;
1192#endif
1193 case TIOCNXCL: /* reset exclusive use of tty */
1194 CLR(tp->t_state, TS_XCLUDE);
1195 break;
1196 case TIOCOUTQ: /* output queue size */
1197 *(int *)data = tp->t_outq.c_cc;
1198 break;
1199 case TIOCSETA_32: /* set termios struct */
1200 case TIOCSETA_64:
1201 case TIOCSETAW_32: /* drain output, set */
1202 case TIOCSETAW_64:
1203 case TIOCSETAF_32: /* drn out, fls in, set */
1204 case TIOCSETAF_64:
1205 { /* drn out, fls in, set */
1206 struct termios *t = (struct termios *)data;
1207 struct termios lcl_termios;
1208
1209#ifdef __LP64__
1210 if (cmd==TIOCSETA_32 || cmd==TIOCSETAW_32 || cmd==TIOCSETAF_32) {
1211 termios32to64((struct termios32 *)data, (struct user_termios *)&lcl_termios);
1212 t = &lcl_termios;
1213 }
1214#else
1215 if (cmd==TIOCSETA_64 || cmd==TIOCSETAW_64 || cmd==TIOCSETAF_64) {
1216 termios64to32((struct user_termios *)data, (struct termios32 *)&lcl_termios);
1217 t = &lcl_termios;
1218 }
1219#endif
1220#if 0
1221 /* XXX bogus test; always false */
1222 if (t->c_ispeed < 0 || t->c_ospeed < 0) {
1223 error = EINVAL;
1224 goto out;
1225 }
1226#endif /* 0 - leave in; may end up being a conformance issue */
1227 if (t->c_ispeed == 0)
1228 t->c_ispeed = t->c_ospeed;
1229 if (cmd == TIOCSETAW_32 || cmd == TIOCSETAF_32 ||
1230 cmd == TIOCSETAW_64 || cmd == TIOCSETAF_64) {
1231 error = ttywait(tp);
1232 if (error) {
1233 goto out;
1234 }
1235 if (cmd == TIOCSETAF_32 || cmd == TIOCSETAF_64)
1236 ttyflush(tp, FREAD);
1237 }
1238 if (!ISSET(t->c_cflag, CIGNORE)) {
1239 /*
1240 * Set device hardware.
1241 */
1242 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1243 goto out;
1244 }
1245 if (ISSET(t->c_cflag, CLOCAL) &&
1246 !ISSET(tp->t_cflag, CLOCAL)) {
1247 /*
1248 * XXX disconnections would be too hard to
1249 * get rid of without this kludge. The only
1250 * way to get rid of controlling terminals
1251 * is to exit from the session leader.
1252 */
1253 CLR(tp->t_state, TS_ZOMBIE);
1254
1255 wakeup(TSA_CARR_ON(tp));
1256 ttwakeup(tp);
1257 ttwwakeup(tp);
1258 }
1259 if ((ISSET(tp->t_state, TS_CARR_ON) ||
1260 ISSET(t->c_cflag, CLOCAL)) &&
1261 !ISSET(tp->t_state, TS_ZOMBIE))
1262 SET(tp->t_state, TS_CONNECTED);
1263 else
1264 CLR(tp->t_state, TS_CONNECTED);
1265 tp->t_cflag = t->c_cflag;
1266 tp->t_ispeed = t->c_ispeed;
1267 tp->t_ospeed = t->c_ospeed;
1268 ttsetwater(tp);
1269 }
1270 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
1271 cmd != TIOCSETAF_32 && cmd != TIOCSETAF_64) {
1272 if (ISSET(t->c_lflag, ICANON))
1273 SET(tp->t_lflag, PENDIN);
1274 else {
1275 /*
1276 * XXX we really shouldn't allow toggling
1277 * ICANON while we're in a non-termios line
1278 * discipline. Now we have to worry about
1279 * panicing for a null queue.
1280 */
1281 if (tp->t_rawq.c_cs && tp->t_canq.c_cs) {
1282 struct clist tq;
1283
1284 catq(&tp->t_rawq, &tp->t_canq);
1285 tq = tp->t_rawq;
1286 tp->t_rawq = tp->t_canq;
1287 tp->t_canq = tq;
1288 }
1289 CLR(tp->t_lflag, PENDIN);
1290 }
1291 ttwakeup(tp);
1292 }
1293 tp->t_iflag = t->c_iflag;
1294 tp->t_oflag = t->c_oflag;
1295 /*
1296 * Make the EXTPROC bit read only.
1297 */
1298 if (ISSET(tp->t_lflag, EXTPROC))
1299 SET(t->c_lflag, EXTPROC);
1300 else
1301 CLR(t->c_lflag, EXTPROC);
1302 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1303 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1304 t->c_cc[VTIME] != tp->t_cc[VTIME])
1305 ttwakeup(tp);
1306 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1307 break;
1308 }
1309 case TIOCSETD: { /* set line discipline */
1310 int t = *(int *)data;
1311 dev_t device = tp->t_dev;
1312
1313 if (t >= nlinesw || t < 0) {
1314 error = ENXIO;
1315 goto out;
1316 }
1317 /*
1318 * If the new line discipline is not equal to the old one,
1319 * close the old one and open the new one.
1320 */
1321 if (t != tp->t_line) {
1322 (*linesw[tp->t_line].l_close)(tp, flag);
1323 error = (*linesw[t].l_open)(device, tp);
1324 if (error) {
1325 /* This is racy; it's possible to lose both */
1326 (void)(*linesw[tp->t_line].l_open)(device, tp);
1327 goto out;
1328 }
1329 tp->t_line = t;
1330 }
1331 break;
1332 }
1333 case TIOCSTART: /* start output, like ^Q */
1334 if (ISSET(tp->t_state, TS_TTSTOP) ||
1335 ISSET(tp->t_lflag, FLUSHO)) {
1336 CLR(tp->t_lflag, FLUSHO);
1337 CLR(tp->t_state, TS_TTSTOP);
1338 ttstart(tp);
1339 }
1340 break;
1341 case TIOCSTI: /* simulate terminal input */
1342 if (suser(kauth_cred_get(), NULL) && (flag & FREAD) == 0) {
1343 error = EPERM;
1344 goto out;
1345 }
1346 if (suser(kauth_cred_get(), NULL) && !isctty(p, tp)) {
1347 error = EACCES;
1348 goto out;
1349 }
1350 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1351 break;
1352 case TIOCSTOP: /* stop output, like ^S */
1353 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1354 SET(tp->t_state, TS_TTSTOP);
1355 ttystop(tp, 0);
1356 }
1357 break;
1358 case TIOCIXON:
1359 ttyunblock(tp);
1360 break;
1361 case TIOCIXOFF:
1362 ttyblock(tp);
1363 break;
1364 case TIOCSCTTY: /* become controlling tty */
1365 /* Session ctty vnode pointer set in vnode layer. */
1366 sessp = proc_session(p);
1367 if (sessp == SESSION_NULL) {
1368 error = EPERM;
1369 goto out;
1370 }
1371
1372 /*
1373 * This can only be done by a session leader.
1374 */
1375 if (!SESS_LEADER(p, sessp)) {
1376 /* SAFE: All callers drop the lock on return */
1377 tty_unlock(tp);
1378 session_rele(sessp);
1379 tty_lock(tp);
1380 error = EPERM;
1381 goto out;
1382 }
1383 /*
1384 * If this terminal is already the controlling terminal for the
1385 * session, nothing to do here.
1386 */
1387 if (tp->t_session == sessp) {
1388 /* SAFE: All callers drop the lock on return */
1389 tty_unlock(tp);
1390 session_rele(sessp);
1391 tty_lock(tp);
1392 error = 0;
1393 goto out;
1394 }
1395 pg = proc_pgrp(p);
1396 /*
1397 * Deny if the terminal is already attached to another session or
1398 * the session already has a terminal vnode.
1399 */
1400 session_lock(sessp);
1401 if (sessp->s_ttyvp || tp->t_session) {
1402 session_unlock(sessp);
1403 /* SAFE: All callers drop the lock on return */
1404 tty_unlock(tp);
1405 if (pg != PGRP_NULL) {
1406 pg_rele(pg);
1407 }
1408 session_rele(sessp);
1409 tty_lock(tp);
1410 error = EPERM;
1411 goto out;
1412 }
1413 sessp->s_ttypgrpid = pg->pg_id;
1414 oldtp = sessp->s_ttyp;
1415 ttyhold(tp);
1416 sessp->s_ttyp = tp;
1417 session_unlock(sessp);
1418 proc_list_lock();
1419 oldsessp = tp->t_session;
1420 oldpg = tp->t_pgrp;
1421 if (oldsessp != SESSION_NULL)
1422 oldsessp->s_ttypgrpid = NO_PID;
1423 /* do not drop refs on sessp and pg as tp holds them */
1424 tp->t_session = sessp;
1425 tp->t_pgrp = pg;
1426 proc_list_unlock();
1427 OSBitOrAtomic(P_CONTROLT, &p->p_flag);
1428 /* SAFE: All callers drop the lock on return */
1429 tty_unlock(tp);
1430 /* drop the reference on prev session and pgrp */
1431 if (oldsessp != SESSION_NULL)
1432 session_rele(oldsessp);
1433 if (oldpg != PGRP_NULL)
1434 pg_rele(oldpg);
1435 if (NULL != oldtp)
1436 ttyfree(oldtp);
1437 tty_lock(tp);
1438 break;
1439
1440 case TIOCSPGRP: { /* set pgrp of tty */
1441 struct pgrp *pgrp = PGRP_NULL;
1442
1443 sessp = proc_session(p);
1444 if (!isctty_sp(p, tp, sessp)) {
1445 if (sessp != SESSION_NULL)
1446 session_rele(sessp);
1447 error = ENOTTY;
1448 goto out;
1449 }
1450 else if ((pgrp = pgfind(*(int *)data)) == PGRP_NULL) {
1451 if (sessp != SESSION_NULL)
1452 session_rele(sessp);
1453 error = EINVAL;
1454 goto out;
1455 } else if (pgrp->pg_session != sessp) {
1456 /* SAFE: All callers drop the lock on return */
1457 tty_unlock(tp);
1458 if (sessp != SESSION_NULL)
1459 session_rele(sessp);
1460 pg_rele(pgrp);
1461 tty_lock(tp);
1462 error = EPERM;
1463 goto out;
1464 }
1465 /*
1466 * The session leader is going away and is possibly going to revoke
1467 * the terminal, we can't change the process group when that is the
1468 * case.
1469 */
1470 if (ISSET(tp->t_state, TS_PGRPHUP)) {
1471 if (sessp != SESSION_NULL)
1472 session_rele(sessp);
1473 pg_rele(pgrp);
1474 error = EPERM;
1475 goto out;
1476 }
1477 proc_list_lock();
1478 oldpg = tp->t_pgrp;
1479 tp->t_pgrp = pgrp;
1480 sessp->s_ttypgrpid = pgrp->pg_id;
1481 proc_list_unlock();
1482
1483 /*
1484 * Wakeup readers to recheck if they are still the foreground
1485 * process group.
1486 *
1487 * ttwakeup() isn't called because the readers aren't getting
1488 * woken up becuse there is something to read but to force
1489 * the re-evaluation of their foreground process group status.
1490 *
1491 * Ordinarily leaving these readers waiting wouldn't be an issue
1492 * as launchd would send them a termination signal eventually
1493 * (if nobody else does). But if this terminal happens to be
1494 * /dev/console, launchd itself could get blocked forever behind
1495 * a revoke of /dev/console and leave the system deadlocked.
1496 */
1497 wakeup(TSA_HUP_OR_INPUT(tp));
1498
1499 /* SAFE: All callers drop the lock on return */
1500 tty_unlock(tp);
1501 if (oldpg != PGRP_NULL)
1502 pg_rele(oldpg);
1503 if (sessp != SESSION_NULL)
1504 session_rele(sessp);
1505 tty_lock(tp);
1506 break;
1507 }
1508 case TIOCSTAT: /* simulate control-T */
1509 ttyinfo_locked(tp);
1510 break;
1511 case TIOCSWINSZ: /* set window size */
1512 if (bcmp((caddr_t)&tp->t_winsize, data,
1513 sizeof (struct winsize))) {
1514 tp->t_winsize = *(struct winsize *)data;
1515 /* SAFE: All callers drop the lock on return */
1516 tty_unlock(tp);
1517 tty_pgsignal(tp, SIGWINCH, 1);
1518 tty_lock(tp);
1519 }
1520 break;
1521 case TIOCSDRAINWAIT:
1522 error = suser(kauth_cred_get(), &p->p_acflag);
1523 if (error) {
1524 goto out;
1525 }
1526 tp->t_timeout = *(int *)data * hz;
1527 wakeup(TSA_OCOMPLETE(tp));
1528 wakeup(TSA_OLOWAT(tp));
1529 break;
1530 case TIOCGDRAINWAIT:
1531 *(int *)data = tp->t_timeout / hz;
1532 break;
1533 default:
1534 error = ttcompat(tp, cmd, data, flag, p);
1535 goto out;
1536 }
1537
1538 error = 0;
1539out:
1540 return(error);
1541}
1542
1543
1544/*
1545 * Locks: Assumes tp is locked on entry, remains locked on exit
1546 */
1547int
1548ttyselect(struct tty *tp, int rw, void *wql, proc_t p)
1549{
1550 int retval = 0;
1551 /*
1552 * Attaching knotes to TTYs needs to call selrecord in order to hook
1553 * up the waitq to the selinfo, regardless of data being ready. See
1554 * filt_ttyattach.
1555 */
1556 bool needs_selrecord = rw & FMARK;
1557 rw &= ~FMARK;
1558
1559 if (tp == NULL) {
1560 return ENXIO;
1561 }
1562
1563 TTY_LOCK_OWNED(tp);
1564
1565 if (tp->t_state & TS_ZOMBIE) {
1566 retval = 1;
1567 goto out;
1568 }
1569
1570 switch (rw) {
1571 case FREAD:
1572 retval = ttnread(tp);
1573 if (retval > 0) {
1574 break;
1575 }
1576
1577 selrecord(p, &tp->t_rsel, wql);
1578 break;
1579 case FWRITE:
1580 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
1581 (tp->t_state & TS_CONNECTED)) {
1582 retval = tp->t_hiwat - tp->t_outq.c_cc;
1583 break;
1584 }
1585
1586 selrecord(p, &tp->t_wsel, wql);
1587 break;
1588 }
1589
1590out:
1591 if (retval > 0 && needs_selrecord) {
1592 switch (rw) {
1593 case FREAD:
1594 selrecord(p, &tp->t_rsel, wql);
1595 break;
1596 case FWRITE:
1597 selrecord(p, &tp->t_wsel, wql);
1598 break;
1599 }
1600 }
1601
1602 return retval;
1603}
1604
1605
1606/*
1607 * This is a wrapper for compatibility with the select vector used by
1608 * cdevsw. It relies on a proper xxxdevtotty routine.
1609 *
1610 * Locks: Assumes tty_lock() is not held prior to calling.
1611 */
1612int
1613ttselect(dev_t dev, int rw, void *wql, proc_t p)
1614{
1615 int rv;
1616 struct tty *tp = cdevsw[major(dev)].d_ttys[minor(dev)];
1617
1618 tty_lock(tp);
1619 rv = ttyselect(tp, rw, wql, p);
1620 tty_unlock(tp);
1621
1622 return (rv);
1623}
1624
1625
1626/*
1627 * Locks: Assumes tp is locked on entry, remains locked on exit
1628 */
1629__private_extern__ int
1630ttnread(struct tty *tp)
1631{
1632 int nread;
1633
1634 TTY_LOCK_OWNED(tp); /* debug assert */
1635
1636 if (ISSET(tp->t_lflag, PENDIN))
1637 ttypend(tp);
1638 nread = tp->t_canq.c_cc;
1639 if (!ISSET(tp->t_lflag, ICANON)) {
1640 nread += tp->t_rawq.c_cc;
1641 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1642 nread = 0;
1643 }
1644 return (nread);
1645}
1646
1647
1648/*
1649 * ttywait
1650 *
1651 * Wait for output to drain.
1652 *
1653 * Parameters: tp Tty on which to wait for output to drain
1654 *
1655 * Returns: 0 Success
1656 * EIO t_timeout too small/expired
1657 * ttysleep:ERESTART Upper layer must redrive the call;
1658 * this is usually done by the Libc
1659 * stub in user space
1660 * ttysleep:EINTR Interrupted (usually a signal)
1661 *
1662 * Notes: Called from proc_exit() and vproc_exit().
1663 *
1664 * Locks: Assumes tp is locked on entry, remains locked on exit
1665 */
1666int
1667ttywait(struct tty *tp)
1668{
1669 int error;
1670
1671 TTY_LOCK_OWNED(tp); /* debug assert */
1672
1673 error = 0;
1674 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1675 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1676 (*tp->t_oproc)(tp);
1677 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1678 ISSET(tp->t_state, TS_CONNECTED)) {
1679 SET(tp->t_state, TS_SO_OCOMPLETE);
1680 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1681 TTOPRI | PCATCH, "ttywai",
1682 tp->t_timeout);
1683 if (error) {
1684 if (error == EWOULDBLOCK)
1685 error = EIO;
1686 break;
1687 }
1688 } else
1689 break;
1690 }
1691 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1692 error = EIO;
1693 return (error);
1694}
1695
1696/*
1697 * Stop the underlying device driver.
1698 *
1699 * Locks: Assumes tty_lock() is held prior to calling.
1700 */
1701static void
1702ttystop(struct tty *tp, int rw)
1703{
1704 TTY_LOCK_OWNED(tp); /* debug assert */
1705
1706 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1707}
1708
1709/*
1710 * Flush if successfully wait.
1711 *
1712 * Locks: Assumes tty_lock() is held prior to calling.
1713 */
1714static int
1715ttywflush(struct tty *tp)
1716{
1717 int error;
1718
1719 TTY_LOCK_OWNED(tp); /* debug assert */
1720
1721 if ((error = ttywait(tp)) == 0)
1722 ttyflush(tp, FREAD);
1723 return (error);
1724}
1725
1726/*
1727 * Flush tty read and/or write queues, notifying anyone waiting.
1728 *
1729 * Locks: Assumes tty_lock() is held prior to calling.
1730 */
1731void
1732ttyflush(struct tty *tp, int rw)
1733{
1734 TTY_LOCK_OWNED(tp); /* debug assert */
1735
1736#if 0
1737again:
1738#endif
1739 if (rw & FWRITE) {
1740 FLUSHQ(&tp->t_outq);
1741 CLR(tp->t_state, TS_TTSTOP);
1742 }
1743 ttystop(tp, rw);
1744 if (rw & FREAD) {
1745 FLUSHQ(&tp->t_canq);
1746 FLUSHQ(&tp->t_rawq);
1747 CLR(tp->t_lflag, PENDIN);
1748 tp->t_rocount = 0;
1749 tp->t_rocol = 0;
1750 CLR(tp->t_state, TS_LOCAL);
1751 ttwakeup(tp);
1752 if (ISSET(tp->t_state, TS_TBLOCK)) {
1753 if (rw & FWRITE)
1754 FLUSHQ(&tp->t_outq);
1755 ttyunblock(tp);
1756
1757 /*
1758 * Don't let leave any state that might clobber the
1759 * next line discipline (although we should do more
1760 * to send the START char). Not clearing the state
1761 * may have caused the "putc to a clist with no
1762 * reserved cblocks" panic/printf.
1763 */
1764 CLR(tp->t_state, TS_TBLOCK);
1765
1766#if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1767 if (ISSET(tp->t_iflag, IXOFF)) {
1768 /*
1769 * XXX wait a bit in the hope that the stop
1770 * character (if any) will go out. Waiting
1771 * isn't good since it allows races. This
1772 * will be fixed when the stop character is
1773 * put in a special queue. Don't bother with
1774 * the checks in ttywait() since the timeout
1775 * will save us.
1776 */
1777 SET(tp->t_state, TS_SO_OCOMPLETE);
1778 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1779 "ttyfls", hz / 10);
1780 /*
1781 * Don't try sending the stop character again.
1782 */
1783 CLR(tp->t_state, TS_TBLOCK);
1784 goto again;
1785 }
1786#endif
1787 }
1788 }
1789 if (rw & FWRITE) {
1790 FLUSHQ(&tp->t_outq);
1791 ttwwakeup(tp);
1792 }
1793}
1794
1795/*
1796 * Copy in the default termios characters.
1797 *
1798 * Locks: Assumes tty_lock() is held prior to calling.
1799 *
1800 * Notes: No assertion; tp is not in scope.
1801 */
1802void
1803termioschars(struct termios *t)
1804{
1805 bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1806}
1807
1808
1809/*
1810 * Handle input high water. Send stop character for the IXOFF case. Turn
1811 * on our input flow control bit and propagate the changes to the driver.
1812 * XXX the stop character should be put in a special high priority queue.
1813 *
1814 * Locks: Assumes tty_lock() is held for the call.
1815 */
1816void
1817ttyblock(struct tty *tp)
1818{
1819 TTY_LOCK_OWNED(tp); /* debug assert */
1820
1821 SET(tp->t_state, TS_TBLOCK);
1822 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1823 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1824 CLR(tp->t_state, TS_TBLOCK); /* try again later */
1825 ttstart(tp);
1826}
1827
1828
1829/*
1830 * Handle input low water. Send start character for the IXOFF case. Turn
1831 * off our input flow control bit and propagate the changes to the driver.
1832 * XXX the start character should be put in a special high priority queue.
1833 *
1834 * Locks: Assumes tty_lock() is held for the call.
1835 */
1836static void
1837ttyunblock(struct tty *tp)
1838{
1839 TTY_LOCK_OWNED(tp); /* debug assert */
1840
1841 CLR(tp->t_state, TS_TBLOCK);
1842 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1843 putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1844 SET(tp->t_state, TS_TBLOCK); /* try again later */
1845 ttstart(tp);
1846}
1847
1848
1849/*
1850 * ttstart
1851 *
1852 * Start tty output
1853 *
1854 * Parameters: tp tty on which to start output
1855 *
1856 * Returns: 0 Success
1857 *
1858 * Locks: Assumes tty_lock() is held for the call.
1859 *
1860 * Notes: This function might as well be void; it always returns success
1861 *
1862 * Called from ttioctl_locked(), LDISC routines, and
1863 * ttycheckoutq(), ttyblock(), ttyunblock(), and tputchar()
1864 */
1865int
1866ttstart(struct tty *tp)
1867{
1868 TTY_LOCK_OWNED(tp); /* debug assert */
1869
1870 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1871 (*tp->t_oproc)(tp);
1872
1873 return (0);
1874}
1875
1876
1877/*
1878 * ttylclose (LDISC)
1879 *
1880 * "close" a line discipline
1881 *
1882 * Locks: Assumes tty_lock() is held prior to calling.
1883 */
1884int
1885ttylclose(struct tty *tp, int flag)
1886{
1887 TTY_LOCK_OWNED(tp); /* debug assert */
1888
1889 if ( (flag & FNONBLOCK) || ttywflush(tp))
1890 ttyflush(tp, FREAD | FWRITE);
1891
1892 return (0);
1893}
1894
1895
1896/*
1897 * ttymodem (LDISC)
1898 *
1899 * Handle modem control transition on a tty.
1900 * Flag indicates new state of carrier.
1901 * Returns 0 if the line should be turned off, otherwise 1.
1902 *
1903 * Locks: Assumes tty_lock() is held prior to calling.
1904 */
1905int
1906ttymodem(struct tty *tp, int flag)
1907{
1908 int rval = 1; /* default return value */
1909
1910 TTY_LOCK_OWNED(tp); /* debug assert */
1911
1912 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1913 /*
1914 * MDMBUF: do flow control according to carrier flag
1915 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP
1916 * works if IXON and IXANY are clear.
1917 */
1918 if (flag) {
1919 CLR(tp->t_state, TS_CAR_OFLOW);
1920 CLR(tp->t_state, TS_TTSTOP);
1921 ttstart(tp);
1922 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1923 SET(tp->t_state, TS_CAR_OFLOW);
1924 SET(tp->t_state, TS_TTSTOP);
1925 ttystop(tp, 0);
1926 }
1927 } else if (flag == 0) {
1928 /*
1929 * Lost carrier.
1930 */
1931 CLR(tp->t_state, TS_CARR_ON);
1932 if (ISSET(tp->t_state, TS_ISOPEN) &&
1933 !ISSET(tp->t_cflag, CLOCAL)) {
1934 SET(tp->t_state, TS_ZOMBIE);
1935 CLR(tp->t_state, TS_CONNECTED);
1936 if (tp->t_session && tp->t_session->s_leader)
1937 psignal(tp->t_session->s_leader, SIGHUP);
1938 ttyflush(tp, FREAD | FWRITE);
1939 rval = 0;
1940 goto out;
1941 }
1942 } else {
1943 /*
1944 * Carrier now on.
1945 */
1946 SET(tp->t_state, TS_CARR_ON);
1947 if (!ISSET(tp->t_state, TS_ZOMBIE))
1948 SET(tp->t_state, TS_CONNECTED);
1949 wakeup(TSA_CARR_ON(tp));
1950 ttwakeup(tp);
1951 ttwwakeup(tp);
1952 }
1953
1954out:
1955 return (rval);
1956}
1957
1958
1959/*
1960 * Reinput pending characters after state switch
1961 * call at spltty().
1962 *
1963 * Locks: Assumes tty_lock() is held for the call.
1964 */
1965static void
1966ttypend(struct tty *tp)
1967{
1968 struct clist tq;
1969 int c;
1970
1971 TTY_LOCK_OWNED(tp); /* debug assert */
1972
1973 CLR(tp->t_lflag, PENDIN);
1974 SET(tp->t_state, TS_TYPEN);
1975 tq = tp->t_rawq;
1976 tp->t_rawq.c_cc = 0;
1977 tp->t_rawq.c_cf = tp->t_rawq.c_cl = NULL;
1978 while ((c = getc(&tq)) >= 0)
1979 ttyinput(c, tp);
1980 CLR(tp->t_state, TS_TYPEN);
1981}
1982
1983
1984/*
1985 * ttread (LDISC)
1986 *
1987 * Process a read call on a tty device.
1988 *
1989 * Locks: Assumes tty_lock() is held prior to calling.
1990 */
1991int
1992ttread(struct tty *tp, struct uio *uio, int flag)
1993{
1994 struct clist *qp;
1995 int c;
1996 tcflag_t lflag;
1997 cc_t *cc = tp->t_cc;
1998 proc_t p = current_proc();
1999 int first, error = 0;
2000 int has_etime = 0, last_cc = 0;
2001 long slp = 0; /* XXX this should be renamed `timo'. */
2002 struct uthread *ut;
2003 struct pgrp * pg;
2004
2005 TTY_LOCK_OWNED(tp); /* debug assert */
2006
2007 ut = (struct uthread *)get_bsdthread_info(current_thread());
2008
2009loop:
2010 lflag = tp->t_lflag;
2011 /*
2012 * take pending input first
2013 */
2014 if (ISSET(lflag, PENDIN)) {
2015 ttypend(tp);
2016 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
2017 }
2018
2019 /*
2020 * Signal the process if it's in the background.
2021 */
2022 if (isbackground(p, tp)) {
2023 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
2024 (ut->uu_sigmask & sigmask(SIGTTIN)) ||
2025 p->p_lflag & P_LPPWAIT) {
2026 error = EIO;
2027 goto err;
2028 }
2029 pg = proc_pgrp(p);
2030 if (pg == PGRP_NULL) {
2031 error = EIO;
2032 goto err;
2033 }
2034 if (pg->pg_jobc == 0) {
2035 /* SAFE: All callers drop the lock on return */
2036 tty_unlock(tp);
2037 pg_rele(pg);
2038 tty_lock(tp);
2039 error = EIO;
2040 goto err;
2041 }
2042 /* SAFE: All callers drop the lock on return */
2043 tty_unlock(tp);
2044 pgsignal(pg, SIGTTIN, 1);
2045 pg_rele(pg);
2046 tty_lock(tp);
2047
2048 /*
2049 * We signalled ourself, so we need to act as if we
2050 * have been "interrupted" from a "sleep" to act on
2051 * the signal. If it's a signal that stops the
2052 * process, that's handled in the signal sending code.
2053 */
2054 error = EINTR;
2055 goto err;
2056 }
2057
2058 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2059 /* EOF - returning 0 */
2060 goto err;
2061 }
2062
2063 /*
2064 * If canonical, use the canonical queue,
2065 * else use the raw queue.
2066 *
2067 * (should get rid of clists...)
2068 */
2069 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
2070
2071 if (flag & IO_NDELAY) {
2072 if (qp->c_cc > 0)
2073 goto read;
2074 if (ISSET(lflag, ICANON) || cc[VMIN] != 0) {
2075 error = EWOULDBLOCK;
2076 }
2077 /* else polling - returning 0 */
2078 goto err;
2079 }
2080 if (!ISSET(lflag, ICANON)) {
2081 int m = cc[VMIN];
2082 long t = cc[VTIME];
2083 struct timeval timecopy;
2084 struct timeval etime = {0, 0}; /* protected by !has_etime */
2085
2086 /*
2087 * Check each of the four combinations.
2088 * (m > 0 && t == 0) is the normal read case.
2089 * It should be fairly efficient, so we check that and its
2090 * companion case (m == 0 && t == 0) first.
2091 * For the other two cases, we compute the target sleep time
2092 * into slp.
2093 */
2094 if (t == 0) {
2095 if (qp->c_cc < m)
2096 goto sleep;
2097 if (qp->c_cc > 0)
2098 goto read;
2099
2100 /* m, t and qp->c_cc are all 0. 0 is enough input. */
2101 goto err;
2102 }
2103 t *= 100000; /* time in us */
2104#define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
2105 ((t1).tv_usec - (t2).tv_usec))
2106 if (m > 0) {
2107 if (qp->c_cc <= 0)
2108 goto sleep;
2109 if (qp->c_cc >= m)
2110 goto read;
2111 microuptime(&timecopy);
2112 if (!has_etime) {
2113 /* first character, start timer */
2114 has_etime = 1;
2115
2116 etime.tv_sec = t / 1000000;
2117 etime.tv_usec = (t - (etime.tv_sec * 1000000));
2118 timeradd(&etime, &timecopy, &etime);
2119
2120 slp = t;
2121 } else if (qp->c_cc > last_cc) {
2122 /* got a character, restart timer */
2123
2124 etime.tv_sec = t / 1000000;
2125 etime.tv_usec = (t - (etime.tv_sec * 1000000));
2126 timeradd(&etime, &timecopy, &etime);
2127
2128 slp = t;
2129 } else {
2130 /* nothing, check expiration */
2131 if (timercmp(&etime, &timecopy, <=))
2132 goto read;
2133
2134 slp = diff(etime, timecopy);
2135 }
2136 last_cc = qp->c_cc;
2137 } else { /* m == 0 */
2138 if (qp->c_cc > 0)
2139 goto read;
2140 microuptime(&timecopy);
2141 if (!has_etime) {
2142 has_etime = 1;
2143
2144 etime.tv_sec = t / 1000000;
2145 etime.tv_usec = (t - (etime.tv_sec * 1000000));
2146 timeradd(&etime, &timecopy, &etime);
2147
2148 slp = t;
2149 } else {
2150 if (timercmp(&etime, &timecopy, <=)) {
2151 /* Timed out, but 0 is enough input. */
2152 goto err;
2153 }
2154 slp = diff(etime, timecopy);
2155 }
2156 }
2157#undef diff
2158 /*
2159 * Rounding down may make us wake up just short
2160 * of the target, so we round up.
2161 * The formula is ceiling(slp * hz/1000000).
2162 * 32-bit arithmetic is enough for hz < 169.
2163 * XXX see hzto() for how to avoid overflow if hz
2164 * is large (divide by `tick' and/or arrange to
2165 * use hzto() if hz is large).
2166 */
2167 slp = (long) (((u_int32_t)slp * hz) + 999999) / 1000000;
2168 goto sleep;
2169 }
2170 if (qp->c_cc <= 0) {
2171sleep:
2172 /*
2173 * There is no input, or not enough input and we can block.
2174 */
2175 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
2176 ISSET(tp->t_state, TS_CONNECTED) ?
2177 "ttyin" : "ttyhup", (int)slp);
2178 if (error == EWOULDBLOCK)
2179 error = 0;
2180 else if (error) {
2181 goto err;
2182 }
2183 /*
2184 * XXX what happens if another process eats some input
2185 * while we are asleep (not just here)? It would be
2186 * safest to detect changes and reset our state variables
2187 * (has_stime and last_cc).
2188 */
2189 slp = 0;
2190 goto loop;
2191 }
2192read:
2193 /*
2194 * Input present, check for input mapping and processing.
2195 */
2196 first = 1;
2197 if (ISSET(lflag, ICANON)
2198 || (ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) )
2199 goto slowcase;
2200 for (;;) {
2201 char ibuf[IBUFSIZ];
2202 int icc;
2203
2204 icc = MIN(uio_resid(uio), IBUFSIZ);
2205 icc = q_to_b(qp, (u_char *)ibuf, icc);
2206 if (icc <= 0) {
2207 if (first)
2208 goto loop;
2209 break;
2210 }
2211 error = uiomove(ibuf, icc, uio);
2212 /*
2213 * XXX if there was an error then we should ungetc() the
2214 * unmoved chars and reduce icc here.
2215 */
2216 if (error)
2217 break;
2218 if (uio_resid(uio) == 0)
2219 break;
2220 first = 0;
2221 }
2222 goto out;
2223slowcase:
2224 for (;;) {
2225 c = getc(qp);
2226 if (c < 0) {
2227 if (first)
2228 goto loop;
2229 break;
2230 }
2231 /*
2232 * delayed suspend (^Y)
2233 */
2234 if (CCEQ(cc[VDSUSP], c) &&
2235 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
2236 /*
2237 * SAFE: All callers drop the lock on return and
2238 * SAFE: current thread will not change out from
2239 * SAFE: under us in the "goto loop" case.
2240 */
2241 tty_unlock(tp);
2242 tty_pgsignal(tp, SIGTSTP, 1);
2243 tty_lock(tp);
2244 if (first) {
2245 error = ttysleep(tp, &ttread, TTIPRI | PCATCH,
2246 "ttybg3", hz);
2247 if (error)
2248 break;
2249 goto loop;
2250 }
2251 break;
2252 }
2253 /*
2254 * Interpret EOF only in canonical mode.
2255 */
2256 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
2257 break;
2258 /*
2259 * Give user character.
2260 */
2261 error = ureadc(c, uio);
2262 if (error)
2263 /* XXX should ungetc(c, qp). */
2264 break;
2265 if (uio_resid(uio) == 0)
2266 break;
2267 /*
2268 * In canonical mode check for a "break character"
2269 * marking the end of a "line of input".
2270 */
2271 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
2272 break;
2273 first = 0;
2274 }
2275
2276out:
2277 /*
2278 * Look to unblock input now that (presumably)
2279 * the input queue has gone down.
2280 */
2281 if (ISSET(tp->t_state, TS_TBLOCK) &&
2282 tp->t_rawq.c_cc + tp->t_canq.c_cc <= I_LOW_WATER)
2283 ttyunblock(tp);
2284
2285err:
2286 return (error);
2287}
2288
2289
2290/*
2291 * Check the output queue on tp for space for a kernel message (from uprintf
2292 * or tprintf). Allow some space over the normal hiwater mark so we don't
2293 * lose messages due to normal flow control, but don't let the tty run amok.
2294 * Sleeps here are not interruptible, but we return prematurely if new signals
2295 * arrive.
2296 *
2297 * Locks: Assumes tty_lock() is held before calling
2298 *
2299 * Notes: This function is called from tprintf() in subr_prf.c
2300 */
2301int
2302ttycheckoutq(struct tty *tp, int wait)
2303{
2304 int hiwat;
2305 sigset_t oldsig;
2306 struct uthread *ut;
2307
2308 TTY_LOCK_OWNED(tp); /* debug assert */
2309
2310 ut = (struct uthread *)get_bsdthread_info(current_thread());
2311
2312 hiwat = tp->t_hiwat;
2313 oldsig = wait ? ut->uu_siglist : 0;
2314 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
2315 while (tp->t_outq.c_cc > hiwat) {
2316 ttstart(tp);
2317 if (tp->t_outq.c_cc <= hiwat)
2318 break;
2319 if (wait == 0 || ut->uu_siglist != oldsig) {
2320 return (0);
2321 }
2322 SET(tp->t_state, TS_SO_OLOWAT);
2323 ttysleep(tp, TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
2324 }
2325 return (1);
2326}
2327
2328
2329/*
2330 * ttwrite (LDISC)
2331 *
2332 * Process a write call on a tty device.
2333 *
2334 * Locks: Assumes tty_lock() is held prior to calling.
2335 */
2336int
2337ttwrite(struct tty *tp, struct uio *uio, int flag)
2338{
2339 char *cp = NULL;
2340 int cc, ce;
2341 proc_t p;
2342 int i, hiwat, error;
2343 user_ssize_t count;
2344 char obuf[OBUFSIZ];
2345 struct uthread *ut;
2346 struct pgrp * pg;
2347
2348 TTY_LOCK_OWNED(tp); /* debug assert */
2349
2350 ut = (struct uthread *)get_bsdthread_info(current_thread());
2351 hiwat = tp->t_hiwat;
2352 count = uio_resid(uio);
2353 error = 0;
2354 cc = 0;
2355loop:
2356 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2357 if (uio_resid(uio) == count)
2358 error = EIO;
2359 goto out;
2360 }
2361 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2362 if (flag & IO_NDELAY) {
2363 error = EWOULDBLOCK;
2364 goto out;
2365 }
2366 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
2367 "ttydcd", 0);
2368 if (error) {
2369 goto out; }
2370 goto loop;
2371 }
2372 /*
2373 * Signal the process if it's in the background.
2374 */
2375 p = current_proc();
2376 if (isbackground(p, tp) &&
2377 ISSET(tp->t_lflag, TOSTOP) && (p->p_lflag & P_LPPWAIT) == 0 &&
2378 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
2379 (ut->uu_sigmask & sigmask(SIGTTOU)) == 0) {
2380
2381 pg = proc_pgrp(p);
2382 if (pg == PGRP_NULL) {
2383 error = EIO;
2384 goto out;
2385 }
2386 if (pg->pg_jobc == 0) {
2387 /* SAFE: All callers drop the lock on return */
2388 tty_unlock(tp);
2389 pg_rele(pg);
2390 tty_lock(tp);
2391 error = EIO;
2392 goto out;
2393 }
2394 /* SAFE: All callers drop the lock on return */
2395 tty_unlock(tp);
2396 pgsignal(pg, SIGTTOU, 1);
2397 pg_rele(pg);
2398 tty_lock(tp);
2399 /*
2400 * We signalled ourself, so we need to act as if we
2401 * have been "interrupted" from a "sleep" to act on
2402 * the signal. If it's a signal that stops the
2403 * process, that's handled in the signal sending code.
2404 */
2405 error = EINTR;
2406 goto out;
2407 }
2408 /*
2409 * Process the user's data in at most OBUFSIZ chunks. Perform any
2410 * output translation. Keep track of high water mark, sleep on
2411 * overflow awaiting device aid in acquiring new space.
2412 */
2413 while (uio_resid(uio) > 0 || cc > 0) {
2414 if (ISSET(tp->t_lflag, FLUSHO)) {
2415 uio_setresid(uio, 0);
2416 return (0);
2417 }
2418 if (tp->t_outq.c_cc > hiwat)
2419 goto ovhiwat;
2420 /*
2421 * Grab a hunk of data from the user, unless we have some
2422 * leftover from last time.
2423 */
2424 if (cc == 0) {
2425 cc = MIN(uio_resid(uio), OBUFSIZ);
2426 cp = obuf;
2427 error = uiomove(cp, cc, uio);
2428 if (error) {
2429 cc = 0;
2430 break;
2431 }
2432 }
2433 /*
2434 * If nothing fancy need be done, grab those characters we
2435 * can handle without any of ttyoutput's processing and
2436 * just transfer them to the output q. For those chars
2437 * which require special processing (as indicated by the
2438 * bits in char_type), call ttyoutput. After processing
2439 * a hunk of data, look for FLUSHO so ^O's will take effect
2440 * immediately.
2441 */
2442 while (cc > 0) {
2443 if (!ISSET(tp->t_oflag, OPOST))
2444 ce = cc;
2445 else {
2446 ce = cc - scanc((u_int)cc, (u_char *)cp,
2447 char_type, CCLASSMASK);
2448 /*
2449 * If ce is zero, then we're processing
2450 * a special character through ttyoutput.
2451 */
2452 if (ce == 0) {
2453 tp->t_rocount = 0;
2454 if (ttyoutput(*cp, tp) >= 0) {
2455 /* out of space */
2456 goto overfull;
2457 }
2458 cp++;
2459 cc--;
2460 if (ISSET(tp->t_lflag, FLUSHO) ||
2461 tp->t_outq.c_cc > hiwat)
2462 goto ovhiwat;
2463 continue;
2464 }
2465 }
2466 /*
2467 * A bunch of normal characters have been found.
2468 * Transfer them en masse to the output queue and
2469 * continue processing at the top of the loop.
2470 * If there are any further characters in this
2471 * <= OBUFSIZ chunk, the first should be a character
2472 * requiring special handling by ttyoutput.
2473 */
2474 tp->t_rocount = 0;
2475 i = b_to_q((u_char *)cp, ce, &tp->t_outq);
2476 ce -= i;
2477 tp->t_column += ce;
2478 cp += ce;
2479 cc -= ce;
2480 tk_nout += ce;
2481 tp->t_outcc += ce;
2482 if (i > 0) {
2483 /* out of space */
2484 goto overfull;
2485 }
2486 if (ISSET(tp->t_lflag, FLUSHO) ||
2487 tp->t_outq.c_cc > hiwat)
2488 break;
2489 }
2490 ttstart(tp);
2491 }
2492out:
2493 /*
2494 * If cc is nonzero, we leave the uio structure inconsistent, as the
2495 * offset and iov pointers have moved forward, but it doesn't matter
2496 * (the call will either return short or restart with a new uio).
2497 */
2498 uio_setresid(uio, (uio_resid(uio) + cc));
2499 return (error);
2500
2501overfull:
2502
2503 /*
2504 * Since we are using ring buffers, if we can't insert any more into
2505 * the output queue, we can assume the ring is full and that someone
2506 * forgot to set the high water mark correctly. We set it and then
2507 * proceed as normal.
2508 */
2509 hiwat = tp->t_outq.c_cc - 1;
2510
2511ovhiwat:
2512 ttstart(tp);
2513 /*
2514 * This can only occur if FLUSHO is set in t_lflag,
2515 * or if ttstart/oproc is synchronous (or very fast).
2516 */
2517 if (tp->t_outq.c_cc <= hiwat) {
2518 goto loop;
2519 }
2520 if (flag & IO_NDELAY) {
2521 uio_setresid(uio, (uio_resid(uio) + cc));
2522 return (uio_resid(uio) == count ? EWOULDBLOCK : 0);
2523 }
2524 SET(tp->t_state, TS_SO_OLOWAT);
2525 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
2526 tp->t_timeout);
2527 if (error == EWOULDBLOCK)
2528 error = EIO;
2529 if (error)
2530 goto out;
2531 goto loop;
2532}
2533
2534
2535/*
2536 * Rubout one character from the rawq of tp
2537 * as cleanly as possible.
2538 *
2539 * Locks: Assumes tty_lock() is held prior to calling.
2540 */
2541static void
2542ttyrub(int c, struct tty *tp)
2543{
2544 u_char *cp;
2545 int savecol;
2546 int tabc;
2547
2548 TTY_LOCK_OWNED(tp); /* debug assert */
2549
2550 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2551 return;
2552 CLR(tp->t_lflag, FLUSHO);
2553 if (ISSET(tp->t_lflag, ECHOE)) {
2554 if (tp->t_rocount == 0) {
2555 /*
2556 * Messed up by ttwrite; retype
2557 */
2558 ttyretype(tp);
2559 return;
2560 }
2561 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
2562 ttyrubo(tp, 2);
2563 else {
2564 CLR(c, ~TTY_CHARMASK);
2565 switch (CCLASS(c)) {
2566 case ORDINARY:
2567 if(!(ISSET(tp->t_iflag, IUTF8) && CCONT(c))) {
2568 ttyrubo(tp, 1);
2569 }
2570 break;
2571 case BACKSPACE:
2572 case CONTROL:
2573 case NEWLINE:
2574 case RETURN:
2575 case VTAB:
2576 if (ISSET(tp->t_lflag, ECHOCTL))
2577 ttyrubo(tp, 2);
2578 break;
2579 case TAB:
2580 if (tp->t_rocount < tp->t_rawq.c_cc) {
2581 ttyretype(tp);
2582 return;
2583 }
2584 savecol = tp->t_column;
2585 SET(tp->t_state, TS_CNTTB);
2586 SET(tp->t_lflag, FLUSHO);
2587 tp->t_column = tp->t_rocol;
2588 for (cp = firstc(&tp->t_rawq, &tabc); cp;
2589 cp = nextc(&tp->t_rawq, cp, &tabc))
2590 ttyecho(tabc, tp);
2591 CLR(tp->t_lflag, FLUSHO);
2592 CLR(tp->t_state, TS_CNTTB);
2593
2594 /* savecol will now be length of the tab. */
2595 savecol -= tp->t_column;
2596 tp->t_column += savecol;
2597 if (savecol > 8)
2598 savecol = 8; /* overflow fixup */
2599 while (--savecol >= 0)
2600 (void)ttyoutput('\b', tp);
2601 break;
2602 default: /* XXX */
2603#define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
2604 printf(PANICSTR, c, CCLASS(c));
2605#ifdef notdef
2606 panic(PANICSTR, c, CCLASS(c));
2607#endif
2608 }
2609 }
2610 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2611 if (!ISSET(tp->t_state, TS_ERASE)) {
2612 SET(tp->t_state, TS_ERASE);
2613 (void)ttyoutput('\\', tp);
2614 }
2615 ttyecho(c, tp);
2616 } else
2617 ttyecho(tp->t_cc[VERASE], tp);
2618 --tp->t_rocount;
2619}
2620
2621
2622/*
2623 * Back over count characters, erasing them.
2624 *
2625 * Locks: Assumes tty_lock() is held prior to calling.
2626 */
2627static void
2628ttyrubo(struct tty *tp, int count)
2629{
2630 TTY_LOCK_OWNED(tp); /* debug assert */
2631
2632 while (count-- > 0) {
2633 (void)ttyoutput('\b', tp);
2634 (void)ttyoutput(' ', tp);
2635 (void)ttyoutput('\b', tp);
2636 }
2637}
2638
2639
2640/*
2641 * ttyretype --
2642 * Reprint the rawq line. Note, it is assumed that c_cc has already
2643 * been checked.
2644 *
2645 * Locks: Assumes tty_lock() is held prior to calling.
2646 */
2647static void
2648ttyretype(struct tty *tp)
2649{
2650 u_char *cp;
2651 int c;
2652
2653 TTY_LOCK_OWNED(tp); /* debug assert */
2654
2655 /* Echo the reprint character. */
2656 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2657 ttyecho(tp->t_cc[VREPRINT], tp);
2658
2659 (void)ttyoutput('\n', tp);
2660
2661 /*
2662 * FREEBSD XXX
2663 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2664 * BIT OF FIRST CHAR.
2665 */
2666 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
2667 ttyecho(c, tp);
2668 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
2669 ttyecho(c, tp);
2670 CLR(tp->t_state, TS_ERASE);
2671
2672 tp->t_rocount = tp->t_rawq.c_cc;
2673 tp->t_rocol = 0;
2674}
2675
2676
2677/*
2678 * Echo a typed character to the terminal.
2679 *
2680 * Locks: Assumes tty_lock() is held prior to calling.
2681 */
2682static void
2683ttyecho(int c, struct tty *tp)
2684{
2685 TTY_LOCK_OWNED(tp); /* debug assert */
2686
2687 if (!ISSET(tp->t_state, TS_CNTTB))
2688 CLR(tp->t_lflag, FLUSHO);
2689 if ((!ISSET(tp->t_lflag, ECHO) &&
2690 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2691 ISSET(tp->t_lflag, EXTPROC))
2692 return;
2693 if (ISSET(tp->t_lflag, ECHOCTL) &&
2694 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2695 ISSET(c, TTY_CHARMASK) == 0177)) {
2696 (void)ttyoutput('^', tp);
2697 CLR(c, ~TTY_CHARMASK);
2698 if (c == 0177)
2699 c = '?';
2700 else
2701 c += 'A' - 1;
2702 }
2703 (void)ttyoutput(c, tp);
2704}
2705
2706
2707/*
2708 * Wake up any readers on a tty.
2709 *
2710 * Locks: Assumes tty_lock() is held for the call.
2711 */
2712void
2713ttwakeup(struct tty *tp)
2714{
2715 TTY_LOCK_OWNED(tp); /* debug assert */
2716
2717 selwakeup(&tp->t_rsel);
2718 KNOTE(&tp->t_rsel.si_note, 1);
2719 if (ISSET(tp->t_state, TS_ASYNC)) {
2720 /*
2721 * XXX: Callers may not revalidate it the tty is closed
2722 * XXX: out from under them by another thread, but we do
2723 * XXX: not support queued signals. This should be safe,
2724 * XXX: since the process we intend to wakeup is in the
2725 * XXX: process group, and will wake up because of the
2726 * XXX: signal anyway.
2727 */
2728 tty_unlock(tp);
2729 tty_pgsignal(tp, SIGIO, 1);
2730 tty_lock(tp);
2731 }
2732 wakeup(TSA_HUP_OR_INPUT(tp));
2733}
2734
2735
2736/*
2737 * ttwwakeup (LDISC)
2738 *
2739 * Wake up any writers on a tty.
2740 *
2741 * Locks: Assumes tty_lock() is held prior to calling.
2742 */
2743void
2744ttwwakeup(struct tty *tp)
2745{
2746 TTY_LOCK_OWNED(tp); /* debug assert */
2747
2748 if (tp->t_outq.c_cc <= tp->t_lowat) {
2749 selwakeup(&tp->t_wsel);
2750 KNOTE(&tp->t_wsel.si_note, 1);
2751 }
2752 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2753 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2754 CLR(tp->t_state, TS_SO_OCOMPLETE);
2755 wakeup(TSA_OCOMPLETE(tp));
2756 }
2757 if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2758 tp->t_outq.c_cc <= tp->t_lowat) {
2759 CLR(tp->t_state, TS_SO_OLOWAT);
2760 wakeup(TSA_OLOWAT(tp));
2761 }
2762}
2763
2764
2765/*
2766 * Look up a code for a specified speed in a conversion table;
2767 * used by drivers to map software speed values to hardware parameters.
2768 *
2769 * Notes: No locks are assumed for this function; it does not
2770 * directly access struct tty.
2771 */
2772int
2773ttspeedtab(int speed, struct speedtab *table)
2774{
2775 for ( ; table->sp_speed != -1; table++)
2776 if (table->sp_speed == speed)
2777 return (table->sp_code);
2778 return (-1);
2779}
2780
2781
2782/*
2783 * Set tty hi and low water marks.
2784 *
2785 * Try to arrange the dynamics so there's about one second
2786 * from hi to low water.
2787 *
2788 * Locks: Assumes tty_lock() is held prior to calling.
2789 */
2790void
2791ttsetwater(struct tty *tp)
2792{
2793 int cps;
2794 unsigned int x;
2795
2796 TTY_LOCK_OWNED(tp); /* debug assert */
2797
2798#define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2799
2800 cps = tp->t_ospeed / 10;
2801 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2802 x += cps;
2803 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
2804 tp->t_hiwat = roundup(x, CBSIZE);
2805#undef CLAMP
2806}
2807
2808/* ttyinfo has been converted to the MACH kernel */
2809#include <mach/thread_info.h>
2810
2811/* XXX Should be in Mach header <kern/thread.h>, but doesn't work */
2812extern kern_return_t thread_info_internal(thread_t thread,
2813 thread_flavor_t flavor,
2814 thread_info_t thread_info_out,
2815 mach_msg_type_number_t *thread_info_count);
2816
2817
2818/*
2819 * Report on state of foreground process group.
2820 *
2821 * Locks: Assumes tty_lock() is held prior to calling.
2822 */
2823void
2824ttyinfo_locked(struct tty *tp)
2825{
2826 int load;
2827 thread_t thread;
2828 uthread_t uthread;
2829 proc_t p;
2830 proc_t pick;
2831 pid_t pickpid;
2832 const char *state;
2833 struct timeval utime;
2834 struct timeval stime;
2835 thread_basic_info_data_t basic_info;
2836 mach_msg_type_number_t mmtn = THREAD_BASIC_INFO_COUNT;
2837 struct pgrp * pg;
2838
2839 TTY_LOCK_OWNED(tp); /* debug assert */
2840
2841 if (ttycheckoutq(tp,0) == 0)
2842 return;
2843
2844 /* Print load average. */
2845 load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2846 ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
2847
2848 /*
2849 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
2850 * that pending input will be retyped on BS.
2851 */
2852 if (tp->t_session == NULL) {
2853 ttyprintf(tp, "not a controlling terminal\n");
2854 tp->t_rocount = 0;
2855 return;
2856}
2857 if (tp->t_pgrp == NULL) {
2858 ttyprintf(tp, "no foreground process group\n");
2859 tp->t_rocount = 0;
2860 return;
2861 }
2862 /* first process in process group */
2863 /* XXX is there a need for pgrp lock ? */
2864 if ((p = tp->t_pgrp->pg_members.lh_first) == NULL) {
2865 ttyprintf(tp, "empty foreground process group\n");
2866 tp->t_rocount = 0;
2867 return;
2868 }
2869
2870 /*
2871 * Pick the most interesting process and copy some of its
2872 * state for printing later.
2873 */
2874 pg = proc_pgrp(p);
2875 pgrp_lock(pg);
2876 /* the proc_compare is non blocking fn, no need to use iterator */
2877 for (pick = NULL; p != NULL; p = p->p_pglist.le_next) {
2878 if (proc_compare(pick, p)) {
2879 pick = p;
2880 pickpid = p->p_pid;
2881 } else {
2882 pickpid = pick->p_pid;
2883 }
2884 }
2885 pgrp_unlock(pg);
2886 /* SAFE: All callers drop the lock on return */
2887 tty_unlock(tp);
2888 pg_rele(pg);
2889 tty_lock(tp);
2890
2891 pick = proc_find(pickpid);
2892 if (pick == PROC_NULL)
2893 return;
2894
2895 if (TAILQ_EMPTY(&pick->p_uthlist) ||
2896 (uthread = TAILQ_FIRST(&pick->p_uthlist)) == NULL ||
2897 (thread = vfs_context_thread(&uthread->uu_context)) == NULL ||
2898 (thread_info_internal(thread, THREAD_BASIC_INFO, (thread_info_t)&basic_info, &mmtn) != KERN_SUCCESS)) {
2899 ttyprintf(tp, "foreground process without thread\n");
2900 tp->t_rocount = 0;
2901 proc_rele(pick);
2902 return;
2903 }
2904
2905 switch(basic_info.run_state) {
2906 case TH_STATE_RUNNING:
2907 state = "running";
2908 break;
2909 case TH_STATE_STOPPED:
2910 state = "stopped";
2911 break;
2912 case TH_STATE_WAITING:
2913 state = "waiting";
2914 break;
2915 case TH_STATE_UNINTERRUPTIBLE:
2916 state = "uninterruptible";
2917 break;
2918 case TH_STATE_HALTED:
2919 state = "halted";
2920 break;
2921 default:
2922 state = "unknown";
2923 break;
2924 }
2925 calcru(pick, &utime, &stime, NULL);
2926 proc_rele(pick);
2927
2928 /* Print command, pid, state, utime, and stime */
2929 ttyprintf(tp, " cmd: %s %d %s %ld.%02du %ld.%02ds\n",
2930 pick->p_comm,
2931 pick->p_pid,
2932 state,
2933 (long)utime.tv_sec, utime.tv_usec / 10000,
2934 (long)stime.tv_sec, stime.tv_usec / 10000);
2935 tp->t_rocount = 0;
2936}
2937
2938
2939/*
2940 * Returns 1 if p2 is "better" than p1
2941 *
2942 * The algorithm for picking the "interesting" process is thus:
2943 *
2944 * 1) Only foreground processes are eligible - implied.
2945 * 2) Runnable processes are favored over anything else. The runner
2946 * with the highest cpu utilization is picked (p_estcpu). Ties are
2947 * broken by picking the highest pid.
2948 * 3) The sleeper with the shortest sleep time is next.
2949 * 4) Further ties are broken by picking the highest pid.
2950 */
2951#define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
2952#define TESTAB(a, b) ((a)<<1 | (b))
2953#define ONLYA 2
2954#define ONLYB 1
2955#define BOTH 3
2956
2957/*
2958 * Locks: pgrp_lock(p2) held on call to this function
2959 * tty_lock(tp) for p2's tty, for which p2 is the foreground
2960 * process, held on call to this function
2961 */
2962static int
2963proc_compare(proc_t p1, proc_t p2)
2964{
2965 /* NOTE THIS FN needs to be NON BLOCKING */
2966
2967 if (p1 == NULL)
2968 return (1);
2969 /*
2970 * see if at least one of them is runnable
2971 */
2972 switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
2973 case ONLYA:
2974 return (0);
2975 case ONLYB:
2976 return (1);
2977 case BOTH:
2978 /*
2979 * tie - favor one with highest recent cpu utilization
2980 */
2981#ifdef _PROC_HAS_SCHEDINFO_
2982 /* Without the support the fields are always zero */
2983 if (p2->p_estcpu > p1->p_estcpu)
2984 return (1);
2985 if (p1->p_estcpu > p2->p_estcpu)
2986 return (0);
2987#endif /* _PROC_HAS_SCHEDINFO_ */
2988 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2989 }
2990 /*
2991 * weed out zombies
2992 */
2993 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
2994 case ONLYA:
2995 return (1);
2996 case ONLYB:
2997 return (0);
2998 case BOTH:
2999 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
3000 }
3001 /*
3002 * pick the one with the smallest sleep time
3003 */
3004#ifdef _PROC_HAS_SCHEDINFO_
3005 /* Without the support the fields are always zero */
3006 if (p2->p_slptime > p1->p_slptime)
3007 return (0);
3008 if (p1->p_slptime > p2->p_slptime)
3009 return (1);
3010#endif /* _PROC_HAS_SCHEDINFO_ */
3011 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
3012}
3013
3014
3015/*
3016 * Output char to tty; console putchar style.
3017 *
3018 * Locks: Assumes tty_lock() is held prior to calling.
3019 *
3020 * Notes: Only ever called from putchar() in subr_prf.c
3021 */
3022int
3023tputchar(int c, struct tty *tp)
3024{
3025 TTY_LOCK_OWNED(tp); /* debug assert */
3026
3027 if (!ISSET(tp->t_state, TS_CONNECTED)) {
3028 return (-1);
3029 }
3030 if (c == '\n')
3031 (void)ttyoutput('\r', tp);
3032 (void)ttyoutput(c, tp);
3033 ttstart(tp);
3034 return (0);
3035}
3036
3037
3038/*
3039 * ttysleep
3040 *
3041 * Sleep on a wait channel waiting for an interrupt or a condition to come
3042 * true so that we are woken up.
3043 *
3044 * Parameters: tp Tty going to sleep
3045 * chan The sleep channel (usually an address
3046 * of a structure member)
3047 * pri priority and flags
3048 * wmesg Wait message; shows up in debugger,
3049 * should show up in "ps", but doesn't
3050 * timo Timeout for the sleep
3051 *
3052 * Returns: 0 Condition came true
3053 * ERESTART Upper layer must redrive the call;
3054 * this is usually done by the Libc
3055 * stub in user space
3056 * msleep0:EINTR Interrupted (usually a signal)
3057 * msleep0:ERESTART Interrupted (usually a masked signal)
3058 * msleep0:EWOULDBLOCK Timeout (timo) already expired
3059 *
3060 * Locks: Assumes tty_lock() is held prior to calling.
3061 *
3062 * Sleep on chan, returning ERESTART if tty changed while we napped and
3063 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by msleep0. If
3064 * the tty is revoked, restarting a pending call will redo validation done
3065 * at the start of the call.
3066 */
3067int
3068ttysleep(struct tty *tp, void *chan, int pri, const char *wmesg, int timo)
3069{
3070 int error;
3071 int gen;
3072
3073 TTY_LOCK_OWNED(tp);
3074
3075 gen = tp->t_gen;
3076 /* Use of msleep0() avoids conversion timo/timespec/timo */
3077 error = msleep0(chan, &tp->t_lock, pri, wmesg, timo, (int (*)(int))0);
3078 if (error)
3079 return (error);
3080 return (tp->t_gen == gen ? 0 : ERESTART);
3081}
3082
3083
3084/*
3085 * Allocate a tty structure and its associated buffers.
3086 *
3087 * Parameters: void
3088 *
3089 * Returns: !NULL Address of new struct tty
3090 * NULL Error ("ENOMEM")
3091 *
3092 * Locks: The tty_lock() of the returned tty is not held when it
3093 * is returned.
3094 */
3095struct tty *
3096ttymalloc(void)
3097{
3098 struct tty *tp;
3099
3100 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO);
3101 if (tp != NULL) {
3102 /* XXX: default to TTYCLSIZE(1024) chars for now */
3103 clalloc(&tp->t_rawq, TTYCLSIZE, 1);
3104 clalloc(&tp->t_canq, TTYCLSIZE, 1);
3105 /* output queue doesn't need quoting */
3106 clalloc(&tp->t_outq, TTYCLSIZE, 0);
3107 lck_mtx_init(&tp->t_lock, tty_lck_grp, tty_lck_attr);
3108 klist_init(&tp->t_rsel.si_note);
3109 klist_init(&tp->t_wsel.si_note);
3110 tp->t_refcnt = 1;
3111 }
3112 return (tp);
3113}
3114
3115/*
3116 * Increment the reference count on a tty.
3117 */
3118void
3119ttyhold(struct tty *tp)
3120{
3121 TTY_LOCK_OWNED(tp);
3122 tp->t_refcnt++;
3123}
3124
3125/*
3126 * Drops a reference count on a tty structure; if the reference count reaches
3127 * zero, then also frees the structure and associated buffers.
3128 */
3129void
3130ttyfree(struct tty *tp)
3131{
3132 TTY_LOCK_NOTOWNED(tp);
3133
3134 tty_lock(tp);
3135 if (--tp->t_refcnt == 0) {
3136 tty_unlock(tp);
3137 ttydeallocate(tp);
3138 } else if (tp->t_refcnt < 0) {
3139 panic("%s: freeing free tty %p", __func__, tp);
3140 } else
3141 tty_unlock(tp);
3142}
3143
3144/*
3145 * Deallocate a tty structure and its buffers.
3146 *
3147 * Locks: The tty_lock() is assumed to not be held at the time of
3148 * the free; this function destroys the mutex.
3149 */
3150static void
3151ttydeallocate(struct tty *tp)
3152{
3153 TTY_LOCK_NOTOWNED(tp); /* debug assert */
3154
3155#if DEBUG
3156 if (!(SLIST_EMPTY(&tp->t_rsel.si_note) && SLIST_EMPTY(&tp->t_wsel.si_note))) {
3157 panic("knotes hooked into a tty when the tty is freed.\n");
3158 }
3159#endif /* DEBUG */
3160
3161 clfree(&tp->t_rawq);
3162 clfree(&tp->t_canq);
3163 clfree(&tp->t_outq);
3164 lck_mtx_destroy(&tp->t_lock, tty_lck_grp);
3165 FREE(tp, M_TTYS);
3166}
3167
3168
3169/*
3170 * Locks: Assumes tty_lock() is held prior to calling.
3171 */
3172int
3173isbackground(proc_t p, struct tty *tp)
3174{
3175 TTY_LOCK_OWNED(tp);
3176
3177 return (tp->t_session != NULL && p->p_pgrp != NULL && (p->p_pgrp != tp->t_pgrp) && isctty_sp(p, tp, p->p_pgrp->pg_session));
3178}
3179
3180static int
3181isctty(proc_t p, struct tty *tp)
3182{
3183 int retval;
3184 struct session * sessp;
3185
3186 sessp = proc_session(p);
3187 retval = (sessp == tp->t_session && p->p_flag & P_CONTROLT);
3188 session_rele(sessp);
3189 return(retval);
3190}
3191
3192static int
3193isctty_sp(proc_t p, struct tty *tp, struct session *sessp)
3194{
3195 return(sessp == tp->t_session && p->p_flag & P_CONTROLT);
3196
3197}
3198
3199
3200static int filt_ttyattach(struct knote *kn, struct kevent_internal_s *kev);
3201static void filt_ttydetach(struct knote *kn);
3202static int filt_ttyevent(struct knote *kn, long hint);
3203static int filt_ttytouch(struct knote *kn, struct kevent_internal_s *kev);
3204static int filt_ttyprocess(struct knote *kn, struct filt_process_s *data, struct kevent_internal_s *kev);
3205
3206SECURITY_READ_ONLY_EARLY(struct filterops) tty_filtops = {
3207 .f_isfd = 1,
3208 .f_attach = filt_ttyattach,
3209 .f_detach = filt_ttydetach,
3210 .f_event = filt_ttyevent,
3211 .f_touch = filt_ttytouch,
3212 .f_process = filt_ttyprocess
3213};
3214
3215/*
3216 * Called with struct tty locked. Returns non-zero if there is data to be read
3217 * or written.
3218 */
3219static int
3220filt_tty_common(struct knote *kn, struct tty *tp)
3221{
3222 int retval = 0;
3223
3224 TTY_LOCK_OWNED(tp); /* debug assert */
3225
3226 if (tp->t_state & TS_ZOMBIE) {
3227 kn->kn_flags |= EV_EOF;
3228 return 1;
3229 }
3230
3231 switch (knote_get_seltype(kn)) {
3232 case FREAD:
3233 retval = ttnread(tp);
3234 break;
3235 case FWRITE:
3236 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
3237 (tp->t_state & TS_CONNECTED)) {
3238 retval = tp->t_hiwat - tp->t_outq.c_cc;
3239 }
3240 break;
3241 }
3242
3243 kn->kn_data = retval;
3244
3245 /*
3246 * TODO(mwidmann, jandrus): For native knote low watermark support,
3247 * check the kn_sfflags for NOTE_LOWAT and check against kn_sdata.
3248 *
3249 * res = ((kn->kn_sfflags & NOTE_LOWAT) != 0) ?
3250 * (kn->kn_data >= kn->kn_sdata) : kn->kn_data;
3251 */
3252
3253 return retval;
3254}
3255
3256/*
3257 * Find the struct tty from a waitq, which is a member of one of the two struct
3258 * selinfos inside the struct tty. Use the seltype to determine which selinfo.
3259 */
3260static struct tty *
3261tty_from_waitq(struct waitq *wq, int seltype)
3262{
3263 struct selinfo *si;
3264 struct tty *tp = NULL;
3265
3266 /*
3267 * The waitq is part of the selinfo structure managed by the driver. For
3268 * certain drivers, we want to hook the knote into the selinfo
3269 * structure's si_note field so selwakeup can call KNOTE.
3270 *
3271 * While 'wq' is not really a queue element, this macro only uses the
3272 * pointer to calculate the offset into a structure given an element
3273 * name.
3274 */
3275 si = qe_element(wq, struct selinfo, si_waitq);
3276
3277 /*
3278 * For TTY drivers, the selinfo structure is somewhere in the struct
3279 * tty. There are two different selinfo structures, and the one used
3280 * corresponds to the type of filter requested.
3281 *
3282 * While 'si' is not really a queue element, this macro only uses the
3283 * pointer to calculate the offset into a structure given an element
3284 * name.
3285 */
3286 switch (seltype) {
3287 case FREAD:
3288 tp = qe_element(si, struct tty, t_rsel);
3289 break;
3290 case FWRITE:
3291 tp = qe_element(si, struct tty, t_wsel);
3292 break;
3293 }
3294
3295 return tp;
3296}
3297
3298static struct tty *
3299tty_from_knote(struct knote *kn)
3300{
3301 return (struct tty *)kn->kn_hook;
3302}
3303
3304/*
3305 * Try to lock the TTY structure associated with a knote.
3306 *
3307 * On success, this function returns a locked TTY structure. Otherwise, NULL is
3308 * returned.
3309 */
3310__attribute__((warn_unused_result))
3311static struct tty *
3312tty_lock_from_knote(struct knote *kn)
3313{
3314 struct tty *tp = tty_from_knote(kn);
3315 if (tp) {
3316 tty_lock(tp);
3317 }
3318
3319 return tp;
3320}
3321
3322/*
3323 * Set the knote's struct tty to the kn_hook field.
3324 *
3325 * The idea is to fake a call to select with our own waitq set. If the driver
3326 * calls selrecord, we'll get a link to their waitq and access to the tty
3327 * structure.
3328 *
3329 * Returns -1 on failure, with the error set in the knote, or selres on success.
3330 */
3331static int
3332tty_set_knote_hook(struct knote *kn)
3333{
3334 uthread_t uth;
3335 vfs_context_t ctx;
3336 vnode_t vp;
3337 kern_return_t kr;
3338 struct waitq *wq = NULL;
3339 struct waitq_set *old_wqs;
3340 struct waitq_set tmp_wqs;
3341 uint64_t rsvd, rsvd_arg;
3342 uint64_t *rlptr = NULL;
3343 int selres = -1;
3344 struct tty *tp;
3345
3346 uth = get_bsdthread_info(current_thread());
3347
3348 ctx = vfs_context_current();
3349 vp = (vnode_t)kn->kn_fp->f_fglob->fg_data;
3350
3351 /*
3352 * Reserve a link element to avoid potential allocation under
3353 * a spinlock.
3354 */
3355 rsvd = rsvd_arg = waitq_link_reserve(NULL);
3356 rlptr = (void *)&rsvd_arg;
3357
3358 /*
3359 * Trick selrecord into hooking a known waitq set into the device's selinfo
3360 * waitq. Once the link is in place, we can get back into the selinfo from
3361 * the waitq and subsequently the tty (see tty_from_waitq).
3362 *
3363 * We can't use a real waitq set (such as the kqueue's) because wakeups
3364 * might happen before we can unlink it.
3365 */
3366 kr = waitq_set_init(&tmp_wqs, SYNC_POLICY_FIFO | SYNC_POLICY_PREPOST, NULL,
3367 NULL);
3368 assert(kr == KERN_SUCCESS);
3369
3370 /*
3371 * Lazy allocate the waitqset to avoid potential allocation under
3372 * a spinlock;
3373 */
3374 waitq_set_lazy_init_link(&tmp_wqs);
3375
3376 old_wqs = uth->uu_wqset;
3377 uth->uu_wqset = &tmp_wqs;
3378 /*
3379 * FMARK forces selects to always call selrecord, even if data is
3380 * available. See ttselect, ptsselect, ptcselect.
3381 *
3382 * selres also contains the data currently available in the tty.
3383 */
3384 selres = VNOP_SELECT(vp, knote_get_seltype(kn) | FMARK, 0, rlptr, ctx);
3385 uth->uu_wqset = old_wqs;
3386
3387 /*
3388 * Make sure to cleanup the reserved link - this guards against
3389 * drivers that may not actually call selrecord().
3390 */
3391 waitq_link_release(rsvd);
3392 if (rsvd == rsvd_arg) {
3393 /*
3394 * The driver didn't call selrecord -- there's no tty hooked up so we
3395 * can't attach.
3396 */
3397 knote_set_error(kn, ENOTTY);
3398 selres = -1;
3399 goto out;
3400 }
3401
3402 /* rlptr may not point to a properly aligned pointer */
3403 memcpy(&wq, rlptr, sizeof(void *));
3404
3405 tp = tty_from_waitq(wq, knote_get_seltype(kn));
3406 assert(tp != NULL);
3407
3408 /*
3409 * Take a reference and stash the tty in the knote.
3410 */
3411 tty_lock(tp);
3412 ttyhold(tp);
3413 kn->kn_hook = tp;
3414 tty_unlock(tp);
3415
3416out:
3417 /*
3418 * Cleaning up the wqset will unlink its waitq and clean up any preposts
3419 * that occurred as a result of data coming in while the tty was attached.
3420 */
3421 waitq_set_deinit(&tmp_wqs);
3422
3423 return selres;
3424}
3425
3426static int
3427filt_ttyattach(struct knote *kn, __unused struct kevent_internal_s *kev)
3428{
3429 int selres = 0;
3430 struct tty *tp;
3431
3432 /*
3433 * This function should be called from filt_specattach (spec_vnops.c),
3434 * so most of the knote data structure should already be initialized.
3435 */
3436
3437 /* don't support offsets in ttys or drivers that don't use struct tty */
3438 if (kn->kn_vnode_use_ofst || !kn->kn_vnode_kqok) {
3439 knote_set_error(kn, ENOTSUP);
3440 return 0;
3441 }
3442
3443 /*
3444 * Connect the struct tty to the knote through the selinfo structure
3445 * referenced by the waitq within the selinfo.
3446 */
3447 selres = tty_set_knote_hook(kn);
3448 if (selres < 0) {
3449 return 0;
3450 }
3451
3452 /*
3453 * Attach the knote to selinfo's klist.
3454 */
3455 tp = tty_lock_from_knote(kn);
3456 if (!tp) {
3457 knote_set_error(kn, ENOENT);
3458 return 0;
3459 }
3460
3461 switch (knote_get_seltype(kn)) {
3462 case FREAD:
3463 KNOTE_ATTACH(&tp->t_rsel.si_note, kn);
3464 break;
3465 case FWRITE:
3466 KNOTE_ATTACH(&tp->t_wsel.si_note, kn);
3467 break;
3468 }
3469
3470 tty_unlock(tp);
3471
3472 return selres;
3473}
3474
3475static void
3476filt_ttydetach(struct knote *kn)
3477{
3478 struct tty *tp;
3479
3480 tp = tty_lock_from_knote(kn);
3481 if (!tp) {
3482 knote_set_error(kn, ENOENT);
3483 return;
3484 }
3485
3486 struct selinfo *si = NULL;
3487 switch (knote_get_seltype(kn)) {
3488 case FREAD:
3489 si = &tp->t_rsel;
3490 break;
3491 case FWRITE:
3492 si = &tp->t_wsel;
3493 break;
3494 /* knote_get_seltype will panic on default */
3495 }
3496
3497 KNOTE_DETACH(&si->si_note, kn);
3498 kn->kn_hook = NULL;
3499
3500 tty_unlock(tp);
3501 ttyfree(tp);
3502}
3503
3504static int
3505filt_ttyevent(struct knote *kn, long hint)
3506{
3507 int ret;
3508 struct tty *tp;
3509 bool revoked = hint & NOTE_REVOKE;
3510 hint &= ~NOTE_REVOKE;
3511
3512 tp = tty_from_knote(kn);
3513 if (!tp) {
3514 knote_set_error(kn, ENOENT);
3515 return 0;
3516 }
3517
3518 if (!hint) {
3519 tty_lock(tp);
3520 }
3521
3522 if (revoked) {
3523 kn->kn_flags |= EV_EOF | EV_ONESHOT;
3524 ret = 1;
3525 } else {
3526 ret = filt_tty_common(kn, tp);
3527 }
3528
3529 if (!hint) {
3530 tty_unlock(tp);
3531 }
3532
3533 return ret;
3534}
3535
3536static int
3537filt_ttytouch(struct knote *kn, struct kevent_internal_s *kev)
3538{
3539 struct tty *tp;
3540 int res = 0;
3541
3542 tp = tty_lock_from_knote(kn);
3543 if (!tp) {
3544 knote_set_error(kn, ENOENT);
3545 return 0;
3546 }
3547
3548 kn->kn_sdata = kev->data;
3549 kn->kn_sfflags = kev->fflags;
3550
3551 if (kn->kn_vnode_kqok) {
3552 res = filt_tty_common(kn, tp);
3553 }
3554
3555 tty_unlock(tp);
3556
3557 return res;
3558}
3559
3560static int
3561filt_ttyprocess(struct knote *kn, __unused struct filt_process_s *data, struct kevent_internal_s *kev)
3562{
3563 struct tty *tp;
3564 int res;
3565
3566 tp = tty_lock_from_knote(kn);
3567 if (!tp) {
3568 knote_set_error(kn, ENOENT);
3569 return 0;
3570 }
3571
3572 res = filt_tty_common(kn, tp);
3573
3574 if (res) {
3575 *kev = kn->kn_kevent;
3576 if (kn->kn_flags & EV_CLEAR) {
3577 kn->kn_fflags = 0;
3578 kn->kn_data = 0;
3579 }
3580 }
3581
3582 tty_unlock(tp);
3583
3584 return res;
3585}