date and time created 88/12/22 13:04:38 by sam
[unix-history] / usr / src / usr.bin / w / w.c
index 5569073..c7292d1 100644 (file)
@@ -11,7 +11,7 @@ char copyright[] =
 #endif not lint
 
 #ifndef lint
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)w.c        5.3 (Berkeley) %G%";
+static char sccsid[] = "@(#)w.c        5.9 (Berkeley) %G%";
 #endif not lint
 
 /*
 #endif not lint
 
 /*
@@ -29,11 +29,14 @@ static char sccsid[] = "@(#)w.c     5.3 (Berkeley) %G%";
 #include <sys/dir.h>
 #include <sys/user.h>
 #include <sys/proc.h>
 #include <sys/dir.h>
 #include <sys/user.h>
 #include <sys/proc.h>
+#include <sys/ioctl.h>
 #include <machine/pte.h>
 #include <sys/vm.h>
 #include <machine/pte.h>
 #include <sys/vm.h>
+#include <sys/tty.h>
 
 #define NMAX sizeof(utmp.ut_name)
 #define LMAX sizeof(utmp.ut_line)
 
 #define NMAX sizeof(utmp.ut_name)
 #define LMAX sizeof(utmp.ut_line)
+#define HMAX sizeof(utmp.ut_host)
 
 #define ARGWIDTH       33      /* # chars left on 80 col crt for args */
 
 
 #define ARGWIDTH       33      /* # chars left on 80 col crt for args */
 
@@ -54,20 +57,20 @@ struct pr {
 int    nproc;
 
 struct nlist nl[] = {
 int    nproc;
 
 struct nlist nl[] = {
+       { "_avenrun" },
+#define        X_AVENRUN       0
+       { "_boottime" },
+#define        X_BOOTTIME      1
        { "_proc" },
        { "_proc" },
-#define        X_PROC          0
+#define        X_PROC          2
        { "_swapdev" },
        { "_swapdev" },
-#define        X_SWAPDEV       1
+#define        X_SWAPDEV       3
        { "_Usrptmap" },
        { "_Usrptmap" },
-#define        X_USRPTMA       2
+#define        X_USRPTMA       4
        { "_usrpt" },
        { "_usrpt" },
-#define        X_USRPT         3
+#define        X_USRPT         5
        { "_nswap" },
        { "_nswap" },
-#define        X_NSWAP         4
-       { "_avenrun" },
-#define        X_AVENRUN       5
-       { "_boottime" },
-#define        X_BOOTTIME      6
+#define        X_NSWAP         6
        { "_nproc" },
 #define        X_NPROC         7
        { "_dmmin" },
        { "_nproc" },
 #define        X_NPROC         7
        { "_dmmin" },
@@ -91,13 +94,13 @@ char        doing[520];             /* process attached to terminal */
 time_t proctime;               /* cpu time of process in doing */
 double avenrun[3];
 struct proc *aproc;
 time_t proctime;               /* cpu time of process in doing */
 double avenrun[3];
 struct proc *aproc;
+struct  tty ttyent;
 
 #define        DIV60(t)        ((t+30)/60)    /* x/60 rounded */ 
 
 #define        DIV60(t)        ((t+30)/60)    /* x/60 rounded */ 
-#define        TTYEQ           (tty == pr[i].w_tty && uid == pr[i].w_uid)
+#define        TTYEQ           (tty == pr[i].w_tty)
 #define IGINT          (1+3*1)         /* ignoring both SIGINT & SIGQUIT */
 
 char   *getargs();
 #define IGINT          (1+3*1)         /* ignoring both SIGINT & SIGQUIT */
 
 char   *getargs();
-char   *fread();
 char   *ctime();
 char   *rindex();
 FILE   *popen();
 char   *ctime();
 char   *rindex();
 FILE   *popen();
@@ -105,8 +108,10 @@ struct     tm *localtime();
 time_t findidle();
 
 int    debug;                  /* true if -d flag: debugging output */
 time_t findidle();
 
 int    debug;                  /* true if -d flag: debugging output */
+int    ttywidth = 80;          /* width of tty */
 int    header = 1;             /* true if -h flag: don't print heading */
 int    lflag = 1;              /* true if -l flag: long style output */
 int    header = 1;             /* true if -h flag: don't print heading */
 int    lflag = 1;              /* true if -l flag: long style output */
+int    prfrom = 1;             /* true if not -f flag: print host from */
 int    login;                  /* true if invoked as login shell */
 time_t idle;                   /* number of minutes user is idle */
 int    nusers;                 /* number of users logged in now */
 int    login;                  /* true if invoked as login shell */
 time_t idle;                   /* number of minutes user is idle */
 int    nusers;                 /* number of users logged in now */
@@ -132,6 +137,7 @@ main(argc, argv)
        register int i, j;
        char *cp;
        register int curpid, empty;
        register int i, j;
        char *cp;
        register int curpid, empty;
+       struct winsize win;
 
        login = (argv[0][0] == '-');
        cp = rindex(argv[0], '/');
 
        login = (argv[0][0] == '-');
        cp = rindex(argv[0], '/');
@@ -147,6 +153,10 @@ main(argc, argv)
                                        debug++;
                                        break;
 
                                        debug++;
                                        break;
 
+                               case 'f':
+                                       prfrom = !prfrom;
+                                       break;
+
                                case 'h':
                                        header = 0;
                                        break;
                                case 'h':
                                        header = 0;
                                        break;
@@ -171,7 +181,7 @@ main(argc, argv)
                        }
                } else {
                        if (!isalnum(argv[1][0]) || argc > 2) {
                        }
                } else {
                        if (!isalnum(argv[1][0]) || argc > 2) {
-                               printf("Usage: %s [ -hlsuw ] [ user ]\n", cp);
+                               printf("Usage: %s [ -hlsfuw ] [ user ]\n", cp);
                                exit(1);
                        } else
                                sel_user = argv[1];
                                exit(1);
                        } else
                                sel_user = argv[1];
@@ -189,8 +199,13 @@ main(argc, argv)
                exit(1);
        }
 
                exit(1);
        }
 
