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