Deleted Added
sdiff udiff text old ( 90375 ) new ( 91140 )
full compact
1/*-
2 * Copyright (c) 1982, 1986, 1990, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)tty.c 8.8 (Berkeley) 1/21/94
39 * $FreeBSD: head/sys/kern/tty.c 90375 2002-02-07 23:06:26Z peter $
40 */
41
42/*-
43 * TODO:
44 * o Fix races for sending the start char in ttyflush().
45 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
46 * With luck, there will be MIN chars before select() returns().
47 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it.

--- 22 unchanged lines hidden (view full) ---

70#include "opt_compat.h"
71#include "opt_uconsole.h"
72
73#include <sys/param.h>
74#include <sys/systm.h>
75#include <sys/filio.h>
76#include <sys/lock.h>
77#include <sys/mutex.h>
78#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
79#include <sys/ioctl_compat.h>
80#endif
81#include <sys/proc.h>
82#define TTYDEFCHARS
83#include <sys/tty.h>
84#undef TTYDEFCHARS
85#include <sys/fcntl.h>

--- 237 unchanged lines hidden (view full) ---

323 err = (ISSET(c, TTY_ERRORMASK));
324 if (err) {
325 CLR(c, TTY_ERRORMASK);
326 if (ISSET(err, TTY_BI)) {
327 if (ISSET(iflag, IGNBRK))
328 return (0);
329 if (ISSET(iflag, BRKINT)) {
330 ttyflush(tp, FREAD | FWRITE);
331 pgsignal(tp->t_pgrp, SIGINT, 1);
332 goto endcase;
333 }
334 if (ISSET(iflag, PARMRK))
335 goto parmrk;
336 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
337 || ISSET(err, TTY_FE)) {
338 if (ISSET(iflag, IGNPAR))
339 return (0);

--- 61 unchanged lines hidden (view full) ---

401 /*
402 * Signals.
403 */
404 if (ISSET(lflag, ISIG)) {
405 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
406 if (!ISSET(lflag, NOFLSH))
407 ttyflush(tp, FREAD | FWRITE);
408 ttyecho(c, tp);
409 pgsignal(tp->t_pgrp,
410 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
411 goto endcase;
412 }
413 if (CCEQ(cc[VSUSP], c)) {
414 if (!ISSET(lflag, NOFLSH))
415 ttyflush(tp, FREAD);
416 ttyecho(c, tp);
417 pgsignal(tp->t_pgrp, SIGTSTP, 1);
418 goto endcase;
419 }
420 }
421 /*
422 * Handle start/stop characters.
423 */
424 if (ISSET(iflag, IXON)) {
425 if (CCEQ(cc[VSTOP], c)) {

--- 101 unchanged lines hidden (view full) ---

527 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
528 ttyretype(tp);
529 goto endcase;
530 }
531 /*
532 * ^T - kernel info and generate SIGINFO
533 */
534 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
535 if (ISSET(lflag, ISIG))
536 pgsignal(tp->t_pgrp, SIGINFO, 1);
537 if (!ISSET(lflag, NOKERNINFO))
538 ttyinfo(tp);
539 goto endcase;
540 }
541 }
542 /*
543 * Check for input buffer overflow
544 */

--- 202 unchanged lines hidden (view full) ---

747 case TIOCLBIS:
748 case TIOCLSET:
749 case TIOCSETC:
750 case OTIOCSETD:
751 case TIOCSETN:
752 case TIOCSETP:
753 case TIOCSLTC:
754#endif
755 while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
756 !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
757 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
758 if (p->p_pgrp->pg_jobc == 0)
759 return (EIO);
760 pgsignal(p->p_pgrp, SIGTTOU, 1);
761 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1",
762 0);
763 if (error)
764 return (error);
765 }
766 break;
767 }
768
769 switch (cmd) { /* Process the ioctl. */
770 case FIOASYNC: /* set/clear async i/o */
771 s = spltty();
772 if (*(int *)data)
773 SET(tp->t_state, TS_ASYNC);

--- 233 unchanged lines hidden (view full) ---

1007 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1008 SET(tp->t_state, TS_TTSTOP);
1009 (*tp->t_stop)(tp, 0);
1010 }
1011 splx(s);
1012 break;
1013 case TIOCSCTTY: /* become controlling tty */
1014 /* Session ctty vnode pointer set in vnode layer. */
1015 if (!SESS_LEADER(p) ||
1016 ((p->p_session->s_ttyvp || tp->t_session) &&
1017 (tp->t_session != p->p_session)))
1018 return (EPERM);
1019 tp->t_session = p->p_session;
1020 tp->t_pgrp = p->p_pgrp;
1021 p->p_session->s_ttyp = tp;
1022 p->p_flag |= P_CONTROLT;
1023 break;
1024 case TIOCSPGRP: { /* set pgrp of tty */
1025 register struct pgrp *pgrp = pgfind(*(int *)data);
1026
1027 if (!isctty(p, tp))
1028 return (ENOTTY);
1029 else if (pgrp == NULL || pgrp->pg_session != p->p_session)
1030 return (EPERM);
1031 tp->t_pgrp = pgrp;
1032 break;
1033 }
1034 case TIOCSTAT: /* simulate control-T */
1035 s = spltty();
1036 ttyinfo(tp);
1037 splx(s);
1038 break;
1039 case TIOCSWINSZ: /* set window size */
1040 if (bcmp((caddr_t)&tp->t_winsize, data,
1041 sizeof (struct winsize))) {
1042 tp->t_winsize = *(struct winsize *)data;
1043 pgsignal(tp->t_pgrp, SIGWINCH, 1);
1044 }
1045 break;
1046 case TIOCSDRAINWAIT:
1047 error = suser_xxx(p->p_ucred, NULL, 0);
1048 if (error)
1049 return (error);
1050 tp->t_timeout = *(int *)data * hz;
1051 wakeup(TSA_OCOMPLETE(tp));

