]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty.c
xnu-792.1.5.tar.gz
[apple/xnu.git] / bsd / kern / tty.c
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
23 /*-
24 * Copyright (c) 1982, 1986, 1990, 1991, 1993
25 * The Regents of the University of California. All rights reserved.
26 * (c) UNIX System Laboratories, Inc.
27 * All or some portions of this file are derived from material licensed
28 * to the University of California by American Telephone and Telegraph
29 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
30 * the permission of UNIX System Laboratories, Inc.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)tty.c 8.8 (Berkeley) 1/21/94
61 */
62 /*-
63 * TODO:
64 * o Fix races for sending the start char in ttyflush().
65 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
66 * With luck, there will be MIN chars before select() returns().
67 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it.
68 * o Don't allow input in TS_ZOMBIE case. It would be visible through
69 * FIONREAD.
70 * o Do the new sio locking stuff here and use it to avoid special
71 * case for EXTPROC?
72 * o Lock PENDIN too?
73 * o Move EXTPROC and/or PENDIN to t_state?
74 * o Wrap most of ttioctl in spltty/splx.
75 * o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
76 * o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
77 * o Don't allow certain termios flags to affect disciplines other
78 * than TTYDISC. Cancel their effects before switch disciplines
79 * and ignore them if they are set while we are in another
80 * discipline.
81 * o Handle c_ispeed = 0 to c_ispeed = c_ospeed conversion here instead
82 * of in drivers and fix drivers that write to tp->t_termios.
83 * o Check for TS_CARR_ON being set while everything is closed and not
84 * waiting for carrier. TS_CARR_ON isn't cleared if nothing is open,
85 * so it would live until the next open even if carrier drops.
86 * o Restore TS_WOPEN since it is useful in pstat. It must be cleared
87 * only when _all_ openers leave open().
88 */
89 #ifdef NeXT
90 #define NSNP 0
91 #else
92 #include "snp.h"
93 #include "opt_uconsole.h"
94 #endif
95
96 #include <sys/param.h>
97 #define TTYDEFCHARS 1
98 #include <sys/systm.h>
99 #undef TTYDEFCHARS
100 #include <sys/ioctl.h>
101 #include <sys/proc_internal.h>
102 #include <sys/kauth.h>
103 #include <sys/file_internal.h>
104 #include <sys/conf.h>
105 #include <sys/dkstat.h>
106 #include <sys/uio.h>
107 #include <sys/kernel.h>
108 #include <sys/vnode.h>
109 #include <sys/syslog.h>
110 #include <sys/user.h>
111 #include <sys/signalvar.h>
112 #include <sys/signalvar.h>
113 #ifndef NeXT
114 #include <sys/resourcevar.h>
115 #endif
116 #include <sys/malloc.h>
117 #if NSNP > 0
118 #include <sys/snoop.h>
119 #endif
120
121 #ifndef NeXT
122 #include <vm/vm.h>
123 #include <vm/vm_param.h>
124 #include <vm/vm_prot.h>
125 #include <vm/lock.h>
126 #include <vm/pmap.h>
127 #include <vm/vm_map.h>
128 #else
129 #include <dev/kmreg_com.h>
130 #include <machine/cons.h>
131 #include <machine/spl.h>
132 #if 0 /* [ */
133 #include <machdep/machine/pmap.h>
134 #endif /* 0 ] */
135 #endif /* !NeXT */
136 #include <sys/resource.h> /* averunnable */
137
138 #ifndef NeXT
139 static int proc_compare(struct proc *p1, struct proc *p2);
140 #endif /* NeXT */
141 static int ttnread(struct tty *tp);
142 static void ttyecho(int c, struct tty *tp);
143 static int ttyoutput(int c, register struct tty *tp);
144 static void ttypend(struct tty *tp);
145 static void ttyretype(struct tty *tp);
146 static void ttyrub(int c, struct tty *tp);
147 static void ttyrubo(struct tty *tp, int count);
148 static void ttystop(struct tty *tp, int rw);
149 static void ttyunblock(struct tty *tp);
150 static int ttywflush(struct tty *tp);
151 static int proc_compare(struct proc *p1, struct proc *p2);
152
153 /*
154 * Table with character classes and parity. The 8th bit indicates parity,
155 * the 7th bit indicates the character is an alphameric or underscore (for
156 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
157 * are 0 then the character needs no special processing on output; classes
158 * other than 0 might be translated or (not currently) require delays.
159 */
160 #define E 0x00 /* Even parity. */
161 #define O 0x80 /* Odd parity. */
162 #define PARITY(c) (char_type[c] & O)
163
164 #define ALPHA 0x40 /* Alpha or underscore. */
165 #define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
166
167 #define CCLASSMASK 0x3f
168 #define CCLASS(c) (char_type[c] & CCLASSMASK)
169
170 #define BS BACKSPACE
171 #define CC CONTROL
172 #define CR RETURN
173 #define NA ORDINARY | ALPHA
174 #define NL NEWLINE
175 #define NO ORDINARY
176 #define TB TAB
177 #define VT VTAB
178
179 static u_char const char_type[] = {
180 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
181 O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
182 O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
183 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
184 O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
185 E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
186 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
187 O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
188 O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
189 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
190 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
191 O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
192 E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
193 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
194 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
195 E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
196 /*
197 * Meta chars; should be settable per character set;
198 * for now, treat them all as normal characters.
199 */
200 NA, NA, NA, NA, NA, NA, NA, NA,
201 NA, NA, NA, NA, NA, NA, NA, NA,
202 NA, NA, NA, NA, NA, NA, NA, NA,
203 NA, NA, NA, NA, NA, NA, NA, NA,
204 NA, NA, NA, NA, NA, NA, NA, NA,
205 NA, NA, NA, NA, NA, NA, NA, NA,
206 NA, NA, NA, NA, NA, NA, NA, NA,
207 NA, NA, NA, NA, NA, NA, NA, NA,
208 NA, NA, NA, NA, NA, NA, NA, NA,
209 NA, NA, NA, NA, NA, NA, NA, NA,
210 NA, NA, NA, NA, NA, NA, NA, NA,
211 NA, NA, NA, NA, NA, NA, NA, NA,
212 NA, NA, NA, NA, NA, NA, NA, NA,
213 NA, NA, NA, NA, NA, NA, NA, NA,
214 NA, NA, NA, NA, NA, NA, NA, NA,
215 NA, NA, NA, NA, NA, NA, NA, NA,
216 };
217 #undef BS
218 #undef CC
219 #undef CR
220 #undef NA
221 #undef NL
222 #undef NO
223 #undef TB
224 #undef VT
225
226 /* Macros to clear/set/test flags. */
227 #define SET(t, f) (t) |= (f)
228 #define CLR(t, f) (t) &= ~(f)
229 #define ISSET(t, f) ((t) & (f))
230
231 /*
232 * Input control starts when we would not be able to fit the maximum
233 * contents of the ping-pong buffers and finishes when we would be able
234 * to fit that much plus 1/8 more.
235 */
236 #define I_HIGH_WATER (TTYHOG - 2 * 256) /* XXX */
237 #define I_LOW_WATER ((TTYHOG - 2 * 256) * 7 / 8) /* XXX */
238
239 #undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */
240 #define MAX_INPUT TTYHOG
241
242 static void
243 termios32to64(struct termios *in, struct user_termios *out)
244 {
245 out->c_iflag = (user_tcflag_t)in->c_iflag;
246 out->c_oflag = (user_tcflag_t)in->c_oflag;
247 out->c_cflag = (user_tcflag_t)in->c_cflag;
248 out->c_lflag = (user_tcflag_t)in->c_lflag;
249
250 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
251 bcopy(in->c_cc, out->c_cc, sizeof(in->c_cc));
252
253 out->c_ispeed = (user_speed_t)in->c_ispeed;
254 out->c_ospeed = (user_speed_t)in->c_ospeed;
255 }
256
257 static void
258 termios64to32(struct user_termios *in, struct termios *out)
259 {
260 out->c_iflag = (tcflag_t)in->c_iflag;
261 out->c_oflag = (tcflag_t)in->c_oflag;
262 out->c_cflag = (tcflag_t)in->c_cflag;
263 out->c_lflag = (tcflag_t)in->c_lflag;
264
265 /* bcopy is OK, since this type is ILP32/LP64 size invariant */
266 bcopy(in->c_cc, out->c_cc, sizeof(in->c_cc));
267
268 out->c_ispeed = (speed_t)in->c_ispeed;
269 out->c_ospeed = (speed_t)in->c_ospeed;
270 }
271
272
273 /*
274 * Initial open of tty, or (re)entry to standard tty line discipline.
275 */
276 int
277 ttyopen(device, tp)
278 dev_t device;
279 register struct tty *tp;
280 {
281 int s;
282 boolean_t funnel_state;
283
284 funnel_state = thread_funnel_set(kernel_flock, TRUE);
285 s = spltty();
286 tp->t_dev = device;
287 if (!ISSET(tp->t_state, TS_ISOPEN)) {
288 SET(tp->t_state, TS_ISOPEN);
289 if (ISSET(tp->t_cflag, CLOCAL)) {
290 SET(tp->t_state, TS_CONNECTED); }
291 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
292 }
293
294 #ifndef NeXT
295 /*
296 * Initialize or restore a cblock allocation policy suitable for
297 * the standard line discipline.
298 */
299 clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
300 clist_alloc_cblocks(&tp->t_outq, TTMAXHIWAT + OBUFSIZ + 100,
301 TTMAXHIWAT + OBUFSIZ + 100);
302 clist_alloc_cblocks(&tp->t_rawq, TTYHOG, TTYHOG);
303 #endif /* !NeXT */
304
305 splx(s);
306 thread_funnel_set(kernel_flock, funnel_state);
307 return (0);
308 }
309
310 /*
311 * Handle close() on a tty line: flush and set to initial state,
312 * bumping generation number so that pending read/write calls
313 * can detect recycling of the tty.
314 * XXX our caller should have done `spltty(); l_close(); ttyclose();'
315 * and l_close() should have flushed, but we repeat the spltty() and
316 * the flush in case there are buggy callers.
317 */
318 int
319 ttyclose(tp)
320 register struct tty *tp;
321 {
322 int s;
323
324 s = spltty();
325 if (constty == tp) {
326 constty = NULL;
327
328 splx(s);
329 spltty();
330
331 #ifdef NeXT
332 /*
333 * Closing current console tty; disable printing of console
334 * messages at bottom-level driver.
335 */
336 (*cdevsw[major(tp->t_dev)].d_ioctl)
337 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, current_proc());
338 #endif /* NeXT */
339 }
340
341 ttyflush(tp, FREAD | FWRITE);
342 #ifndef NeXT
343 clist_free_cblocks(&tp->t_canq);
344 clist_free_cblocks(&tp->t_outq);
345 clist_free_cblocks(&tp->t_rawq);
346 #endif
347
348 #if NSNP > 0
349 if (ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
350 snpdown((struct snoop *)tp->t_sc);
351 #endif
352
353 tp->t_gen++;
354 tp->t_line = TTYDISC;
355 tp->t_pgrp = NULL;
356 tp->t_session = NULL;
357 tp->t_state = 0;
358 #if NeXT
359 selthreadclear(&tp->t_wsel);
360 selthreadclear(&tp->t_rsel);
361 #endif
362 splx(s);
363 return (0);
364 }
365
366 #define FLUSHQ(q) { \
367 if ((q)->c_cc) \
368 ndflush(q, (q)->c_cc); \
369 }
370
371 /* Is 'c' a line delimiter ("break" character)? */
372 #define TTBREAKC(c, lflag) \
373 ((c) == '\n' || (((c) == cc[VEOF] || \
374 (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \
375 (c) != _POSIX_VDISABLE))
376
377 /*
378 * Process input of a single character received on a tty.
379 */
380 int
381 ttyinput(c, tp)
382 register int c;
383 register struct tty *tp;
384 {
385 register tcflag_t iflag, lflag;
386 register cc_t *cc;
387 int i, err, retval;
388 boolean_t funnel_state;
389
390 funnel_state = thread_funnel_set(kernel_flock, TRUE);
391
392 /*
393 * If input is pending take it first.
394 */
395 lflag = tp->t_lflag;
396 if (ISSET(lflag, PENDIN))
397 ttypend(tp);
398 /*
399 * Gather stats.
400 */
401 if (ISSET(lflag, ICANON)) {
402 ++tk_cancc;
403 ++tp->t_cancc;
404 } else {
405 ++tk_rawcc;
406 ++tp->t_rawcc;
407 }
408 ++tk_nin;
409
410 /*
411 * Block further input iff:
412 * current input > threshold AND input is available to user program
413 * AND input flow control is enabled and not yet invoked.
414 * The 3 is slop for PARMRK.
415 */
416 iflag = tp->t_iflag;
417 if (tp->t_rawq.c_cc + tp->t_canq.c_cc > I_HIGH_WATER - 3 &&
418 (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
419 (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
420 !ISSET(tp->t_state, TS_TBLOCK))
421 ttyblock(tp);
422
423 /* Handle exceptional conditions (break, parity, framing). */
424 cc = tp->t_cc;
425 err = (ISSET(c, TTY_ERRORMASK));
426 if (err) {
427 CLR(c, TTY_ERRORMASK);
428 if (ISSET(err, TTY_BI)) {
429 if (ISSET(iflag, IGNBRK)) {
430 thread_funnel_set(kernel_flock, funnel_state);
431 return (0);
432 }
433 if (ISSET(iflag, BRKINT)) {
434 ttyflush(tp, FREAD | FWRITE);
435 pgsignal(tp->t_pgrp, SIGINT, 1);
436 goto endcase;
437 }
438 if (ISSET(iflag, PARMRK))
439 goto parmrk;
440 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
441 || ISSET(err, TTY_FE)) {
442 if (ISSET(iflag, IGNPAR)) {
443 thread_funnel_set(kernel_flock, funnel_state);
444 return (0);
445 }
446 else if (ISSET(iflag, PARMRK)) {
447 parmrk:
448 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
449 MAX_INPUT - 3)
450 goto input_overflow;
451 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
452 (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
453 (void)putc(c | TTY_QUOTE, &tp->t_rawq);
454 goto endcase;
455 } else
456 c = 0;
457 }
458 }
459
460 if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
461 CLR(c, 0x80);
462 if (!ISSET(lflag, EXTPROC)) {
463 /*
464 * Check for literal nexting very first
465 */
466 if (ISSET(tp->t_state, TS_LNCH)) {
467 SET(c, TTY_QUOTE);
468 CLR(tp->t_state, TS_LNCH);
469 }
470 /*
471 * Scan for special characters. This code
472 * is really just a big case statement with
473 * non-constant cases. The bottom of the
474 * case statement is labeled ``endcase'', so goto
475 * it after a case match, or similar.
476 */
477
478 /*
479 * Control chars which aren't controlled
480 * by ICANON, ISIG, or IXON.
481 */
482 if (ISSET(lflag, IEXTEN)) {
483 if (CCEQ(cc[VLNEXT], c)) {
484 if (ISSET(lflag, ECHO)) {
485 if (ISSET(lflag, ECHOE)) {
486 (void)ttyoutput('^', tp);
487 (void)ttyoutput('\b', tp);
488 } else
489 ttyecho(c, tp);
490 }
491 SET(tp->t_state, TS_LNCH);
492 goto endcase;
493 }
494 if (CCEQ(cc[VDISCARD], c)) {
495 if (ISSET(lflag, FLUSHO))
496 CLR(tp->t_lflag, FLUSHO);
497 else {
498 ttyflush(tp, FWRITE);
499 ttyecho(c, tp);
500 if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
501 ttyretype(tp);
502 SET(tp->t_lflag, FLUSHO);
503 }
504 goto startoutput;
505 }
506 }
507 /*
508 * Signals.
509 */
510 if (ISSET(lflag, ISIG)) {
511 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
512 if (!ISSET(lflag, NOFLSH))
513 ttyflush(tp, FREAD | FWRITE);
514 ttyecho(c, tp);
515 pgsignal(tp->t_pgrp,
516 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
517 goto endcase;
518 }
519 if (CCEQ(cc[VSUSP], c)) {
520 if (!ISSET(lflag, NOFLSH))
521 ttyflush(tp, FREAD);
522 ttyecho(c, tp);
523 pgsignal(tp->t_pgrp, SIGTSTP, 1);
524 goto endcase;
525 }
526 }
527 /*
528 * Handle start/stop characters.
529 */
530 if (ISSET(iflag, IXON)) {
531 if (CCEQ(cc[VSTOP], c)) {
532 if (!ISSET(tp->t_state, TS_TTSTOP)) {
533 SET(tp->t_state, TS_TTSTOP);
534 ttystop(tp, 0);
535 thread_funnel_set(kernel_flock, funnel_state);
536 return (0);
537 }
538 if (!CCEQ(cc[VSTART], c)) {
539 thread_funnel_set(kernel_flock, funnel_state);
540 return (0);
541 }
542 /*
543 * if VSTART == VSTOP then toggle
544 */
545 goto endcase;
546 }
547 if (CCEQ(cc[VSTART], c))
548 goto restartoutput;
549 }
550 /*
551 * IGNCR, ICRNL, & INLCR
552 */
553 if (c == '\r') {
554 if (ISSET(iflag, IGNCR)) {
555 thread_funnel_set(kernel_flock, funnel_state);
556 return (0);
557 }
558 else if (ISSET(iflag, ICRNL))
559 c = '\n';
560 } else if (c == '\n' && ISSET(iflag, INLCR))
561 c = '\r';
562 }
563 if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
564 /*
565 * From here on down canonical mode character
566 * processing takes place.
567 */
568 /*
569 * erase (^H / ^?)
570 */
571 if (CCEQ(cc[VERASE], c)) {
572 if (tp->t_rawq.c_cc)
573 ttyrub(unputc(&tp->t_rawq), tp);
574 goto endcase;
575 }
576 /*
577 * kill (^U)
578 */
579 if (CCEQ(cc[VKILL], c)) {
580 if (ISSET(lflag, ECHOKE) &&
581 tp->t_rawq.c_cc == tp->t_rocount &&
582 !ISSET(lflag, ECHOPRT))
583 while (tp->t_rawq.c_cc)
584 ttyrub(unputc(&tp->t_rawq), tp);
585 else {
586 ttyecho(c, tp);
587 if (ISSET(lflag, ECHOK) ||
588 ISSET(lflag, ECHOKE))
589 ttyecho('\n', tp);
590 FLUSHQ(&tp->t_rawq);
591 tp->t_rocount = 0;
592 }
593 CLR(tp->t_state, TS_LOCAL);
594 goto endcase;
595 }
596 /*
597 * word erase (^W)
598 */
599 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
600 int ctype;
601
602 /*
603 * erase whitespace
604 */
605 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
606 ttyrub(c, tp);
607 if (c == -1)
608 goto endcase;
609 /*
610 * erase last char of word and remember the
611 * next chars type (for ALTWERASE)
612 */
613 ttyrub(c, tp);
614 c = unputc(&tp->t_rawq);
615 if (c == -1)
616 goto endcase;
617 if (c == ' ' || c == '\t') {
618 (void)putc(c, &tp->t_rawq);
619 goto endcase;
620 }
621 ctype = ISALPHA(c);
622 /*
623 * erase rest of word
624 */
625 do {
626 ttyrub(c, tp);
627 c = unputc(&tp->t_rawq);
628 if (c == -1)
629 goto endcase;
630 } while (c != ' ' && c != '\t' &&
631 (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
632 (void)putc(c, &tp->t_rawq);
633 goto endcase;
634 }
635 /*
636 * reprint line (^R)
637 */
638 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
639 ttyretype(tp);
640 goto endcase;
641 }
642 /*
643 * ^T - kernel info and generate SIGINFO
644 */
645 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
646 if (ISSET(lflag, ISIG))
647 pgsignal(tp->t_pgrp, SIGINFO, 1);
648 if (!ISSET(lflag, NOKERNINFO))
649 ttyinfo(tp);
650 goto endcase;
651 }
652 }
653 /*
654 * Check for input buffer overflow
655 */
656 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
657 input_overflow:
658 if (ISSET(iflag, IMAXBEL)) {
659 if (tp->t_outq.c_cc < tp->t_hiwat)
660 (void)ttyoutput(CTRL('g'), tp);
661 }
662 goto endcase;
663 }
664
665 if ( c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
666 && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
667 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
668
669 /*
670 * Put data char in q for user and
671 * wakeup on seeing a line delimiter.
672 */
673 if (putc(c, &tp->t_rawq) >= 0) {
674 if (!ISSET(lflag, ICANON)) {
675 ttwakeup(tp);
676 ttyecho(c, tp);
677 goto endcase;
678 }
679 if (TTBREAKC(c, lflag)) {
680 tp->t_rocount = 0;
681 catq(&tp->t_rawq, &tp->t_canq);
682 ttwakeup(tp);
683 } else if (tp->t_rocount++ == 0)
684 tp->t_rocol = tp->t_column;
685 if (ISSET(tp->t_state, TS_ERASE)) {
686 /*
687 * end of prterase \.../
688 */
689 CLR(tp->t_state, TS_ERASE);
690 (void)ttyoutput('/', tp);
691 }
692 i = tp->t_column;
693 ttyecho(c, tp);
694 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
695 /*
696 * Place the cursor over the '^' of the ^D.
697 */
698 i = min(2, tp->t_column - i);
699 while (i > 0) {
700 (void)ttyoutput('\b', tp);
701 i--;
702 }
703 }
704 }
705 endcase:
706 /*
707 * IXANY means allow any character to restart output.
708 */
709 if (ISSET(tp->t_state, TS_TTSTOP) &&
710 !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) {
711 thread_funnel_set(kernel_flock, funnel_state);
712 return (0);
713 }
714 restartoutput:
715 CLR(tp->t_lflag, FLUSHO);
716 CLR(tp->t_state, TS_TTSTOP);
717 startoutput:
718 retval = ttstart(tp);
719 thread_funnel_set(kernel_flock, funnel_state);
720 return (retval);
721 }
722
723 /*
724 * Output a single character on a tty, doing output processing
725 * as needed (expanding tabs, newline processing, etc.).
726 * Returns < 0 if succeeds, otherwise returns char to resend.
727 * Must be recursive.
728 */
729 static int
730 ttyoutput(c, tp)
731 register int c;
732 register struct tty *tp;
733 {
734 register tcflag_t oflag;
735 register int col, s;
736
737 oflag = tp->t_oflag;
738 if (!ISSET(oflag, OPOST)) {
739 if (ISSET(tp->t_lflag, FLUSHO))
740 return (-1);
741 if (putc(c, &tp->t_outq))
742 return (c);
743 tk_nout++;
744 tp->t_outcc++;
745 return (-1);
746 }
747 /*
748 * Do tab expansion if OXTABS is set. Special case if we external
749 * processing, we don't do the tab expansion because we'll probably
750 * get it wrong. If tab expansion needs to be done, let it happen
751 * externally.
752 */
753 CLR(c, ~TTY_CHARMASK);
754 if (c == '\t' &&
755 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
756 c = 8 - (tp->t_column & 7);
757 if (!ISSET(tp->t_lflag, FLUSHO)) {
758 s = spltty(); /* Don't interrupt tabs. */
759 c -= b_to_q(" ", c, &tp->t_outq);
760 tk_nout += c;
761 tp->t_outcc += c;
762 splx(s);
763 }
764 tp->t_column += c;
765 return (c ? -1 : '\t');
766 }
767 if (c == CEOT && ISSET(oflag, ONOEOT))
768 return (-1);
769
770 /*
771 * Newline translation: if ONLCR is set,
772 * translate newline into "\r\n".
773 */
774 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
775 tk_nout++;
776 tp->t_outcc++;
777 if (putc('\r', &tp->t_outq))
778 return (c);
779 }
780 tk_nout++;
781 tp->t_outcc++;
782 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
783 return (c);
784
785 col = tp->t_column;
786 switch (CCLASS(c)) {
787 case BACKSPACE:
788 if (col > 0)
789 --col;
790 break;
791 case CONTROL:
792 break;
793 case NEWLINE:
794 case RETURN:
795 col = 0;
796 break;
797 case ORDINARY:
798 ++col;
799 break;
800 case TAB:
801 col = (col + 8) & ~7;
802 break;
803 }
804 tp->t_column = col;
805 return (-1);
806 }
807
808 /*
809 * Ioctls for all tty devices. Called after line-discipline specific ioctl
810 * has been called to do discipline-specific functions and/or reject any
811 * of these ioctl commands.
812 */
813 /* ARGSUSED */
814 int
815 ttioctl(register struct tty *tp,
816 u_long cmd, caddr_t data, int flag,
817 struct proc *p)
818 {
819 int s, error;
820 struct uthread *ut;
821
822 ut = (struct uthread *)get_bsdthread_info(current_thread());
823 /* If the ioctl involves modification, hang if in the background. */
824 switch (cmd) {
825 case TIOCFLUSH:
826 case TIOCSETA:
827 case TIOCSETA_64:
828 case TIOCSETD:
829 case TIOCSETAF:
830 case TIOCSETAF_64:
831 case TIOCSETAW:
832 case TIOCSETAW_64:
833 #ifdef notdef
834 case TIOCSPGRP:
835 #endif
836 case TIOCSTAT:
837 case TIOCSTI:
838 case TIOCSWINSZ:
839 #if COMPAT_43_TTY || defined(COMPAT_SUNOS)
840 case TIOCLBIC:
841 case TIOCLBIS:
842 case TIOCLSET:
843 case TIOCSETC:
844 case OTIOCSETD:
845 case TIOCSETN:
846 case TIOCSETP:
847 case TIOCSLTC:
848 #endif
849 while (isbackground(p, tp) &&
850 (p->p_flag & P_PPWAIT) == 0 &&
851 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
852 (ut->uu_sigmask & sigmask(SIGTTOU)) == 0) {
853 if (p->p_pgrp->pg_jobc == 0)
854 return (EIO);
855 pgsignal(p->p_pgrp, SIGTTOU, 1);
856 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH | PTTYBLOCK, "ttybg1",
857 0);
858 if (error)
859 return (error);
860 }
861 break;
862 }
863
864 switch (cmd) { /* Process the ioctl. */
865 case FIOASYNC: /* set/clear async i/o */
866 s = spltty();
867 if (*(int *)data)
868 SET(tp->t_state, TS_ASYNC);
869 else
870 CLR(tp->t_state, TS_ASYNC);
871 splx(s);
872 break;
873 case FIONBIO: /* set/clear non-blocking i/o */
874 break; /* XXX: delete. */
875 case FIONREAD: /* get # bytes to read */
876 s = spltty();
877 *(int *)data = ttnread(tp);
878 splx(s);
879 break;
880 case TIOCEXCL: /* set exclusive use of tty */
881 s = spltty();
882 SET(tp->t_state, TS_XCLUDE);
883 splx(s);
884 break;
885 case TIOCFLUSH: { /* flush buffers */
886 register int flags = *(int *)data;
887
888 if (flags == 0)
889 flags = FREAD | FWRITE;
890 else
891 flags &= FREAD | FWRITE;
892 ttyflush(tp, flags);
893 break;
894 }
895 #ifdef NeXT
896 case TIOCSCONS: {
897 /* Set current console device to this line */
898 int bogusData = 1;
899 data = (caddr_t) &bogusData;
900
901 /* No break - Fall through to BSD code */
902 }
903 #endif /* NeXT */
904 case TIOCCONS: { /* become virtual console */
905 if (*(int *)data) {
906 if (constty && constty != tp &&
907 ISSET(constty->t_state, TS_CONNECTED)) {
908 return (EBUSY);
909 }
910 #if defined(NeXT) || !defined(UCONSOLE)
911 if ( (error = suser(kauth_cred_get(), &p->p_acflag)) )
912 return (error);
913 #endif
914 constty = tp;
915 } else if (tp == constty) {
916 constty = NULL;
917 }
918 #ifdef NeXT
919 if (constty) {
920 (*cdevsw[major(cons.t_dev)].d_ioctl)
921 (cons.t_dev, KMIOCDISABLCONS, NULL, 0, p);
922 } else {
923 (*cdevsw[major(tp->t_dev)].d_ioctl)
924 (tp->t_dev, KMIOCDISABLCONS, NULL, 0, p);
925 }
926 #endif /* NeXT */
927 break;
928 }
929 case TIOCDRAIN: /* wait till output drained */
930 error = ttywait(tp);
931 if (error)
932 return (error);
933 break;
934 case TIOCGETA: /* get termios struct */
935 case TIOCGETA_64: { /* get termios struct */
936 if (IS_64BIT_PROCESS(p)) {
937 termios32to64(&tp->t_termios, (struct user_termios *)data);
938 } else {
939 bcopy(&tp->t_termios, data, sizeof(struct termios));
940 }
941 break;
942 }
943 case TIOCGETD: /* get line discipline */
944 *(int *)data = tp->t_line;
945 break;
946 case TIOCGWINSZ: /* get window size */
947 *(struct winsize *)data = tp->t_winsize;
948 break;
949 case TIOCGPGRP: /* get pgrp of tty */
950 if (!isctty(p, tp))
951 return (ENOTTY);
952 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
953 break;
954 #ifdef TIOCHPCL
955 case TIOCHPCL: /* hang up on last close */
956 s = spltty();
957 SET(tp->t_cflag, HUPCL);
958 splx(s);
959 break;
960 #endif
961 case TIOCNXCL: /* reset exclusive use of tty */
962 s = spltty();
963 CLR(tp->t_state, TS_XCLUDE);
964 splx(s);
965 break;
966 case TIOCOUTQ: /* output queue size */
967 *(int *)data = tp->t_outq.c_cc;
968 break;
969 case TIOCSETA: /* set termios struct */
970 case TIOCSETA_64:
971 case TIOCSETAW: /* drain output, set */
972 case TIOCSETAW_64:
973 case TIOCSETAF: /* drn out, fls in, set */
974 case TIOCSETAF_64: { /* drn out, fls in, set */
975 register struct termios *t = (struct termios *)data;
976 struct termios lcl_termios;
977
978 if (IS_64BIT_PROCESS(p)) {
979 termios64to32((struct user_termios *)data, &lcl_termios);
980 t = &lcl_termios;
981 }
982 if (t->c_ispeed < 0 || t->c_ospeed < 0)
983 return (EINVAL);
984 s = spltty();
985 if (cmd == TIOCSETAW || cmd == TIOCSETAF ||
986 cmd == TIOCSETAW_64 || cmd == TIOCSETAF_64) {
987 error = ttywait(tp);
988 if (error) {
989 splx(s);
990 return (error);
991 }
992 if (cmd == TIOCSETAF || cmd == TIOCSETAF_64)
993 ttyflush(tp, FREAD);
994 }
995 if (!ISSET(t->c_cflag, CIGNORE)) {
996 /*
997 * Set device hardware.
998 */
999 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1000 splx(s);
1001 return (error);
1002 }
1003 if (ISSET(t->c_cflag, CLOCAL) &&
1004 !ISSET(tp->t_cflag, CLOCAL)) {
1005 /*
1006 * XXX disconnections would be too hard to
1007 * get rid of without this kludge. The only
1008 * way to get rid of controlling terminals
1009 * is to exit from the session leader.
1010 */
1011 CLR(tp->t_state, TS_ZOMBIE);
1012
1013 wakeup(TSA_CARR_ON(tp));
1014 ttwakeup(tp);
1015 ttwwakeup(tp);
1016 }
1017 if ((ISSET(tp->t_state, TS_CARR_ON) ||
1018 ISSET(t->c_cflag, CLOCAL)) &&
1019 !ISSET(tp->t_state, TS_ZOMBIE))
1020 SET(tp->t_state, TS_CONNECTED);
1021 else
1022 CLR(tp->t_state, TS_CONNECTED);
1023 tp->t_cflag = t->c_cflag;
1024 tp->t_ispeed = t->c_ispeed;
1025 tp->t_ospeed = t->c_ospeed;
1026 ttsetwater(tp);
1027 }
1028 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
1029 cmd != TIOCSETAF && cmd != TIOCSETAF_64) {
1030 if (ISSET(t->c_lflag, ICANON))
1031 SET(tp->t_lflag, PENDIN);
1032 else {
1033 /*
1034 * XXX we really shouldn't allow toggling
1035 * ICANON while we're in a non-termios line
1036 * discipline. Now we have to worry about
1037 * panicing for a null queue.
1038 */
1039 #ifndef NeXT
1040 if (tp->t_canq.c_cbreserved > 0 &&
1041 tp->t_rawq.c_cbreserved > 0) {
1042 catq(&tp->t_rawq, &tp->t_canq);
1043 /*
1044 * XXX the queue limits may be
1045 * different, so the old queue
1046 * swapping method no longer works.
1047 */
1048 catq(&tp->t_canq, &tp->t_rawq);
1049 }
1050 #else
1051 if (tp->t_rawq.c_cs && tp->t_canq.c_cs) {
1052 struct clist tq;
1053
1054 catq(&tp->t_rawq, &tp->t_canq);
1055 tq = tp->t_rawq;
1056 tp->t_rawq = tp->t_canq;
1057 tp->t_canq = tq;
1058 }
1059 #endif /* !NeXT */
1060 CLR(tp->t_lflag, PENDIN);
1061 }
1062 ttwakeup(tp);
1063 }
1064 tp->t_iflag = t->c_iflag;
1065 tp->t_oflag = t->c_oflag;
1066 /*
1067 * Make the EXTPROC bit read only.
1068 */
1069 if (ISSET(tp->t_lflag, EXTPROC))
1070 SET(t->c_lflag, EXTPROC);
1071 else
1072 CLR(t->c_lflag, EXTPROC);
1073 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1074 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1075 t->c_cc[VTIME] != tp->t_cc[VTIME])
1076 ttwakeup(tp);
1077 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1078 splx(s);
1079 break;
1080 }
1081 case TIOCSETD: { /* set line discipline */
1082 register int t = *(int *)data;
1083 dev_t device = tp->t_dev;
1084
1085 if (t >= nlinesw)
1086 return (ENXIO);
1087 if (t != tp->t_line) {
1088 s = spltty();
1089 (*linesw[tp->t_line].l_close)(tp, flag);
1090 error = (*linesw[t].l_open)(device, tp);
1091 if (error) {
1092 (void)(*linesw[tp->t_line].l_open)(device, tp);
1093 splx(s);
1094 return (error);
1095 }
1096 tp->t_line = t;
1097 splx(s);
1098 }
1099 break;
1100 }
1101 case TIOCSTART: /* start output, like ^Q */
1102 s = spltty();
1103 if (ISSET(tp->t_state, TS_TTSTOP) ||
1104 ISSET(tp->t_lflag, FLUSHO)) {
1105 CLR(tp->t_lflag, FLUSHO);
1106 CLR(tp->t_state, TS_TTSTOP);
1107 ttstart(tp);
1108 }
1109 splx(s);
1110 break;
1111 case TIOCSTI: /* simulate terminal input */
1112 if (suser(kauth_cred_get(), NULL) && (flag & FREAD) == 0)
1113 return (EPERM);
1114 if (suser(kauth_cred_get(), NULL) && !isctty(p, tp))
1115 return (EACCES);
1116 s = spltty();
1117 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1118 splx(s);
1119 break;
1120 case TIOCSTOP: /* stop output, like ^S */
1121 s = spltty();
1122 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1123 SET(tp->t_state, TS_TTSTOP);
1124 ttystop(tp, 0);
1125 }
1126 splx(s);
1127 break;
1128 case TIOCSCTTY: /* become controlling tty */
1129 /* Session ctty vnode pointer set in vnode layer. */
1130 if (!SESS_LEADER(p) ||
1131 ((p->p_session->s_ttyvp || tp->t_session) &&
1132 (tp->t_session != p->p_session)))
1133 return (EPERM);
1134 tp->t_session = p->p_session;
1135 tp->t_pgrp = p->p_pgrp;
1136 p->p_session->s_ttyp = tp;
1137 p->p_flag |= P_CONTROLT;
1138 /* The backgrounded process blocking on tty now
1139 * could be foregound process. Wake such processes
1140 */
1141 tty_pgsignal(tp->t_pgrp, SIGCONT);
1142 break;
1143 case TIOCSPGRP: { /* set pgrp of tty */
1144 register struct pgrp *pgrp = pgfind(*(int *)data);
1145
1146 if (!isctty(p, tp))
1147 return (ENOTTY);
1148 else if (pgrp == NULL || pgrp->pg_session != p->p_session)
1149 return (EPERM);
1150 tp->t_pgrp = pgrp;
1151 /* The backgrounded process blocking on tty now
1152 * could be foregound process. Wake such processes
1153 */
1154 tty_pgsignal(tp->t_pgrp, SIGCONT);
1155 break;
1156 }
1157 case TIOCSTAT: /* simulate control-T */
1158 s = spltty();
1159 ttyinfo(tp);
1160 splx(s);
1161 break;
1162 case TIOCSWINSZ: /* set window size */
1163 if (bcmp((caddr_t)&tp->t_winsize, data,
1164 sizeof (struct winsize))) {
1165 tp->t_winsize = *(struct winsize *)data;
1166 pgsignal(tp->t_pgrp, SIGWINCH, 1);
1167 }
1168 break;
1169 case TIOCSDRAINWAIT:
1170 error = suser(kauth_cred_get(), &p->p_acflag);
1171 if (error)
1172 return (error);
1173 tp->t_timeout = *(int *)data * hz;
1174 wakeup(TSA_OCOMPLETE(tp));
1175 wakeup(TSA_OLOWAT(tp));
1176 break;
1177 case TIOCGDRAINWAIT:
1178 *(int *)data = tp->t_timeout / hz;
1179 break;
1180 default:
1181 #if COMPAT_43_TTY || defined(COMPAT_SUNOS)
1182 #ifdef NeXT
1183 return (ttcompat(tp, cmd, data, flag, p));
1184 #else
1185 return (ttcompat(tp, cmd, data, flag));
1186 #endif /* NeXT */
1187 #else
1188 return (ENOTTY);
1189 #endif
1190 }
1191
1192 return (0);
1193 }
1194
1195 int
1196 ttyselect(tp, rw, wql, p)
1197 struct tty *tp;
1198 int rw;
1199 void * wql;
1200 struct proc *p;
1201 {
1202 int s;
1203
1204 if (tp == NULL)
1205 return (ENXIO);
1206
1207 s = spltty();
1208 switch (rw) {
1209 case FREAD:
1210 if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
1211 goto win;
1212 selrecord(p, &tp->t_rsel, wql);
1213 break;
1214 case FWRITE:
1215 if ((tp->t_outq.c_cc <= tp->t_lowat &&
1216 ISSET(tp->t_state, TS_CONNECTED))
1217 || ISSET(tp->t_state, TS_ZOMBIE)) {
1218 win: splx(s);
1219 return (1);
1220 }
1221 selrecord(p, &tp->t_wsel, wql);
1222 break;
1223 }
1224 splx(s);
1225 return (0);
1226 }
1227
1228 /*
1229 * This is a wrapper for compatibility with the select vector used by
1230 * cdevsw. It relies on a proper xxxdevtotty routine.
1231 */
1232 int
1233 ttselect(dev, rw, wql, p)
1234 dev_t dev;
1235 int rw;
1236 void * wql;
1237 struct proc *p;
1238 {
1239 #ifndef NeXT
1240 return ttyselect((*cdevsw[major(dev)]->d_devtotty)(dev), rw, wql, p);
1241 #else
1242 return ttyselect(cdevsw[major(dev)].d_ttys[minor(dev)], rw, wql, p);
1243 #endif
1244 }
1245
1246 /*
1247 * Must be called at spltty().
1248 */
1249 static int
1250 ttnread(tp)
1251 struct tty *tp;
1252 {
1253 int nread;
1254
1255 if (ISSET(tp->t_lflag, PENDIN))
1256 ttypend(tp);
1257 nread = tp->t_canq.c_cc;
1258 if (!ISSET(tp->t_lflag, ICANON)) {
1259 nread += tp->t_rawq.c_cc;
1260 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1261 nread = 0;
1262 }
1263 return (nread);
1264 }
1265
1266 /*
1267 * Wait for output to drain.
1268 */
1269 int
1270 ttywait(tp)
1271 register struct tty *tp;
1272 {
1273 int error, s;
1274
1275 error = 0;
1276 s = spltty();
1277 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1278 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1279 (*tp->t_oproc)(tp);
1280 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1281 ISSET(tp->t_state, TS_CONNECTED)) {
1282 SET(tp->t_state, TS_SO_OCOMPLETE);
1283 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1284 TTOPRI | PCATCH, "ttywai",
1285 tp->t_timeout);
1286 if (error) {
1287 if (error == EWOULDBLOCK)
1288 error = EIO;
1289 break;
1290 }
1291 } else
1292 break;
1293 }
1294 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1295 error = EIO;
1296 splx(s);
1297 return (error);
1298 }
1299
1300 static void
1301 ttystop(tp, rw)
1302 struct tty *tp;
1303 int rw;
1304 {
1305 #ifdef sun4c /* XXX */
1306 (*tp->t_stop)(tp, rw);
1307 #elif defined(NeXT)
1308 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1309 #else
1310 (*cdevsw[major(tp->t_dev)]->d_stop)(tp, rw);
1311 #endif
1312 }
1313
1314 /*
1315 * Flush if successfully wait.
1316 */
1317 static int
1318 ttywflush(tp)
1319 struct tty *tp;
1320 {
1321 int error;
1322
1323 if ((error = ttywait(tp)) == 0)
1324 ttyflush(tp, FREAD);
1325 return (error);
1326 }
1327
1328 /*
1329 * Flush tty read and/or write queues, notifying anyone waiting.
1330 */
1331 void
1332 ttyflush(tp, rw)
1333 register struct tty *tp;
1334 int rw;
1335 {
1336 register int s;
1337
1338 s = spltty();
1339 #if 0
1340 again:
1341 #endif
1342 if (rw & FWRITE) {
1343 FLUSHQ(&tp->t_outq);
1344 CLR(tp->t_state, TS_TTSTOP);
1345 }
1346 ttystop(tp, rw);
1347 if (rw & FREAD) {
1348 FLUSHQ(&tp->t_canq);
1349 FLUSHQ(&tp->t_rawq);
1350 CLR(tp->t_lflag, PENDIN);
1351 tp->t_rocount = 0;
1352 tp->t_rocol = 0;
1353 CLR(tp->t_state, TS_LOCAL);
1354 ttwakeup(tp);
1355 if (ISSET(tp->t_state, TS_TBLOCK)) {
1356 if (rw & FWRITE)
1357 FLUSHQ(&tp->t_outq);
1358 ttyunblock(tp);
1359
1360 /*
1361 * Don't let leave any state that might clobber the
1362 * next line discipline (although we should do more
1363 * to send the START char). Not clearing the state
1364 * may have caused the "putc to a clist with no
1365 * reserved cblocks" panic/printf.
1366 */
1367 CLR(tp->t_state, TS_TBLOCK);
1368
1369 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1370 if (ISSET(tp->t_iflag, IXOFF)) {
1371 /*
1372 * XXX wait a bit in the hope that the stop
1373 * character (if any) will go out. Waiting
1374 * isn't good since it allows races. This
1375 * will be fixed when the stop character is
1376 * put in a special queue. Don't bother with
1377 * the checks in ttywait() since the timeout
1378 * will save us.
1379 */
1380 SET(tp->t_state, TS_SO_OCOMPLETE);
1381 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1382 "ttyfls", hz / 10);
1383 /*
1384 * Don't try sending the stop character again.
1385 */
1386 CLR(tp->t_state, TS_TBLOCK);
1387 goto again;
1388 }
1389 #endif
1390 }
1391 }
1392 if (rw & FWRITE) {
1393 FLUSHQ(&tp->t_outq);
1394 ttwwakeup(tp);
1395 }
1396 splx(s);
1397 }
1398
1399 /*
1400 * Copy in the default termios characters.
1401 */
1402 void
1403 termioschars(t)
1404 struct termios *t;
1405 {
1406
1407 bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1408 }
1409
1410 /*
1411 * Old interface.
1412 */
1413 void
1414 ttychars(tp)
1415 struct tty *tp;
1416 {
1417
1418 termioschars(&tp->t_termios);
1419 }
1420
1421 /*
1422 * Handle input high water. Send stop character for the IXOFF case. Turn
1423 * on our input flow control bit and propagate the changes to the driver.
1424 * XXX the stop character should be put in a special high priority queue.
1425 */
1426 void
1427 ttyblock(tp)
1428 struct tty *tp;
1429 {
1430
1431 SET(tp->t_state, TS_TBLOCK);
1432 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1433 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1434 CLR(tp->t_state, TS_TBLOCK); /* try again later */
1435 ttstart(tp);
1436 }
1437
1438 /*
1439 * Handle input low water. Send start character for the IXOFF case. Turn
1440 * off our input flow control bit and propagate the changes to the driver.
1441 * XXX the start character should be put in a special high priority queue.
1442 */
1443 static void
1444 ttyunblock(tp)
1445 struct tty *tp;
1446 {
1447
1448 CLR(tp->t_state, TS_TBLOCK);
1449 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1450 putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1451 SET(tp->t_state, TS_TBLOCK); /* try again later */
1452 ttstart(tp);
1453 }
1454
1455 #if defined(NeXT) || defined(notyet)
1456 /* FreeBSD: Not used by any current (i386) drivers. */
1457 /*
1458 * Restart after an inter-char delay.
1459 */
1460 void
1461 ttrstrt(tp_arg)
1462 void *tp_arg;
1463 {
1464 struct tty *tp;
1465 int s;
1466
1467 #if DIAGNOSTIC
1468 if (tp_arg == NULL)
1469 panic("ttrstrt");
1470 #endif
1471 tp = tp_arg;
1472 s = spltty();
1473
1474 CLR(tp->t_state, TS_TIMEOUT);
1475 ttstart(tp);
1476
1477 splx(s);
1478 }
1479 #endif /* NeXT || notyet */
1480
1481 int
1482 ttstart(tp)
1483 struct tty *tp;
1484 {
1485 boolean_t funnel_state;
1486
1487 funnel_state = thread_funnel_set(kernel_flock, TRUE);
1488
1489 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1490 (*tp->t_oproc)(tp);
1491 thread_funnel_set(kernel_flock, funnel_state);
1492 return (0);
1493 }
1494
1495 /*
1496 * "close" a line discipline
1497 */
1498 int
1499 ttylclose(tp, flag)
1500 struct tty *tp;
1501 int flag;
1502 {
1503 boolean_t funnel_state;
1504
1505 funnel_state = thread_funnel_set(kernel_flock, TRUE);
1506 if ( (flag & FNONBLOCK) || ttywflush(tp))
1507 ttyflush(tp, FREAD | FWRITE);
1508 thread_funnel_set(kernel_flock, funnel_state);
1509 return (0);
1510 }
1511
1512 /*
1513 * Handle modem control transition on a tty.
1514 * Flag indicates new state of carrier.
1515 * Returns 0 if the line should be turned off, otherwise 1.
1516 */
1517 int
1518 ttymodem(tp, flag)
1519 register struct tty *tp;
1520 int flag;
1521 {
1522 boolean_t funnel_state;
1523
1524 funnel_state = thread_funnel_set(kernel_flock, TRUE);
1525
1526 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1527 /*
1528 * MDMBUF: do flow control according to carrier flag
1529 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP
1530 * works if IXON and IXANY are clear.
1531 */
1532 if (flag) {
1533 CLR(tp->t_state, TS_CAR_OFLOW);
1534 CLR(tp->t_state, TS_TTSTOP);
1535 ttstart(tp);
1536 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1537 SET(tp->t_state, TS_CAR_OFLOW);
1538 SET(tp->t_state, TS_TTSTOP);
1539 ttystop(tp, 0);
1540 }
1541 } else if (flag == 0) {
1542 /*
1543 * Lost carrier.
1544 */
1545 CLR(tp->t_state, TS_CARR_ON);
1546 if (ISSET(tp->t_state, TS_ISOPEN) &&
1547 !ISSET(tp->t_cflag, CLOCAL)) {
1548 SET(tp->t_state, TS_ZOMBIE);
1549 CLR(tp->t_state, TS_CONNECTED);
1550 if (tp->t_session && tp->t_session->s_leader)
1551 psignal(tp->t_session->s_leader, SIGHUP);
1552 ttyflush(tp, FREAD | FWRITE);
1553 thread_funnel_set(kernel_flock, funnel_state);
1554 return (0);
1555 }
1556 } else {
1557 /*
1558 * Carrier now on.
1559 */
1560 SET(tp->t_state, TS_CARR_ON);
1561 if (!ISSET(tp->t_state, TS_ZOMBIE))
1562 SET(tp->t_state, TS_CONNECTED);
1563 wakeup(TSA_CARR_ON(tp));
1564 ttwakeup(tp);
1565 ttwwakeup(tp);
1566 }
1567 thread_funnel_set(kernel_flock, funnel_state);
1568 return (1);
1569 }
1570
1571 /*
1572 * Reinput pending characters after state switch
1573 * call at spltty().
1574 */
1575 static void
1576 ttypend(tp)
1577 register struct tty *tp;
1578 {
1579 struct clist tq;
1580 register int c;
1581
1582 CLR(tp->t_lflag, PENDIN);
1583 SET(tp->t_state, TS_TYPEN);
1584 #ifndef NeXT
1585 /*
1586 * XXX this assumes too much about clist internals. It may even
1587 * fail if the cblock slush pool is empty. We can't allocate more
1588 * cblocks here because we are called from an interrupt handler
1589 * and clist_alloc_cblocks() can wait.
1590 */
1591 tq = tp->t_rawq;
1592 bzero(&tp->t_rawq, sizeof tp->t_rawq);
1593 tp->t_rawq.c_cbmax = tq.c_cbmax;
1594 tp->t_rawq.c_cbreserved = tq.c_cbreserved;
1595 #else
1596 tq = tp->t_rawq;
1597 tp->t_rawq.c_cc = 0;
1598 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
1599 #endif /* !NeXT */
1600 while ((c = getc(&tq)) >= 0)
1601 ttyinput(c, tp);
1602 CLR(tp->t_state, TS_TYPEN);
1603 }
1604
1605 /*
1606 * Process a read call on a tty device.
1607 */
1608 int
1609 ttread(tp, uio, flag)
1610 register struct tty *tp;
1611 struct uio *uio;
1612 int flag;
1613 {
1614 register struct clist *qp;
1615 register int c;
1616 register tcflag_t lflag;
1617 register cc_t *cc = tp->t_cc;
1618 register struct proc *p = current_proc();
1619 int s, first, error = 0;
1620 int has_etime = 0, last_cc = 0;
1621 long slp = 0; /* XXX this should be renamed `timo'. */
1622 boolean_t funnel_state;
1623 struct uthread *ut;
1624
1625 funnel_state = thread_funnel_set(kernel_flock, TRUE);
1626
1627 ut = (struct uthread *)get_bsdthread_info(current_thread());
1628
1629 loop:
1630 s = spltty();
1631 lflag = tp->t_lflag;
1632 /*
1633 * take pending input first
1634 */
1635 if (ISSET(lflag, PENDIN)) {
1636 ttypend(tp);
1637 splx(s); /* reduce latency */
1638 s = spltty();
1639 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
1640 }
1641
1642 /*
1643 * Hang process if it's in the background.
1644 */
1645 if (isbackground(p, tp)) {
1646 splx(s);
1647 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
1648 (ut->uu_sigmask & sigmask(SIGTTIN)) ||
1649 p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0) {
1650 thread_funnel_set(kernel_flock, funnel_state);
1651 return (EIO);
1652 }
1653 pgsignal(p->p_pgrp, SIGTTIN, 1);
1654 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH | PTTYBLOCK, "ttybg2", 0);
1655 if (error){
1656 thread_funnel_set(kernel_flock, funnel_state);
1657 return (error);
1658 }
1659 goto loop;
1660 }
1661
1662 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1663 splx(s);
1664 thread_funnel_set(kernel_flock, funnel_state);
1665 return (0); /* EOF */
1666 }
1667
1668 /*
1669 * If canonical, use the canonical queue,
1670 * else use the raw queue.
1671 *
1672 * (should get rid of clists...)
1673 */
1674 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1675
1676 if (flag & IO_NDELAY) {
1677 if (qp->c_cc > 0)
1678 goto read;
1679 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1680 splx(s);
1681 thread_funnel_set(kernel_flock, funnel_state);
1682 return (0);
1683 }
1684 splx(s);
1685 thread_funnel_set(kernel_flock, funnel_state);
1686 return (EWOULDBLOCK);
1687 }
1688 if (!ISSET(lflag, ICANON)) {
1689 int m = cc[VMIN];
1690 long t = cc[VTIME];
1691 struct timeval etime, timecopy;
1692
1693 /*
1694 * Check each of the four combinations.
1695 * (m > 0 && t == 0) is the normal read case.
1696 * It should be fairly efficient, so we check that and its
1697 * companion case (m == 0 && t == 0) first.
1698 * For the other two cases, we compute the target sleep time
1699 * into slp.
1700 */
1701 if (t == 0) {
1702 if (qp->c_cc < m)
1703 goto sleep;
1704 if (qp->c_cc > 0)
1705 goto read;
1706
1707 /* m, t and qp->c_cc are all 0. 0 is enough input. */
1708 splx(s);
1709 thread_funnel_set(kernel_flock, funnel_state);
1710 return (0);
1711 }
1712 t *= 100000; /* time in us */
1713 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1714 ((t1).tv_usec - (t2).tv_usec))
1715 if (m > 0) {
1716 if (qp->c_cc <= 0)
1717 goto sleep;
1718 if (qp->c_cc >= m)
1719 goto read;
1720 microuptime(&timecopy);
1721 if (!has_etime) {
1722 /* first character, start timer */
1723 has_etime = 1;
1724
1725 etime.tv_sec = t / 1000000;
1726 etime.tv_usec = (t - (etime.tv_sec * 1000000));
1727 timeradd(&etime, &timecopy, &etime);
1728
1729 slp = t;
1730 } else if (qp->c_cc > last_cc) {
1731 /* got a character, restart timer */
1732
1733 etime.tv_sec = t / 1000000;
1734 etime.tv_usec = (t - (etime.tv_sec * 1000000));
1735 timeradd(&etime, &timecopy, &etime);
1736
1737 slp = t;
1738 } else {
1739 /* nothing, check expiration */
1740 if (timercmp(&etime, &timecopy, <=))
1741 goto read;
1742
1743 slp = diff(etime, timecopy);
1744 }
1745 last_cc = qp->c_cc;
1746 } else { /* m == 0 */
1747 if (qp->c_cc > 0)
1748 goto read;
1749 microuptime(&timecopy);
1750 if (!has_etime) {
1751 has_etime = 1;
1752
1753 etime.tv_sec = t / 1000000;
1754 etime.tv_usec = (t - (etime.tv_sec * 1000000));
1755 timeradd(&etime, &timecopy, &etime);
1756
1757 slp = t;
1758 } else {
1759 if (timercmp(&etime, &timecopy, <=)) {
1760 /* Timed out, but 0 is enough input. */
1761 splx(s);
1762 thread_funnel_set(kernel_flock, funnel_state);
1763 return (0);
1764 }
1765 slp = diff(etime, timecopy);
1766 }
1767 }
1768 #undef diff
1769 /*
1770 * Rounding down may make us wake up just short
1771 * of the target, so we round up.
1772 * The formula is ceiling(slp * hz/1000000).
1773 * 32-bit arithmetic is enough for hz < 169.
1774 * XXX see hzto() for how to avoid overflow if hz
1775 * is large (divide by `tick' and/or arrange to
1776 * use hzto() if hz is large).
1777 */
1778 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1779 goto sleep;
1780 }
1781 if (qp->c_cc <= 0) {
1782 sleep:
1783 /*
1784 * There is no input, or not enough input and we can block.
1785 */
1786 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
1787 ISSET(tp->t_state, TS_CONNECTED) ?
1788 "ttyin" : "ttyhup", (int)slp);
1789 splx(s);
1790 if (error == EWOULDBLOCK)
1791 error = 0;
1792 else if (error) {
1793 thread_funnel_set(kernel_flock, funnel_state);
1794 return (error);
1795 }
1796 /*
1797 * XXX what happens if another process eats some input
1798 * while we are asleep (not just here)? It would be
1799 * safest to detect changes and reset our state variables
1800 * (has_stime and last_cc).
1801 */
1802 slp = 0;
1803 goto loop;
1804 }
1805 read:
1806 splx(s);
1807 /*
1808 * Input present, check for input mapping and processing.
1809 */
1810 first = 1;
1811 #ifdef NeXT
1812 if (ISSET(lflag, ICANON)
1813 || (ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) )
1814 #else
1815 if (ISSET(lflag, ICANON | ISIG))
1816 #endif
1817 goto slowcase;
1818 for (;;) {
1819 char ibuf[IBUFSIZ];
1820 int icc;
1821
1822 icc = min(uio_resid(uio), IBUFSIZ);
1823 icc = q_to_b(qp, ibuf, icc);
1824 if (icc <= 0) {
1825 if (first)
1826 goto loop;
1827 break;
1828 }
1829 error = uiomove(ibuf, icc, uio);
1830 /*
1831 * XXX if there was an error then we should ungetc() the
1832 * unmoved chars and reduce icc here.
1833 */
1834 #if NSNP > 0
1835 if (ISSET(tp->t_lflag, ECHO) &&
1836 ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
1837 snpin((struct snoop *)tp->t_sc, ibuf, icc);
1838 #endif
1839 if (error)
1840 break;
1841 if (uio_resid(uio) == 0)
1842 break;
1843 first = 0;
1844 }
1845 goto out;
1846 slowcase:
1847 for (;;) {
1848 c = getc(qp);
1849 if (c < 0) {
1850 if (first)
1851 goto loop;
1852 break;
1853 }
1854 /*
1855 * delayed suspend (^Y)
1856 */
1857 if (CCEQ(cc[VDSUSP], c) &&
1858 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1859 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1860 if (first) {
1861 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1862 "ttybg3", 0);
1863 if (error)
1864 break;
1865 goto loop;
1866 }
1867 break;
1868 }
1869 /*
1870 * Interpret EOF only in canonical mode.
1871 */
1872 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1873 break;
1874 /*
1875 * Give user character.
1876 */
1877 error = ureadc(c, uio);
1878 if (error)
1879 /* XXX should ungetc(c, qp). */
1880 break;
1881 #if NSNP > 0
1882 /*
1883 * Only snoop directly on input in echo mode. Non-echoed
1884 * input will be snooped later iff the application echoes it.
1885 */
1886 if (ISSET(tp->t_lflag, ECHO) &&
1887 ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
1888 snpinc((struct snoop *)tp->t_sc, (char)c);
1889 #endif
1890 if (uio_resid(uio) == 0)
1891 break;
1892 /*
1893 * In canonical mode check for a "break character"
1894 * marking the end of a "line of input".
1895 */
1896 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1897 break;
1898 first = 0;
1899 }
1900
1901 out:
1902 /*
1903 * Look to unblock input now that (presumably)
1904 * the input queue has gone down.
1905 */
1906 s = spltty();
1907 if (ISSET(tp->t_state, TS_TBLOCK) &&
1908 tp->t_rawq.c_cc + tp->t_canq.c_cc <= I_LOW_WATER)
1909 ttyunblock(tp);
1910 splx(s);
1911
1912 thread_funnel_set(kernel_flock, funnel_state);
1913 return (error);
1914 }
1915
1916 /*
1917 * Check the output queue on tp for space for a kernel message (from uprintf
1918 * or tprintf). Allow some space over the normal hiwater mark so we don't
1919 * lose messages due to normal flow control, but don't let the tty run amok.
1920 * Sleeps here are not interruptible, but we return prematurely if new signals
1921 * arrive.
1922 */
1923 int
1924 ttycheckoutq(tp, wait)
1925 register struct tty *tp;
1926 int wait;
1927 {
1928 int hiwat, s;
1929 sigset_t oldsig;
1930 struct uthread *ut;
1931
1932 ut = (struct uthread *)get_bsdthread_info(current_thread());
1933
1934 hiwat = tp->t_hiwat;
1935 s = spltty();
1936 oldsig = wait ? ut->uu_siglist : 0;
1937 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
1938 while (tp->t_outq.c_cc > hiwat) {
1939 ttstart(tp);
1940 if (tp->t_outq.c_cc <= hiwat)
1941 break;
1942 if (wait == 0 || ut->uu_siglist != oldsig) {
1943 splx(s);
1944 return (0);
1945 }
1946 SET(tp->t_state, TS_SO_OLOWAT);
1947 tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
1948 }
1949 splx(s);
1950 return (1);
1951 }
1952
1953 /*
1954 * Process a write call on a tty device.
1955 */
1956 int
1957 ttwrite(tp, uio, flag)
1958 register struct tty *tp;
1959 register struct uio *uio;
1960 int flag;
1961 {
1962 register char *cp = NULL;
1963 register int cc, ce;
1964 register struct proc *p;
1965 int i, hiwat, count, error, s;
1966 char obuf[OBUFSIZ];
1967 boolean_t funnel_state;
1968 struct uthread *ut;
1969
1970 funnel_state = thread_funnel_set(kernel_flock, TRUE);
1971
1972 ut = (struct uthread *)get_bsdthread_info(current_thread());
1973 hiwat = tp->t_hiwat;
1974 // LP64todo - fix this!
1975 count = uio_resid(uio);
1976 error = 0;
1977 cc = 0;
1978 loop:
1979 s = spltty();
1980 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1981 splx(s);
1982 if (uio_resid(uio) == count)
1983 error = EIO;
1984 goto out;
1985 }
1986 if (!ISSET(tp->t_state, TS_CONNECTED)) {
1987 if (flag & IO_NDELAY) {
1988 splx(s);
1989 error = EWOULDBLOCK;
1990 goto out;
1991 }
1992 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
1993 "ttydcd", 0);
1994 splx(s);
1995 if (error) {
1996 goto out; }
1997 goto loop;
1998 }
1999 splx(s);
2000 /*
2001 * Hang the process if it's in the background.
2002 */
2003 p = current_proc();
2004 if (isbackground(p, tp) &&
2005 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
2006 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
2007 (ut->uu_sigmask & sigmask(SIGTTOU)) == 0) {
2008 if (p->p_pgrp->pg_jobc == 0) {
2009 error = EIO;
2010 goto out;
2011 }
2012 pgsignal(p->p_pgrp, SIGTTOU, 1);
2013 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH | PTTYBLOCK, "ttybg4", 0);
2014 if (error)
2015 goto out;
2016 goto loop;
2017 }
2018 /*
2019 * Process the user's data in at most OBUFSIZ chunks. Perform any
2020 * output translation. Keep track of high water mark, sleep on
2021 * overflow awaiting device aid in acquiring new space.
2022 */
2023 while (uio_resid(uio) > 0 || cc > 0) {
2024 if (ISSET(tp->t_lflag, FLUSHO)) {
2025 uio_setresid(uio, 0);
2026 thread_funnel_set(kernel_flock, funnel_state);
2027 return (0);
2028 }
2029 if (tp->t_outq.c_cc > hiwat)
2030 goto ovhiwat;
2031 /*
2032 * Grab a hunk of data from the user, unless we have some
2033 * leftover from last time.
2034 */
2035 if (cc == 0) {
2036 cc = min(uio_resid(uio), OBUFSIZ);
2037 cp = obuf;
2038 error = uiomove(cp, cc, uio);
2039 if (error) {
2040 cc = 0;
2041 break;
2042 }
2043 #if NSNP > 0
2044 if (ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL)
2045 snpin((struct snoop *)tp->t_sc, cp, cc);
2046 #endif
2047 }
2048 /*
2049 * If nothing fancy need be done, grab those characters we
2050 * can handle without any of ttyoutput's processing and
2051 * just transfer them to the output q. For those chars
2052 * which require special processing (as indicated by the
2053 * bits in char_type), call ttyoutput. After processing
2054 * a hunk of data, look for FLUSHO so ^O's will take effect
2055 * immediately.
2056 */
2057 while (cc > 0) {
2058 if (!ISSET(tp->t_oflag, OPOST))
2059 ce = cc;
2060 else {
2061 ce = cc - scanc((u_int)cc, (u_char *)cp,
2062 char_type, CCLASSMASK);
2063 /*
2064 * If ce is zero, then we're processing
2065 * a special character through ttyoutput.
2066 */
2067 if (ce == 0) {
2068 tp->t_rocount = 0;
2069 if (ttyoutput(*cp, tp) >= 0) {
2070 #ifdef NeXT
2071 /* out of space */
2072 goto overfull;
2073 #else
2074 /* No Clists, wait a bit. */
2075 ttstart(tp);
2076 if (flag & IO_NDELAY) {
2077 error = EWOULDBLOCK;
2078 goto out;
2079 }
2080 error = ttysleep(tp, &lbolt,
2081 TTOPRI|PCATCH,
2082 "ttybf1", 0);
2083 if (error)
2084 goto out;
2085 goto loop;
2086 #endif /* NeXT */
2087 }
2088 cp++;
2089 cc--;
2090 if (ISSET(tp->t_lflag, FLUSHO) ||
2091 tp->t_outq.c_cc > hiwat)
2092 goto ovhiwat;
2093 continue;
2094 }
2095 }
2096 /*
2097 * A bunch of normal characters have been found.
2098 * Transfer them en masse to the output queue and
2099 * continue processing at the top of the loop.
2100 * If there are any further characters in this
2101 * <= OBUFSIZ chunk, the first should be a character
2102 * requiring special handling by ttyoutput.
2103 */
2104 tp->t_rocount = 0;
2105 i = b_to_q(cp, ce, &tp->t_outq);
2106 ce -= i;
2107 tp->t_column += ce;
2108 cp += ce, cc -= ce, tk_nout += ce;
2109 tp->t_outcc += ce;
2110 if (i > 0) {
2111 #ifdef NeXT
2112 /* out of space */
2113 goto overfull;
2114 #else
2115 /* No Clists, wait a bit. */
2116 ttstart(tp);
2117 if (flag & IO_NDELAY) {
2118 error = EWOULDBLOCK;
2119 goto out;
2120 }
2121 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
2122 "ttybf2", 0);
2123 if (error)
2124 goto out;
2125 goto loop;
2126 #endif /* NeXT */
2127 }
2128 if (ISSET(tp->t_lflag, FLUSHO) ||
2129 tp->t_outq.c_cc > hiwat)
2130 break;
2131 }
2132 ttstart(tp);
2133 }
2134 out:
2135 /*
2136 * If cc is nonzero, we leave the uio structure inconsistent, as the
2137 * offset and iov pointers have moved forward, but it doesn't matter
2138 * (the call will either return short or restart with a new uio).
2139 */
2140 uio_setresid(uio, (uio_resid(uio) + cc));
2141 thread_funnel_set(kernel_flock, funnel_state);
2142 return (error);
2143
2144 #ifdef NeXT
2145 overfull:
2146
2147 /*
2148 * Since we are using ring buffers, if we can't insert any more into
2149 * the output queue, we can assume the ring is full and that someone
2150 * forgot to set the high water mark correctly. We set it and then
2151 * proceed as normal.
2152 */
2153 hiwat = tp->t_outq.c_cc - 1;
2154 #endif
2155
2156 ovhiwat:
2157 ttstart(tp);
2158 s = spltty();
2159 /*
2160 * This can only occur if FLUSHO is set in t_lflag,
2161 * or if ttstart/oproc is synchronous (or very fast).
2162 */
2163 if (tp->t_outq.c_cc <= hiwat) {
2164 splx(s);
2165 goto loop;
2166 }
2167 if (flag & IO_NDELAY) {
2168 splx(s);
2169 uio_setresid(uio, (uio_resid(uio) + cc));
2170 thread_funnel_set(kernel_flock, funnel_state);
2171 return (uio_resid(uio) == count ? EWOULDBLOCK : 0);
2172 }
2173 SET(tp->t_state, TS_SO_OLOWAT);
2174 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
2175 tp->t_timeout);
2176 splx(s);
2177 if (error == EWOULDBLOCK)
2178 error = EIO;
2179 if (error)
2180 goto out;
2181 goto loop;
2182 }
2183
2184 /*
2185 * Rubout one character from the rawq of tp
2186 * as cleanly as possible.
2187 */
2188 static void
2189 ttyrub(c, tp)
2190 register int c;
2191 register struct tty *tp;
2192 {
2193 register u_char *cp;
2194 register int savecol;
2195 int tabc, s;
2196
2197 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2198 return;
2199 CLR(tp->t_lflag, FLUSHO);
2200 if (ISSET(tp->t_lflag, ECHOE)) {
2201 if (tp->t_rocount == 0) {
2202 /*
2203 * Messed up by ttwrite; retype
2204 */
2205 ttyretype(tp);
2206 return;
2207 }
2208 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
2209 ttyrubo(tp, 2);
2210 else {
2211 CLR(c, ~TTY_CHARMASK);
2212 switch (CCLASS(c)) {
2213 case ORDINARY:
2214 ttyrubo(tp, 1);
2215 break;
2216 case BACKSPACE:
2217 case CONTROL:
2218 case NEWLINE:
2219 case RETURN:
2220 case VTAB:
2221 if (ISSET(tp->t_lflag, ECHOCTL))
2222 ttyrubo(tp, 2);
2223 break;
2224 case TAB:
2225 if (tp->t_rocount < tp->t_rawq.c_cc) {
2226 ttyretype(tp);
2227 return;
2228 }
2229 s = spltty();
2230 savecol = tp->t_column;
2231 SET(tp->t_state, TS_CNTTB);
2232 SET(tp->t_lflag, FLUSHO);
2233 tp->t_column = tp->t_rocol;
2234 #ifndef NeXT
2235 cp = tp->t_rawq.c_cf;
2236 if (cp)
2237 tabc = *cp; /* XXX FIX NEXTC */
2238 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
2239 ttyecho(tabc, tp);
2240 #else
2241 for (cp = firstc(&tp->t_rawq, &tabc); cp;
2242 cp = nextc(&tp->t_rawq, cp, &tabc))
2243 ttyecho(tabc, tp);
2244 #endif /* !NeXT */
2245 CLR(tp->t_lflag, FLUSHO);
2246 CLR(tp->t_state, TS_CNTTB);
2247 splx(s);
2248
2249 /* savecol will now be length of the tab. */
2250 savecol -= tp->t_column;
2251 tp->t_column += savecol;
2252 if (savecol > 8)
2253 savecol = 8; /* overflow fixup */
2254 while (--savecol >= 0)
2255 (void)ttyoutput('\b', tp);
2256 break;
2257 default: /* XXX */
2258 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
2259 (void)printf(PANICSTR, c, CCLASS(c));
2260 #ifdef notdef
2261 panic(PANICSTR, c, CCLASS(c));
2262 #endif
2263 }
2264 }
2265 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2266 if (!ISSET(tp->t_state, TS_ERASE)) {
2267 SET(tp->t_state, TS_ERASE);
2268 (void)ttyoutput('\\', tp);
2269 }
2270 ttyecho(c, tp);
2271 } else
2272 ttyecho(tp->t_cc[VERASE], tp);
2273 --tp->t_rocount;
2274 }
2275
2276 /*
2277 * Back over count characters, erasing them.
2278 */
2279 static void
2280 ttyrubo(struct tty *tp, int count)
2281 {
2282
2283 while (count-- > 0) {
2284 (void)ttyoutput('\b', tp);
2285 (void)ttyoutput(' ', tp);
2286 (void)ttyoutput('\b', tp);
2287 }
2288 }
2289
2290 /*
2291 * ttyretype --
2292 * Reprint the rawq line. Note, it is assumed that c_cc has already
2293 * been checked.
2294 */
2295 static void
2296 ttyretype(tp)
2297 register struct tty *tp;
2298 {
2299 register u_char *cp;
2300 int s, c;
2301
2302 /* Echo the reprint character. */
2303 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2304 ttyecho(tp->t_cc[VREPRINT], tp);
2305
2306 (void)ttyoutput('\n', tp);
2307
2308 /*
2309 * FREEBSD XXX
2310 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2311 * BIT OF FIRST CHAR.
2312 */
2313 s = spltty();
2314 #ifndef NeXT
2315 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
2316 cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
2317 ttyecho(c, tp);
2318 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
2319 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
2320 ttyecho(c, tp);
2321 #else NeXT
2322 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
2323 ttyecho(c, tp);
2324 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
2325 ttyecho(c, tp);
2326 #endif /* !NeXT */
2327 CLR(tp->t_state, TS_ERASE);
2328 splx(s);
2329
2330 tp->t_rocount = tp->t_rawq.c_cc;
2331 tp->t_rocol = 0;
2332 }
2333
2334 /*
2335 * Echo a typed character to the terminal.
2336 */
2337 static void
2338 ttyecho(c, tp)
2339 register int c;
2340 register struct tty *tp;
2341 {
2342
2343 if (!ISSET(tp->t_state, TS_CNTTB))
2344 CLR(tp->t_lflag, FLUSHO);
2345 if ((!ISSET(tp->t_lflag, ECHO) &&
2346 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2347 ISSET(tp->t_lflag, EXTPROC))
2348 return;
2349 if (ISSET(tp->t_lflag, ECHOCTL) &&
2350 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2351 ISSET(c, TTY_CHARMASK) == 0177)) {
2352 (void)ttyoutput('^', tp);
2353 CLR(c, ~TTY_CHARMASK);
2354 if (c == 0177)
2355 c = '?';
2356 else
2357 c += 'A' - 1;
2358 }
2359 (void)ttyoutput(c, tp);
2360 }
2361
2362 /*
2363 * Wake up any readers on a tty.
2364 */
2365 void
2366 ttwakeup(tp)
2367 register struct tty *tp;
2368 {
2369
2370 #ifndef NeXT
2371 if (tp->t_rsel.si_pid != 0)
2372 #endif
2373 selwakeup(&tp->t_rsel);
2374 if (ISSET(tp->t_state, TS_ASYNC))
2375 pgsignal(tp->t_pgrp, SIGIO, 1);
2376 wakeup(TSA_HUP_OR_INPUT(tp));
2377 }
2378
2379 /*
2380 * Wake up any writers on a tty.
2381 */
2382 void
2383 ttwwakeup(tp)
2384 register struct tty *tp;
2385 {
2386 #ifndef NeXT
2387 if (tp->t_wsel.si_pid != 0 && tp->t_outq.c_cc <= tp->t_lowat)
2388 #else
2389 if (tp->t_outq.c_cc <= tp->t_lowat)
2390 #endif
2391 selwakeup(&tp->t_wsel);
2392 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2393 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2394 CLR(tp->t_state, TS_SO_OCOMPLETE);
2395 wakeup(TSA_OCOMPLETE(tp));
2396 }
2397 if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2398 tp->t_outq.c_cc <= tp->t_lowat) {
2399 CLR(tp->t_state, TS_SO_OLOWAT);
2400 wakeup(TSA_OLOWAT(tp));
2401 }
2402 }
2403
2404 /*
2405 * Look up a code for a specified speed in a conversion table;
2406 * used by drivers to map software speed values to hardware parameters.
2407 */
2408 int
2409 ttspeedtab(speed, table)
2410 int speed;
2411 register struct speedtab *table;
2412 {
2413
2414 for ( ; table->sp_speed != -1; table++)
2415 if (table->sp_speed == speed)
2416 return (table->sp_code);
2417 return (-1);
2418 }
2419
2420 /*
2421 * Set tty hi and low water marks.
2422 *
2423 * Try to arrange the dynamics so there's about one second
2424 * from hi to low water.
2425 *
2426 */
2427 void
2428 ttsetwater(struct tty *tp)
2429 {
2430 int cps;
2431 unsigned int x;
2432
2433 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2434
2435 cps = tp->t_ospeed / 10;
2436 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2437 x += cps;
2438 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
2439 tp->t_hiwat = roundup(x, CBSIZE);
2440 #undef CLAMP
2441 }
2442
2443 /* NeXT ttyinfo has been converted to the MACH kernel */
2444 #include <mach/thread_info.h>
2445
2446 /* XXX Should be in Mach header <kern/thread.h>, but doesn't work */
2447 extern kern_return_t thread_info_internal(thread_t thread,
2448 thread_flavor_t flavor,
2449 thread_info_t thread_info_out,
2450 mach_msg_type_number_t *thread_info_count);
2451
2452 /*
2453 * Report on state of foreground process group.
2454 */
2455 void
2456 ttyinfo(struct tty *tp)
2457 {
2458 int load;
2459 thread_t thread;
2460 uthread_t uthread;
2461 struct proc *p;
2462 struct proc *pick;
2463 const char *state;
2464 struct timeval utime;
2465 struct timeval stime;
2466 thread_basic_info_data_t basic_info;
2467 mach_msg_type_number_t mmtn = THREAD_BASIC_INFO_COUNT;
2468
2469 if (ttycheckoutq(tp,0) == 0)
2470 return;
2471
2472 /* Print load average. */
2473 load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2474 ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100);
2475
2476 /*
2477 * On return following a ttyprintf(), we set tp->t_rocount to 0 so
2478 * that pending input will be retyped on BS.
2479 */
2480 if (tp->t_session == NULL) {
2481 ttyprintf(tp, "not a controlling terminal\n");
2482 tp->t_rocount = 0;
2483 return;
2484 }
2485 if (tp->t_pgrp == NULL) {
2486 ttyprintf(tp, "no foreground process group\n");
2487 tp->t_rocount = 0;
2488 return;
2489 }
2490 /* first process in process group */
2491 if ((p = tp->t_pgrp->pg_members.lh_first) == NULL) {
2492 ttyprintf(tp, "empty foreground process group\n");
2493 tp->t_rocount = 0;
2494 return;
2495 }
2496
2497 /*
2498 * Pick the most interesting process and copy some of its
2499 * state for printing later.
2500 */
2501 for (pick = NULL; p != NULL; p = p->p_pglist.le_next) {
2502 if (proc_compare(pick, p))
2503 pick = p;
2504 }
2505
2506 if (TAILQ_EMPTY(&pick->p_uthlist) ||
2507 (uthread = TAILQ_FIRST(&pick->p_uthlist)) == NULL ||
2508 (thread = uthread->uu_act) == NULL ||
2509 (thread_info_internal(thread, THREAD_BASIC_INFO, (thread_info_t)&basic_info, &mmtn) != KERN_SUCCESS)) {
2510 ttyprintf(tp, "foreground process without thread\n");
2511 tp->t_rocount = 0;
2512 return;
2513 }
2514
2515 switch(basic_info.run_state) {
2516 case TH_STATE_RUNNING:
2517 state = "running";
2518 break;
2519 case TH_STATE_STOPPED:
2520 state = "stopped";
2521 break;
2522 case TH_STATE_WAITING:
2523 state = "waiting";
2524 break;
2525 case TH_STATE_UNINTERRUPTIBLE:
2526 state = "uninterruptible";
2527 break;
2528 case TH_STATE_HALTED:
2529 state = "halted";
2530 break;
2531 default:
2532 state = "unknown";
2533 break;
2534 }
2535 calcru(pick, &utime, &stime, NULL);
2536
2537 /* Print command, pid, state, utime, and stime */
2538 ttyprintf(tp, " cmd: %s %d %s %ld.%02ldu %ld.%02lds\n",
2539 pick->p_comm,
2540 pick->p_pid,
2541 state,
2542 (long)utime.tv_sec, utime.tv_usec / 10000,
2543 (long)stime.tv_sec, stime.tv_usec / 10000);
2544 tp->t_rocount = 0;
2545 }
2546
2547 /*
2548 * Returns 1 if p2 is "better" than p1
2549 *
2550 * The algorithm for picking the "interesting" process is thus:
2551 *
2552 * 1) Only foreground processes are eligible - implied.
2553 * 2) Runnable processes are favored over anything else. The runner
2554 * with the highest cpu utilization is picked (p_estcpu). Ties are
2555 * broken by picking the highest pid.
2556 * 3) The sleeper with the shortest sleep time is next.
2557 * 4) Further ties are broken by picking the highest pid.
2558 */
2559 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
2560 #define TESTAB(a, b) ((a)<<1 | (b))
2561 #define ONLYA 2
2562 #define ONLYB 1
2563 #define BOTH 3
2564
2565 static int
2566 proc_compare(p1, p2)
2567 register struct proc *p1, *p2;
2568 {
2569
2570 if (p1 == NULL)
2571 return (1);
2572 /*
2573 * see if at least one of them is runnable
2574 */
2575 switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
2576 case ONLYA:
2577 return (0);
2578 case ONLYB:
2579 return (1);
2580 case BOTH:
2581 /*
2582 * tie - favor one with highest recent cpu utilization
2583 */
2584 if (p2->p_estcpu > p1->p_estcpu)
2585 return (1);
2586 if (p1->p_estcpu > p2->p_estcpu)
2587 return (0);
2588 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2589 }
2590 /*
2591 * weed out zombies
2592 */
2593 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
2594 case ONLYA:
2595 return (1);
2596 case ONLYB:
2597 return (0);
2598 case BOTH:
2599 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2600 }
2601 /*
2602 * pick the one with the smallest sleep time
2603 */
2604 if (p2->p_slptime > p1->p_slptime)
2605 return (0);
2606 if (p1->p_slptime > p2->p_slptime)
2607 return (1);
2608 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2609 }
2610
2611 /*
2612 * Output char to tty; console putchar style.
2613 */
2614 int
2615 tputchar(c, tp)
2616 int c;
2617 struct tty *tp;
2618 {
2619 register int s;
2620
2621 s = spltty();
2622 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2623 splx(s);
2624 return (-1);
2625 }
2626 if (c == '\n')
2627 (void)ttyoutput('\r', tp);
2628 (void)ttyoutput(c, tp);
2629 ttstart(tp);
2630 splx(s);
2631 return (0);
2632 }
2633
2634 /*
2635 * Sleep on chan, returning ERESTART if tty changed while we napped and
2636 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep. If
2637 * the tty is revoked, restarting a pending call will redo validation done
2638 * at the start of the call.
2639 */
2640 int
2641 ttysleep(struct tty *tp, void *chan, int pri, const char *wmesg, int timo)
2642 {
2643 int error;
2644 int gen;
2645
2646 gen = tp->t_gen;
2647 error = tsleep(chan, pri, wmesg, timo);
2648 if (error)
2649 return (error);
2650 return (tp->t_gen == gen ? 0 : ERESTART);
2651 }
2652
2653 #ifdef NeXT
2654 /*
2655 * Allocate a tty structure and its associated buffers.
2656 */
2657 struct tty *
2658 ttymalloc(void)
2659 {
2660 struct tty *tp;
2661
2662 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO);
2663 if (tp != NULL) {
2664 /* XXX: default to TTYCLSIZE(1024) chars for now */
2665 clalloc(&tp->t_rawq, TTYCLSIZE, 1);
2666 clalloc(&tp->t_canq, TTYCLSIZE, 1);
2667 /* output queue doesn't need quoting */
2668 clalloc(&tp->t_outq, TTYCLSIZE, 0);
2669 }
2670 return(tp);
2671 }
2672
2673 /*
2674 * Free a tty structure and its buffers.
2675 */
2676 void
2677 ttyfree(tp)
2678 struct tty *tp;
2679 {
2680 clfree(&tp->t_rawq);
2681 clfree(&tp->t_canq);
2682 clfree(&tp->t_outq);
2683 FREE(tp, M_TTYS);
2684 }
2685
2686 #else /* !NeXT */
2687
2688 #ifdef notyet
2689 /*
2690 * XXX this is usable not useful or used. Most tty drivers have
2691 * ifdefs for using ttymalloc() but assume a different interface.
2692 */
2693 /*
2694 * Allocate a tty struct. Clists in the struct will be allocated by
2695 * ttyopen().
2696 */
2697 struct tty *
2698 ttymalloc()
2699 {
2700 struct tty *tp;
2701
2702 MALLOC(tp, struct tty *, sizeof *tp, M_TTYS, M_WAITOK|M_ZERO);
2703 return (tp);
2704 }
2705 #endif
2706
2707 #if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */
2708 /*
2709 * Free a tty struct. Clists in the struct should have been freed by
2710 * ttyclose().
2711 */
2712 void
2713 ttyfree(tp)
2714 struct tty *tp;
2715 {
2716 FREE(tp, M_TTYS);
2717 }
2718 #endif /* 0 */
2719 #endif /* NeXT */