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
119 static LCK_GRP_DECLARE(tty_lck_grp, "tty");
120 os_refgrp_decl(static, t_refgrp, "tty", NULL);
121
122 __private_extern__ int ttnread(struct tty *tp);
123 static void ttyecho(int c, struct tty *tp);
124 static int ttyoutput(int c, struct tty *tp);
125 static void ttypend(struct tty *tp);
126 static void ttyretype(struct tty *tp);
127 static void ttyrub(int c, struct tty *tp);
128 static void ttyrubo(struct tty *tp, int count);
129 static void ttystop(struct tty *tp, int rw);
130 static void ttyunblock(struct tty *tp);
131 static int ttywflush(struct tty *tp);
132 static int proc_compare(proc_t p1, proc_t p2);
133
134 void ttyhold(struct tty *tp);
135 static void ttydeallocate(struct tty *tp);
136
137 static bool isbackground(proc_t p, struct tty *tp);
138 static bool isctty(proc_t p, struct tty *tp);
139 static 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
172 static 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
termios32to64(struct termios32 * in,struct user_termios * out)233 termios32to64(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(in->c_cc, out->c_cc, 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
termios64to32(struct user_termios * in,struct termios32 * out)248 termios64to32(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(in->c_cc, out->c_cc, 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 */
274 void
tty_lock(struct tty * tp)275 tty_lock(struct tty *tp)
276 {
277 TTY_LOCK_NOTOWNED(tp); /* debug assert */
278 ttyhold(tp);
279 lck_mtx_lock(&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 */
293 bool
tty_trylock(struct tty * tp)294 tty_trylock(struct tty *tp)
295 {
296 TTY_LOCK_NOTOWNED(tp); /* debug assert */
297 ttyhold(tp);
298 if (lck_mtx_try_lock(&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
310 bool
tty_islocked(struct tty * tp)311 tty_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 */
329 void
tty_unlock(struct tty * tp)330 tty_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(&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 */
345 int
ttyopen(dev_t device,struct tty * tp)346 ttyopen(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(&tp->t_winsize, 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 */
375 int
ttyclose(struct tty * tp)376 ttyclose(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(oldsessp);
428 freetp = session_clear_tty_locked(oldsessp);
429 session_unlock(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(oldsessp);
439 if (freetp) {
440 ttyfree(freetp);
441 }
442 }
443 pgrp_rele(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(&tp->t_wsel.si_note, NOTE_REVOKE, true);
455 selthreadclear(&tp->t_wsel);
456 knote(&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 */
485 int
ttyinput(int c,struct tty * tp)486 ttyinput(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, 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)) {
551 parmrk:
552 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
553 MAX_INPUT - 3) {
554 goto input_overflow;
555 }
556 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
557 (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
558 (void)putc(c | TTY_QUOTE, &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('^', tp);
594 (void)ttyoutput('\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, 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, 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, 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 = unputc(&tp->t_rawq)), tp);
696 } while (tp->t_rawq.c_cc && CCONT(c));
697 } else {
698 ttyrub(unputc(&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(unputc(&tp->t_rawq), tp);
712 }
713 } else {
714 ttyecho(c, tp);
715 if (ISSET(lflag, ECHOK) ||
716 ISSET(lflag, ECHOKE)) {
717 ttyecho('\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(&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(&tp->t_rawq);
746 if (c == -1) {
747 goto endcase;
748 }
749 if (c == ' ' || c == '\t') {
750 (void)putc(c, &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(&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, &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, 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) {
793 input_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(0377 | TTY_QUOTE, &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, &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(&tp->t_rawq, &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('/', 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(2, tp->t_column - i);
838 while (i > 0) {
839 (void)ttyoutput('\b', tp);
840 i--;
841 }
842 }
843 }
844
845 endcase:
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
854 restartoutput:
855 CLR(tp->t_lflag, FLUSHO);
856 CLR(tp->t_state, TS_TTSTOP);
857
858 startoutput:
859 /* Start the output */
860 retval = ttstart(tp);
861
862 out:
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 */
883 static int
ttyoutput(int c,struct tty * tp)884 ttyoutput(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, &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((const u_char *)" ", c, &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('\r', &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, &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 */
991 int
ttioctl(struct tty * tp,u_long cmd,caddr_t data,int flag,proc_t p)992 ttioctl(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, 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 */
1061 int
ttioctl_locked(struct tty * tp,u_long cmd,caddr_t data,int flag,proc_t p)1062 ttioctl_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(pg);
1114 tty_lock(tp);
1115 error = EIO;
1116 goto out;
1117 }
1118 pgsignal(pg, SIGTTOU, 1);
1119 pgrp_rele(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, 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(kauth_cred_get(), &p->p_acflag))) {
1180 if (constty) {
1181 if (constty == tp) {
1182 ttyfree_locked(constty);
1183 } else {
1184 ttyfree(constty);
1185 }
1186 constty = NULL;
1187 }
1188 goto out;
1189 }
1190 if (tp != constty) {
1191 freetp = set_constty(tp);
1192 if (freetp != NULL) {
1193 if (freetp == tp) {
1194 ttyfree_locked(freetp);
1195 } else {
1196 ttyfree(freetp);
1197 }
1198 freetp = NULL;
1199 }
1200 if (constty != NULL) {
1201 // constty != tp, so constty is not locked
1202 ttyfree(constty);
1203 }
1204 constty = copy_constty();
1205 }
1206 } else if (tp == constty) {
1207 freetp = set_constty(NULL);
1208 if (freetp != NULL) {
1209 if (freetp == tp) {
1210 ttyfree_locked(freetp);
1211 } else {
1212 ttyfree(freetp);
1213 }
1214 freetp = NULL;
1215 }
1216 // constty == tp, so constty is locked
1217 ttyfree_locked(constty);
1218 constty = NULL;
1219 }
1220 if (constty) {
1221 (*cdevsw[major(constty->t_dev)].d_ioctl)
1222 (constty->t_dev, KMIOCDISABLCONS, NULL, 0, p);
1223 } else {
1224 (*cdevsw[major(tp->t_dev)].d_ioctl)
1225 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, p);
1226 }
1227 if (constty != NULL) {
1228 if (constty == tp) {
1229 ttyfree_locked(constty);
1230 } else {
1231 ttyfree(constty);
1232 }
1233 }
1234 break;
1235 }
1236 case TIOCDRAIN: /* wait till output drained */
1237 error = ttywait(tp);
1238 if (error) {
1239 goto out;
1240 }
1241 break;
1242 case TIOCGETA_32: /* get termios struct */
1243 #ifdef __LP64__
1244 termios64to32((struct user_termios *)&tp->t_termios, (struct termios32 *)data);
1245 #else
1246 bcopy(&tp->t_termios, data, sizeof(struct termios));
1247 #endif
1248 break;
1249 case TIOCGETA_64: /* get termios struct */
1250 #ifdef __LP64__
1251 bcopy(&tp->t_termios, data, sizeof(struct termios));
1252 #else
1253 termios32to64((struct termios32 *)&tp->t_termios, (struct user_termios *)data);
1254 #endif
1255 break;
1256 case TIOCGETD: /* get line discipline */
1257 *(int *)data = tp->t_line;
1258 break;
1259 case TIOCGWINSZ: /* get window size */
1260 *(struct winsize *)data = tp->t_winsize;
1261 break;
1262 case TIOCGPGRP: /* get pgrp of tty */
1263 if (!isctty(p, tp)) {
1264 error = ENOTTY;
1265 goto out;
1266 }
1267 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
1268 break;
1269 #ifdef TIOCHPCL
1270 case TIOCHPCL: /* hang up on last close */
1271 SET(tp->t_cflag, HUPCL);
1272 break;
1273 #endif
1274 case TIOCNXCL: /* reset exclusive use of tty */
1275 CLR(tp->t_state, TS_XCLUDE);
1276 break;
1277 case TIOCOUTQ: /* output queue size */
1278 *(int *)data = tp->t_outq.c_cc;
1279 break;
1280 case TIOCSETA_32: /* set termios struct */
1281 case TIOCSETA_64:
1282 case TIOCSETAW_32: /* drain output, set */
1283 case TIOCSETAW_64:
1284 case TIOCSETAF_32: /* drn out, fls in, set */
1285 case TIOCSETAF_64:
1286 { /* drn out, fls in, set */
1287 struct termios *t = (struct termios *)data;
1288 struct termios lcl_termios;
1289
1290 #ifdef __LP64__
1291 if (cmd == TIOCSETA_32 || cmd == TIOCSETAW_32 || cmd == TIOCSETAF_32) {
1292 termios32to64((struct termios32 *)data, (struct user_termios *)&lcl_termios);
1293 t = &lcl_termios;
1294 }
1295 #else
1296 if (cmd == TIOCSETA_64 || cmd == TIOCSETAW_64 || cmd == TIOCSETAF_64) {
1297 termios64to32((struct user_termios *)data, (struct termios32 *)&lcl_termios);
1298 t = &lcl_termios;
1299 }
1300 #endif
1301 #if 0
1302 /* XXX bogus test; always false */
1303 if (t->c_ispeed < 0 || t->c_ospeed < 0) {
1304 error = EINVAL;
1305 goto out;
1306 }
1307 #endif /* 0 - leave in; may end up being a conformance issue */
1308 if (t->c_ispeed == 0) {
1309 t->c_ispeed = t->c_ospeed;
1310 }
1311 if (cmd == TIOCSETAW_32 || cmd == TIOCSETAF_32 ||
1312 cmd == TIOCSETAW_64 || cmd == TIOCSETAF_64) {
1313 error = ttywait(tp);
1314 if (error) {
1315 goto out;
1316 }
1317 if (cmd == TIOCSETAF_32 || cmd == TIOCSETAF_64) {
1318 ttyflush(tp, FREAD);
1319 }
1320 }
1321 if (!ISSET(t->c_cflag, CIGNORE)) {
1322 /*
1323 * Set device hardware.
1324 */
1325 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1326 goto out;
1327 }
1328 if (ISSET(t->c_cflag, CLOCAL) &&
1329 !ISSET(tp->t_cflag, CLOCAL)) {
1330 /*
1331 * XXX disconnections would be too hard to
1332 * get rid of without this kludge. The only
1333 * way to get rid of controlling terminals
1334 * is to exit from the session leader.
1335 */
1336 CLR(tp->t_state, TS_ZOMBIE);
1337
1338 wakeup(TSA_CARR_ON(tp));
1339 ttwakeup(tp);
1340 ttwwakeup(tp);
1341 }
1342 if ((ISSET(tp->t_state, TS_CARR_ON) ||
1343 ISSET(t->c_cflag, CLOCAL)) &&
1344 !ISSET(tp->t_state, TS_ZOMBIE)) {
1345 SET(tp->t_state, TS_CONNECTED);
1346 } else {
1347 CLR(tp->t_state, TS_CONNECTED);
1348 }
1349 tp->t_cflag = t->c_cflag;
1350 tp->t_ispeed = t->c_ispeed;
1351 tp->t_ospeed = t->c_ospeed;
1352 ttsetwater(tp);
1353 }
1354 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
1355 cmd != TIOCSETAF_32 && cmd != TIOCSETAF_64) {
1356 if (ISSET(t->c_lflag, ICANON)) {
1357 SET(tp->t_lflag, PENDIN);
1358 } else {
1359 /*
1360 * XXX we really shouldn't allow toggling
1361 * ICANON while we're in a non-termios line
1362 * discipline. Now we have to worry about
1363 * panicing for a null queue.
1364 */
1365 if (tp->t_rawq.c_cs && tp->t_canq.c_cs) {
1366 struct clist tq;
1367
1368 catq(&tp->t_rawq, &tp->t_canq);
1369 tq = tp->t_rawq;
1370 tp->t_rawq = tp->t_canq;
1371 tp->t_canq = tq;
1372 }
1373 CLR(tp->t_lflag, PENDIN);
1374 }
1375 ttwakeup(tp);
1376 }
1377 tp->t_iflag = t->c_iflag;
1378 tp->t_oflag = t->c_oflag;
1379 /*
1380 * Make the EXTPROC bit read only.
1381 */
1382 if (ISSET(tp->t_lflag, EXTPROC)) {
1383 SET(t->c_lflag, EXTPROC);
1384 } else {
1385 CLR(t->c_lflag, EXTPROC);
1386 }
1387 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1388 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1389 t->c_cc[VTIME] != tp->t_cc[VTIME]) {
1390 ttwakeup(tp);
1391 }
1392 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1393 break;
1394 }
1395 case TIOCSETD: { /* set line discipline */
1396 int t = *(int *)data;
1397 dev_t device = tp->t_dev;
1398
1399 if (t >= nlinesw || t < 0) {
1400 error = ENXIO;
1401 goto out;
1402 }
1403 /*
1404 * If the new line discipline is not equal to the old one,
1405 * close the old one and open the new one.
1406 */
1407 if (t != tp->t_line) {
1408 (*linesw[tp->t_line].l_close)(tp, flag);
1409 error = (*linesw[t].l_open)(device, tp);
1410 if (error) {
1411 /* This is racy; it's possible to lose both */
1412 (void)(*linesw[tp->t_line].l_open)(device, tp);
1413 goto out;
1414 }
1415 tp->t_line = t;
1416 }
1417 break;
1418 }
1419 case TIOCSTART: /* start output, like ^Q */
1420 if (ISSET(tp->t_state, TS_TTSTOP) ||
1421 ISSET(tp->t_lflag, FLUSHO)) {
1422 CLR(tp->t_lflag, FLUSHO);
1423 CLR(tp->t_state, TS_TTSTOP);
1424 ttstart(tp);
1425 }
1426 break;
1427 case TIOCSTI: /* simulate terminal input */
1428 if (suser(kauth_cred_get(), NULL) && (flag & FREAD) == 0) {
1429 error = EPERM;
1430 goto out;
1431 }
1432 if (suser(kauth_cred_get(), NULL) && !isctty(p, tp)) {
1433 error = EACCES;
1434 goto out;
1435 }
1436 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1437 break;
1438 case TIOCSTOP: /* stop output, like ^S */
1439 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1440 SET(tp->t_state, TS_TTSTOP);
1441 ttystop(tp, 0);
1442 }
1443 break;
1444 case TIOCIXON:
1445 ttyunblock(tp);
1446 break;
1447 case TIOCIXOFF:
1448 ttyblock(tp);
1449 break;
1450 case TIOCSCTTY: /* become controlling tty */
1451 /* Session ctty vnode pointer set in vnode layer. */
1452 pg = proc_pgrp(p, &sessp);
1453 if (pg == PGRP_NULL) {
1454 error = EPERM;
1455 goto out;
1456 }
1457
1458 /*
1459 * This can only be done by a session leader.
1460 */
1461 if (!SESS_LEADER(p, sessp)) {
1462 /* SAFE: All callers drop the lock on return */
1463 tty_unlock(tp);
1464 pgrp_rele(pg);
1465 tty_lock(tp);
1466 error = EPERM;
1467 goto out;
1468 }
1469 /*
1470 * If this terminal is already the controlling terminal for the
1471 * session, nothing to do here.
1472 */
1473 if (tp->t_session == sessp) {
1474 /* SAFE: All callers drop the lock on return */
1475 tty_unlock(tp);
1476 pgrp_rele(pg);
1477 tty_lock(tp);
1478 error = 0;
1479 goto out;
1480 }
1481
1482 /*
1483 * Deny if the terminal is already attached to another session or
1484 * the session already has a terminal vnode.
1485 */
1486 proc_list_lock();
1487 session_lock(sessp);
1488 if (sessp->s_ttyvp || tp->t_session) {
1489 session_unlock(sessp);
1490 proc_list_unlock();
1491 /* SAFE: All callers drop the lock on return */
1492 tty_unlock(tp);
1493 pgrp_rele(pg);
1494 tty_lock(tp);
1495 error = EPERM;
1496 goto out;
1497 }
1498
1499 sessp->s_ttypgrpid = pg->pg_id;
1500 oldtp = session_set_tty_locked(sessp, tp);
1501
1502 oldpg = tp->t_pgrp;
1503 oldsessp = tp->t_session;
1504 tp->t_pgrp = pg; /* donate pg ref */
1505 tp->t_session = session_ref(sessp);
1506 session_unlock(sessp);
1507
1508 if (oldsessp) {
1509 session_lock(oldsessp);
1510 freetp = session_clear_tty_locked(oldsessp);
1511 session_unlock(oldsessp);
1512 }
1513
1514 os_atomic_or(&p->p_flag, P_CONTROLT, relaxed);
1515 proc_list_unlock();
1516 tty_unlock(tp);
1517
1518 if (oldsessp) {
1519 session_rele(oldsessp);
1520 if (freetp) {
1521 ttyfree(freetp);
1522 }
1523 }
1524 pgrp_rele(oldpg);
1525 if (NULL != oldtp) {
1526 ttyfree(oldtp);
1527 }
1528
1529 /* SAFE: All callers drop the lock on return */
1530 tty_lock(tp);
1531 break;
1532
1533 case TIOCSPGRP: { /* set pgrp of tty */
1534 struct pgrp *pgrp = PGRP_NULL;
1535
1536 pg = proc_pgrp(p, &sessp);
1537 if (!isctty_sp(p, tp, sessp)) {
1538 pgrp_rele(pg);
1539 error = ENOTTY;
1540 goto out;
1541 } else if ((pgrp = pgrp_find(*(int *)data)) == PGRP_NULL) {
1542 pgrp_rele(pg);
1543 error = EINVAL;
1544 goto out;
1545 } else if (pgrp->pg_session != sessp) {
1546 /* SAFE: All callers drop the lock on return */
1547 tty_unlock(tp);
1548 pgrp_rele(pg);
1549 pgrp_rele(pgrp);
1550 tty_lock(tp);
1551 error = EPERM;
1552 goto out;
1553 }
1554
1555 proc_list_lock();
1556 oldpg = tp->t_pgrp;
1557 tp->t_pgrp = pgrp;
1558 proc_list_unlock();
1559
1560 session_lock(sessp);
1561 sessp->s_ttypgrpid = pgrp->pg_id;
1562 session_unlock(sessp);
1563
1564 /*
1565 * Wakeup readers to recheck if they are still the foreground
1566 * process group.
1567 *
1568 * ttwakeup() isn't called because the readers aren't getting
1569 * woken up because there is something to read but to force
1570 * the re-evaluation of their foreground process group status.
1571 *
1572 * Ordinarily leaving these readers waiting wouldn't be an issue
1573 * as launchd would send them a termination signal eventually
1574 * (if nobody else does). But if this terminal happens to be
1575 * /dev/console, launchd itself could get blocked forever behind
1576 * a revoke of /dev/console and leave the system deadlocked.
1577 */
1578 wakeup(TSA_HUP_OR_INPUT(tp));
1579
1580 /* SAFE: All callers drop the lock on return */
1581 tty_unlock(tp);
1582 pgrp_rele(oldpg);
1583 pgrp_rele(pg);
1584 tty_lock(tp);
1585 break;
1586 }
1587 case TIOCSTAT: /* simulate control-T */
1588 ttyinfo_locked(tp);
1589 break;
1590 case TIOCSWINSZ: /* set window size */
1591 if (bcmp((caddr_t)&tp->t_winsize, data,
1592 sizeof(struct winsize))) {
1593 tp->t_winsize = *(struct winsize *)data;
1594 /* SAFE: All callers drop the lock on return */
1595 tty_pgsignal_locked(tp, SIGWINCH, 1);
1596 }
1597 break;
1598 case TIOCSDRAINWAIT:
1599 error = suser(kauth_cred_get(), &p->p_acflag);
1600 if (error) {
1601 goto out;
1602 }
1603 tp->t_timeout = *(int *)data * hz;
1604 wakeup(TSA_OCOMPLETE(tp));
1605 wakeup(TSA_OLOWAT(tp));
1606 break;
1607 case TIOCGDRAINWAIT:
1608 *(int *)data = tp->t_timeout / hz;
1609 break;
1610 case TIOCREVOKE:
1611 SET(tp->t_state, TS_REVOKE);
1612 tp->t_gen++;
1613 /*
1614 * At this time, only this wait channel is woken up as only
1615 * ttread has been problematic. It is possible we may need
1616 * to add wake up other tty wait addresses as well.
1617 */
1618 wakeup(TSA_HUP_OR_INPUT(tp));
1619 break;
1620 case TIOCREVOKECLEAR:
1621 CLR(tp->t_state, TS_REVOKE);
1622 break;
1623 default:
1624 error = ttcompat(tp, cmd, data, flag, p);
1625 goto out;
1626 }
1627
1628 error = 0;
1629 out:
1630 return error;
1631 }
1632
1633
1634 /*
1635 * Locks: Assumes tp is locked on entry, remains locked on exit
1636 */
1637 int
ttyselect(struct tty * tp,int rw,void * wql,proc_t p)1638 ttyselect(struct tty *tp, int rw, void *wql, proc_t p)
1639 {
1640 int retval = 0;
1641 /*
1642 * Attaching knotes to TTYs needs to call selrecord in order to hook
1643 * up the waitq to the selinfo, regardless of data being ready. See
1644 * filt_ttyattach.
1645 */
1646 bool needs_selrecord = rw & FMARK;
1647 rw &= ~FMARK;
1648
1649 if (tp == NULL) {
1650 return ENXIO;
1651 }
1652
1653 TTY_LOCK_OWNED(tp);
1654
1655 if (tp->t_state & TS_ZOMBIE) {
1656 retval = 1;
1657 goto out;
1658 }
1659
1660 switch (rw) {
1661 case FREAD:
1662 retval = ttnread(tp);
1663 if (retval > 0) {
1664 break;
1665 }
1666
1667 selrecord(p, &tp->t_rsel, wql);
1668 break;
1669 case FWRITE:
1670 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
1671 (tp->t_state & TS_CONNECTED)) {
1672 retval = tp->t_hiwat - tp->t_outq.c_cc;
1673 break;
1674 }
1675
1676 selrecord(p, &tp->t_wsel, wql);
1677 break;
1678 }
1679
1680 out:
1681 if (retval > 0 && needs_selrecord) {
1682 switch (rw) {
1683 case FREAD:
1684 selrecord(p, &tp->t_rsel, wql);
1685 break;
1686 case FWRITE:
1687 selrecord(p, &tp->t_wsel, wql);
1688 break;
1689 }
1690 }
1691
1692 return retval;
1693 }
1694
1695
1696 /*
1697 * This is a wrapper for compatibility with the select vector used by
1698 * cdevsw. It relies on a proper xxxdevtotty routine.
1699 *
1700 * Locks: Assumes tty_lock() is not held prior to calling.
1701 */
1702 int
ttselect(dev_t dev,int rw,void * wql,proc_t p)1703 ttselect(dev_t dev, int rw, void *wql, proc_t p)
1704 {
1705 int rv;
1706 struct tty *tp = cdevsw[major(dev)].d_ttys[minor(dev)];
1707
1708 tty_lock(tp);
1709 rv = ttyselect(tp, rw, wql, p);
1710 tty_unlock(tp);
1711
1712 return rv;
1713 }
1714
1715
1716 /*
1717 * Locks: Assumes tp is locked on entry, remains locked on exit
1718 */
1719 __private_extern__ int
ttnread(struct tty * tp)1720 ttnread(struct tty *tp)
1721 {
1722 int nread;
1723
1724 TTY_LOCK_OWNED(tp); /* debug assert */
1725
1726 if (ISSET(tp->t_lflag, PENDIN)) {
1727 ttypend(tp);
1728 }
1729 nread = tp->t_canq.c_cc;
1730 if (!ISSET(tp->t_lflag, ICANON)) {
1731 nread += tp->t_rawq.c_cc;
1732 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0) {
1733 nread = 0;
1734 }
1735 }
1736 return nread;
1737 }
1738
1739
1740 /*
1741 * ttywait
1742 *
1743 * Wait for output to drain.
1744 *
1745 * Parameters: tp Tty on which to wait for output to drain
1746 *
1747 * Returns: 0 Success
1748 * EIO t_timeout too small/expired
1749 * ttysleep:ERESTART Upper layer must redrive the call;
1750 * this is usually done by the Libc
1751 * stub in user space
1752 * ttysleep:EINTR Interrupted (usually a signal)
1753 *
1754 * Notes: Called from proc_exit() and vproc_exit().
1755 *
1756 * Locks: Assumes tp is locked on entry, remains locked on exit
1757 */
1758 int
ttywait(struct tty * tp)1759 ttywait(struct tty *tp)
1760 {
1761 int error;
1762
1763 TTY_LOCK_OWNED(tp); /* debug assert */
1764
1765 error = 0;
1766 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1767 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1768 (*tp->t_oproc)(tp);
1769 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1770 ISSET(tp->t_state, TS_CONNECTED)) {
1771 SET(tp->t_state, TS_SO_OCOMPLETE);
1772 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1773 TTOPRI | PCATCH, "ttywai",
1774 tp->t_timeout);
1775 if (error) {
1776 if (error == EWOULDBLOCK) {
1777 error = EIO;
1778 }
1779 break;
1780 }
1781 } else {
1782 break;
1783 }
1784 }
1785 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY))) {
1786 error = EIO;
1787 }
1788 return error;
1789 }
1790
1791 /*
1792 * Stop the underlying device driver.
1793 *
1794 * Locks: Assumes tty_lock() is held prior to calling.
1795 */
1796 static void
ttystop(struct tty * tp,int rw)1797 ttystop(struct tty *tp, int rw)
1798 {
1799 TTY_LOCK_OWNED(tp); /* debug assert */
1800
1801 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1802 }
1803
1804 /*
1805 * Flush if successfully wait.
1806 *
1807 * Locks: Assumes tty_lock() is held prior to calling.
1808 */
1809 static int
ttywflush(struct tty * tp)1810 ttywflush(struct tty *tp)
1811 {
1812 int error;
1813
1814 TTY_LOCK_OWNED(tp); /* debug assert */
1815
1816 if ((error = ttywait(tp)) == 0) {
1817 ttyflush(tp, FREAD);
1818 }
1819 return error;
1820 }
1821
1822 /*
1823 * Flush tty read and/or write queues, notifying anyone waiting.
1824 *
1825 * Locks: Assumes tty_lock() is held prior to calling.
1826 */
1827 void
ttyflush(struct tty * tp,int rw)1828 ttyflush(struct tty *tp, int rw)
1829 {
1830 TTY_LOCK_OWNED(tp); /* debug assert */
1831
1832 #if 0
1833 again:
1834 #endif
1835 if (rw & FWRITE) {
1836 FLUSHQ(&tp->t_outq);
1837 CLR(tp->t_state, TS_TTSTOP);
1838 }
1839 ttystop(tp, rw);
1840 if (rw & FREAD) {
1841 FLUSHQ(&tp->t_canq);
1842 FLUSHQ(&tp->t_rawq);
1843 CLR(tp->t_lflag, PENDIN);
1844 tp->t_rocount = 0;
1845 tp->t_rocol = 0;
1846 CLR(tp->t_state, TS_LOCAL);
1847 ttwakeup(tp);
1848 if (ISSET(tp->t_state, TS_TBLOCK)) {
1849 if (rw & FWRITE) {
1850 FLUSHQ(&tp->t_outq);
1851 }
1852 ttyunblock(tp);
1853
1854 /*
1855 * Don't let leave any state that might clobber the
1856 * next line discipline (although we should do more
1857 * to send the START char). Not clearing the state
1858 * may have caused the "putc to a clist with no
1859 * reserved cblocks" panic/printf.
1860 */
1861 CLR(tp->t_state, TS_TBLOCK);
1862
1863 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1864 if (ISSET(tp->t_iflag, IXOFF)) {
1865 /*
1866 * XXX wait a bit in the hope that the stop
1867 * character (if any) will go out. Waiting
1868 * isn't good since it allows races. This
1869 * will be fixed when the stop character is
1870 * put in a special queue. Don't bother with
1871 * the checks in ttywait() since the timeout
1872 * will save us.
1873 */
1874 SET(tp->t_state, TS_SO_OCOMPLETE);
1875 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1876 "ttyfls", hz / 10);
1877 /*
1878 * Don't try sending the stop character again.
1879 */
1880 CLR(tp->t_state, TS_TBLOCK);
1881 goto again;
1882 }
1883 #endif
1884 }
1885 }
1886 if (rw & FWRITE) {
1887 FLUSHQ(&tp->t_outq);
1888 ttwwakeup(tp);
1889 }
1890 }
1891
1892 /*
1893 * Copy in the default termios characters.
1894 *
1895 * Locks: Assumes tty_lock() is held prior to calling.
1896 *
1897 * Notes: No assertion; tp is not in scope.
1898 */
1899 void
termioschars(struct termios * t)1900 termioschars(struct termios *t)
1901 {
1902 bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1903 }
1904
1905
1906 /*
1907 * Handle input high water. Send stop character for the IXOFF case. Turn
1908 * on our input flow control bit and propagate the changes to the driver.
1909 * XXX the stop character should be put in a special high priority queue.
1910 *
1911 * Locks: Assumes tty_lock() is held for the call.
1912 */
1913 void
ttyblock(struct tty * tp)1914 ttyblock(struct tty *tp)
1915 {
1916 TTY_LOCK_OWNED(tp); /* debug assert */
1917
1918 SET(tp->t_state, TS_TBLOCK);
1919 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1920 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0) {
1921 CLR(tp->t_state, TS_TBLOCK); /* try again later */
1922 }
1923 ttstart(tp);
1924 }
1925
1926
1927 /*
1928 * Handle input low water. Send start character for the IXOFF case. Turn
1929 * off our input flow control bit and propagate the changes to the driver.
1930 * XXX the start character should be put in a special high priority queue.
1931 *
1932 * Locks: Assumes tty_lock() is held for the call.
1933 */
1934 static void
ttyunblock(struct tty * tp)1935 ttyunblock(struct tty *tp)
1936 {
1937 TTY_LOCK_OWNED(tp); /* debug assert */
1938
1939 CLR(tp->t_state, TS_TBLOCK);
1940 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1941 putc(tp->t_cc[VSTART], &tp->t_outq) != 0) {
1942 SET(tp->t_state, TS_TBLOCK); /* try again later */
1943 }
1944 ttstart(tp);
1945 }
1946
1947
1948 /*
1949 * ttstart
1950 *
1951 * Start tty output
1952 *
1953 * Parameters: tp tty on which to start output
1954 *
1955 * Returns: 0 Success
1956 *
1957 * Locks: Assumes tty_lock() is held for the call.
1958 *
1959 * Notes: This function might as well be void; it always returns success
1960 *
1961 * Called from ttioctl_locked(), LDISC routines, and
1962 * ttycheckoutq(), ttyblock(), ttyunblock(), and tputchar()
1963 */
1964 int
ttstart(struct tty * tp)1965 ttstart(struct tty *tp)
1966 {
1967 TTY_LOCK_OWNED(tp); /* debug assert */
1968
1969 if (tp->t_oproc != NULL) { /* XXX: Kludge for pty. */
1970 (*tp->t_oproc)(tp);
1971 }
1972
1973 return 0;
1974 }
1975
1976
1977 /*
1978 * ttylclose (LDISC)
1979 *
1980 * "close" a line discipline
1981 *
1982 * Locks: Assumes tty_lock() is held prior to calling.
1983 */
1984 int
ttylclose(struct tty * tp,int flag)1985 ttylclose(struct tty *tp, int flag)
1986 {
1987 TTY_LOCK_OWNED(tp); /* debug assert */
1988
1989 if ((flag & FNONBLOCK) || ttywflush(tp)) {
1990 ttyflush(tp, FREAD | FWRITE);
1991 }
1992
1993 return 0;
1994 }
1995
1996
1997 /*
1998 * ttymodem (LDISC)
1999 *
2000 * Handle modem control transition on a tty.
2001 * Flag indicates new state of carrier.
2002 * Returns 0 if the line should be turned off, otherwise 1.
2003 *
2004 * Locks: Assumes tty_lock() is held prior to calling.
2005 */
2006 int
ttymodem(struct tty * tp,int flag)2007 ttymodem(struct tty *tp, int flag)
2008 {
2009 int rval = 1; /* default return value */
2010
2011 TTY_LOCK_OWNED(tp); /* debug assert */
2012
2013 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
2014 /*
2015 * MDMBUF: do flow control according to carrier flag
2016 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP
2017 * works if IXON and IXANY are clear.
2018 */
2019 if (flag) {
2020 CLR(tp->t_state, TS_CAR_OFLOW);
2021 CLR(tp->t_state, TS_TTSTOP);
2022 ttstart(tp);
2023 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
2024 SET(tp->t_state, TS_CAR_OFLOW);
2025 SET(tp->t_state, TS_TTSTOP);
2026 ttystop(tp, 0);
2027 }
2028 } else if (flag == 0) {
2029 /*
2030 * Lost carrier.
2031 */
2032 CLR(tp->t_state, TS_CARR_ON);
2033 if (ISSET(tp->t_state, TS_ISOPEN) &&
2034 !ISSET(tp->t_cflag, CLOCAL)) {
2035 SET(tp->t_state, TS_ZOMBIE);
2036 CLR(tp->t_state, TS_CONNECTED);
2037 if (tp->t_session && tp->t_session->s_leader) {
2038 psignal(tp->t_session->s_leader, SIGHUP);
2039 }
2040 ttyflush(tp, FREAD | FWRITE);
2041 rval = 0;
2042 goto out;
2043 }
2044 } else {
2045 /*
2046 * Carrier now on.
2047 */
2048 SET(tp->t_state, TS_CARR_ON);
2049 if (!ISSET(tp->t_state, TS_ZOMBIE)) {
2050 SET(tp->t_state, TS_CONNECTED);
2051 }
2052 wakeup(TSA_CARR_ON(tp));
2053 ttwakeup(tp);
2054 ttwwakeup(tp);
2055 }
2056
2057 out:
2058 return rval;
2059 }
2060
2061
2062 /*
2063 * Reinput pending characters after state switch
2064 * call at spltty().
2065 *
2066 * Locks: Assumes tty_lock() is held for the call.
2067 */
2068 static void
ttypend(struct tty * tp)2069 ttypend(struct tty *tp)
2070 {
2071 struct clist tq;
2072 int c;
2073
2074 TTY_LOCK_OWNED(tp); /* debug assert */
2075
2076 CLR(tp->t_lflag, PENDIN);
2077 SET(tp->t_state, TS_TYPEN);
2078 tq = tp->t_rawq;
2079 tp->t_rawq.c_cc = 0;
2080 tp->t_rawq.c_cf = tp->t_rawq.c_cl = NULL;
2081 while ((c = getc(&tq)) >= 0) {
2082 ttyinput(c, tp);
2083 }
2084 CLR(tp->t_state, TS_TYPEN);
2085 }
2086
2087
2088 /*
2089 * ttread (LDISC)
2090 *
2091 * Process a read call on a tty device.
2092 *
2093 * Locks: Assumes tty_lock() is held prior to calling.
2094 */
2095 int
ttread(struct tty * tp,struct uio * uio,int flag)2096 ttread(struct tty *tp, struct uio *uio, int flag)
2097 {
2098 struct clist *qp;
2099 int c;
2100 tcflag_t lflag;
2101 cc_t *cc = tp->t_cc;
2102 proc_t p = current_proc();
2103 int first, error = 0;
2104 int has_etime = 0, last_cc = 0;
2105 long slp = 0; /* XXX this should be renamed `timo'. */
2106 struct uthread *ut;
2107 struct pgrp * pg;
2108
2109 TTY_LOCK_OWNED(tp); /* debug assert */
2110
2111 ut = current_uthread();
2112
2113 loop:
2114 lflag = tp->t_lflag;
2115 /*
2116 * take pending input first
2117 */
2118 if (ISSET(lflag, PENDIN)) {
2119 ttypend(tp);
2120 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
2121 }
2122
2123 /*
2124 * Signal the process if it's in the background. If the terminal is
2125 * getting revoked, everybody is in the background.
2126 */
2127 if (isbackground(p, tp) || ISSET(tp->t_state, TS_REVOKE)) {
2128 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
2129 (ut->uu_sigmask & sigmask(SIGTTIN)) ||
2130 p->p_lflag & P_LPPWAIT) {
2131 error = EIO;
2132 goto err;
2133 }
2134 pg = proc_pgrp(p, NULL);
2135 if (pg == PGRP_NULL) {
2136 error = EIO;
2137 goto err;
2138 }
2139 if (pg->pg_jobc == 0) {
2140 /* SAFE: All callers drop the lock on return */
2141 tty_unlock(tp);
2142 pgrp_rele(pg);
2143 tty_lock(tp);
2144 error = EIO;
2145 goto err;
2146 }
2147 /* SAFE: All callers drop the lock on return */
2148 tty_unlock(tp);
2149 pgsignal(pg, SIGTTIN, 1);
2150 pgrp_rele(pg);
2151 tty_lock(tp);
2152
2153 /*
2154 * We signalled ourself, so we need to act as if we
2155 * have been "interrupted" from a "sleep" to act on
2156 * the signal. If it's a signal that stops the
2157 * process, that's handled in the signal sending code.
2158 */
2159 error = EINTR;
2160 goto err;
2161 }
2162
2163 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2164 /* EOF - returning 0 */
2165 goto err;
2166 }
2167
2168 /*
2169 * If canonical, use the canonical queue,
2170 * else use the raw queue.
2171 *
2172 * (should get rid of clists...)
2173 */
2174 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
2175
2176 if (flag & IO_NDELAY) {
2177 if (qp->c_cc > 0) {
2178 goto read;
2179 }
2180 if (ISSET(lflag, ICANON) || cc[VMIN] != 0) {
2181 error = EWOULDBLOCK;
2182 }
2183 /* else polling - returning 0 */
2184 goto err;
2185 }
2186 if (!ISSET(lflag, ICANON)) {
2187 int m = cc[VMIN];
2188 long t = cc[VTIME];
2189 struct timeval timecopy;
2190 struct timeval etime = {.tv_sec = 0, .tv_usec = 0}; /* protected by !has_etime */
2191
2192 /*
2193 * Check each of the four combinations.
2194 * (m > 0 && t == 0) is the normal read case.
2195 * It should be fairly efficient, so we check that and its
2196 * companion case (m == 0 && t == 0) first.
2197 * For the other two cases, we compute the target sleep time
2198 * into slp.
2199 */
2200 if (t == 0) {
2201 if (qp->c_cc < m) {
2202 goto sleep;
2203 }
2204 if (qp->c_cc > 0) {
2205 goto read;
2206 }
2207
2208 /* m, t and qp->c_cc are all 0. 0 is enough input. */
2209 goto err;
2210 }
2211 t *= 100000; /* time in us */
2212 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
2213 ((t1).tv_usec - (t2).tv_usec))
2214 if (m > 0) {
2215 if (qp->c_cc <= 0) {
2216 goto sleep;
2217 }
2218 if (qp->c_cc >= m) {
2219 goto read;
2220 }
2221 microuptime(&timecopy);
2222 if (!has_etime || qp->c_cc > last_cc) {
2223 /* first character or got a character, start timer */
2224 has_etime = 1;
2225
2226 etime.tv_sec = t / 1000000;
2227 etime.tv_usec =
2228 (__darwin_suseconds_t)(t - (etime.tv_sec * 1000000));
2229 timeradd(&etime, &timecopy, &etime);
2230
2231 slp = t;
2232 } else {
2233 /* nothing, check expiration */
2234 if (timercmp(&etime, &timecopy, <=)) {
2235 goto read;
2236 }
2237
2238 slp = diff(etime, timecopy);
2239 }
2240 last_cc = qp->c_cc;
2241 } else { /* m == 0 */
2242 if (qp->c_cc > 0) {
2243 goto read;
2244 }
2245 microuptime(&timecopy);
2246 if (!has_etime) {
2247 has_etime = 1;
2248
2249 etime.tv_sec = t / 1000000;
2250 etime.tv_usec =
2251 (__darwin_suseconds_t)(t - (etime.tv_sec * 1000000));
2252 timeradd(&etime, &timecopy, &etime);
2253
2254 slp = t;
2255 } else {
2256 if (timercmp(&etime, &timecopy, <=)) {
2257 /* Timed out, but 0 is enough input. */
2258 goto err;
2259 }
2260 slp = diff(etime, timecopy);
2261 }
2262 }
2263 #undef diff
2264 /*
2265 * Rounding down may make us wake up just short
2266 * of the target, so we round up.
2267 * The formula is ceiling(slp * hz/1000000).
2268 * 32-bit arithmetic is enough for hz < 169.
2269 * XXX see hzto() for how to avoid overflow if hz
2270 * is large (divide by `tick' and/or arrange to
2271 * use hzto() if hz is large).
2272 */
2273 slp = (long) (((u_int32_t)slp * hz) + 999999) / 1000000;
2274 goto sleep;
2275 }
2276 if (qp->c_cc <= 0) {
2277 sleep:
2278 /*
2279 * There is no input, or not enough input and we can block.
2280 */
2281 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
2282 ISSET(tp->t_state, TS_CONNECTED) ?
2283 "ttyin" : "ttyhup", (int)slp);
2284 if (error == EWOULDBLOCK) {
2285 error = 0;
2286 } else if (error) {
2287 goto err;
2288 }
2289 /*
2290 * XXX what happens if another process eats some input
2291 * while we are asleep (not just here)? It would be
2292 * safest to detect changes and reset our state variables
2293 * (has_stime and last_cc).
2294 */
2295 slp = 0;
2296 goto loop;
2297 }
2298 read:
2299 /*
2300 * Input present, check for input mapping and processing.
2301 */
2302 first = 1;
2303 if (ISSET(lflag, ICANON)
2304 || (ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG))) {
2305 goto slowcase;
2306 }
2307 for (;;) {
2308 char ibuf[IBUFSIZ];
2309 int icc;
2310 ssize_t size = uio_resid(uio);
2311 if (size < 0) {
2312 error = ERANGE;
2313 break;
2314 }
2315
2316 icc = (int)MIN(size, IBUFSIZ);
2317 icc = q_to_b(qp, (u_char *)ibuf, icc);
2318 if (icc <= 0) {
2319 if (first) {
2320 goto loop;
2321 }
2322 break;
2323 }
2324 error = uiomove(ibuf, icc, uio);
2325 /*
2326 * XXX if there was an error then we should ungetc() the
2327 * unmoved chars and reduce icc here.
2328 */
2329 if (error) {
2330 break;
2331 }
2332 if (uio_resid(uio) == 0) {
2333 break;
2334 }
2335 first = 0;
2336 }
2337 goto out;
2338 slowcase:
2339 for (;;) {
2340 c = getc(qp);
2341 if (c < 0) {
2342 if (first) {
2343 goto loop;
2344 }
2345 break;
2346 }
2347 /*
2348 * delayed suspend (^Y)
2349 */
2350 if (CCEQ(cc[VDSUSP], c) &&
2351 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
2352 /*
2353 * SAFE: All callers drop the lock on return and
2354 * SAFE: current thread will not change out from
2355 * SAFE: under us in the "goto loop" case.
2356 */
2357 tty_pgsignal_locked(tp, SIGTSTP, 1);
2358 if (first) {
2359 error = ttysleep(tp, &ttread, TTIPRI | PCATCH,
2360 "ttybg3", hz);
2361 if (error) {
2362 break;
2363 }
2364 goto loop;
2365 }
2366 break;
2367 }
2368 /*
2369 * Interpret EOF only in canonical mode.
2370 */
2371 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON)) {
2372 break;
2373 }
2374 /*
2375 * Give user character.
2376 */
2377 error = ureadc(c, uio);
2378 if (error) {
2379 /* XXX should ungetc(c, qp). */
2380 break;
2381 }
2382 if (uio_resid(uio) == 0) {
2383 break;
2384 }
2385 /*
2386 * In canonical mode check for a "break character"
2387 * marking the end of a "line of input".
2388 */
2389 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag)) {
2390 break;
2391 }
2392 first = 0;
2393 }
2394
2395 out:
2396 /*
2397 * Look to unblock input now that (presumably)
2398 * the input queue has gone down.
2399 */
2400 if (ISSET(tp->t_state, TS_TBLOCK) &&
2401 tp->t_rawq.c_cc + tp->t_canq.c_cc <= I_LOW_WATER) {
2402 ttyunblock(tp);
2403 }
2404
2405 err:
2406 return error;
2407 }
2408
2409
2410 /*
2411 * Check the output queue on tp for space for a kernel message (from uprintf
2412 * or tprintf). Allow some space over the normal hiwater mark so we don't
2413 * lose messages due to normal flow control, but don't let the tty run amok.
2414 * Sleeps here are not interruptible, but we return prematurely if new signals
2415 * arrive.
2416 *
2417 * Locks: Assumes tty_lock() is held before calling
2418 *
2419 * Notes: This function is called from tprintf() in subr_prf.c
2420 */
2421 int
ttycheckoutq(struct tty * tp,int wait)2422 ttycheckoutq(struct tty *tp, int wait)
2423 {
2424 int hiwat;
2425 sigset_t oldsig;
2426 struct uthread *ut;
2427
2428 TTY_LOCK_OWNED(tp); /* debug assert */
2429
2430 ut = current_uthread();
2431
2432 hiwat = tp->t_hiwat;
2433 oldsig = wait ? ut->uu_siglist : 0;
2434 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) {
2435 while (tp->t_outq.c_cc > hiwat) {
2436 ttstart(tp);
2437 if (tp->t_outq.c_cc <= hiwat) {
2438 break;
2439 }
2440 if (wait == 0 || ut->uu_siglist != oldsig) {
2441 return 0;
2442 }
2443 SET(tp->t_state, TS_SO_OLOWAT);
2444 ttysleep(tp, TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
2445 }
2446 }
2447 return 1;
2448 }
2449
2450
2451 /*
2452 * ttwrite (LDISC)
2453 *
2454 * Process a write call on a tty device.
2455 *
2456 * Locks: Assumes tty_lock() is held prior to calling.
2457 */
2458 int
ttwrite(struct tty * tp,struct uio * uio,int flag)2459 ttwrite(struct tty *tp, struct uio *uio, int flag)
2460 {
2461 char *cp = NULL;
2462 int cc, ce;
2463 proc_t p;
2464 int i, hiwat, error;
2465 user_ssize_t count;
2466 char obuf[OBUFSIZ];
2467 struct uthread *ut;
2468 struct pgrp * pg;
2469
2470 TTY_LOCK_OWNED(tp); /* debug assert */
2471
2472 ut = current_uthread();
2473 hiwat = tp->t_hiwat;
2474 count = uio_resid(uio);
2475 error = 0;
2476 cc = 0;
2477 loop:
2478 if (ISSET(tp->t_state, TS_ZOMBIE)) {
2479 if (uio_resid(uio) == count) {
2480 error = EIO;
2481 }
2482 goto out;
2483 }
2484 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2485 if (flag & IO_NDELAY) {
2486 error = EWOULDBLOCK;
2487 goto out;
2488 }
2489 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
2490 "ttydcd", 0);
2491 if (error) {
2492 goto out;
2493 }
2494 goto loop;
2495 }
2496 /*
2497 * Signal the process if it's in the background.
2498 */
2499 p = current_proc();
2500 if (isbackground(p, tp) &&
2501 ISSET(tp->t_lflag, TOSTOP) && (p->p_lflag & P_LPPWAIT) == 0 &&
2502 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
2503 (ut->uu_sigmask & sigmask(SIGTTOU)) == 0) {
2504 pg = proc_pgrp(p, NULL);
2505 if (pg == PGRP_NULL) {
2506 error = EIO;
2507 goto out;
2508 }
2509 if (pg->pg_jobc == 0) {
2510 /* SAFE: All callers drop the lock on return */
2511 tty_unlock(tp);
2512 pgrp_rele(pg);
2513 tty_lock(tp);
2514 error = EIO;
2515 goto out;
2516 }
2517 /* SAFE: All callers drop the lock on return */
2518 tty_unlock(tp);
2519 pgsignal(pg, SIGTTOU, 1);
2520 pgrp_rele(pg);
2521 tty_lock(tp);
2522 /*
2523 * We signalled ourself, so we need to act as if we
2524 * have been "interrupted" from a "sleep" to act on
2525 * the signal. If it's a signal that stops the
2526 * process, that's handled in the signal sending code.
2527 */
2528 error = EINTR;
2529 goto out;
2530 }
2531 /*
2532 * Process the user's data in at most OBUFSIZ chunks. Perform any
2533 * output translation. Keep track of high water mark, sleep on
2534 * overflow awaiting device aid in acquiring new space.
2535 */
2536 while (uio_resid(uio) > 0 || cc > 0) {
2537 if (ISSET(tp->t_lflag, FLUSHO)) {
2538 uio_setresid(uio, 0);
2539 return 0;
2540 }
2541 if (tp->t_outq.c_cc > hiwat) {
2542 goto ovhiwat;
2543 }
2544 /*
2545 * Grab a hunk of data from the user, unless we have some
2546 * leftover from last time.
2547 */
2548 if (cc == 0) {
2549 ssize_t size = uio_resid(uio);
2550 if (size < 0) {
2551 error = ERANGE;
2552 break;
2553 }
2554 cc = (int)MIN((size_t)size, OBUFSIZ);
2555 cp = obuf;
2556 error = uiomove(cp, cc, uio);
2557 if (error) {
2558 cc = 0;
2559 break;
2560 }
2561 }
2562 /*
2563 * If nothing fancy need be done, grab those characters we
2564 * can handle without any of ttyoutput's processing and
2565 * just transfer them to the output q. For those chars
2566 * which require special processing (as indicated by the
2567 * bits in char_type), call ttyoutput. After processing
2568 * a hunk of data, look for FLUSHO so ^O's will take effect
2569 * immediately.
2570 */
2571 while (cc > 0) {
2572 if (!ISSET(tp->t_oflag, OPOST)) {
2573 ce = cc;
2574 } else {
2575 ce = (int)((size_t)cc - scanc((size_t)cc,
2576 (u_char *)cp, char_type, CCLASSMASK));
2577 /*
2578 * If ce is zero, then we're processing
2579 * a special character through ttyoutput.
2580 */
2581 if (ce == 0) {
2582 tp->t_rocount = 0;
2583 if (ttyoutput(*cp, tp) >= 0) {
2584 /* out of space */
2585 goto overfull;
2586 }
2587 cp++;
2588 cc--;
2589 if (ISSET(tp->t_lflag, FLUSHO) ||
2590 tp->t_outq.c_cc > hiwat) {
2591 goto ovhiwat;
2592 }
2593 continue;
2594 }
2595 }
2596 /*
2597 * A bunch of normal characters have been found.
2598 * Transfer them en masse to the output queue and
2599 * continue processing at the top of the loop.
2600 * If there are any further characters in this
2601 * <= OBUFSIZ chunk, the first should be a character
2602 * requiring special handling by ttyoutput.
2603 */
2604 tp->t_rocount = 0;
2605 i = b_to_q((u_char *)cp, ce, &tp->t_outq);
2606 ce -= i;
2607 tp->t_column += ce;
2608 cp += ce;
2609 cc -= ce;
2610 tk_nout += ce;
2611 tp->t_outcc += ce;
2612 if (i > 0) {
2613 /* out of space */
2614 goto overfull;
2615 }
2616 if (ISSET(tp->t_lflag, FLUSHO) ||
2617 tp->t_outq.c_cc > hiwat) {
2618 break;
2619 }
2620 }
2621 ttstart(tp);
2622 }
2623 out:
2624 /*
2625 * If cc is nonzero, we leave the uio structure inconsistent, as the
2626 * offset and iov pointers have moved forward, but it doesn't matter
2627 * (the call will either return short or restart with a new uio).
2628 */
2629 uio_setresid(uio, (uio_resid(uio) + cc));
2630 return error;
2631
2632 overfull:
2633
2634 /*
2635 * Since we are using ring buffers, if we can't insert any more into
2636 * the output queue, we can assume the ring is full and that someone
2637 * forgot to set the high water mark correctly. We set it and then
2638 * proceed as normal.
2639 */
2640 hiwat = tp->t_outq.c_cc - 1;
2641
2642 ovhiwat:
2643 ttstart(tp);
2644 /*
2645 * This can only occur if FLUSHO is set in t_lflag,
2646 * or if ttstart/oproc is synchronous (or very fast).
2647 */
2648 if (tp->t_outq.c_cc <= hiwat) {
2649 goto loop;
2650 }
2651 if (flag & IO_NDELAY) {
2652 uio_setresid(uio, (uio_resid(uio) + cc));
2653 return uio_resid(uio) == count ? EWOULDBLOCK : 0;
2654 }
2655 SET(tp->t_state, TS_SO_OLOWAT);
2656 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
2657 tp->t_timeout);
2658 if (error == EWOULDBLOCK) {
2659 error = EIO;
2660 }
2661 if (error) {
2662 goto out;
2663 }
2664 goto loop;
2665 }
2666
2667
2668 /*
2669 * Rubout one character from the rawq of tp
2670 * as cleanly as possible.
2671 *
2672 * Locks: Assumes tty_lock() is held prior to calling.
2673 */
2674 static void
ttyrub(int c,struct tty * tp)2675 ttyrub(int c, struct tty *tp)
2676 {
2677 u_char *cp;
2678 int savecol;
2679 int tabc;
2680
2681 TTY_LOCK_OWNED(tp); /* debug assert */
2682
2683 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC)) {
2684 return;
2685 }
2686 CLR(tp->t_lflag, FLUSHO);
2687 if (ISSET(tp->t_lflag, ECHOE)) {
2688 if (tp->t_rocount == 0) {
2689 /*
2690 * Messed up by ttwrite; retype
2691 */
2692 ttyretype(tp);
2693 return;
2694 }
2695 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE)) {
2696 ttyrubo(tp, 2);
2697 } else {
2698 CLR(c, ~TTY_CHARMASK);
2699 switch (CCLASS(c)) {
2700 case ORDINARY:
2701 if (!(ISSET(tp->t_iflag, IUTF8) && CCONT(c))) {
2702 ttyrubo(tp, 1);
2703 }
2704 break;
2705 case BACKSPACE:
2706 case CONTROL:
2707 case NEWLINE:
2708 case RETURN:
2709 case VTAB:
2710 if (ISSET(tp->t_lflag, ECHOCTL)) {
2711 ttyrubo(tp, 2);
2712 }
2713 break;
2714 case TAB:
2715 if (tp->t_rocount < tp->t_rawq.c_cc) {
2716 ttyretype(tp);
2717 return;
2718 }
2719 savecol = tp->t_column;
2720 SET(tp->t_state, TS_CNTTB);
2721 SET(tp->t_lflag, FLUSHO);
2722 tp->t_column = tp->t_rocol;
2723 for (cp = firstc(&tp->t_rawq, &tabc); cp;
2724 cp = nextc(&tp->t_rawq, cp, &tabc)) {
2725 ttyecho(tabc, tp);
2726 }
2727 CLR(tp->t_lflag, FLUSHO);
2728 CLR(tp->t_state, TS_CNTTB);
2729
2730 /* savecol will now be length of the tab. */
2731 savecol -= tp->t_column;
2732 tp->t_column += savecol;
2733 if (savecol > 8) {
2734 savecol = 8; /* overflow fixup */
2735 }
2736 while (--savecol >= 0) {
2737 (void)ttyoutput('\b', tp);
2738 }
2739 break;
2740 default: /* XXX */
2741 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
2742 printf(PANICSTR, c, CCLASS(c));
2743 #ifdef notdef
2744 panic(PANICSTR, c, CCLASS(c));
2745 #endif
2746 }
2747 }
2748 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2749 if (!ISSET(tp->t_state, TS_ERASE)) {
2750 SET(tp->t_state, TS_ERASE);
2751 (void)ttyoutput('\\', tp);
2752 }
2753 ttyecho(c, tp);
2754 } else {
2755 ttyecho(tp->t_cc[VERASE], tp);
2756 }
2757 --tp->t_rocount;
2758 }
2759
2760
2761 /*
2762 * Back over count characters, erasing them.
2763 *
2764 * Locks: Assumes tty_lock() is held prior to calling.
2765 */
2766 static void
ttyrubo(struct tty * tp,int count)2767 ttyrubo(struct tty *tp, int count)
2768 {
2769 TTY_LOCK_OWNED(tp); /* debug assert */
2770
2771 while (count-- > 0) {
2772 (void)ttyoutput('\b', tp);
2773 (void)ttyoutput(' ', tp);
2774 (void)ttyoutput('\b', tp);
2775 }
2776 }
2777
2778
2779 /*
2780 * ttyretype --
2781 * Reprint the rawq line. Note, it is assumed that c_cc has already
2782 * been checked.
2783 *
2784 * Locks: Assumes tty_lock() is held prior to calling.
2785 */
2786 static void
ttyretype(struct tty * tp)2787 ttyretype(struct tty *tp)
2788 {
2789 u_char *cp;
2790 int c;
2791
2792 TTY_LOCK_OWNED(tp); /* debug assert */
2793
2794 /* Echo the reprint character. */
2795 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE) {
2796 ttyecho(tp->t_cc[VREPRINT], tp);
2797 }
2798
2799 (void)ttyoutput('\n', tp);
2800
2801 /*
2802 * FREEBSD XXX
2803 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2804 * BIT OF FIRST CHAR.
2805 */
2806 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c)) {
2807 ttyecho(c, tp);
2808 }
2809 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c)) {
2810 ttyecho(c, tp);
2811 }
2812 CLR(tp->t_state, TS_ERASE);
2813
2814 tp->t_rocount = tp->t_rawq.c_cc;
2815 tp->t_rocol = 0;
2816 }
2817
2818
2819 /*
2820 * Echo a typed character to the terminal.
2821 *
2822 * Locks: Assumes tty_lock() is held prior to calling.
2823 */
2824 static void
ttyecho(int c,struct tty * tp)2825 ttyecho(int c, struct tty *tp)
2826 {
2827 TTY_LOCK_OWNED(tp); /* debug assert */
2828
2829 if (!ISSET(tp->t_state, TS_CNTTB)) {
2830 CLR(tp->t_lflag, FLUSHO);
2831 }
2832 if ((!ISSET(tp->t_lflag, ECHO) &&
2833 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2834 ISSET(tp->t_lflag, EXTPROC)) {
2835 return;
2836 }
2837 if (ISSET(tp->t_lflag, ECHOCTL) &&
2838 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2839 ISSET(c, TTY_CHARMASK) == 0177)) {
2840 (void)ttyoutput('^', tp);
2841 CLR(c, ~TTY_CHARMASK);
2842 if (c == 0177) {
2843 c = '?';
2844 } else {
2845 c += 'A' - 1;
2846 }
2847 }
2848 (void)ttyoutput(c, tp);
2849 }
2850
2851 static void
ttwakeup_knote(struct selinfo * sip,long hint)2852 ttwakeup_knote(struct selinfo *sip, long hint)
2853 {
2854 if ((sip->si_flags & SI_KNPOSTING) == 0) {
2855 sip->si_flags |= SI_KNPOSTING;
2856 KNOTE(&sip->si_note, hint);
2857 sip->si_flags &= ~SI_KNPOSTING;
2858 }
2859 }
2860
2861
2862 /*
2863 * Wake up any readers on a tty.
2864 *
2865 * Locks: Assumes tty_lock() is held for the call.
2866 */
2867 void
ttwakeup(struct tty * tp)2868 ttwakeup(struct tty *tp)
2869 {
2870 TTY_LOCK_OWNED(tp); /* debug assert */
2871
2872 selwakeup(&tp->t_rsel);
2873 ttwakeup_knote(&tp->t_rsel, 0);
2874 if (ISSET(tp->t_state, TS_ASYNC)) {
2875 /*
2876 * XXX: Callers may not revalidate it the tty is closed
2877 * XXX: out from under them by another thread, but we do
2878 * XXX: not support queued signals. This should be safe,
2879 * XXX: since the process we intend to wakeup is in the
2880 * XXX: process group, and will wake up because of the
2881 * XXX: signal anyway.
2882 */
2883 tty_pgsignal_locked(tp, SIGIO, 1);
2884 }
2885 wakeup(TSA_HUP_OR_INPUT(tp));
2886 }
2887
2888
2889 /*
2890 * ttwwakeup (LDISC)
2891 *
2892 * Wake up any writers on a tty.
2893 *
2894 * Locks: Assumes tty_lock() is held prior to calling.
2895 */
2896 void
ttwwakeup(struct tty * tp)2897 ttwwakeup(struct tty *tp)
2898 {
2899 TTY_LOCK_OWNED(tp); /* debug assert */
2900
2901 if (tp->t_outq.c_cc <= tp->t_lowat) {
2902 selwakeup(&tp->t_wsel);
2903 ttwakeup_knote(&tp->t_wsel, 0);
2904 }
2905 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2906 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2907 CLR(tp->t_state, TS_SO_OCOMPLETE);
2908 wakeup(TSA_OCOMPLETE(tp));
2909 }
2910 if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2911 tp->t_outq.c_cc <= tp->t_lowat) {
2912 CLR(tp->t_state, TS_SO_OLOWAT);
2913 wakeup(TSA_OLOWAT(tp));
2914 }
2915 }
2916
2917
2918 /*
2919 * Look up a code for a specified speed in a conversion table;
2920 * used by drivers to map software speed values to hardware parameters.
2921 *
2922 * Notes: No locks are assumed for this function; it does not
2923 * directly access struct tty.
2924 */
2925 int
ttspeedtab(int speed,struct speedtab * table)2926 ttspeedtab(int speed, struct speedtab *table)
2927 {
2928 for (; table->sp_speed != -1; table++) {
2929 if (table->sp_speed == speed) {
2930 return table->sp_code;
2931 }
2932 }
2933 return -1;
2934 }
2935
2936
2937 /*
2938 * Set tty hi and low water marks.
2939 *
2940 * Try to arrange the dynamics so there's about one second
2941 * from hi to low water.
2942 *
2943 * Locks: Assumes tty_lock() is held prior to calling.
2944 */
2945 void
ttsetwater(struct tty * tp)2946 ttsetwater(struct tty *tp)
2947 {
2948 speed_t cps;
2949 unsigned int x;
2950
2951 TTY_LOCK_OWNED(tp); /* debug assert */
2952
2953 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2954
2955 cps = tp->t_ospeed / 10;
2956 static_assert(TTMAXLOWAT <= UINT_MAX, "max low water fits in unsigned int");
2957 static_assert(TTMINLOWAT <= UINT_MAX, "min low water fits in unsigned int");
2958 tp->t_lowat = x = (unsigned int)CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2959 x += cps;
2960 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
2961 tp->t_hiwat = roundup(x, CBSIZE);
2962 #undef CLAMP
2963 }
2964
2965 /* ttyinfo has been converted to the MACH kernel */
2966 #include <mach/thread_info.h>
2967
2968 /* XXX Should be in Mach header <kern/thread.h>, but doesn't work */
2969 extern kern_return_t thread_info_internal(thread_t thread,
2970 thread_flavor_t flavor,
2971 thread_info_t thread_info_out,
2972 mach_msg_type_number_t *thread_info_count);
2973
2974
2975 /*
2976 * Report on state of foreground process group.
2977 *
2978 * Locks: Assumes tty_lock() is held prior to calling.
2979 */
2980 void
ttyinfo_locked(struct tty * tp)2981 ttyinfo_locked(struct tty *tp)
2982 {
2983 int load;
2984 uthread_t uthread;
2985 proc_t p;
2986 proc_t pick;
2987 pid_t pickpid;
2988 const char *state;
2989 struct timeval utime;
2990 struct timeval stime;
2991 thread_basic_info_data_t basic_info;
2992 mach_msg_type_number_t mmtn = THREAD_BASIC_INFO_COUNT;
2993 struct pgrp * pg;
2994
2995 TTY_LOCK_OWNED(tp); /* debug assert */
2996
2997 if (ttycheckoutq(tp, 0) == 0) {
2998 return;
2999 }
3000
3001 /* Print load average. */
3002 load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
3003 ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
3004
3005 /*
3006 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
3007 * that pending input will be retyped on BS.
3008 */
3009 if (tp->t_session == NULL) {
3010 ttyprintf(tp, "not a controlling terminal\n");
3011 tp->t_rocount = 0;
3012 return;
3013 }
3014 if (tp->t_pgrp == NULL) {
3015 ttyprintf(tp, "no foreground process group\n");
3016 tp->t_rocount = 0;
3017 return;
3018 }
3019
3020 /* get a reference on the process group before locking it */
3021 pg = tty_pgrp_locked(tp);
3022
3023 pgrp_lock(pg);
3024 /* the proc_compare is non blocking fn, no need to use iterator */
3025 pick = NULL;
3026 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
3027 if (proc_compare(pick, p)) {
3028 pick = p;
3029 pickpid = proc_getpid(p);
3030 } else {
3031 pickpid = proc_getpid(pick);
3032 }
3033 }
3034 pgrp_unlock(pg);
3035 /* SAFE: All callers drop the lock on return */
3036 tty_unlock(tp);
3037 pgrp_rele(pg);
3038
3039 pick = proc_find(pickpid);
3040 if (pick == PROC_NULL) {
3041 tty_lock(tp);
3042 return;
3043 }
3044
3045 tty_lock(tp);
3046 proc_lock(pick);
3047 if (TAILQ_EMPTY(&pick->p_uthlist) ||
3048 (uthread = TAILQ_FIRST(&pick->p_uthlist)) == NULL ||
3049 (thread_info_internal(get_machthread(uthread), THREAD_BASIC_INFO, (thread_info_t)&basic_info, &mmtn) != KERN_SUCCESS)) {
3050 proc_unlock(pick);
3051 ttyprintf(tp, "foreground process without thread\n");
3052 tp->t_rocount = 0;
3053 proc_rele(pick);
3054 return;
3055 }
3056 proc_unlock(pick);
3057
3058 switch (basic_info.run_state) {
3059 case TH_STATE_RUNNING:
3060 state = "running";
3061 break;
3062 case TH_STATE_STOPPED:
3063 state = "stopped";
3064 break;
3065 case TH_STATE_WAITING:
3066 state = "waiting";
3067 break;
3068 case TH_STATE_UNINTERRUPTIBLE:
3069 state = "uninterruptible";
3070 break;
3071 case TH_STATE_HALTED:
3072 state = "halted";
3073 break;
3074 default:
3075 state = "unknown";
3076 break;
3077 }
3078 calcru(pick, &utime, &stime, NULL);
3079
3080 /* Print command, pid, state, utime, and stime */
3081 ttyprintf(tp, " cmd: %s %d %s %ld.%02du %ld.%02ds\n",
3082 pick->p_comm,
3083 proc_getpid(pick),
3084 state,
3085 (long)utime.tv_sec, utime.tv_usec / 10000,
3086 (long)stime.tv_sec, stime.tv_usec / 10000);
3087
3088 proc_rele(pick);
3089 tp->t_rocount = 0;
3090 }
3091
3092
3093 /*
3094 * Returns 1 if p2 is "better" than p1
3095 *
3096 * The algorithm for picking the "interesting" process is thus:
3097 *
3098 * 1) Only foreground processes are eligible - implied.
3099 * 2) Runnable processes are favored over anything else. The runner
3100 * with the highest cpu utilization is picked (p_estcpu). Ties are
3101 * broken by picking the highest pid.
3102 * 3) The sleeper with the shortest sleep time is next.
3103 * 4) Further ties are broken by picking the highest pid.
3104 */
3105 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
3106 #define TESTAB(a, b) ((a)<<1 | (b))
3107 #define ONLYA 2
3108 #define ONLYB 1
3109 #define BOTH 3
3110
3111 /*
3112 * Locks: pgrp_lock(p2) held on call to this function
3113 * tty_lock(tp) for p2's tty, for which p2 is the foreground
3114 * process, held on call to this function
3115 */
3116 static int
proc_compare(proc_t p1,proc_t p2)3117 proc_compare(proc_t p1, proc_t p2)
3118 {
3119 /* NOTE THIS FN needs to be NON BLOCKING */
3120
3121 if (p1 == NULL) {
3122 return 1;
3123 }
3124 /*
3125 * see if at least one of them is runnable
3126 */
3127 switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
3128 case ONLYA:
3129 return 0;
3130 case ONLYB:
3131 return 1;
3132 case BOTH:
3133 /*
3134 * tie - favor one with highest recent cpu utilization
3135 */
3136 #ifdef _PROC_HAS_SCHEDINFO_
3137 /* Without the support the fields are always zero */
3138 if (p2->p_estcpu > p1->p_estcpu) {
3139 return 1;
3140 }
3141 if (p1->p_estcpu > p2->p_estcpu) {
3142 return 0;
3143 }
3144 #endif /* _PROC_HAS_SCHEDINFO_ */
3145 return proc_getpid(p2) > proc_getpid(p1); /* tie - return highest pid */
3146 }
3147 /*
3148 * weed out zombies
3149 */
3150 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
3151 case ONLYA:
3152 return 1;
3153 case ONLYB:
3154 return 0;
3155 case BOTH:
3156 return proc_getpid(p2) > proc_getpid(p1); /* tie - return highest pid */
3157 }
3158 /*
3159 * pick the one with the smallest sleep time
3160 */
3161 #ifdef _PROC_HAS_SCHEDINFO_
3162 /* Without the support the fields are always zero */
3163 if (p2->p_slptime > p1->p_slptime) {
3164 return 0;
3165 }
3166 if (p1->p_slptime > p2->p_slptime) {
3167 return 1;
3168 }
3169 #endif /* _PROC_HAS_SCHEDINFO_ */
3170 return proc_getpid(p2) > proc_getpid(p1); /* tie - return highest pid */
3171 }
3172
3173
3174 /*
3175 * Output char to tty; console putchar style.
3176 *
3177 * Locks: Assumes tty_lock() is held prior to calling.
3178 *
3179 * Notes: Only ever called from putchar() in subr_prf.c
3180 */
3181 int
tputchar(int c,struct tty * tp)3182 tputchar(int c, struct tty *tp)
3183 {
3184 TTY_LOCK_OWNED(tp); /* debug assert */
3185
3186 if (!ISSET(tp->t_state, TS_CONNECTED)) {
3187 return -1;
3188 }
3189 if (c == '\n') {
3190 (void)ttyoutput('\r', tp);
3191 }
3192 (void)ttyoutput(c, tp);
3193 ttstart(tp);
3194 return 0;
3195 }
3196
3197
3198 /*
3199 * ttysleep
3200 *
3201 * Sleep on a wait channel waiting for an interrupt or a condition to come
3202 * true so that we are woken up.
3203 *
3204 * Parameters: tp Tty going to sleep
3205 * chan The sleep channel (usually an address
3206 * of a structure member)
3207 * pri priority and flags
3208 * wmesg Wait message; shows up in debugger,
3209 * should show up in "ps", but doesn't
3210 * timo Timeout for the sleep
3211 *
3212 * Returns: 0 Condition came true
3213 * ERESTART Upper layer must redrive the call;
3214 * this is usually done by the Libc
3215 * stub in user space
3216 * msleep0:EINTR Interrupted (usually a signal)
3217 * msleep0:ERESTART Interrupted (usually a masked signal)
3218 * msleep0:EWOULDBLOCK Timeout (timo) already expired
3219 *
3220 * Locks: Assumes tty_lock() is held prior to calling.
3221 *
3222 * Sleep on chan, returning ERESTART if tty changed while we napped and
3223 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by msleep0. If
3224 * the tty is revoked, restarting a pending call will redo validation done
3225 * at the start of the call.
3226 */
3227 int
ttysleep(struct tty * tp,void * chan,int pri,const char * wmesg,int timo)3228 ttysleep(struct tty *tp, void *chan, int pri, const char *wmesg, int timo)
3229 {
3230 int error;
3231 int gen;
3232
3233 TTY_LOCK_OWNED(tp);
3234
3235 if (tp->t_state & TS_REVOKE) {
3236 return ERESTART;
3237 }
3238
3239 gen = tp->t_gen;
3240 /* Use of msleep0() avoids conversion timo/timespec/timo */
3241 error = msleep0(chan, &tp->t_lock, pri, wmesg, timo, (int (*)(int))0);
3242 if (error) {
3243 return error;
3244 }
3245 return tp->t_gen == gen ? 0 : ERESTART;
3246 }
3247
3248
3249 /*
3250 * Allocate a tty structure and its associated buffers.
3251 *
3252 * Parameters: void
3253 *
3254 * Returns: !NULL Address of new struct tty
3255 * NULL Error ("ENOMEM")
3256 *
3257 * Locks: The tty_lock() of the returned tty is not held when it
3258 * is returned.
3259 */
3260 struct tty *
ttymalloc(void)3261 ttymalloc(void)
3262 {
3263 struct tty *tp;
3264
3265 tp = kalloc_type(struct tty, Z_WAITOK | Z_ZERO | Z_NOFAIL);
3266 /* XXX: default to TTYCLSIZE(1024) chars for now */
3267 clalloc(&tp->t_rawq, TTYCLSIZE, 1);
3268 clalloc(&tp->t_canq, TTYCLSIZE, 1);
3269 /* output queue doesn't need quoting */
3270 clalloc(&tp->t_outq, TTYCLSIZE, 0);
3271 lck_mtx_init(&tp->t_lock, &tty_lck_grp, LCK_ATTR_NULL);
3272 klist_init(&tp->t_rsel.si_note);
3273 klist_init(&tp->t_wsel.si_note);
3274 os_ref_init_raw(&tp->t_refcnt, &t_refgrp);
3275 return tp;
3276 }
3277
3278 /*
3279 * Increment the reference count on a tty.
3280 */
3281 void
ttyhold(struct tty * tp)3282 ttyhold(struct tty *tp)
3283 {
3284 assert(tp != NULL);
3285 os_ref_retain_raw(&tp->t_refcnt, &t_refgrp);
3286 }
3287
3288 /*
3289 * Drops a reference count on a tty structure; if the reference count reaches
3290 * zero, then also frees the structure and associated buffers.
3291 */
3292 void
ttyfree(struct tty * tp)3293 ttyfree(struct tty *tp)
3294 {
3295 assert(tp != NULL);
3296 TTY_LOCK_NOTOWNED(tp);
3297
3298 if (os_ref_release_raw(&tp->t_refcnt, &t_refgrp) == 0) {
3299 ttydeallocate(tp);
3300 }
3301 }
3302
3303 /*
3304 * Drops a reference count on a tty structure while holding the tty lock.
3305 * Panics if the last reference is dropped.
3306 */
3307 void
ttyfree_locked(struct tty * tp)3308 ttyfree_locked(struct tty *tp)
3309 {
3310 assert(tp != NULL);
3311 TTY_LOCK_OWNED(tp);
3312 os_ref_release_live_raw(&tp->t_refcnt, &t_refgrp);
3313 }
3314
3315 /*
3316 * Deallocate a tty structure and its buffers.
3317 *
3318 * Locks: The tty_lock() is assumed to not be held at the time of
3319 * the free; this function destroys the mutex.
3320 */
3321 static void
ttydeallocate(struct tty * tp)3322 ttydeallocate(struct tty *tp)
3323 {
3324 TTY_LOCK_NOTOWNED(tp); /* debug assert */
3325
3326 #if DEBUG
3327 if (!(SLIST_EMPTY(&tp->t_rsel.si_note) && SLIST_EMPTY(&tp->t_wsel.si_note))) {
3328 panic("knotes hooked into a tty when the tty is freed.");
3329 }
3330 #endif /* DEBUG */
3331
3332 clfree(&tp->t_rawq);
3333 clfree(&tp->t_canq);
3334 clfree(&tp->t_outq);
3335 lck_mtx_destroy(&tp->t_lock, &tty_lck_grp);
3336 kfree_type(struct tty, tp);
3337 }
3338
3339
3340 /*
3341 * Locks: Assumes tty_lock() is held prior to calling.
3342 */
3343 static bool
isbackground(proc_t p,struct tty * tp)3344 isbackground(proc_t p, struct tty *tp)
3345 {
3346 TTY_LOCK_OWNED(tp);
3347
3348 if (tp->t_pgrp == NULL ||
3349 (uintptr_t)tp->t_pgrp == smr_unsafe_load(&p->p_pgrp)) {
3350 return false;
3351 }
3352
3353 if (tp->t_session == SESSION_NULL) {
3354 return false;
3355 }
3356
3357 /*
3358 * same as isctty_sp(p, tp, p->p_pgrp->pg_session)
3359 * without dereferencing p->p_pgrp
3360 */
3361 return tp->t_session->s_sid == proc_sessionid(p) && (p->p_flag & P_CONTROLT);
3362 }
3363
3364 static bool
isctty(proc_t p,struct tty * tp)3365 isctty(proc_t p, struct tty *tp)
3366 {
3367 struct session *sessp;
3368 struct pgrp *pg;
3369 bool retval = false;
3370
3371 pg = proc_pgrp(p, &sessp);
3372 retval = isctty_sp(p, tp, sessp);
3373 pgrp_rele(pg);
3374
3375 return retval;
3376 }
3377
3378 static bool
isctty_sp(proc_t p,struct tty * tp,struct session * sessp)3379 isctty_sp(proc_t p, struct tty *tp, struct session *sessp)
3380 {
3381 return sessp == tp->t_session && (p->p_flag & P_CONTROLT);
3382 }
3383
3384
3385 static int filt_ttyattach(struct knote *kn, struct kevent_qos_s *kev);
3386 static void filt_ttydetach(struct knote *kn);
3387 static int filt_ttyevent(struct knote *kn, long hint);
3388 static int filt_ttytouch(struct knote *kn, struct kevent_qos_s *kev);
3389 static int filt_ttyprocess(struct knote *kn, struct kevent_qos_s *kev);
3390
3391 SECURITY_READ_ONLY_EARLY(struct filterops) tty_filtops = {
3392 .f_isfd = 1,
3393 .f_attach = filt_ttyattach,
3394 .f_detach = filt_ttydetach,
3395 .f_event = filt_ttyevent,
3396 .f_touch = filt_ttytouch,
3397 .f_process = filt_ttyprocess
3398 };
3399
3400 /*
3401 * Called with struct tty locked. Returns non-zero if there is data to be read
3402 * or written.
3403 */
3404 static int
filt_tty_common(struct knote * kn,struct kevent_qos_s * kev,struct tty * tp)3405 filt_tty_common(struct knote *kn, struct kevent_qos_s *kev, struct tty *tp)
3406 {
3407 int retval = 0;
3408 int64_t data = 0;
3409
3410 TTY_LOCK_OWNED(tp); /* debug assert */
3411
3412 switch (kn->kn_filter) {
3413 case EVFILT_READ:
3414 /*
3415 * ttnread can change the tty state,
3416 * hence must be done upfront, before any other check.
3417 */
3418 data = ttnread(tp);
3419 retval = (data != 0);
3420 break;
3421 case EVFILT_WRITE:
3422 if ((tp->t_outq.c_cc <= tp->t_lowat) &&
3423 (tp->t_state & TS_CONNECTED)) {
3424 data = tp->t_hiwat - tp->t_outq.c_cc;
3425 retval = (data != 0);
3426 }
3427 break;
3428 default:
3429 panic("tty kevent: unexpected filter: %d, kn = %p, tty = %p",
3430 kn->kn_filter, kn, tp);
3431 break;
3432 }
3433
3434 /*
3435 * TODO(mwidmann, jandrus): For native knote low watermark support,
3436 * check the kn_sfflags for NOTE_LOWAT and check against kn_sdata.
3437 *
3438 * res = ((kn->kn_sfflags & NOTE_LOWAT) != 0) ?
3439 * (kn->kn_data >= kn->kn_sdata) : kn->kn_data;
3440 */
3441
3442 if (tp->t_state & TS_ZOMBIE) {
3443 kn->kn_flags |= EV_EOF;
3444 }
3445 if (kn->kn_flags & EV_EOF) {
3446 retval = 1;
3447 }
3448 if (retval && kev) {
3449 knote_fill_kevent(kn, kev, data);
3450 }
3451
3452 return retval;
3453 }
3454
3455 /*
3456 * Find the struct tty from a waitq, which is a member of one of the two struct
3457 * selinfos inside the struct tty. Use the seltype to determine which selinfo.
3458 */
3459 static struct tty *
tty_from_waitq(struct waitq * wq,int seltype)3460 tty_from_waitq(struct waitq *wq, int seltype)
3461 {
3462 /*
3463 * The waitq is part of the selinfo structure managed by the driver.
3464 * For certain drivers, we want to hook the knote into the selinfo
3465 * structure's si_note field so selwakeup can call KNOTE.
3466 *
3467 * For TTY drivers, the selinfo structure is somewhere in the struct
3468 * tty. There are two different selinfo structures, and the one used
3469 * corresponds to the type of filter requested.
3470 */
3471 switch (seltype) {
3472 case FREAD:
3473 return __container_of(wq, struct tty, t_rsel.si_waitq);
3474 case FWRITE:
3475 return __container_of(wq, struct tty, t_wsel.si_waitq);
3476 default:
3477 return NULL;
3478 }
3479 }
3480
3481 static struct tty *
tty_from_knote(struct knote * kn)3482 tty_from_knote(struct knote *kn)
3483 {
3484 return (struct tty *)knote_kn_hook_get_raw(kn);
3485 }
3486
3487 static int
filt_ttyattach(struct knote * kn,__unused struct kevent_qos_s * kev)3488 filt_ttyattach(struct knote *kn, __unused struct kevent_qos_s *kev)
3489 {
3490 uthread_t uth = current_uthread();
3491 vfs_context_t ctx = vfs_context_current();
3492 vnode_t vp = (vnode_t)fp_get_data(kn->kn_fp);
3493 struct select_set *old_wqs;
3494 int selres;
3495
3496 /*
3497 * This function should be called from spec_kqfilter (spec_vnops.c),
3498 * so most of the knote data structure should already be initialized.
3499 */
3500
3501 /* don't support offsets in ttys or drivers that don't use struct tty */
3502 if (kn->kn_vnode_use_ofst || !kn->kn_vnode_kqok) {
3503 knote_set_error(kn, ENOTSUP);
3504 return 0;
3505 }
3506
3507 /*
3508 * Connect the struct tty to the knote through the selinfo structure
3509 * referenced by the waitq within the selinfo.
3510 *
3511 * FMARK forces selects to always call selrecord, even if data is
3512 * available. See ttselect, ptsselect, ptcselect.
3513 *
3514 * selres also contains the data currently available in the tty.
3515 */
3516 selspec_record_hook_t block = ^(struct selinfo *si){
3517 struct tty *tp;
3518
3519 tp = tty_from_waitq(&si->si_waitq, knote_get_seltype(kn));
3520 TTY_LOCK_OWNED(tp);
3521
3522 /* Attach the knote to selinfo's klist and take a ref */
3523 ttyhold(tp);
3524 knote_kn_hook_set_raw(kn, tp);
3525 KNOTE_ATTACH(&si->si_note, kn);
3526 };
3527
3528 old_wqs = uth->uu_selset;
3529 uth->uu_selset = SELSPEC_RECORD_MARKER;
3530 selres = VNOP_SELECT(vp, knote_get_seltype(kn) | FMARK, 0, block, ctx);
3531 uth->uu_selset = old_wqs;
3532
3533 if (knote_kn_hook_get_raw(kn) == NULL) {
3534 /*
3535 * The driver didn't call selrecord --
3536 * there's no tty hooked up so we can't attach.
3537 */
3538 knote_set_error(kn, ENOTTY);
3539 return 0;
3540 }
3541
3542 return selres;
3543 }
3544
3545 static void
filt_ttydetach(struct knote * kn)3546 filt_ttydetach(struct knote *kn)
3547 {
3548 struct tty *tp = tty_from_knote(kn);
3549
3550 tty_lock(tp);
3551
3552 if (!KNOTE_IS_AUTODETACHED(kn)) {
3553 switch (kn->kn_filter) {
3554 case EVFILT_READ:
3555 KNOTE_DETACH(&tp->t_rsel.si_note, kn);
3556 break;
3557 case EVFILT_WRITE:
3558 KNOTE_DETACH(&tp->t_wsel.si_note, kn);
3559 break;
3560 default:
3561 panic("invalid knote %p detach, filter: %d", kn, kn->kn_filter);
3562 break;
3563 }
3564 }
3565
3566 // Remove dangling reference
3567 knote_kn_hook_set_raw(kn, NULL);
3568
3569 tty_unlock(tp);
3570 ttyfree(tp);
3571 }
3572
3573 static int
filt_ttyevent(struct knote * kn,long hint)3574 filt_ttyevent(struct knote *kn, long hint)
3575 {
3576 struct tty *tp = tty_from_knote(kn);
3577 int ret;
3578
3579 TTY_LOCK_OWNED(tp);
3580
3581 if (hint & NOTE_REVOKE) {
3582 kn->kn_flags |= EV_EOF | EV_ONESHOT;
3583 ret = 1;
3584 } else {
3585 ret = filt_tty_common(kn, NULL, tp);
3586 }
3587
3588 return ret;
3589 }
3590
3591 static int
filt_ttytouch(struct knote * kn,struct kevent_qos_s * kev)3592 filt_ttytouch(struct knote *kn, struct kevent_qos_s *kev)
3593 {
3594 struct tty *tp = tty_from_knote(kn);
3595 int res = 0;
3596
3597 tty_lock(tp);
3598
3599 kn->kn_sdata = kev->data;
3600 kn->kn_sfflags = kev->fflags;
3601
3602 if (kn->kn_vnode_kqok) {
3603 res = filt_tty_common(kn, NULL, tp);
3604 }
3605
3606 tty_unlock(tp);
3607
3608 return res;
3609 }
3610
3611 static int
filt_ttyprocess(struct knote * kn,struct kevent_qos_s * kev)3612 filt_ttyprocess(struct knote *kn, struct kevent_qos_s *kev)
3613 {
3614 struct tty *tp = tty_from_knote(kn);
3615 int res;
3616
3617 tty_lock(tp);
3618
3619 res = filt_tty_common(kn, kev, tp);
3620
3621 tty_unlock(tp);
3622
3623 return res;
3624 }
3625