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 91140 2002-02-23 11:12:57Z tanimura $
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#include <sys/sx.h>
79#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
80#include <sys/ioctl_compat.h>
81#endif
82#include <sys/proc.h>
83#define TTYDEFCHARS
84#include <sys/tty.h>
85#undef TTYDEFCHARS
86#include <sys/fcntl.h>
--- 237 unchanged lines hidden (view full) ---
324 err = (ISSET(c, TTY_ERRORMASK));
325 if (err) {
326 CLR(c, TTY_ERRORMASK);
327 if (ISSET(err, TTY_BI)) {
328 if (ISSET(iflag, IGNBRK))
329 return (0);
330 if (ISSET(iflag, BRKINT)) {
331 ttyflush(tp, FREAD | FWRITE);
332 if (tp->t_pgrp != NULL) {
333 PGRP_LOCK(tp->t_pgrp);
334 pgsignal(tp->t_pgrp, SIGINT, 1);
335 PGRP_UNLOCK(tp->t_pgrp);
336 }
337 goto endcase;
338 }
339 if (ISSET(iflag, PARMRK))
340 goto parmrk;
341 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
342 || ISSET(err, TTY_FE)) {
343 if (ISSET(iflag, IGNPAR))
344 return (0);
--- 61 unchanged lines hidden (view full) ---
406 /*
407 * Signals.
408 */
409 if (ISSET(lflag, ISIG)) {
410 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
411 if (!ISSET(lflag, NOFLSH))
412 ttyflush(tp, FREAD | FWRITE);
413 ttyecho(c, tp);
414 if (tp->t_pgrp != NULL) {
415 PGRP_LOCK(tp->t_pgrp);
416 pgsignal(tp->t_pgrp,
417 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
418 PGRP_UNLOCK(tp->t_pgrp);
419 }
420 goto endcase;
421 }
422 if (CCEQ(cc[VSUSP], c)) {
423 if (!ISSET(lflag, NOFLSH))
424 ttyflush(tp, FREAD);
425 ttyecho(c, tp);
426 if (tp->t_pgrp != NULL) {
427 PGRP_LOCK(tp->t_pgrp);
428 pgsignal(tp->t_pgrp, SIGTSTP, 1);
429 PGRP_UNLOCK(tp->t_pgrp);
430 }
431 goto endcase;
432 }
433 }
434 /*
435 * Handle start/stop characters.
436 */
437 if (ISSET(iflag, IXON)) {
438 if (CCEQ(cc[VSTOP], c)) {
--- 101 unchanged lines hidden (view full) ---
540 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
541 ttyretype(tp);
542 goto endcase;
543 }
544 /*
545 * ^T - kernel info and generate SIGINFO
546 */
547 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
548 if (ISSET(lflag, ISIG) && tp->t_pgrp != NULL) {
549 PGRP_LOCK(tp->t_pgrp);
550 pgsignal(tp->t_pgrp, SIGINFO, 1);
551 PGRP_UNLOCK(tp->t_pgrp);
552 }
553 if (!ISSET(lflag, NOKERNINFO))
554 ttyinfo(tp);
555 goto endcase;
556 }
557 }
558 /*
559 * Check for input buffer overflow
560 */
--- 202 unchanged lines hidden (view full) ---
763 case TIOCLBIS:
764 case TIOCLSET:
765 case TIOCSETC:
766 case OTIOCSETD:
767 case TIOCSETN:
768 case TIOCSETP:
769 case TIOCSLTC:
770#endif
771 PGRPSESS_SLOCK();
772 PROC_LOCK(p);
773 while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
774 !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
775 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
776 if (p->p_pgrp->pg_jobc == 0) {
777 PROC_UNLOCK(p);
778 PGRPSESS_SUNLOCK();
779 return (EIO);
780 }
781 PROC_UNLOCK(p);
782 PGRP_LOCK(p->p_pgrp);
783 pgsignal(p->p_pgrp, SIGTTOU, 1);
784 PGRP_UNLOCK(p->p_pgrp);
785 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1",
786 0);
787 if (error) {
788 PGRPSESS_SUNLOCK();
789 return (error);
790 }
791 PROC_LOCK(p);
792 }
793 PROC_UNLOCK(p);
794 PGRPSESS_SUNLOCK();
795 break;
796 }
797
798 switch (cmd) { /* Process the ioctl. */
799 case FIOASYNC: /* set/clear async i/o */
800 s = spltty();
801 if (*(int *)data)
802 SET(tp->t_state, TS_ASYNC);
--- 233 unchanged lines hidden (view full) ---
1036 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1037 SET(tp->t_state, TS_TTSTOP);
1038 (*tp->t_stop)(tp, 0);
1039 }
1040 splx(s);
1041 break;
1042 case TIOCSCTTY: /* become controlling tty */
1043 /* Session ctty vnode pointer set in vnode layer. */
1044 PGRPSESS_XLOCK();
1045 if (!SESS_LEADER(p) ||
1046 ((p->p_session->s_ttyvp || tp->t_session) &&
1047 (tp->t_session != p->p_session))) {
1048 PGRPSESS_XUNLOCK();
1049 return (EPERM);
1050 }
1051 tp->t_session = p->p_session;
1052 tp->t_pgrp = p->p_pgrp;
1053 SESS_LOCK(p->p_session);
1054 p->p_session->s_ttyp = tp;
1055 SESS_UNLOCK(p->p_session);
1056 PROC_LOCK(p);
1057 p->p_flag |= P_CONTROLT;
1058 PROC_UNLOCK(p);
1059 PGRPSESS_XUNLOCK();
1060 break;
1061 case TIOCSPGRP: { /* set pgrp of tty */
1062 register struct pgrp *pgrp;
1063
1064 PGRPSESS_SLOCK();
1065 pgrp = pgfind(*(int *)data);
1066 if (!isctty(p, tp)) {
1067 if (pgrp != NULL)
1068 PGRP_UNLOCK(pgrp);
1069 PGRPSESS_SUNLOCK();
1070 return (ENOTTY);
1071 }
1072 if (pgrp == NULL) {
1073 PGRPSESS_SUNLOCK();
1074 return (EPERM);
1075 }
1076 PGRP_UNLOCK(pgrp);
1077 if (pgrp->pg_session != p->p_session) {
1078 PGRPSESS_SUNLOCK();
1079 return (EPERM);
1080 }
1081 PGRPSESS_SUNLOCK();
1082 tp->t_pgrp = pgrp;
1083 break;
1084 }
1085 case TIOCSTAT: /* simulate control-T */
1086 s = spltty();
1087 ttyinfo(tp);
1088 splx(s);
1089 break;
1090 case TIOCSWINSZ: /* set window size */
1091 if (bcmp((caddr_t)&tp->t_winsize, data,
1092 sizeof (struct winsize))) {
1093 tp->t_winsize = *(struct winsize *)data;
1094 if (tp->t_pgrp != NULL) {
1095 PGRP_LOCK(tp->t_pgrp);
1096 pgsignal(tp->t_pgrp, SIGWINCH, 1);
1097 PGRP_UNLOCK(tp->t_pgrp);
1098 }
1099 }
1100 break;
1101 case TIOCSDRAINWAIT:
1102 error = suser_xxx(p->p_ucred, NULL, 0);
1103 if (error)
1104 return (error);
1105 tp->t_timeout = *(int *)data * hz;
1106 wakeup(TSA_OCOMPLETE(tp));
--- 402 unchanged lines hidden (view full) ---
1509 /*
1510 * Lost carrier.
1511 */
1512 CLR(tp->t_state, TS_CARR_ON);
1513 if (ISSET(tp->t_state, TS_ISOPEN) &&
1514 !ISSET(tp->t_cflag, CLOCAL)) {
1515 SET(tp->t_state, TS_ZOMBIE);
1516 CLR(tp->t_state, TS_CONNECTED);
1517 if (tp->t_session) {
1518 PGRPSESS_SLOCK();
1519 if (tp->t_session->s_leader) {
1520 struct proc *p;
1521
1522 p = tp->t_session->s_leader;
1523 PROC_LOCK(p);
1524 psignal(p, SIGHUP);
1525 PROC_UNLOCK(p);
1526 }
1527 PGRPSESS_SUNLOCK();
1528 }
1529 ttyflush(tp, FREAD | FWRITE);
1530 return (0);
1531 }
1532 } else {
1533 /*
1534 * Carrier now on.
1535 */
--- 67 unchanged lines hidden (view full) ---
1603 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
1604 }
1605
1606 /*
1607 * Hang process if it's in the background.
1608 */
1609 if (isbackground(p, tp)) {
1610 splx(s);
1611 PGRPSESS_SLOCK();
1612 PROC_LOCK(p);
1613 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
1614 SIGISMEMBER(p->p_sigmask, SIGTTIN) ||
1615 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) {
1616 PROC_UNLOCK(p);
1617 PGRPSESS_SUNLOCK();
1618 return (EIO);
1619 }
1620 PROC_UNLOCK(p);
1621 PGRP_LOCK(p->p_pgrp);
1622 PGRPSESS_SUNLOCK();
1623 pgsignal(p->p_pgrp, SIGTTIN, 1);
1624 PGRP_UNLOCK(p->p_pgrp);
1625 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1626 if (error)
1627 return (error);
1628 goto loop;
1629 }
1630
1631 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1632 splx(s);
--- 157 unchanged lines hidden (view full) ---
1790 goto loop;
1791 break;
1792 }
1793 /*
1794 * delayed suspend (^Y)
1795 */
1796 if (CCEQ(cc[VDSUSP], c) &&
1797 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1798 if (tp->t_pgrp != NULL) {
1799 PGRP_LOCK(tp->t_pgrp);
1800 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1801 PGRP_UNLOCK(tp->t_pgrp);
1802 }
1803 if (first) {
1804 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1805 "ttybg3", 0);
1806 if (error)
1807 break;
1808 goto loop;
1809 }
1810 break;
--- 111 unchanged lines hidden (view full) ---
1922 goto out;
1923 goto loop;
1924 }
1925 splx(s);
1926 /*
1927 * Hang the process if it's in the background.
1928 */
1929 p = curproc;
1930 PGRPSESS_SLOCK();
1931 PROC_LOCK(p);
1932 if (isbackground(p, tp) &&
1933 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
1934 !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
1935 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
1936 if (p->p_pgrp->pg_jobc == 0) {
1937 PROC_UNLOCK(p);
1938 PGRPSESS_SUNLOCK();
1939 error = EIO;
1940 goto out;
1941 }
1942 PROC_UNLOCK(p);
1943 PGRP_LOCK(p->p_pgrp);
1944 PGRPSESS_SUNLOCK();
1945 pgsignal(p->p_pgrp, SIGTTOU, 1);
1946 PGRP_UNLOCK(p->p_pgrp);
1947 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
1948 if (error)
1949 goto out;
1950 goto loop;
1951 } else {
1952 PROC_UNLOCK(p);
1953 PGRPSESS_SUNLOCK();
1954 }
1955 /*
1956 * Process the user's data in at most OBUFSIZ chunks. Perform any
1957 * output translation. Keep track of high water mark, sleep on
1958 * overflow awaiting device aid in acquiring new space.
1959 */
1960 while (uio->uio_resid > 0 || cc > 0) {
1961 if (ISSET(tp->t_lflag, FLUSHO)) {
--- 444 unchanged lines hidden (view full) ---
2406 /* Print load average. */
2407 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2408 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2409
2410 if (tp->t_session == NULL)
2411 ttyprintf(tp, "not a controlling terminal\n");
2412 else if (tp->t_pgrp == NULL)
2413 ttyprintf(tp, "no foreground process group\n");
2414 else {
2415 PGRP_LOCK(tp->t_pgrp);
2416 if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) {
2417 PGRP_UNLOCK(tp->t_pgrp);
2418 ttyprintf(tp, "empty foreground process group\n");
2419 } else {
2420 PGRP_UNLOCK(tp->t_pgrp);
2421 mtx_lock_spin(&sched_lock);
2422
2423 /* Pick interesting process. */
2424 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
2425 if (proc_compare(pick, p))
2426 pick = p;
2427
2428 td = FIRST_THREAD_IN_PROC(pick);
2429 stmp = pick->p_stat == SRUN ? "running" : /* XXXKSE */
2430 td->td_wmesg ? td->td_wmesg : "iowait";
2431 calcru(pick, &utime, &stime, NULL);
2432 ltmp = pick->p_stat == SIDL || pick->p_stat == SWAIT ||
2433 pick->p_stat == SZOMB ? 0 :
2434 pgtok(vmspace_resident_count(pick->p_vmspace));
2435 mtx_unlock_spin(&sched_lock);
2436
2437 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
2438 stmp);
2439
2440 /* Print user time. */
2441 ttyprintf(tp, "%lld.%02ldu ",
2442 utime.tv_sec, utime.tv_usec / 10000);
2443
2444 /* Print system time. */
2445 ttyprintf(tp, "%ld.%02lds ",
2446 (long)stime.tv_sec, stime.tv_usec / 10000);
2447
2448 /* Print percentage cpu, resident set size. */
2449 ttyprintf(tp, "%d%% %ldk\n", tmp / 100, ltmp);
2450
2451 }
2452 }
2453 tp->t_rocount = 0; /* so pending input will be retyped if BS */
2454}
2455
2456/*
2457 * Returns 1 if p2 is "better" than p1
2458 *
2459 * The algorithm for picking the "interesting" process is thus:
--- 224 unchanged lines hidden ---
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 91140 2002-02-23 11:12:57Z tanimura $
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#include <sys/sx.h>
79#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
80#include <sys/ioctl_compat.h>
81#endif
82#include <sys/proc.h>
83#define TTYDEFCHARS
84#include <sys/tty.h>
85#undef TTYDEFCHARS
86#include <sys/fcntl.h>
--- 237 unchanged lines hidden (view full) ---
324 err = (ISSET(c, TTY_ERRORMASK));
325 if (err) {
326 CLR(c, TTY_ERRORMASK);
327 if (ISSET(err, TTY_BI)) {
328 if (ISSET(iflag, IGNBRK))
329 return (0);
330 if (ISSET(iflag, BRKINT)) {
331 ttyflush(tp, FREAD | FWRITE);
332 if (tp->t_pgrp != NULL) {
333 PGRP_LOCK(tp->t_pgrp);
334 pgsignal(tp->t_pgrp, SIGINT, 1);
335 PGRP_UNLOCK(tp->t_pgrp);
336 }
337 goto endcase;
338 }
339 if (ISSET(iflag, PARMRK))
340 goto parmrk;
341 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
342 || ISSET(err, TTY_FE)) {
343 if (ISSET(iflag, IGNPAR))
344 return (0);
--- 61 unchanged lines hidden (view full) ---
406 /*
407 * Signals.
408 */
409 if (ISSET(lflag, ISIG)) {
410 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
411 if (!ISSET(lflag, NOFLSH))
412 ttyflush(tp, FREAD | FWRITE);
413 ttyecho(c, tp);
414 if (tp->t_pgrp != NULL) {
415 PGRP_LOCK(tp->t_pgrp);
416 pgsignal(tp->t_pgrp,
417 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
418 PGRP_UNLOCK(tp->t_pgrp);
419 }
420 goto endcase;
421 }
422 if (CCEQ(cc[VSUSP], c)) {
423 if (!ISSET(lflag, NOFLSH))
424 ttyflush(tp, FREAD);
425 ttyecho(c, tp);
426 if (tp->t_pgrp != NULL) {
427 PGRP_LOCK(tp->t_pgrp);
428 pgsignal(tp->t_pgrp, SIGTSTP, 1);
429 PGRP_UNLOCK(tp->t_pgrp);
430 }
431 goto endcase;
432 }
433 }
434 /*
435 * Handle start/stop characters.
436 */
437 if (ISSET(iflag, IXON)) {
438 if (CCEQ(cc[VSTOP], c)) {
--- 101 unchanged lines hidden (view full) ---
540 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
541 ttyretype(tp);
542 goto endcase;
543 }
544 /*
545 * ^T - kernel info and generate SIGINFO
546 */
547 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
548 if (ISSET(lflag, ISIG) && tp->t_pgrp != NULL) {
549 PGRP_LOCK(tp->t_pgrp);
550 pgsignal(tp->t_pgrp, SIGINFO, 1);
551 PGRP_UNLOCK(tp->t_pgrp);
552 }
553 if (!ISSET(lflag, NOKERNINFO))
554 ttyinfo(tp);
555 goto endcase;
556 }
557 }
558 /*
559 * Check for input buffer overflow
560 */
--- 202 unchanged lines hidden (view full) ---
763 case TIOCLBIS:
764 case TIOCLSET:
765 case TIOCSETC:
766 case OTIOCSETD:
767 case TIOCSETN:
768 case TIOCSETP:
769 case TIOCSLTC:
770#endif
771 PGRPSESS_SLOCK();
772 PROC_LOCK(p);
773 while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
774 !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
775 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
776 if (p->p_pgrp->pg_jobc == 0) {
777 PROC_UNLOCK(p);
778 PGRPSESS_SUNLOCK();
779 return (EIO);
780 }
781 PROC_UNLOCK(p);
782 PGRP_LOCK(p->p_pgrp);
783 pgsignal(p->p_pgrp, SIGTTOU, 1);
784 PGRP_UNLOCK(p->p_pgrp);
785 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1",
786 0);
787 if (error) {
788 PGRPSESS_SUNLOCK();
789 return (error);
790 }
791 PROC_LOCK(p);
792 }
793 PROC_UNLOCK(p);
794 PGRPSESS_SUNLOCK();
795 break;
796 }
797
798 switch (cmd) { /* Process the ioctl. */
799 case FIOASYNC: /* set/clear async i/o */
800 s = spltty();
801 if (*(int *)data)
802 SET(tp->t_state, TS_ASYNC);
--- 233 unchanged lines hidden (view full) ---
1036 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1037 SET(tp->t_state, TS_TTSTOP);
1038 (*tp->t_stop)(tp, 0);
1039 }
1040 splx(s);
1041 break;
1042 case TIOCSCTTY: /* become controlling tty */
1043 /* Session ctty vnode pointer set in vnode layer. */
1044 PGRPSESS_XLOCK();
1045 if (!SESS_LEADER(p) ||
1046 ((p->p_session->s_ttyvp || tp->t_session) &&
1047 (tp->t_session != p->p_session))) {
1048 PGRPSESS_XUNLOCK();
1049 return (EPERM);
1050 }
1051 tp->t_session = p->p_session;
1052 tp->t_pgrp = p->p_pgrp;
1053 SESS_LOCK(p->p_session);
1054 p->p_session->s_ttyp = tp;
1055 SESS_UNLOCK(p->p_session);
1056 PROC_LOCK(p);
1057 p->p_flag |= P_CONTROLT;
1058 PROC_UNLOCK(p);
1059 PGRPSESS_XUNLOCK();
1060 break;
1061 case TIOCSPGRP: { /* set pgrp of tty */
1062 register struct pgrp *pgrp;
1063
1064 PGRPSESS_SLOCK();
1065 pgrp = pgfind(*(int *)data);
1066 if (!isctty(p, tp)) {
1067 if (pgrp != NULL)
1068 PGRP_UNLOCK(pgrp);
1069 PGRPSESS_SUNLOCK();
1070 return (ENOTTY);
1071 }
1072 if (pgrp == NULL) {
1073 PGRPSESS_SUNLOCK();
1074 return (EPERM);
1075 }
1076 PGRP_UNLOCK(pgrp);
1077 if (pgrp->pg_session != p->p_session) {
1078 PGRPSESS_SUNLOCK();
1079 return (EPERM);
1080 }
1081 PGRPSESS_SUNLOCK();
1082 tp->t_pgrp = pgrp;
1083 break;
1084 }
1085 case TIOCSTAT: /* simulate control-T */
1086 s = spltty();
1087 ttyinfo(tp);
1088 splx(s);
1089 break;
1090 case TIOCSWINSZ: /* set window size */
1091 if (bcmp((caddr_t)&tp->t_winsize, data,
1092 sizeof (struct winsize))) {
1093 tp->t_winsize = *(struct winsize *)data;
1094 if (tp->t_pgrp != NULL) {
1095 PGRP_LOCK(tp->t_pgrp);
1096 pgsignal(tp->t_pgrp, SIGWINCH, 1);
1097 PGRP_UNLOCK(tp->t_pgrp);
1098 }
1099 }
1100 break;
1101 case TIOCSDRAINWAIT:
1102 error = suser_xxx(p->p_ucred, NULL, 0);
1103 if (error)
1104 return (error);
1105 tp->t_timeout = *(int *)data * hz;
1106 wakeup(TSA_OCOMPLETE(tp));
--- 402 unchanged lines hidden (view full) ---
1509 /*
1510 * Lost carrier.
1511 */
1512 CLR(tp->t_state, TS_CARR_ON);
1513 if (ISSET(tp->t_state, TS_ISOPEN) &&
1514 !ISSET(tp->t_cflag, CLOCAL)) {
1515 SET(tp->t_state, TS_ZOMBIE);
1516 CLR(tp->t_state, TS_CONNECTED);
1517 if (tp->t_session) {
1518 PGRPSESS_SLOCK();
1519 if (tp->t_session->s_leader) {
1520 struct proc *p;
1521
1522 p = tp->t_session->s_leader;
1523 PROC_LOCK(p);
1524 psignal(p, SIGHUP);
1525 PROC_UNLOCK(p);
1526 }
1527 PGRPSESS_SUNLOCK();
1528 }
1529 ttyflush(tp, FREAD | FWRITE);
1530 return (0);
1531 }
1532 } else {
1533 /*
1534 * Carrier now on.
1535 */
--- 67 unchanged lines hidden (view full) ---
1603 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
1604 }
1605
1606 /*
1607 * Hang process if it's in the background.
1608 */
1609 if (isbackground(p, tp)) {
1610 splx(s);
1611 PGRPSESS_SLOCK();
1612 PROC_LOCK(p);
1613 if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
1614 SIGISMEMBER(p->p_sigmask, SIGTTIN) ||
1615 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) {
1616 PROC_UNLOCK(p);
1617 PGRPSESS_SUNLOCK();
1618 return (EIO);
1619 }
1620 PROC_UNLOCK(p);
1621 PGRP_LOCK(p->p_pgrp);
1622 PGRPSESS_SUNLOCK();
1623 pgsignal(p->p_pgrp, SIGTTIN, 1);
1624 PGRP_UNLOCK(p->p_pgrp);
1625 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1626 if (error)
1627 return (error);
1628 goto loop;
1629 }
1630
1631 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1632 splx(s);
--- 157 unchanged lines hidden (view full) ---
1790 goto loop;
1791 break;
1792 }
1793 /*
1794 * delayed suspend (^Y)
1795 */
1796 if (CCEQ(cc[VDSUSP], c) &&
1797 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1798 if (tp->t_pgrp != NULL) {
1799 PGRP_LOCK(tp->t_pgrp);
1800 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1801 PGRP_UNLOCK(tp->t_pgrp);
1802 }
1803 if (first) {
1804 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1805 "ttybg3", 0);
1806 if (error)
1807 break;
1808 goto loop;
1809 }
1810 break;
--- 111 unchanged lines hidden (view full) ---
1922 goto out;
1923 goto loop;
1924 }
1925 splx(s);
1926 /*
1927 * Hang the process if it's in the background.
1928 */
1929 p = curproc;
1930 PGRPSESS_SLOCK();
1931 PROC_LOCK(p);
1932 if (isbackground(p, tp) &&
1933 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
1934 !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
1935 !SIGISMEMBER(p->p_sigmask, SIGTTOU)) {
1936 if (p->p_pgrp->pg_jobc == 0) {
1937 PROC_UNLOCK(p);
1938 PGRPSESS_SUNLOCK();
1939 error = EIO;
1940 goto out;
1941 }
1942 PROC_UNLOCK(p);
1943 PGRP_LOCK(p->p_pgrp);
1944 PGRPSESS_SUNLOCK();
1945 pgsignal(p->p_pgrp, SIGTTOU, 1);
1946 PGRP_UNLOCK(p->p_pgrp);
1947 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
1948 if (error)
1949 goto out;
1950 goto loop;
1951 } else {
1952 PROC_UNLOCK(p);
1953 PGRPSESS_SUNLOCK();
1954 }
1955 /*
1956 * Process the user's data in at most OBUFSIZ chunks. Perform any
1957 * output translation. Keep track of high water mark, sleep on
1958 * overflow awaiting device aid in acquiring new space.
1959 */
1960 while (uio->uio_resid > 0 || cc > 0) {
1961 if (ISSET(tp->t_lflag, FLUSHO)) {
--- 444 unchanged lines hidden (view full) ---
2406 /* Print load average. */
2407 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2408 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2409
2410 if (tp->t_session == NULL)
2411 ttyprintf(tp, "not a controlling terminal\n");
2412 else if (tp->t_pgrp == NULL)
2413 ttyprintf(tp, "no foreground process group\n");
2414 else {
2415 PGRP_LOCK(tp->t_pgrp);
2416 if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) {
2417 PGRP_UNLOCK(tp->t_pgrp);
2418 ttyprintf(tp, "empty foreground process group\n");
2419 } else {
2420 PGRP_UNLOCK(tp->t_pgrp);
2421 mtx_lock_spin(&sched_lock);
2422
2423 /* Pick interesting process. */
2424 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
2425 if (proc_compare(pick, p))
2426 pick = p;
2427
2428 td = FIRST_THREAD_IN_PROC(pick);
2429 stmp = pick->p_stat == SRUN ? "running" : /* XXXKSE */
2430 td->td_wmesg ? td->td_wmesg : "iowait";
2431 calcru(pick, &utime, &stime, NULL);
2432 ltmp = pick->p_stat == SIDL || pick->p_stat == SWAIT ||
2433 pick->p_stat == SZOMB ? 0 :
2434 pgtok(vmspace_resident_count(pick->p_vmspace));
2435 mtx_unlock_spin(&sched_lock);
2436
2437 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
2438 stmp);
2439
2440 /* Print user time. */
2441 ttyprintf(tp, "%lld.%02ldu ",
2442 utime.tv_sec, utime.tv_usec / 10000);
2443
2444 /* Print system time. */
2445 ttyprintf(tp, "%ld.%02lds ",
2446 (long)stime.tv_sec, stime.tv_usec / 10000);
2447
2448 /* Print percentage cpu, resident set size. */
2449 ttyprintf(tp, "%d%% %ldk\n", tmp / 100, ltmp);
2450
2451 }
2452 }
2453 tp->t_rocount = 0; /* so pending input will be retyped if BS */
2454}
2455
2456/*
2457 * Returns 1 if p2 is "better" than p1
2458 *
2459 * The algorithm for picking the "interesting" process is thus:
--- 224 unchanged lines hidden ---