-       if (firstchar != 'u')
+       if (firstchar == 'u')   /* uptime(1) */
+               nl[X_BOOTTIME+1].n_name = "";
+       else {                  /* then read in procs, get window size */
                readpr();
                readpr();
+               if (ioctl(1, TIOCGWINSZ, &win) != -1 && win.ws_col > 70)
+                       ttywidth = win.ws_col;
+       }
 
        ut = fopen("/etc/utmp","r");
        time(&now);
 
        ut = fopen("/etc/utmp","r");
        time(&now);
@@ -246,12 +261,16 @@ main(argc, argv)
                        printf(" %.2f", avenrun[i]);
                }
                printf("\n");
                        printf(" %.2f", avenrun[i]);
                }
                printf("\n");
-               if (firstchar == 'u')
+               if (firstchar == 'u')   /* if this was uptime(1), finished */
                        exit(0);
 
                /* Headers for rest of output */
                        exit(0);
 
                /* Headers for rest of output */
-               if (lflag)
+               if (lflag && prfrom)
+                       printf("User     tty from           login@  idle   JCPU   PCPU  what\n");
+               else if (lflag)
                        printf("User     tty       login@  idle   JCPU   PCPU  what\n");
                        printf("User     tty       login@  idle   JCPU   PCPU  what\n");
+               else if (prfrom)
+                       printf("User    tty from            idle  what\n");
                else
                        printf("User    tty  idle  what\n");
                fflush(stdout);
                else
                        printf("User    tty  idle  what\n");
                fflush(stdout);
