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