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