--- 402 unchanged lines hidden (view full) ---

1454 /*
1455 * Lost carrier.
1456 */
1457 CLR(tp->t_state, TS_CARR_ON);
1458 if (ISSET(tp->t_state, TS_ISOPEN) &&
1459 !ISSET(tp->t_cflag, CLOCAL)) {
1460 SET(tp->t_state, TS_ZOMBIE);
1461 CLR(tp->t_state, TS_CONNECTED);
1462 if (tp->t_session && tp->t_session->s_leader) {
1463 struct proc *p;
1464
1465 p = tp->t_session->s_leader;
1466 PROC_LOCK(p);
1467 psignal(p, SIGHUP);
1468 PROC_UNLOCK(p);
1469 }
1470 ttyflush(tp, FREAD | FWRITE);
1471 return (0);
1472 }
1473 } else {
1474 /*
1475 * Carrier now on.
1476 */

--- 67 unchanged lines hidden (view full) ---

1544 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
1545 }
1546
1547 /*
1548 * Hang process if it's in the background.
1549 */
1550 if (isbackground(p, tp)) {
1551 splx(s);
1552 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
1553 SIGISMEMBER(p->p_sigmask, SIGTTIN) ||
1554 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0)
1555 return (EIO);
1556 pgsignal(p->p_pgrp, SIGTTIN, 1);
1557 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1558 if (error)
1559 return (error);
1560 goto loop;
1561 }
1562
1563 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1564 splx(s);

--- 157 unchanged lines hidden (view full) ---

1722 goto loop;
1723 break;
1724 }
1725 /*
1726 * delayed suspend (^Y)
1727 */
1728 if (CCEQ(cc[VDSUSP], c) &&
1729 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1730 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1731 if (first) {
1732 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1733 "ttybg3", 0);
1734 if (error)
1735 break;
1736 goto loop;
1737 }
1738 break;

--- 111 unchanged lines hidden (view full) ---

1850 goto out;
1851 goto loop;
1852 }
1853 splx(s);
1854 /*
1855 * Hang the process if it's in the background.
1856 */
1857 p = curproc;
1858 if (isbackground(p, tp) &&
1859 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
1860 !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
1861 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
1862 if (p->p_pgrp->pg_jobc == 0) {
1863 error = EIO;
1864 goto out;
1865 }
1866 pgsignal(p->p_pgrp, SIGTTOU, 1);
1867 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
1868 if (error)
1869 goto out;
1870 goto loop;
1871 }
1872 /*
1873 * Process the user's data in at most OBUFSIZ chunks. Perform any
1874 * output translation. Keep track of high water mark, sleep on
1875 * overflow awaiting device aid in acquiring new space.
1876 */
1877 while (uio->uio_resid > 0 || cc > 0) {
1878 if (ISSET(tp->t_lflag, FLUSHO)) {

--- 444 unchanged lines hidden (view full) ---

2323 /* Print load average. */
2324 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2325 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2326
2327 if (tp->t_session == NULL)
2328 ttyprintf(tp, "not a controlling terminal\n");
2329 else if (tp->t_pgrp == NULL)
2330 ttyprintf(tp, "no foreground process group\n");
2331 else if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0)
2332 ttyprintf(tp, "empty foreground process group\n");
2333 else {
2334 mtx_lock_spin(&sched_lock);
2335
2336 /* Pick interesting process. */
2337 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
2338 if (proc_compare(pick, p))
2339 pick = p;
2340
2341 td = FIRST_THREAD_IN_PROC(pick);
2342 stmp = pick->p_stat == SRUN ? "running" : /* XXXKSE */
2343 td->td_wmesg ? td->td_wmesg : "iowait";
2344 calcru(pick, &utime, &stime, NULL);
2345 ltmp = pick->p_stat == SIDL || pick->p_stat == SWAIT ||
2346 pick->p_stat == SZOMB ? 0 :
2347 pgtok(vmspace_resident_count(pick->p_vmspace));
2348 mtx_unlock_spin(&sched_lock);
2349
2350 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
2351 stmp);
2352
2353 /* Print user time. */
2354 ttyprintf(tp, "%ld.%02ldu ",
2355 (long)utime.tv_sec, utime.tv_usec / 10000);
2356
2357 /* Print system time. */
2358 ttyprintf(tp, "%ld.%02lds ",
2359 (long)stime.tv_sec, stime.tv_usec / 10000);
2360
2361 /* Print percentage cpu, resident set size. */
2362 ttyprintf(tp, "%d%% %ldk\n", tmp / 100, ltmp);
2363 }
2364 tp->t_rocount = 0; /* so pending input will be retyped if BS */
2365}
2366
2367/*
2368 * Returns 1 if p2 is "better" than p1
2369 *
2370 * The algorithm for picking the "interesting" process is thus:

--- 224 unchanged lines hidden ---