home *** CD-ROM | disk | FTP | other *** search
- From: allbery@ncoast.UUCP (Brandon S. Allbery)
- Newsgroups: comp.sources.misc
- Subject: Load average, "w", and status line for USG systems
- Message-ID: <3733@ncoast.UUCP>
- Date: 2 Aug 87 19:12:50 GMT
- Sender: allbery@ncoast.UUCP
- Organization: Cleveland Public Access UN*X, Cleveland, Oh
- Lines: 1447
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8708/1
-
- Herein are some programs I use under System V. They are:
-
- avenrun -- a daemon which calculates an approximate load average from the
- "runque" and "runocc" parameters in the kernel "sysinfo" structure.
- Thanks to Phil Budne for the original, which forged "rwho" packets
- for USG systems on BSD networks; this one puts its load average into
- an array of 3 (double)'s in a shm segment identified by ftok("/unix",
- 'a').
-
- w -- The BSD "w" program, large as life. It works as expected, except that
- the "JCPU" is a kludge; USG doesn't keep per-session CPU time.
-
- csl -- A status line program. It displays things in "panels" which "rotate"
- every 5 seconds. The information displayed is:
-
- - sender and subject of mail in your mailbox,
- one message per panel
- - current program (if possible), login name,
- # of messages in mailbox, current date/time
- - full name and terminal (useful!), # non-daemons
- running
- - list of system users, similar to "who -q"
- - lines from $HOME/.messages, one per panel
-
- I've been using these for a few months without problems. Enjoy!
- ++Brandon
-
- #--------------------------------CUT HERE-------------------------------------
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # -rw-r--r-- 1 allbery System 1579 May 7 22:09 README.w
- # -rw-r--r-- 1 allbery System 8210 May 7 21:52 avenrun.c
- # -rw-r--r-- 1 allbery System 8313 May 7 21:52 csl.c
- # -rw-r--r-- 1 allbery System 7909 May 7 21:28 w.c
- # -rw-r--r-- 1 allbery System 1023 May 7 22:51 avenrun.1m
- # -rw-r--r-- 1 allbery System 3217 May 7 22:39 csl.1l
- # -rw-r--r-- 1 allbery System 3056 May 7 23:12 w.1l
- #
- echo 'x - README.w'
- if test -f README.w; then echo 'shar: not overwriting README.w'; else
- sed 's/^X//' << '________This_Is_The_END________' > README.w
- XThe following are some programs which give you some familiar BSD utilities
- Xin a System V environment. The programs are:
- X
- X w - Yes, "w", as big as life! Requires...
- X avenrun - A program to be invoked in /etc/rc which computes
- X a "load average" from information in the "sysinfo"
- X structure of the kernel. Based on a program by
- X Phil Budne which forges "rwhod" packets for mixed
- X networks; #define RWHOD for the original program.
- X csl - I have no idea what the BSD "sysline" does, but this
- X is my idea of a status line. The name stands for
- X "cyclic status line"; it doesn't even attempt to
- X fit everything into one line, instead it cycles
- X through a set of "panels". See the man page.
- X This also wants "avenrun" to be running.
- X
- XNote that "w" (and ONLY "w") can be compiled for System III or Xenix 3.0;
- Xthis is in fact the default, use -DSYS5 to get the full version.
- X
- XNo Makefile; the compile commands are trivial:
- X
- X cc -O -o w w.c -DSYS5 # omit the -DSYS5 for System III
- X cc -O -o avenrun avenrun.c # add -DRWHOD for rwhod forgery
- X cc -O -o csl csl.c
- X
- X"w" requires read permission on /dev/kmem, /dev/mem, and /dev/swap. "avenrun"
- Xrequires read permission on /dev/kmem (to read the sysinfo structure). "csl"
- Xcan run as a normal user program. On tdi2 we keep /dev/*mem and /dev/swap
- X-r--r----- root/sys and have "avenrun" and "w" setgid sys.
- X
- XIf someone wants to tell me what "sysline" under BSD does, I'd be interested
- Xin writing a real one. But "csl" is everything in one small package, so I
- Xwill probably continue to use it.
- X
- XEnjoy!
- X
- X++Brando
- ________This_Is_The_END________
- if test `wc -l < README.w` -ne 37; then
- echo 'shar: README.w was damaged during transit (should have been 37 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - avenrun.c'
- if test -f avenrun.c; then echo 'shar: not overwriting avenrun.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > avenrun.c
- X/*
- X * ldavg.c -- compute load averages for System V
- X * Phil Budne @ Boston U / DSG
- X *
- X * Forges BSD 4.2 rwhod packets containing system load averages
- X * (#ifdef RWHOD for this, else a shm segment is used, ftok("/unix", 'a'))
- X */
- X
- X# include <sys/types.h> /* system types */
- X# include <sys/sysinfo.h> /* sysinfo structure */
- X# include <sys/utsname.h> /* for uname(2) */
- X# include <sys/stat.h> /* for stat(2) */
- X# include <sys/param.h> /* for HZ */
- X# include <stdio.h>
- X# include <nlist.h>
- X# include <time.h>
- X# include <math.h>
- X# include <utmp.h>
- X# include <fcntl.h>
- X#ifdef RWHOD
- X# include "rwhod.h" /* (from BSD) */
- X#else SHM
- X# include <sys/ipc.h>
- X# include <sys/shm.h>
- X#endif RWHOD
- X
- X/* # define DEBUG /**/
- X#ifdef RWHOD
- X# define UDP 1
- X# define DSK 1
- X# define PMUL 100
- X
- X# if UDP
- X# include "netdb.h"
- Xunsigned short port = 513;
- Xunsigned long ipaddr;
- X# endif
- X#endif RWHOD
- X
- Xextern struct utmp *getutent();
- X
- X# define SYSTEM "/unix"
- X# define KMEM "/dev/kmem"
- X
- Xstruct nlist nl[] = {
- X# define NL_SYSINFO 0
- X { "_sysinfo" }, /* 0 */
- X# define NL_LBOLT 1
- X { "_lbolt" }, /* 1 */
- X { 0 }
- X};
- X
- X#ifdef RWHOD
- Xstruct whod proto;
- Xstruct utsname utsn;
- Xchar whopacket[100];
- X#else SHM
- Xkey_t aven_key;
- Xint aven_shm;
- Xdouble *aven_seg;
- X#endif RWHOD
- Xint fd, memfd;
- X
- Xchar *system = SYSTEM;
- Xchar *kmem = KMEM;
- Xchar *argv0;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X switch (fork()) {
- X case -1:
- X perror("fork");
- X exit(1);
- X case 0:
- X break;
- X default:
- X exit(0);
- X }
- X argv0 = argv[0];
- X#ifdef RWHOD
- X uname(&utsn); /* get system names */
- X#endif RWHOD
- X setpgrp(); /* create own pgrp */
- X init_nlist(); /* get name values, open kmem */
- X init_packet(); /* initialize packet prototype */
- X doit(); /* never returns */
- X} /* main */
- X
- Xinit_nlist() {
- X nlist(system, nl); /* get system values */
- X
- X if(nl[NL_SYSINFO].n_value == 0) {
- X fprintf(stderr, "%s: can't find sysinf structure\n", argv0);
- X exit(1);
- X } /* no value */
- X
- X if ((memfd = open(kmem, O_RDONLY)) < 0) {
- X fprintf(stderr, "%s: no mem\n", argv0);
- X exit(1);
- X } /* could not open kmem */
- X
- X} /* init_nlist */
- X
- X# define PERIOD 5 /* sample period (in seconds) */
- X# define INTERVAL1 60 /* average interval 1 (in seconds) */
- X# define INTERVAL2 (5*60) /* average interval 2 (in seconds) */
- X# define INTERVAL3 (15*60) /* average interval 3 (in seconds) */
- X# define PACKINTERVAL 30 /* interval for make_packet */
- X
- Xdoit() {
- X struct sysinfo sinf;
- X int packt = 0;
- X long occ, que, nocc, nque, n, c;
- X double avg1, avg2, avg3, new;
- X double exp1, exp2, exp3;
- X
- X exp1 = exp( - ((double) PERIOD) / INTERVAL1 );
- X exp2 = exp( - ((double) PERIOD) / INTERVAL2 );
- X exp3 = exp( - ((double) PERIOD) / INTERVAL3 );
- X
- X getsysinf(&sinf); /* prime the pump */
- X occ = sinf.runocc; /* number of samples */
- X que = sinf.runque; /* run queue summation */
- X
- X avg1 = avg2 = avg3 = ((double) que) / occ;
- X
- X for( ; ; ) {
- X if( --packt < 0 ) {
- X#ifdef RWHOD
- X make_packet((int) (avg1 * PMUL),
- X (int) (avg2 * PMUL),
- X (int) (avg3 * PMUL));
- X#else SHM
- X make_packet(avg1, avg2, avg3);
- X#endif RWHOD
- X packt = PACKINTERVAL / PERIOD;
- X } /* packet time */
- X
- X/* printf("runque: %ld runocc: %ld\n", que, occ ); /**/
- X
- X sleep(PERIOD);
- X getsysinf(&sinf); /* get new info */
- X nocc = sinf.runocc;
- X nque = sinf.runque;
- X
- X n = nocc - occ; /* get number of times updated */
- X if( n <= 0 ) continue;
- X c = nque - que - n; /* get number of runners w/o us */
- X if( c < 0 ) c = 0; /* mumble! */
- X
- X new = ((double) c ) / n; /* new instantaneous avg */
- X
- X /************************************************/
- X /* The following formula is used to achieve */
- X /* exponential decay of old measurements: */
- X /* avgN = avgN * expN + new * (1 - expN) */
- X /* */
- X /* However, the factorized forms below */
- X /* require fewer floating point operations. */
- X /************************************************/
- X
- X avg1 = ((avg1 - new) * exp1) + new;
- X avg2 = ((avg2 - new) * exp2) + new;
- X avg3 = ((avg3 - new) * exp3) + new;
- X
- X occ = nocc;
- X que = nque;
- X
- X } /* for ever */
- X} /* doit */
- X
- Xgetsysinf(s)
- Xstruct sysinfo *s;
- X{
- X l_lseek(memfd, (long)nl[NL_SYSINFO].n_value, 0);
- X r_read(memfd, (char *)s, sizeof(struct sysinfo));
- X}
- X
- X/* lseek with error checking */
- Xl_lseek(fd, offset, whence)
- Xint fd, whence;
- Xlong offset;
- X{
- X if (lseek(fd, offset, whence) == -1) {
- X fprintf(stderr, "%s: error on lseek\n", argv0);
- X exit(1);
- X }
- X}
- X
- X/* read with error checking */
- Xr_read (fd, buf, nbytes)
- Xint fd, nbytes;
- Xchar *buf;
- X{
- X if (read(fd, buf, nbytes) != nbytes) {
- X fprintf(stderr, "%s: error on read\n", argv0);
- X exit(1);
- X }
- X}
- X
- Xinit_packet() {
- X#ifdef RWHOD
- X time_t boothz;
- X# if UDP
- X struct hostent *he;
- X
- X he = gethostbyname( "localnet" );
- X if( he == NULL || he->h_addr == 0 ) {
- X fprintf(stderr, "no address: localnet\n");
- X exit( 1 );
- X }
- X ipaddr = he->h_addr;
- X# endif
- X# if DSK
- X sprintf(whopacket, "/usr/spool/rwho/whod.%s", utsn.nodename);
- X# endif
- X memset(&proto, '\0', sizeof proto); /* clear proto packet */
- X
- X strncat(proto.wd_hostname, utsn.nodename, 9); /* at most 9, add null */
- X proto.wd_vers = WHODVERSION;
- X proto.wd_type = WHODTYPE_STATUS;
- X
- X l_lseek(memfd, (long)nl[NL_LBOLT].n_value, 0);
- X r_read(memfd, (char *)&boothz, sizeof( boothz ) );
- X proto.wd_boottime = time(0) - (boothz / HZ);
- X#else SHM
- X if ((aven_key = ftok(SYSTEM, 'a')) == (key_t) -1) {
- X perror(SYSTEM);
- X exit(1);
- X }
- X if ((aven_shm = shmget(aven_key, 3 * sizeof (double), IPC_CREAT|IPC_EXCL|0644)) < 0) {
- X perror("shmget");
- X exit(1);
- X }
- X if ((int) (aven_seg = (double *) shmat(aven_shm, (char *) 0, 0)) == -1) {
- X perror("shmat");
- X if (shmdt((char *) aven_seg) == -1)
- X perror("shmdt");
- X if (shmctl(aven_shm, IPC_RMID, (struct shmid_ds *) 0) < 0)
- X perror("shmctl(IPC_RMID)");
- X exit(1);
- X }
- X#endif RWHOD
- X
- X} /* init_packet */
- X
- Xmake_packet(iavg1, iavg2, iavg3)
- X#ifdef RWHOD
- Xlong iavg1, iavg2, iavg3;
- X#else SHM
- Xdouble iavg1, iavg2, iavg3;
- X#endif RWHOD
- X{
- X#ifdef RWHOD
- X static struct whod packet; /* local packet copy */
- X register struct whoent *wep; /* pointer to packet whoent */
- X register struct utmp *utp; /* return from getutent */
- X int whof, cc; /* output file, char count */
- X
- X packet = proto; /* copy proto packet */
- X time(&packet.wd_sendtime);
- X time(&packet.wd_recvtime); /* forge this !! */
- X packet.wd_loadav[0] = iavg1;
- X packet.wd_loadav[1] = iavg2;
- X packet.wd_loadav[2] = iavg3;
- X
- X setutent(); /* open utmp file */
- X wep = &packet.wd_we[0]; /* get pointer to first user in pkt */
- X
- X while( (utp = getutent()) != NULL ) {
- X if( (utp->ut_type == USER_PROCESS) && utp->ut_user[0]) {
- X strncpy(wep->we_utmp.out_line, utp->ut_id, 4);
- X wep->we_utmp.out_line[4] = '\0';
- X
- X strncpy(wep->we_utmp.out_name, utp->ut_user, 8);
- X
- X wep->we_utmp.out_time = utp->ut_time;
- X
- X wep->we_idle = idletime(utp);
- X wep++; /* bump packet pointer */
- X } /* user process */
- X } /* while */
- X endutent();
- X
- X# if DSK
- X whof = creat(whopacket, 0644); /* open packt file */
- X if( whof >= 0 ) {
- X cc = (char *)wep - (char *)&packet;
- X if( write(whof, (char *)&packet, cc) != cc )
- X perror("write failed");
- X close(whof);
- X } /* file opened */
- X else perror(whopacket);
- X# endif
- X# if UDP
- X cc = (char *)wep - (char *)&packet;
- X udpsend( (char *)&packet, cc, ipaddr, port, port, 1);
- X# endif
- X# ifdef DEBUG
- X fprintf(stderr, "wrote packet (%d)\n", cc);
- X fflush(stderr);
- X# endif
- X#else SHM
- X aven_seg[0] = iavg1;
- X aven_seg[1] = iavg2;
- X aven_seg[2] = iavg3;
- X#endif RWHOD
- X} /* make_packet */
- X
- X#ifdef RWHOD
- Xidletime(up)
- Xstruct utmp *up;
- X{
- X register int i;
- X register char *cp, *dp;
- X char ttyname[10];
- X struct stat buf;
- X time_t now;
- X
- X cp = "/dev/";
- X dp = ttyname;
- X
- X while( *cp != '\0' ) /* copy "/dev/" */
- X *dp++ = *cp++;
- X
- X cp = up->ut_line; /* get line name */
- X if( *cp == 's' ) /* starts with an 's'? (sxtnnn) */
- X *dp++ = 'v'; /* insert a 'v' */
- X
- X for( i = 0; i < 8; i++ ) /* copy line name */
- X if( (*dp++ = *cp++) == '\0' ) break; /* or until null */
- X
- X if( stat(ttyname, &buf) != 0 ) /* get file status */
- X return( 0 );
- X
- X time(&now); /* get current time */
- X i = now - buf.st_atime; /* get differnce from last acces */
- X return( i ); /* return idle time */
- X} /* idletime */
- X#endif RWHOD
- ________This_Is_The_END________
- if test `wc -l < avenrun.c` -ne 342; then
- echo 'shar: avenrun.c was damaged during transit (should have been 342 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - csl.c'
- if test -f csl.c; then echo 'shar: not overwriting csl.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > csl.c
- X#include <curses.h>
- X#include <a.out.h>
- X#include <term.h>
- X#include <time.h>
- X#include <fcntl.h>
- X#include <varargs.h>
- X#include <pwd.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include <sys/ipc.h>
- X#include <sys/shm.h>
- X#include <sys/param.h>
- X#include <sys/dir.h>
- X#include <sys/proc.h>
- X#include <sys/user.h>
- X#include <sys/var.h>
- X#include <sys/inode.h>
- X#include <sys/file.h>
- X#include <sys/stat.h>
- X#include <sys/sysmacros.h>
- X#include <utmp.h>
- X
- X#define DISPLAY 5 /* seconds between panels */
- X
- Xchar SObuf[BUFSIZ], lock[1024], messages[1024], fullname[64], logname[64];
- Xdouble *avenrun;
- Xint kmem, nproc, mem, swap, mail;
- Xdaddr_t swplo;
- X
- Xextern char *getenv(), *curcmd(), *ttyname(), *strrchr(), *itoa(), *fname(), *strchr();
- Xextern int cleanup();
- Xextern void setpwent();
- Xextern struct passwd *getpwnam();
- Xextern long time();
- Xextern void setutent();
- Xextern struct utmp *getutent();
- X
- Xstruct nlist k[] = {
- X {"_proc"},
- X {"_v"},
- X {"_swplo"},
- X {0},
- X};
- X
- Xchar *weekday[] = {
- X "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
- X};
- X
- Xmain() {
- X int cnt, nmsg, avend_id, aprogs, panel;
- X char *cp, *cmd;
- X key_t avend_k;
- X struct tm *now;
- X long instant;
- X char msg[1024], subj[1024], from[128], mailf[128];
- X char *fp, *bp, *logtty;
- X struct utmp *user;
- X
- X setupterm((char *) 0, fileno(stdout), (int *) 0);
- X if (!has_status_line) {
- X fprintf(stderr, "csl: terminal doesn't have a status line\n");
- X exit(1);
- X }
- X switch (fork()) {
- X case 0:
- X break;
- X case -1:
- X perror("csl");
- X exit(1);
- X default:
- X exit(0);
- X }
- X signal(SIGINT, SIG_IGN);
- X signal(SIGQUIT, SIG_IGN);
- X signal(SIGHUP, cleanup);
- X freopen("/dev/null", "r", stdin);
- X if (nlist("/unix", k) != 0) {
- X perror("/unix");
- X exit(2);
- X }
- X if ((kmem = open("/dev/kmem", O_RDONLY)) == -1) {
- X perror("/dev/kmem");
- X exit(1);
- X }
- X if ((mem = open("/dev/mem", O_RDONLY)) == -1) {
- X perror("/dev/mem");
- X exit(1);
- X }
- X if ((swap = open("/dev/swap", O_RDONLY)) == -1) {
- X perror("/dev/swap");
- X exit(1);
- X }
- X if ((cp = getenv("LOGNAME")) == (char *) 0)
- X strcpy(logname, "daemon");
- X else
- X strcpy(logname, cp);
- X fname(fullname);
- X getnproc();
- X if ((cp = getenv("HOME")) == (char *) 0) {
- X strcpy(lock, "./.syslinelock");
- X strcpy(messages, "./.messages");
- X }
- X else {
- X sprintf(lock, "%s/.syslinelock", cp);
- X sprintf(messages, "%s/.messages", cp);
- X }
- X setbuf(stdout, SObuf);
- X if ((avend_k = ftok("/unix", 'a')) == (key_t) -1) {
- X perror("/unix");
- X exit(1);
- X }
- X if ((avend_id = shmget(avend_k, 3 * sizeof (double), 0644)) < 0)
- X avenrun = (double *) 0;
- X else if ((int) (avenrun = (double *) shmat(avend_id, (char *) 0, SHM_RDONLY)) == -1) {
- X perror("shmat");
- X exit(1);
- X }
- X lseek(kmem, k[3].n_value, 0);
- X read(kmem, &swplo, sizeof swplo);
- X logtty = strrchr(ttyname(fileno(stdout)), '/') + 1;
- X sprintf(mailf, "/usr/mail/%s", logname);
- X for (;;) {
- X if (access(lock, 0) == 0) {
- X putp(dis_status_line);
- X fflush(stdout);
- X while (access(lock, 0) == 0)
- X sleep(30);
- X }
- X panel = 1;
- X from[0] = '\0';
- X subj[0] = '\0';
- X if ((mail = open(mailf, O_RDONLY)) == -1)
- X nmsg = 0;
- X else {
- X cnt = 0;
- X while (rgets(mail, msg, sizeof msg) != -1) {
- X if (strncmp(msg, "From ", 5) == 0) {
- X int mcnt;
- X
- X if (from[0] != '\0')
- X showpanel(panel++, "New mail from %s: %s", from, (subj[0]? subj: "[No subject]"));
- X subj[0] = '\0';
- X cnt++;
- X for (mcnt = 5; msg[mcnt] != '\0'; mcnt++)
- X if (msg[mcnt] == ' ')
- X break;
- X msg[mcnt++] = '\0';
- X if ((fp = strrchr(msg + 5, '!')) == (char *) 0)
- X strcpy(from, msg + 5);
- X else {
- X *fp = '\0';
- X if ((bp = strrchr(msg + 5, '!')) == (char *) 0)
- X bp = msg + 5;
- X *fp = '!';
- X strcpy(from, bp);
- X }
- X subj[0] = '\0';
- X }
- X else if (strncmp(msg, "Subject: ", 9) == 0)
- X strcpy(subj, msg + 9);
- X }
- X close(mail);
- X if (from[0] != '\0')
- X showpanel(panel++, "New mail from %s: %s", from, (subj[0]? subj: "[No subject]"));
- X nmsg = cnt;
- X }
- X cmd = curcmd(&aprogs);
- X time(&instant);
- X now = localtime(&instant);
- X if (avenrun != (double *) 0)
- X showpanel(panel++, " %s // %s // %4.2f %4.2f %4.2f // %s msgs // %3s %02d/%02d %02d:%02d ", cmd, logname, avenrun[0], avenrun[1], avenrun[2], (nmsg == 0? "No": itoa(nmsg)), weekday[now->tm_wday], now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min);
- X else
- X showpanel(panel++, " %s // %s // %s msgs // %3s %02d/%02d %02d:%02d //", cmd, logname, (nmsg == 0? "No": itoa(nmsg)), weekday[now->tm_wday], now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min);
- X showpanel(panel++, " ``%s'' on %s // %d active programs", fullname, logtty, aprogs);
- X if ((mail = open(messages, O_RDONLY)) != -1) {
- X while (rgets(mail, msg, sizeof msg) != -1)
- X showpanel(panel++, "%s", msg);
- X close(mail);
- X }
- X setutent();
- X cnt = 0;
- X msg[0] = '\0';
- X while ((user = getutent()) != (struct utmp *) 0) {
- X if (user->ut_type != USER_PROCESS)
- X continue;
- X sprintf(subj, "%.8s", user->ut_user);
- X if (msg[0] != '\0')
- X strcat(msg, ", ");
- X strcat(msg, subj);
- X cnt++;
- X }
- X showpanel(panel++, " %d users: %s", cnt, msg);
- X }
- X}
- X
- Xcleanup() {
- X if (avenrun != (double *) 0 && shmdt(avenrun) < 0) {
- X perror("shmdt");
- X exit(1);
- X }
- X reset_shell_mode();
- X exit(0);
- X}
- X
- Xgetnproc() {
- X struct var v;
- X
- X lseek(kmem, k[1].n_value, 0);
- X read(kmem, &v, sizeof v);
- X nproc = v.v_proc;
- X}
- X
- Xchar *curcmd(progp)
- Xint *progp; {
- X struct proc p;
- X struct user cmd;
- X struct file f;
- X struct inode i;
- X static struct stat idev;
- X static int pgrp, mypid;
- X static char cmdname[DIRSIZ + 1];
- X long stime;
- X int cnt;
- X static int didit = 0;
- X
- X if (didit == 0) {
- X stat("/dev/null", &idev);
- X pgrp = getpgrp();
- X mypid = getpid();
- X didit = 1;
- X }
- X *progp = 0;
- X stime = 0L;
- X strcpy(cmdname, "???");
- X lseek(kmem, k[0].n_value, 0);
- X for (cnt = 0; cnt < nproc; cnt++) {
- X read(kmem, &p, sizeof p);
- X if (p.p_stat != SRUN && p.p_stat != SSLEEP)
- X continue;
- X if (p.p_pid == mypid)
- X continue;
- X if (p.p_pgrp != pgrp)
- X continue;
- X if (p.p_stat == SSLEEP && (long) p.p_wchan >= k[0].n_value && (long) p.p_wchan < k[0].n_value + nproc * sizeof p)
- X continue; /* sleeping on a child */
- X (*progp)++;
- X if (p.p_flag & SLOAD) {
- X lseek(mem, (long) (NBPC * p.p_addr), 0);
- X read(mem, &cmd, sizeof cmd);
- X }
- X else {
- X lseek(swap, (swplo + p.p_swaddr + ctod(p.p_swsize) - ctod(USIZE)) << 9, 0);
- X read(swap, &cmd, sizeof cmd);
- X }
- X if (cmd.u_ttyp == 0)
- X continue;
- X/* AAUGH! USG VAR csh'es close stdin!!! That's absolutely insane!!!
- X * if (p.p_pid != p.p_ppid && cmd.u_ofile[0] == 0)
- X * continue;
- X */
- X if (cmd.u_ofile[0] != 0) {
- X lseek(kmem, cmd.u_ofile[0], 0);
- X read(kmem, &f, sizeof f);
- X lseek(kmem, f.f_inode, 0);
- X read(kmem, &i, sizeof i);
- X lseek(kmem, k[0].n_value + cnt * sizeof p, 0);
- X if (i.i_dev == idev.st_dev && i.i_number == idev.st_ino && cmd.u_signal[SIGINT] == (long) SIG_IGN)
- X continue; /* ignore background processes */
- X }
- X if (cmd.u_start < stime)
- X continue;
- X stime = cmd.u_start;
- X strncpy(cmdname, cmd.u_comm, DIRSIZ);
- X }
- X return cmdname;
- X}
- X
- Xrgets(fd, buf, maxlen)
- Xchar *buf;
- Xunsigned maxlen; {
- X unsigned cnt;
- X
- X *buf = '\0';
- X for (cnt = 0; cnt < maxlen - 1 && read(fd, buf, 1) > 0 && *buf != '\n'; cnt++, buf++)
- X ;
- X if (cnt == 0 && *buf != '\n')
- X return -1;
- X *buf = '\0';
- X return cnt;
- X}
- X
- Xchar *itoa(n) {
- X static char ibuf[20];
- X
- X sprintf(ibuf, "%d", n);
- X return ibuf;
- X}
- X
- X/* Does the lint declaration below actually *do* anything? */
- X/*VARARGS PRINTFLIKE2*/
- Xshowpanel(va_alist)
- Xva_dcl {
- X va_list args;
- X int panel, cnt;
- X static char buf[5120];
- X register char *cp;
- X
- X va_start(args);
- X panel = va_arg(args, int);
- X cp = va_arg(args, char *);
- X sprintf(buf, "%2.2d>", panel);
- X vsprintf(buf + 3, cp, args);
- X putp(tparm(to_status_line, 0));
- X for (cp = buf, cnt = 0; cnt < width_status_line && *cp != '\0'; cp++, cnt++)
- X putchar(*cp);
- X while (cnt++ < width_status_line)
- X putchar(' ');
- X putp(from_status_line);
- X fflush(stdout);
- X sleep(DISPLAY);
- X}
- X
- X/*
- X * If you use RJE fullnames :0000-Foo Z. Bar(0000):, change this.
- X * If you aren't running RJE, why bother with it?
- X */
- X
- Xchar *fname(buf)
- Xchar *buf; {
- X static char fbuf[128];
- X struct passwd *me;
- X char *cp;
- X
- X setpwent();
- X me = getpwnam(logname);
- X endpwent();
- X if (me == (struct passwd *) 0)
- X strcpy(fbuf, logname);
- X else {
- X strcpy(fbuf, me->pw_gecos);
- X if ((cp = strchr(fbuf, ',')) != (char *) 0)
- X *cp = '\0';
- X }
- X if (buf == (char *) 0)
- X return fbuf;
- X strcpy(buf, fbuf);
- X return buf;
- X}
- ________This_Is_The_END________
- if test `wc -l < csl.c` -ne 348; then
- echo 'shar: csl.c was damaged during transit (should have been 348 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - w.c'
- if test -f w.c; then echo 'shar: not overwriting w.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > w.c
- X/*
- X * %W% %E% %U% ncoast!bsa %Z%
- X * %Z% Copyright (C) 1985 by Brandon S. Allbery, All Rights Reserved %Z%
- X */
- X
- X#ifndef lint
- Xstatic char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
- Xstatic char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
- X#endif lint
- X
- X#include <stdio.h>
- X#include <time.h>
- X#include <signal.h>
- X#include <a.out.h>
- X#ifdef SYS5
- X#include <sys/types.h>
- X#endif
- X#include <sys/param.h>
- X#include <sys/var.h>
- X#include <sys/proc.h>
- X#include <sys/dir.h>
- X#include <sys/user.h>
- X#include <sys/stat.h>
- X#ifdef SYS5
- X#include <sys/ipc.h>
- X#include <sys/shm.h>
- X#include <sys/sysmacros.h>
- X#endif
- X#include <utmp.h>
- X
- X#define UTMP "/etc/utmp"
- X#ifndef KERNEL
- X#define KERNEL "/unix"
- X#endif
- X#define KMEM "/dev/kmem"
- X#define PMEM "/dev/mem"
- X#define SMEM "/dev/swap"
- X
- X#define MIN (60)
- X#define HOUR (MIN * 60)
- X#define DAY (HOUR * 24)
- X#define WEEK (DAY * 7)
- X#define MONTH (DAY * 30)
- X
- XFILE *kfd;
- XFILE *mfd;
- XFILE *sfd;
- XFILE *utmp;
- Xlong nproc;
- Xchar _SObuf[BUFSIZ];
- Xdaddr_t swplo;
- Xshort mypid;
- X
- Xstruct nlist kernel[] = {
- X {"_v"},
- X {"_proc"},
- X {"_swplo"},
- X {NULL},
- X};
- X
- Xchar *months[] = {
- X "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- X};
- X
- Xstruct tm *localtime();
- Xchar *vtime();
- Xchar *uptime();
- Xchar *itoa();
- X
- Xmain() {
- X struct utmp user;
- X short ucnt;
- X long now;
- X struct var vars;
- X#ifdef SYS5
- X int shm_id;
- X key_t shm_k;
- X double *avenrun;
- X#endif
- X
- X setbuf(stdout, _SObuf);
- X mypid = getpid();
- X time(&now);
- X if (nlist(KERNEL, kernel) == -1) {
- X perror(KERNEL);
- X exit(2);
- X }
- X if ((utmp = fopen(UTMP, "r")) == NULL) {
- X perror(UTMP);
- X exit(1);
- X }
- X ucnt = 0;
- X while (fread(&user, sizeof user, 1, utmp) > 0) {
- X#ifdef SYS5
- X if (user.ut_type != USER_PROCESS)
- X#else
- X if (user.ut_name[0] == '\0')
- X#endif
- X continue;
- X ucnt++;
- X }
- X if (kfd == NULL) {
- X if ((kfd = fopen(KMEM, "r")) == NULL) {
- X perror(KMEM);
- X exit(3);
- X }
- X }
- X fseek(kfd, kernel[0].n_value, 0);
- X fread(&vars, sizeof vars, 1, kfd);
- X nproc = vars.v_proc;
- X fseek(kfd, kernel[2].n_value, 0);
- X fread(&swplo, sizeof swplo, 1, kfd);
- X if (mfd == NULL) {
- X if ((mfd = fopen(PMEM, "r")) == NULL) {
- X perror(PMEM);
- X exit(4);
- X }
- X }
- X if (sfd == NULL) {
- X if ((sfd = fopen(SMEM, "r")) == NULL) {
- X perror(SMEM);
- X exit(5);
- X }
- X }
- X#ifdef SYS5
- X if ((shm_k = ftok(KERNEL, 'a')) == (key_t) -1) {
- X perror(KERNEL);
- X exit(2);
- X }
- X if ((shm_id = shmget(shm_k, 3 * sizeof *avenrun, 0644)) < 0) {
- X perror("shmget()");
- X exit(2);
- X }
- X if ((int) (avenrun = (double *) shmat(shm_id, (char *) 0, SHM_RDONLY)) == -1) {
- X perror("shmat()");
- X exit(2);
- X }
- X printf(" %s up%s, %d users, load average: %.1f, %.1f, %.1f\nUser tty login@ idle JCPU PCPU what\n", vtime(&now), uptime(), ucnt, avenrun[0], avenrun[1], avenrun[2]);
- X if (shmdt((char *) avenrun) == -1) {
- X perror("shmdt()");
- X exit(2);
- X }
- X#else
- X printf(" %s up%s, %d users, load average: not available under sys3\nUser tty login@ idle JCPU PCPU what\n", vtime(&now), uptime(), ucnt);
- X#endif
- X rewind(utmp);
- X while (fread(&user, sizeof user, 1, utmp) > 0) {
- X#ifdef SYS5
- X if (user.ut_type != USER_PROCESS)
- X#else
- X if (user.ut_name[0] == '\0')
- X#endif
- X continue;
- X show(&user);
- X }
- X fclose(utmp);
- X exit(0);
- X}
- X
- Xchar *uptime() {
- X static char timebuf[128];
- X#ifdef SYS5
- X struct utmp bootdata;
- X#else
- X struct proc swapper;
- X struct user bootproc;
- X#endif
- X long oldpos, now;
- X short cnt, ocnt;
- X
- X#ifdef SYS5
- X oldpos = fseek(utmp, 0L, 0);
- X do {
- X fread(&bootdata, sizeof bootdata, 1, utmp);
- X } while (bootdata.ut_type != BOOT_TIME);
- X fseek(utmp, oldpos, 0);
- X#else
- X oldpos = fseek(kfd, 0L, 1);
- X fseek(kfd, kernel[1].n_value, 0);
- X fread(&swapper, sizeof swapper, 1, kfd);
- X fseek(kfd, oldpos, 0);
- X oldpos = fseek(mfd, 0L, 1);
- X fseek(mfd, ctob(swapper.p_addr), 0);
- X fread(&bootproc, sizeof bootproc, 1, mfd);
- X fseek(mfd, 0L, 1);
- X#endif
- X time(&now);
- X#ifdef SYS5
- X now -= bootdata.ut_time;
- X#else
- X now -= bootproc.u_start;
- X#endif
- X if (now < 0L)
- X return " with strange clock time";
- X timebuf[0] = '\0';
- X ocnt = 0;
- X cnt = 0;
- X while (now >= MONTH) {
- X cnt++;
- X now -= MONTH;
- X }
- X if (cnt > 0) {
- X strcat(timebuf, itoa(cnt));
- X strcat(timebuf, " mon");
- X if (cnt > 1)
- X strcat(timebuf, "s");
- X if (++ocnt == 2)
- X return timebuf;
- X }
- X cnt = 0;
- X while (now >= WEEK) {
- X cnt++;
- X now -= WEEK;
- X }
- X if (cnt > 0) {
- X strcat(timebuf, itoa(cnt));
- X strcat(timebuf, " wk");
- X if (cnt > 1)
- X strcat(timebuf, "s");
- X if (++ocnt == 2)
- X return timebuf;
- X }
- X cnt = 0;
- X while (now >= DAY) {
- X cnt++;
- X now -= DAY;
- X }
- X if (cnt > 0) {
- X strcat(timebuf, itoa(cnt));
- X strcat(timebuf, " day");
- X if (cnt > 1)
- X strcat(timebuf, "s");
- X if (++ocnt == 2)
- X return timebuf;
- X }
- X cnt = 0;
- X while (now >= HOUR) {
- X cnt++;
- X now -= HOUR;
- X }
- X if (cnt > 0) {
- X strcat(timebuf, itoa(cnt));
- X strcat(timebuf, " hr");
- X if (cnt > 1)
- X strcat(timebuf, "s");
- X }
- X return timebuf;
- X}
- X
- Xchar *itoa(n)
- Xint n; {
- X static char buf[20];
- X
- X sprintf(buf, " %d", n);
- X return buf;
- X}
- X
- Xshow(uinfo)
- Xstruct utmp *uinfo; {
- X struct stat sbuf;
- X struct proc proc;
- X struct user prog;
- X char ttydev[16];
- X long now, cnt, offset, jcpu;
- X short mpid, isswap;
- X FILE *ufd;
- X
- X strcpy(ttydev, "/dev/");
- X strncpy(&ttydev[5], uinfo->ut_line, 8);
- X ttydev[13] = '\0';
- X if (stat(ttydev, &sbuf) != 0) {
- X perror(ttydev);
- X return;
- X }
- X time(&now);
- X now -= sbuf.st_atime;
- X printf("%-8.8s %-8.8s %7s ", uinfo->ut_name, uinfo->ut_line, vtime(&uinfo->ut_time));
- X if (now > DAY)
- X printf("%4dd", now / DAY);
- X else if (now > HOUR)
- X printf("%2d:%02d", now / HOUR, (now % HOUR) / 60);
- X else if (now > MIN)
- X printf("%5d", now / MIN);
- X else
- X printf(" ");
- X putchar(' ');
- X fseek(kfd, kernel[1].n_value, 0);
- X mpid = -1;
- X jcpu = 0;
- X for (cnt = 0; cnt < nproc; cnt++) {
- X fread(&proc, sizeof proc, 1, kfd);
- X if (proc.p_stat == 0 || proc.p_stat == SZOMB || proc.p_stat == SWAIT)
- X continue;
- X if (proc.p_flag & SLOAD) {
- X fseek(mfd, ctob(proc.p_addr), 0);
- X fread(&prog, sizeof prog, 1, mfd);
- X isswap = 0;
- X }
- X else {
- X#ifdef SYS5
- X fseek(sfd, (swplo + proc.p_swaddr + ctod(proc.p_swsize) - ctod(USIZE)) << 9, 0);
- X#else
- X fseek(sfd, (long) (swplo + proc.p_addr) << 9, 0);
- X#endif
- X fread(&prog, sizeof prog, 1, sfd);
- X isswap = 1;
- X }
- X if (prog.u_ttyp == NULL)
- X continue;
- X if (sbuf.st_rdev != prog.u_ttyd)
- X continue;
- X jcpu += prog.u_utime + prog.u_stime;
- X if (proc.p_pid == mypid)
- X continue;
- X if (proc.p_pid > mpid)
- X mpid = proc.p_pid;
- X }
- X if (mpid == -1)
- X printf("[can't stat]");
- X else {
- X fseek(kfd, kernel[1].n_value, 0);
- X for (cnt = 0; cnt < nproc; cnt++) {
- X fread(&proc, sizeof proc, 1, kfd);
- X if (proc.p_pid == mpid)
- X break;
- X }
- X if (proc.p_pid != mpid)
- X printf("[interstice]");
- X else {
- X if (proc.p_flag & SLOAD) {
- X fseek(mfd, ctob(proc.p_addr), 0);
- X fread(&prog, sizeof prog, 1, mfd);
- X }
- X else {
- X#ifdef SYS5
- X fseek(sfd, (swplo + proc.p_swaddr + ctod(proc.p_swsize) - ctod(USIZE)) << 9, 0);
- X#else
- X fseek(sfd, (long) (swplo + proc.p_addr) << 9, 0);
- X#endif
- X fread(&prog, sizeof prog, 1, sfd);
- X }
- X printf("%3d:%02d %3d:%02d ", jcpu / MIN, jcpu % MIN, (prog.u_utime + prog.u_stime) / MIN, (prog.u_utime + prog.u_stime) % MIN);
- X prog.u_procp = &proc;
- X pcmd(&prog);
- X }
- X }
- X putchar('\n');
- X}
- X
- Xchar *vtime(when)
- Xlong *when; {
- X struct tm then, now;
- X static char buf[20];
- X short hour, min, ampm;
- X long clock;
- X
- X time(&clock);
- X now = *localtime(&clock);
- X then = *localtime(when);
- X if (then.tm_mon != now.tm_mon || then.tm_mday != now.tm_mday) {
- X sprintf(buf, "%s %2d", months[then.tm_mon], then.tm_mday);
- X return buf;
- X }
- X min = then.tm_min;
- X if (then.tm_hour == 0) {
- X ampm = 'a';
- X hour = 12;
- X }
- X else if (then.tm_hour > 0 && then.tm_hour < 12) {
- X ampm = 'a';
- X hour = then.tm_hour;
- X }
- X else if (then.tm_hour == 12) {
- X ampm = 'p';
- X hour = 12;
- X }
- X else {
- X ampm = 'p';
- X hour = then.tm_hour - 12;
- X }
- X sprintf(buf, "%d:%02d%cm", hour, min, ampm);
- X return buf;
- X}
- X
- Xpcmd(uinfo)
- Xstruct user *uinfo; {
- X /* someday look up the user's command line */
- X printf("%-.14s", uinfo->u_comm);
- X}
- ________This_Is_The_END________
- if test `wc -l < w.c` -ne 390; then
- echo 'shar: w.c was damaged during transit (should have been 390 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - avenrun.1m'
- if test -f avenrun.1m; then echo 'shar: not overwriting avenrun.1m'; else
- sed 's/^X//' << '________This_Is_The_END________' > avenrun.1m
- X.TH AVENRUN 1M
- X.SH NAME
- Xavenrun \- compute load averages
- X.SH SYNOPSIS
- X.B avenrun
- X.SH DESCRIPTION
- X.B
- XAvenrun
- Xis a program to generate load average numbers on systems running AT&T's
- Xversion of UNIX(R). (UNIX is a registered trademark of AT&T.) It does
- Xits job by creating a shared memory segment whose key is the value of
- X.I ftok(\"/unix\", 'a')
- Xwhich contains three (double)'s. It then updates this structure with the
- X1-minute, 5-minute, and 15-minute load averages, as calculated from the
- Xsysinfo structure of the kernel (the "runque" and "runocc" entries).
- X.P
- XThe load average is only an approximation of the actual number, which is
- Xthe average number of processes on the run queue. It is about as close as
- Xyou can get without actually computing the load average in the kernel as
- Xprocesses are placed on the run queue.
- X.SH FILES
- X.ta \w'/dev/kmem 'u
- X/unix system namelist
- X.br
- X/dev/kmem kernel memory, for the sysinfo structure
- X.DT
- X.SH SEE ALSO
- Xstdipc(3), shmop(2), sa(4).
- X.SH BUGS
- XIt really should be in the kernel.
- ________This_Is_The_END________
- if test `wc -l < avenrun.1m` -ne 30; then
- echo 'shar: avenrun.1m was damaged during transit (should have been 30 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - csl.1l'
- if test -f csl.1l; then echo 'shar: not overwriting csl.1l'; else
- sed 's/^X//' << '________This_Is_The_END________' > csl.1l
- X.TH CSL local
- X.SH NAME
- Xcsl \- cyclic status line
- X.SH SYNOPSIS
- X.B csl
- X.SH DESCRIPTION
- X.B Csl
- Xis a program for displaying interesting information on the status line
- Xof a terminal which possesses one. The information is shown in "panels"
- Xwhich are displayed for five seconds before going to the next panel.
- XAfter the last panel is displayed, the first panel will be redisplayed.
- X.PP
- XThe panels display information in the following order:
- X.IP
- X- mail messages, one per panel; sender and subject
- X.IP
- X- current program, login name, load average, current time
- X.IP
- X- full name, terminal, number of active programs
- X.IP
- X- lines from $HOME/.messages, one per panel
- X.IP
- X- current users on the system
- X.PP
- XAn example of some successive panels:
- X.nf
- X
- X 01>From bobw: Re: x10.bas
- X 02>From root: [No subject]
- X 03> jove // brandon // 0.76 1.02 0.95 // Thu 05/08 16:56
- X 04> "Brandon Allbery" on tty2 // 3 active programs
- X 05>START THE MONTHLY REPORTS!!!
- X
- X.fi
- X.PP
- X.B Csl
- Xlooks for terminfo definitions "hsl", "tsl", "fsl", "wsl", and "dsl".
- XIt does not make use of the parameterization feature except to position
- Xto the first column of the status line, so non-addressable status lines
- X(such as on the Wyse 50 and Wyse 75) can be used.
- X.P
- XIf the file
- X.I $HOME/.syslinelock
- Xis found to exist at the beginning of a cycle,
- X.B csl
- Xwaits until the file disappears before performing any more displays.
- XThis is useful when
- X.B csl
- Xupsets the display from a particular program, or on terminals which
- Xdo not accept keyboard commands while the status line is being loaded
- X(e.g. the Wyse 75) when rapid keyboard input is required.
- X.SH FILES
- X.ta \w'$HOME/.syslinelock 'u
- X$HOME/.syslinelock Disables status line
- X.br
- X$HOME/.messages Scanned for messages to display
- X.br
- X/usr/mail/$LOGNAME Scanned for new mail
- X.br
- X/etc/passwd The user's full name is stored here
- X.br
- X/etc/utmp Current users, and the current user's terminal
- X.DT
- X.SH NOTES
- X.B Csl
- Xwill refuse to run on a terminal whose terminfo description does not
- Xinclude the boolean attribute "hsl". See terminfo(4) for information
- Xabout the status line attributes of terminfo.
- X.PP
- XThe full name of a user is expected to be the (only) entry in the pw_gecos
- Xfield of /etc/passwd for that user (see
- X.B getpwent(3) .
- XRJE format (of the form
- X"0000-user(0000)") is not understood.
- X.SH SEE ALSO
- Xterminfo(4), avenrun(1m).
- X.SH BUGS
- X.B Csl
- Xshould scan for $HOME/.syslinelock after each panel, rather than at
- Xthe beginning of a cycle.
- X.PP
- XThings can change while
- X.I csl
- Xis displaying a panel; in general, changes are not seen until the next
- Xcycle.
- X.PP
- XFull names are not always easy to figure out under System V. Some sites
- Xuse the RJE format, others use the BSD format.
- X.B Csl
- Xuses BSD because it's straightforward, the full name is the pw_gecos field
- Xup to a comma.
- X.PP
- XBecause VAR versions of
- X.B csh(1)
- Xinsist on closing their fd 0,
- X.B csl
- Xmust admit such programs as being running in the foreground. This causes
- Xvarious lies about the name of the current process.
- X.PP
- XOn systems running MH, the mail checking routines will fail; they
- Xexpect "normal" UUCP mailboxes, not MMDF maildrops. Perhaps the
- Xbest fix for this is to run
- X.B ims(local)
- Xinstead.
- X.PP
- XIt isn't
- X.B statline(1) .
- X(This may be a feature.)
- ________This_Is_The_END________
- if test `wc -l < csl.1l` -ne 108; then
- echo 'shar: csl.1l was damaged during transit (should have been 108 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - w.1l'
- if test -f w.1l; then echo 'shar: not overwriting w.1l'; else
- sed 's/^X//' << '________This_Is_The_END________' > w.1l
- X.TH W 1 local
- X.SH NAME
- Xw \- display users and processes
- X.SH SYNOPSIS
- X.B w
- X.SH DESCRIPTION
- X.B W
- Xis a program which displays an "intelligent" listing of the current users,
- Xwhat they're doing, and how active they are. There are two basic kinds
- Xof information displayed: system information and per-user information.
- XAn example is shown below.
- X.nf
- X
- X 10:55pm up 2 wks 2 days, 4 users, load average: 1.2, 1.0, 0.8
- XUser tty login@ idle JCPU PCPU what
- Xrhg tty6 10:36pm 12:20 12:20 csh
- Xrobertd tty7 10:21pm 9:21 9:21 csh
- Xbobw tty13 10:26pm 160:35 149:43 rn
- Xallbery tty15 9:47pm 50:22 0:18 sh
- X
- X.fi
- XThe first line displays the current time, how long the system has been up,
- Xthe number of users, and the load average (if available; not under System
- XIII). The other lines display for each user, the user's login name, the
- Xterminal the user is on, the time the user logged in, how long the user has
- Xbeen idle, the CPU time used by the current program and total CPU for the
- Xlogin session, and the current program.
- X.SH FILES
- X.ta \w'/dev/kmem 'u
- X/dev/kmem System memory (the process table)
- X.br
- X/dev/mem In-core program images
- X.br
- X/dev/swap Swapped program images
- X.br
- X/dev Searches for terminals
- X.br
- X/etc/utmp Current system users and boot time
- X.DT
- X.SH NOTES
- X.B W
- Xdisplays the process name as shown by
- X.B ps(1)
- Xwithout the -f argument.
- X.SH SEE ALSO
- Xavenrun(1m), ps(1), who(1).
- X.SH BUGS
- XJCPU and current process are both kludges. The former is really only the
- XCPU of running programs in the terminal session, as System V does not retain
- Xuser and system times for all programs in a sessionl; the latter attempts to
- Xdisregard background processes, but it is nearly impossible to successfully
- Xdetermine if a program is in the background or not. This is exacerbated by
- Xthe fact that VAR csh(1)'s, when available, look suspiciously like
- Xbackground processes because they close their standard input.
- X.PP
- XIf the user block is demand paged,
- X.B w
- Xwon't find it; I don't have access to a demand-paged system.
- X.PP
- X.B who -u
- Xand
- X.B w
- Xhave different ideas on what constitutes idle time; one uses time of last
- Xinput, the other the time of last output.
- X.PP
- XThe boot time isn't guaranteed to be correct if you don't have a real time
- Xclock with battery backup. There is also a kludge which will not affect
- Xnormal systems, but which deals with a tendency for Plexus systems to
- Xforward-date the system clock by one month.
- X.PP
- XIt is possible that reading the summarized child's system and user times
- Xwould produce a better approximation of JCPU. This is only likely, however,
- Xif the times are updated recursively.
- X.PP
- XThings can change while
- X.B w
- Xis running; this occasionally causes the current program to be printed as
- X"[can't stat]" or as "[interstice]".
- X.PP
- XIf you want "w" to work correctly, get 4.2BSD.
- X.PP
- XIt should really take options for the system namelist, memory, and
- Xswap files, as well as the key of the shared memory partition; it should
- Xalso recover gracefully if avenrun(1m) isn't running.
- ________This_Is_The_END________
- if test `wc -l < w.1l` -ne 84; then
- echo 'shar: w.1l was damaged during transit (should have been 84 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
- --
- Brandon S. Allbery, moderator of comp.sources.misc and comp.binaries.ibm.pc
- {{harvard,mit-eddie}!necntc,well!hoptoad,sun!cwruecmp!hal}!ncoast!allbery
- ARPA: necntc!ncoast!allbery@harvard.harvard.edu Fido: 157/502 MCI: BALLBERY
- <<ncoast Public Access UNIX: +1 216 781 6201 24hrs. 300/1200/2400 baud>>
-