@@ -337,45 +356,60 @@ gettty()
 putline()
 {
        register int tm;
 putline()
 {
        register int tm;
+       int width = ttywidth - 1;
 
        /* print login name of the user */
        printf("%-*.*s ", NMAX, NMAX, utmp.ut_name);
 
        /* print login name of the user */
        printf("%-*.*s ", NMAX, NMAX, utmp.ut_name);
+       width -= NMAX + 1;
 
        /* print tty user is on */
 
        /* print tty user is on */
-       if (lflag)
+       if (lflag && !prfrom) {
                /* long form: all (up to) LMAX chars */
                printf("%-*.*s", LMAX, LMAX, utmp.ut_line);
                /* long form: all (up to) LMAX chars */
                printf("%-*.*s", LMAX, LMAX, utmp.ut_line);
-       else {
+               width -= LMAX;
+        } else {
                /* short form: 2 chars, skipping 'tty' if there */
                if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y')
                        printf("%-2.2s", &utmp.ut_line[3]);
                else
                        printf("%-2.2s", utmp.ut_line);
                /* short form: 2 chars, skipping 'tty' if there */
                if (utmp.ut_line[0]=='t' && utmp.ut_line[1]=='t' && utmp.ut_line[2]=='y')
                        printf("%-2.2s", &utmp.ut_line[3]);
                else
                        printf("%-2.2s", utmp.ut_line);
+               width -= 2;
        }
 
        }
 
-       if (lflag)
+       if (prfrom) {
+               printf(" %-14.14s", utmp.ut_host);
+               width -= 15;
+       }
+
+       if (lflag) {
                /* print when the user logged in */
                prtat(&utmp.ut_time);
                /* print when the user logged in */
                prtat(&utmp.ut_time);
+               width -= 8;
+       }
 
        /* print idle time */
        if (idle >= 36 * 60)
                printf("%2ddays ", (idle + 12 * 60) / (24 * 60));
        else
                prttime(idle," ");
 
        /* print idle time */
        if (idle >= 36 * 60)
                printf("%2ddays ", (idle + 12 * 60) / (24 * 60));
        else
                prttime(idle," ");
+       width -= 7;
 
        if (lflag) {
                /* print CPU time for all processes & children */
                prttime(jobtime," ");
 
        if (lflag) {
                /* print CPU time for all processes & children */
                prttime(jobtime," ");
+               width -= 7;
                /* print cpu time for interesting process */
                prttime(proctime," ");
                /* print cpu time for interesting process */
                prttime(proctime," ");
+               width -= 7;
        }
 
        /* what user is doing, either command tail or args */
        }
 
        /* what user is doing, either command tail or args */
-       printf(" %-.32s\n",doing);
+       printf(" %-.*s\n", width-1, doing);
        fflush(stdout);
 }
 
 /* find & return number of minutes current tty has been idle */
        fflush(stdout);
 }
 
 /* find & return number of minutes current tty has been idle */
+time_t
 findidle()
 {
        struct stat stbuf;
 findidle()
 {
        struct stat stbuf;
@@ -447,6 +481,11 @@ prtat(time)
 /*
  * readpr finds and reads in the array pr, containing the interesting
  * parts of the proc and user tables for each live process.
 /*
  * readpr finds and reads in the array pr, containing the interesting
  * parts of the proc and user tables for each live process.
+ * We only accept procs whos controlling tty has a pgrp equal to the
+ * pgrp of the proc.  This accurately defines the notion of the current
+ * process(s), but because of time skew, we always read in the tty struct
+ * after reading the proc, even though the same tty struct may have been
+ * read earlier on.
  */
 readpr()
 {
  */
 readpr()
 {
@@ -492,7 +531,8 @@ readpr()
                lseek(kmem, (int)(aproc + pn), 0);
                read(kmem, &mproc, sizeof mproc);
                /* decide if it's an interesting process */
                lseek(kmem, (int)(aproc + pn), 0);
                read(kmem, &mproc, sizeof mproc);
                /* decide if it's an interesting process */
-               if (mproc.p_stat==0 || mproc.p_stat==SZOMB || mproc.p_pgrp==0)
+               if (mproc.p_stat==0 || mproc.p_stat==SZOMB 
+                   || mproc.p_stat==SSTOP || mproc.p_pgrp==0)
                        continue;
                /* find & read in the user structure */
                if ((mproc.p_flag & SLOAD) == 0) {
                        continue;
                /* find & read in the user structure */
                if ((mproc.p_flag & SLOAD) == 0) {
@@ -531,6 +571,13 @@ cont:
                if (up.u_ttyp == NULL)
                        continue;
 
                if (up.u_ttyp == NULL)
                        continue;
 
+               /* only include a process whose tty has a pgrp which matchs its own */
+               lseek(kmem, (long)up.u_ttyp, 0);
+               if (read(kmem, &ttyent, sizeof(ttyent)) != sizeof(ttyent))
+                       continue;
+               if (ttyent.t_pgrp != mproc.p_pgrp)
+                       continue;
+
                /* save the interesting parts */
                pr[np].w_pid = mproc.p_pid;
                pr[np].w_flag = mproc.p_flag;
                /* save the interesting parts */
                pr[np].w_pid = mproc.p_pid;
                pr[np].w_flag = mproc.p_flag;