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