w6ps - XENIX 386 "realtime" ps on Wyse 60
Warren Tucker
wht at tridom.uucp
Sat Oct 28 05:52:48 AEST 1989
This ditty displays XENIX V/386 process status in "real time" on a Wyse
60 in native mode. Login shells (**argv == '-') are omitted. It works
with SCO XENIX V/386 2.3.1 and beyond and compiles ok with development
system 2.3.1. Just unshar and make. The README talks about necessary
permissions.
#!/bin/sh
# shar: Shell Archiver (v1.22)
#
# Run the following text with /bin/sh to create:
# README
# Makefile
# w6.c
# w6.h
# w6ps.c
#
if test -f README; then echo "File README exists"; else
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
Xw6ps - XENIX V/386 Wyse 60 process status display in 43-line, 132-col mode
X
XThis ditty displays XENIX V/386 process status in "real time" on a Wyse
X60 in native mode. Login shells (**argv == '-') are omitted. It works
Xwith SCO XENIX V/386 2.3.1 and beyond and compiles ok with development
Xsystem 2.3.1.
X
XIt is offered to the public domain with no warranty as-is: a reasonable
X"ps" that doesn't blow up with seek errors (so far :-)) and a decent
Xtoolkit for Wyse 60 manipulation and kmem/mem munging.
X
XNOTES:
X1. w6ps must be able to access /dev/{*mem,swap}. This means:
X a. chmod +r /dev/{*mem,swap} BAD IDEA
X b. chown sysinfo w6ps;chmod u+s w6ps
X
X2. I use a Wyse 60 as a non-enabled terminal on "/dev/tty2h" and the
Xprogram has that name hard-coded; you'll probably need to change
X'w6tty_default' in w6.c.
X
X3. The program misbehaves if there are more than about 40 "non-login"
Xprocesses.
X
X4. The terminal is expected to be set for 9600 baud.
X
X5. w6test tests the w6.c driver.
SHAR_EOF
chmod 0644 README || echo "restore of README fails"
fi
if test -f Makefile; then echo "File Makefile exists"; else
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X# CHK=0xD8E4
X#
X# Makefile for w6test and w6ps
X#
X# NOTE: w6ps needs chown sysinfo,chmod u+s for access to /dev/{*mem,swap}
X#
X#+:EDITS:
X#:01-07-1989-12:21-wht-creation
X
XC_EXTRA = -i -M3
XCFLAGS = -LARGE -DLINT_ARGS -Ox -K $(C_EXTRA)
XLDFLAGS = $(C_EXTRA) -lx
X
X.c.o:; cc -c $(CFLAGS) $*.c
X
XW6PS_OFILES = \
X w6ps.o\
X w6.o
X
Xall: w6ps w6test
X
Xw6test: w6test.o
X cc $(LDFLAGS) w6test.o -o w6test
X
Xw6ps: $(W6PS_OFILES)
X cc $(LDFLAGS) $(W6PS_OFILES) -o w6ps
X
Xw6test.o: w6.c
X cc -DTEST -Fow6test.o -c $(CFLAGS) w6.c
SHAR_EOF
chmod 0644 Makefile || echo "restore of Makefile fails"
fi
if test -f w6.c; then echo "File w6.c exists"; else
echo "x - extracting w6.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > w6.c &&
X/* CHK=0xF46E */
X
Xchar *w6tty_default = "/dev/tty2h";
X
X/*+-------------------------------------------------------------------------
X w6.c - Wyse 60 (native mode) display driver
X ...!gatech!emory!tridom!wht - Public Domain
X
X Defined functions:
X _w6_delta_attr(bit,state)
X _w6_lgetc(char_rtnd)
X main()
X w6_132cols()
X w6_24lines()
X w6_25lines()
X w6_42lines()
X w6_43lines()
X w6_80cols()
X w6attr(attr)
X w6blink(on)
X w6close()
X w6clr()
X w6clrline()
X w6clrtobot()
X w6clrtoeol()
X w6ctrl(ctrl_cmd)
X w6dim(on)
X w6eolwrap(on)
X w6home()
X w6ins_line()
X w6mon_mode(on)
X w6move(y,x)
X w6norm()
X w6oneseg()
X w6open(line)
X w6prog_fkey_label(keynum,str)
X w6prog_fkey_str(keynum,str)
X w6putc(ch)
X w6reverse(on)
X w6scroll(onflag)
X w6set_time()
X w6topline(msg)
X w6underline(on)
X w6xonxoff(on)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-04-1989-18:03-wht-creation */
X
X#include <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/errno.h>
X
X#if defined(M_XENIX)
X#include <sys/stat.h>
X#include <sys/ioctl.h>
X#include <string.h>
X#include <fcntl.h>
X#include <termio.h>
X#endif
X
X#if defined(pyr)
X#include <sys/stat.h>
X#include <sys/file.h>
X#include <sys/termio.h>
X#include <strings.h>
X#endif
X
X#include <time.h>
X#include <sys/timeb.h>
X
X#include "w6.h"
Xextern int errno;
X
Xint w6fd = -1; /* file descriptor for line */
Xchar w6_ttyname[64]; /* /dev/ttyname for line */
Xstruct termio w6_termio; /* attributes for the line to remote */
X
X
Xvoid w6putc(ch)
Xchar ch;
X{ write(w6fd,&ch,1); }
X
Xvoid w6putcs(str,count) char *str; int count;
X{ write(w6fd,str,count);}
X
Xvoid w6puts(str) char *str;
X{ write(w6fd,str,strlen(str));}
X
Xvoid w6xonxoff(on)
X{ w6putcs("\033c2",3); w6putc(on ? '1' : '0'); }
X
Xvoid w6clr() /* clear screen */
X{ w6putc(26);}
X
Xchar w6_home[]={ ESC,'{'};
Xvoid w6home() /* home screen */
X{ w6putcs(w6_home,2); }
X
Xvoid w6scroll(onflag) /* scroll on/off */
X{ w6putc(ESC); w6putc((onflag) ? 'O' : 'N'); }
X
Xvoid w6oneseg() /* whole screen one segment */
X{
Xstatic char w6_oneseg[]={ ESC,'x','0',};
X w6putcs(w6_oneseg,3);
X}
X
Xvoid w6topline(msg)
Xchar *msg;
X{
Xstatic char w6_topline[]={ESC,'F'};
X w6putcs(w6_topline,2);
X w6putcs(msg,strlen(msg));
X w6putc(0x0D);
X}
X
Xvoid w6ctrl(ctrl_cmd) /* display control */
Xint ctrl_cmd;
X{
Xstatic char w6_ctrl[]={ ESC,'`' };
X w6putcs(w6_ctrl,2);
X w6putc(ctrl_cmd);
X}
Xstatic int _w6_cols = -1;
X
Xvoid w6_132cols()
X{ w6ctrl(W6_132);_w6_cols = 132;}
Xvoid w6_80cols()
X{ w6ctrl(W6_80); _w6_cols = 80;}
X
Xvoid _w6lines(spec) char spec;
X{ static char cmd[] = {ESC,'e'};
X w6putcs(cmd,2); w6putc(spec);
X}
Xvoid w6_24lines()
X{ _w6lines('('); }
Xvoid w6_25lines()
X{ _w6lines(')'); }
Xvoid w6_42lines()
X{ _w6lines('*'); }
Xvoid w6_43lines()
X{ _w6lines('+'); }
X
Xvoid w6ins_line()
X{ w6putc(ESC);w6putc('E');}
X
Xvoid w6move(y,x)
Xunsigned char y,x;
X{
Xchar buf[16];
X if(_w6_cols == 80)
X sprintf(buf,"\033=%c%c",y+20,x+20);
X else
X sprintf(buf,"\033a%dR%dC",y + 1,x + 1);
X w6puts(buf);
X}
X
Xvoid w6clrtoeol()
X{ static char cmd[]={ESC,'c','O'};
X w6putcs(cmd,3);
X}
X
Xvoid w6clrtobot()
X{ static char cmd[]={ESC,'Y'};
X w6putcs(cmd,2);
X}
X
Xvoid w6clrline()
X{ static char cmd[]={0x0D,ESC,'c','O'};
X w6putcs(cmd,4);
X}
X
Xvoid w6set_time()
X{
Xchar buf[10];
Xlong time();
Xlong now = time((long *)0);
Xstruct tm *localtime();
Xstruct tm *lt = localtime(&now);
X sprintf(buf,"\033c8%02d%02d",lt->tm_hour,lt->tm_min);
X w6puts(buf);
X}
X
X
Xstatic char w6_attrcmd[]={ ESC,'G'};
Xstatic char w6_attr = '0';
X
Xvoid w6norm() /* normal attribute */
X{
X w6_attr = '0';
X w6putcs(w6_attrcmd,2);
X w6putc(w6_attr);
X}
X
Xvoid w6attr(attr) /* absolute */
X{
X w6_attr = '0' | attr;
X w6putcs(w6_attrcmd,2);
X w6putc(w6_attr);
X}
X
Xvoid _w6_delta_attr(bit,state) /* delta */
Xunsigned char bit,state;
X{
X if(state)
X w6_attr |= bit;
X else
X w6_attr &= ~bit;
X w6putcs(w6_attrcmd,2);
X w6putc(w6_attr);
X}
X
Xvoid w6blink(on) /* blink */
X{ _w6_delta_attr(W6BLINK,on); }
X
Xvoid w6reverse(on) /* reverse */
X{ _w6_delta_attr(W6REVERSE,on); }
X
Xvoid w6underline(on) /* reverse */
X{ _w6_delta_attr(W6UNDERLINE,on); }
X
Xvoid w6dim(on) /* dim */
X{ _w6_delta_attr(W6DIM,on); }
X
X
Xvoid w6eolwrap(on)
X{ w6putcs("\033d",2); w6putc(on ? '/' : '.'); }
X
Xvoid w6mon_mode(on)
X{ w6eolwrap(on); w6putc(ESC); w6putc(on ? 'U' : 'u'); }
X
Xvoid w6prog_fkey_str(keynum,str)
Xint keynum;
Xchar *str;
X{
Xchar wstr[128];
X sprintf(wstr,"\033z%c%s\177",keynum - 1 + '@',str);
X w6puts(wstr);
X
X} /* end of w6prog_fkey_str */
X
Xvoid w6prog_fkey_label(keynum,str)
Xint keynum;
Xchar *str;
X{
Xchar wstr[128];
X
X sprintf(wstr,"\033z%c%s\177",keynum - 1 + '0',str);
X write(w6fd,wstr,strlen(wstr));
X
X} /* end of w6prog_fkey_label */
X
X/*+-------------------------------------------------------------------------
X _w6_lgetc(char_rtnd) -- get char from line
X--------------------------------------------------------------------------*/
Xvoid
X_w6_lgetc(char_rtnd)
Xchar *char_rtnd;
X{
Xextern int errno;
X
XREAD_AGAIN:
X errno = 0;
X if(read(w6fd,char_rtnd,1) < 1)
X {
X if(errno == EINTR) /* if signal interrupted, ... */
X goto READ_AGAIN;
X exit(250);
X }
X} /* end of _w6_lgetc */
X
X/*+----------------------------------------------------------------------
X w6open(line)
Xreturns negative W6_OPEN_ codes if failure else positive pid using line
Xelse 0 if successful open
X------------------------------------------------------------------------*/
Xint
Xw6open(line)
Xchar *line;
X{
Xregister int itmp;
X
X strcpy(w6_ttyname,line);
X if(!strcmp(w6_ttyname,"/dev/tty"))
X return(W6_OPEN_INVALID);
X if(w6fd >= 0)
X return(W6_OPEN_ALREADY);
X
X w6fd = open(w6_ttyname,O_RDWR | O_NDELAY,0777);
X if(w6fd < 0)
X {
X perror(w6_ttyname);
X return(W6_OPEN_OPNFAIL);
X }
X else
X {
X fcntl(w6fd,F_SETFL,O_RDWR);
X ioctl(w6fd,(int)TCGETA,(char *) &w6_termio);
X w6_termio.c_iflag = IGNPAR | IGNBRK | IXON;
X w6_termio.c_oflag = OPOST | ONLCR | ONOCR;
X w6_termio.c_cflag = CREAD | CLOCAL | CS8 | CSTOPB | B9600;
X#if defined(USE_XCLUDE)
X w6_termio.c_lflag = XCLUDE;
X#else
X w6_termio.c_lflag = 0;
X#endif
X w6_termio.c_cc[VMIN] = 1;
X w6_termio.c_cc[VTIME] = 1;
X ioctl(w6fd,(int)TCSETA,(char *) &w6_termio);
X }
X
X w6mon_mode(0);
X w6xonxoff(1);
X w6set_time();
X return(0);
X
X} /* end of w6open */
X
X/*+-----------------------------------------------------------------------
X w6close()
X------------------------------------------------------------------------*/
Xvoid w6close()
X{
X if(w6fd < 0)
X return;
X close(w6fd);
X w6fd = -1;
X
X} /* end of w6close */
X
X#if defined(TEST)
Xmain()
X{
Xregister int offset;
Xregister int itmp;
X
X if(itmp = w6open(w6tty_default))
X {
X printf("w6open error %d\n",itmp);
X exit(1);
X }
X
X w6set_time();
X w6ctrl(W6SCROFF);
X w6clr();
X w6topline("");
X w6ctrl(W6SCRON);
X w6ctrl(W6CUROFF);
X w6eolwrap(1);
X w6topline("Wyse 60 test");
X w6_132cols();
X w6_43lines();
X
X for(offset = 0; offset < 100; offset += 10)
X {
X for(itmp = 1; itmp < 10; itmp++)
X {
X w6move(itmp,itmp + offset);
X w6putc('\\');
X }
X
X for(itmp = 9; itmp > 0; itmp--)
X {
X w6move(itmp,offset + 20 - itmp);
X w6putc('/');
X }
X }
X
X w6move(16,0);
X
X w6norm();
X w6puts("normal");
X w6putc('\n');
X
X w6reverse(1);
X w6puts("reverse");
X w6putc('\n');
X
X w6dim(1);
X w6puts("dim reverse");
X w6norm();
X w6putc('\n');
X
X w6blink(1);
X w6puts("blinking\n");
X
X w6attr(W6DIM);
X w6puts("dim\n");
X
X w6blink(1);
X w6puts("dim blinking");
X w6norm();
X w6putc('\n');
X
X w6move(23,0,stdout);
X w6ctrl(W6SCRON);
X
X w6ctrl(W6CURLIN);
X w6ctrl(W6CURON);
X w6move(0,0);
X w6puts("*");
X w6move(42,0);
X w6puts("*");
X w6close();
X exit(1);
X}
X
X#endif
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
chmod 0644 w6.c || echo "restore of w6.c fails"
fi
if test -f w6.h; then echo "File w6.h exists"; else
echo "x - extracting w6.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > w6.h &&
X/* CHK=0xE557 */
X/*+-------------------------------------------------------------------------
X w6.h
X ...!gatech!emory!tridom!wht - Public Domain
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-05-1989-18:35-wht-creation */
X
X#ifdef ESC
X#undef ESC
X#endif
X#define ESC 0x1B
X
X/* w6open() and related routines error codes */
X#define W6_OPEN_INVALID -1 /* for invalid tty name */
X#define W6_OPEN_UNKPID -2 /* unknown pid using line */
X#define W6_OPEN_LCKERR -3 /* lock file open error */
X#define W6_OPEN_NODEV -4 /* device does not exist */
X#define W6_OPEN_OPNFAIL -5 /* could not open line */
X#define W6_OPEN_ALREADY -6 /* line already open */
X
X/* w6ctrl() parameters */
X#define W6CUROFF '0' /* cursor off */
X#define W6CURON '1' /* cursor on */
X#define W6CURBLK '2' /* cursor steady block */
X#define W6CURLINBLINK '3' /* cursor blinking block */
X#define W6CURLIN '4' /* cursor steady line */
X#define W6CURBLKBLINK '5' /* cursor blinking block */
X#define W6SCROFF '8' /* turn off screen */
X#define W6SCRON '9' /* turn on screen */
X#define W6_132 ';' /* 132 column */
X#define W6_80 ':' /* 80 column */
X#define W6SCRLJUMP '@' /* jump scroll */
X#define W6SCRLSMOOTH1 '<' /* smooth scroll 1 line per second */
X#define W6SCRLSMOOTH2 '=' /* smooth scroll 2 line per second */
X#define W6SCRLSMOOTH4 '>' /* smooth scroll 4 line per second */
X#define W6SCRLSMOOTH8 '?' /* smooth scroll 8 line per second */
X
X/* w6attr() parameters */
X#define W6BLINK 0x02
X#define W6REVERSE 0x04
X#define W6UNDERLINE 0x08
X#define W6DIM 0x40
X
SHAR_EOF
chmod 0644 w6.h || echo "restore of w6.h fails"
fi
if test -f w6ps.c; then echo "File w6ps.c exists"; else
echo "x - extracting w6ps.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > w6ps.c &&
X/* CHK=0xC5D1 */
X/*+-------------------------------------------------------------------------
X w6ps.c - XENIX V/386 Wyse 60 process status display
X ...!gatech!emory!tridom!wht - Public Domain
X
X Defined functions:
X display_line0()
X display_proc(iproc,initial)
X display_procs(initial)
X error_term(text)
X find_utmp_for_pgrp(pgrp)
X get_cpu_time_str(timeval)
X get_procs()
X get_user(proc,slot,user)
X getpwent_and_enter(uid)
X init_uid_name_hash()
X main(argc,argv,envp)
X perror_term(text,code)
X pgrp_to_ttyname(pgrp)
X proc_pid_compare(p1,p2)
X read_utmp()
X uid_name_enter(uid,name)
X uid_to_name(uid)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-05-1989-13:27-wht-creation */
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <pwd.h>
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/page.h>
X#include <sys/seg.h>
X#include <sys/proc.h>
X#include <sys/signal.h>
X#include <sys/dir.h>
X#include <sys/user.h>
X#include <sys/var.h>
X#include <sys/utsname.h>
X#include <utmp.h>
X#include "w6.h"
X
Xchar *malloc(int);
Xchar *calloc(int,int);
X
Xextern int errno;
X
Xint memfd;
Xint kmemfd;
Xint swapfd;
X
Xint w6ps_pid;
Xint noldprocs;
Xint nprocs;
Xint mpid;
Xint hz;
Xunsigned short avenrun[3];
Xstruct var v;
Xstruct file *files;
Xstruct inode *inodes;
Xstruct text *texts;
Xstruct proc *procs;
Xstruct proc *oldprocs;
Xstruct mount *mounts;
Xstruct buf *bufs;
Xstruct buf *bufstart;
Xstruct user user;
Xdaddr_t swplo;
Xstruct utsname utsname;
Xtime_t ktime;
Xtime_t klbolt;
X#define MAX_UTMP 32
Xint nutmps = 0;
Xstruct utmp utmps[MAX_UTMP];
X
X#define XL_V 0
X#define XL_FILE 1
X#define XL_INODE 2
X#define XL_PROC 3
X#define XL_TEXT 4
X#define XL_MOUNT 5
X#define XL_BUFFER 6
X#define XL_SWPLO 7
X#define XL_TIME 8
X#define XL_LBOLT 9
X#define XL_UTSNAME 10
X#define XL_USER 11
X#define XL_AVENRUN 12
X#define XL_MPID 13
X#define XL_HZ 14
X
Xstruct xlist namelist[] =
X{
X { 0,0,0,"_v" },
X { 0,0,0,"_file" },
X { 0,0,0,"_inode" },
X { 0,0,0,"_proc" },
X { 0,0,0,"_text" },
X { 0,0,0,"_mount" },
X { 0,0,0,"_bufstrt" },
X { 0,0,0,"_swplo" },
X { 0,0,0,"_time" },
X { 0,0,0,"_lbolt" },
X { 0,0,0,"_utsname" },
X { 0,0,0,"_u" },
X { 0,0,0,"_avenrun" },
X { 0,0,0,"_mpid" },
X { 0,0,0,"_hz" },
X { 0,0,0,(char *) 0 }
X};
X
Xperror_term(text,code)
Xchar *text;
Xint code;
X{
X fputs(text,stdout);
X printf(" code=%d ",code);
X perror("");
X exit(1);
X}
X
Xerror_term(text)
Xchar *text;
X{
X fputs(text,stdout);
X exit(1);
X}
X
X/*+-------------------------------------------------------------------------
X read_utmp()
X--------------------------------------------------------------------------*/
Xvoid
Xread_utmp()
X{
Xint utmpfd;
Xstruct utmp *tutmp = utmps;
X
X nutmps = 0;
X if((utmpfd = open("/etc/utmp",O_RDONLY,755)) < 0)
X {
X perror_term("/etc/utmp",errno);
X exit(1);
X }
X
X while(read(utmpfd,(char *)(tutmp++),sizeof(struct utmp)) > 0)
X {
X if(++nutmps == MAX_UTMP)
X error_term("too many utmp entries for me to handle");
X }
X close(utmpfd);
X} /* end of read_utmp */
X
X/*+-------------------------------------------------------------------------
X find_utmp_for_pgrp(pgrp)
X--------------------------------------------------------------------------*/
Xstruct utmp *
Xfind_utmp_for_pgrp(pgrp)
Xint pgrp;
X{
Xstruct utmp *tutmp = utmps;
Xregister int count = nutmps;
X
X while(count--)
X {
X if(tutmp->ut_pid == pgrp)
X return(tutmp);
X tutmp++;
X }
X return((struct utmp *)0);
X} /* end of find_utmp_for_pgrp */
X
X/*+-------------------------------------------------------------------------
X pgrp_to_ttyname(pgrp)
X--------------------------------------------------------------------------*/
Xchar *
Xpgrp_to_ttyname(pgrp)
Xint pgrp;
X{
Xstruct utmp *tutmp;
X
X if(!(tutmp = find_utmp_for_pgrp(pgrp)))
X {
X read_utmp();
X tutmp = find_utmp_for_pgrp(pgrp);
X }
X if(!tutmp)
X return("??");
X else
X return(tutmp->ut_id);
X} /* end of pgrp_to_ttyname */
X
X/*+-------------------------------------------------------------------------
X get_user(proc,slot,user)
X--------------------------------------------------------------------------*/
Xget_user(proc,slot,user)
Xstruct proc *proc;
Xint slot; /* not used */
Xstruct user *user;
X{
X struct proc *first_proc = (struct proc *) namelist[XL_PROC].xl_value;
X long swapaddr;
X int i;
X
X if((proc->p_flag & (SSWAP|SPARTOUT)) || ! (proc->p_flag & SLOAD))
X {
X swapaddr = proc->p_addr[0].te_frameno * NBPC;
X lseek(swapfd,swapaddr,0);
X read(swapfd,user,sizeof *user);
X } else
X {
X lseek(memfd,proc->p_addr[0].te_frameno * NBPC,0);
X read(memfd,user,sizeof *user);
X }
X if((user->u_procp - first_proc) == proc->p_dummy0)
X return(1);
X else
X return(0);
X
X} /* end of get_user */
X
X/*+-------------------------------------------------------------------------
Xuid to username conversion; thanks for the idea to William LeFebvre
X--------------------------------------------------------------------------*/
X#define UID_NAME_HASH_SIZE 127 /* prime */
X#define HASH_EMPTY -1
X#define HASHIT(i) ((i) % UID_NAME_HASH_SIZE)
X
Xstruct uid_name_hash_entry {
X int uid;
X char name[10];
X};
X
Xstruct uid_name_hash_entry uid_name_table[UID_NAME_HASH_SIZE];
Xint uid_count = 0;
X
X/*+-------------------------------------------------------------------------
X init_uid_name_hash()
X--------------------------------------------------------------------------*/
Xvoid
Xinit_uid_name_hash()
X{
Xregister int ihash = 0;
Xregister struct uid_name_hash_entry *hashent = uid_name_table;
X
X while(ihash++ < UID_NAME_HASH_SIZE)
X {
X hashent->uid = HASH_EMPTY;
X hashent++;
X }
X} /* end of init_uid_name_hash */
X
X/*+-------------------------------------------------------------------------
X uid_name_enter(uid,name)
X--------------------------------------------------------------------------*/
Xint
Xuid_name_enter(uid,name)
Xregister int uid;
Xregister char *name;
X{
Xregister int table_uid;
Xregister int hashval;
X
X if(++uid_count >= UID_NAME_HASH_SIZE)
X error_term("too many user names");
X
X hashval = HASHIT(uid);
X while((table_uid = uid_name_table[hashval].uid) != HASH_EMPTY)
X {
X if(table_uid == uid)
X return(hashval);
X hashval = (hashval + 1) % UID_NAME_HASH_SIZE;
X }
X
X uid_name_table[hashval].uid = uid;
X strncpy(uid_name_table[hashval].name,name,
X sizeof(uid_name_table[0].name));
X
X return(hashval);
X
X} /* end of uid_name_enter */
X
X/*+-------------------------------------------------------------------------
X getpwent_and_enter(uid)
X--------------------------------------------------------------------------*/
Xgetpwent_and_enter(uid)
Xregister int uid;
X{
Xregister int hashval;
Xregister struct passwd *pwd;
Xchar errant[10];
Xstruct passwd *getpwuid();
X
X pwd = getpwuid(uid);
X endpwent();
X if(pwd)
X {
X hashval = uid_name_enter(pwd->pw_uid,pwd->pw_name);
X return(hashval);
X }
X sprintf(errant,"%d",uid);
X return(uid_name_enter(uid,errant));
X} /* end of getpwent_and_enter */
X
X/*+-------------------------------------------------------------------------
X uid_to_name(uid)
X--------------------------------------------------------------------------*/
Xchar *
Xuid_to_name(uid)
Xregister int uid;
X{
Xregister int uid_hash;
Xregister int table_uid;
Xregister char *name;
X
X uid_hash = HASHIT(uid);
X while((table_uid = uid_name_table[uid_hash].uid) != uid)
X {
X if(table_uid == HASH_EMPTY)
X {
X /* not in hash table */
X uid_hash = getpwent_and_enter(uid);
X break; /* out of while */
X }
X uid_hash = (uid_hash + 1) % UID_NAME_HASH_SIZE;
X }
X return(uid_name_table[uid_hash].name);
X} /* end of char *uid_to_name */
X
X/*+-----------------------------------------------------------------------
X char *get_cpu_time_str(timeval)
X 6-char static string address is returned
X------------------------------------------------------------------------*/
Xchar *get_cpu_time_str(timeval)
Xlong timeval;
X{
Xstatic char timestr[10];
Xlong mm,ss;
X
X/* timeval /= hz; */
X timeval /= 50;
X mm = timeval / 60L;
X timeval -= mm * 60L;
X ss = timeval;
X
X if(mm > 999)
X sprintf(timestr,"%5ldu",mm);
X else
X sprintf(timestr,"%3lu:%02lu",mm,ss);
X return(timestr);
X} /* end of get_cpu_time_str */
X
X#define AVENRUN_Y 0
X#define AVENRUN_X 0
X/*+-------------------------------------------------------------------------
X display_line0()
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_line0()
X{
Xregister int count;
Xregister int itmp;
Xchar s64[64];
X
X w6move(AVENRUN_Y,AVENRUN_X);
X
X lseek(kmemfd,namelist[XL_AVENRUN].xl_value,0);
X read(kmemfd,avenrun,sizeof(avenrun));
X
X lseek(kmemfd,namelist[XL_MPID].xl_value,0);
X read(kmemfd,&mpid,sizeof(mpid));
X
X sprintf(s64,"last pid: %5d load averages:",
X mpid,avenrun[0],avenrun[1],0);
X w6puts(s64);
X
X for(count = 0; count < 3; count++)
X {
X itmp = avenrun[count];
X sprintf(s64," %d.%02d",itmp / 100, itmp % 100);
X w6puts(s64);
X }
X
X} /* end of display_line0 */
X
X#define PROC_Y 2
X#define PROC_X 0
X#define UID_X 2
X#define PID_X 12
X#define PPID_X 18
X#define PGRP_X 24
X#define CPU_X 30
X#define TIM_X 34
X#define PRI_X 38
X#define NICE_X 42
X#define WSIZE_X 45
X#define TSIZE_X 50
X#define SSIZE_X 55
X#define UTIME_X 60
X#define STIME_X 67
X#define TTY_X 74
X#define CMD_X 78
X
X/*+-------------------------------------------------------------------------
X display_proc(iproc,initial)
X00000000001111111111222222222233333333334444444444555555555566666666667777777777
X01234567890123456789012345678901234567890123456789012345678901234567890123456789
XS USER PID PPID PGRP CPU TIM PRI NI WSIZ TSIZ SSIZ UCPU SCPU TTY CM
X# ########X ##### ##### ##### ### ### ### ## #### #### #### ###### ###### ### ##
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_proc(iproc,initial)
Xregister int iproc;
Xregister int initial;
X{
Xregister int positioned = 0;
Xregister int itmp;
Xregister int got_user;
Xstruct proc *tproc = procs + iproc;
Xstruct proc *oproc = oldprocs + iproc;
Xstatic char *p_stat_str = " S?RIZTXXX";
Xchar buf[20];
X
X if((itmp = (tproc->p_stat == SRUN)) ||
X ((tproc->p_stat != SRUN) && (oproc->p_stat == SRUN)))
X {
X initial = 1;
X if(itmp && (tproc->p_pid != w6ps_pid))
X {
X w6reverse(1);
X w6dim(1);
X }
X }
X
X if(initial || (tproc->p_stat != oproc->p_stat))
X {
X w6move(PROC_Y + 2 + iproc,PROC_X);
X w6putc(p_stat_str[tproc->p_stat]);
X w6putc(' ');
X positioned = 1;
X }
X
X if(initial || (tproc->p_uid != oproc->p_uid))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + UID_X);
X sprintf(buf,"%8s",uid_to_name(tproc->p_uid));
X w6puts(buf);
X w6putc((tproc->p_uid != tproc->p_suid) ? '#' : ' ');
X w6putc(' ');
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_pid != oproc->p_pid))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + PID_X);
X sprintf(buf,"%5d ",tproc->p_pid);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_ppid != oproc->p_ppid))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + PPID_X);
X sprintf(buf,"%5d ",tproc->p_ppid);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_pgrp != oproc->p_pgrp))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + PGRP_X);
X sprintf(buf,"%5d ",tproc->p_pgrp);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_cpu != oproc->p_cpu))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + CPU_X);
X sprintf(buf,"%3u ",tproc->p_cpu);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_time != oproc->p_time))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + TIM_X);
X sprintf(buf,"%3u ",tproc->p_time);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_pri != oproc->p_pri))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + PRI_X);
X sprintf(buf,"%3u ",tproc->p_pri);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_nice != oproc->p_nice))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + NICE_X);
X sprintf(buf,"%2d ",tproc->p_nice);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_wsize != oproc->p_wsize))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + WSIZE_X);
X sprintf(buf,"%4d ",tproc->p_wsize);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_tsize != oproc->p_tsize))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + TSIZE_X);
X sprintf(buf,"%4d ",tproc->p_tsize);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X if(initial || (tproc->p_ssize != oproc->p_ssize))
X {
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + SSIZE_X);
X sprintf(buf,"%4d ",tproc->p_ssize);
X w6puts(buf);
X positioned = 1;
X }
X else
X positioned = 0;
X
X/* since not saving user area, always update fields from it */
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + UTIME_X);
X if(got_user = get_user(tproc,iproc,&user))
X {
X w6puts(get_cpu_time_str(user.u_utime));
X w6putc(' ');
X w6puts(get_cpu_time_str(user.u_stime));
X w6putc(' ');
X }
X else
X w6puts("------ ------ ");
X positioned = 1;
X
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + TTY_X);
X sprintf(buf,"%3.3s ",pgrp_to_ttyname(tproc->p_pgrp));
X w6puts(buf);
X positioned = 1;
X
X if(!positioned)
X w6move(PROC_Y + 2 + iproc,PROC_X + CMD_X);
X if(got_user)
X {
X register char *cptr = user.u_psargs;
X while(*cptr)
X {
X *cptr &= 0x7F;
X if(*cptr < 0x20)
X *cptr = 0x20;
X cptr++;
X }
X w6puts(user.u_psargs);
X }
X else
X {
X switch(tproc->p_stat)
X {
X case SIDL:
X w6puts("------ in creation ------");
X break;
X case SZOMB:
X w6puts("----- in termination -----");
X break;
X case SXBRK:
X case SXSTK:
X case SXTXT:
X w6puts("-------- swapping --------");
X default:
X w6puts("???");
X }
X }
X
X w6clrtoeol();
X w6norm();
X
X} /* end of display_proc */
X
X/*+-------------------------------------------------------------------------
X display_procs(initial)
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_procs(initial)
Xint initial;
X{
Xregister int iproc;
X for(iproc = 0; iproc < nprocs; iproc++)
X display_proc(iproc,(iproc >= noldprocs) ? 1 : initial);
X w6clrtobot();
X} /* end of display_procs */
X
X/*+-------------------------------------------------------------------------
X proc_pid_compare(p1,p2)
X--------------------------------------------------------------------------*/
Xproc_pid_compare(p1,p2)
Xstruct proc *p1;
Xstruct proc *p2;
X{
X return(p1->p_pid - p2->p_pid);
X} /* end of proc_pid_compare */
X
X/*+-------------------------------------------------------------------------
X get_procs()
X--------------------------------------------------------------------------*/
Xvoid
Xget_procs()
X{
Xregister int iproc;
Xregister int proc_size = v.v_proc * sizeof(struct proc);
Xstruct proc *tproc;
X
X/* save old proc structure */
X memcpy((char *)oldprocs,(char *)procs,proc_size);
X noldprocs = nprocs;
X
X/* read current procs - steal iproc register int temporarily */
X lseek(kmemfd,namelist[XL_PROC].xl_value,0);
X if((iproc = read(kmemfd,procs,proc_size)) != proc_size)
X perror_term("get_procs: cannot read kmem",iproc);
X
X/* if slot not in use, force to end when sorting */
X nprocs = 0;
X for(iproc = 0;iproc < v.v_proc;iproc++)
X {
X tproc = procs + iproc;
X tproc->p_dummy0 = iproc; /* save slot number */
X if((tproc->p_stat == 0) || (tproc->p_pgrp == tproc->p_pid) ||
X (tproc->p_pgrp == 0))
X tproc->p_pid = 32767;
X else
X nprocs++;
X }
X
X/* sort new procs array */
X qsort((char *)procs,v.v_proc,sizeof(struct proc),proc_pid_compare);
X
X} /* end of get_procs */
X
X/*+-------------------------------------------------------------------------
X main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xregister int itmp;
Xchar s80[80];
Xextern char *w6tty_default;
X
X setbuf(stdout,NULL);
X setbuf(stderr,NULL);
X
X w6ps_pid = getpid();
X
X if(itmp = w6open(w6tty_default))
X {
X printf("w6open error %d\n",itmp);
X exit(1);
X }
X
X w6ctrl(W6SCROFF);
X w6clr();
X w6topline("");
X w6ctrl(W6SCRON);
X w6ctrl(W6CUROFF);
X w6eolwrap(1);
X w6_132cols();
X w6_43lines();
X
X if(access("/xenix",4))
X {
X fprintf(stderr,"must have read access to /xenix\n");
X exit(1);
X }
X if(xlist("/xenix",namelist) != 0)
X {
X perror("w6ps: namelist");
X exit(1);
X }
X
X if(access("/dev/mem",4) || access("/dev/kmem",4) ||
X access("/dev/swap",4))
X {
X fprintf(stderr,"w6ps: must be owned by root or sysinfo + setuid\n");
X exit(1);
X }
X
X if((memfd = open("/dev/mem",O_RDONLY)) < 0)
X {
X perror("w6ps: /dev/mem");
X exit(1);
X }
X if((kmemfd = open("/dev/kmem",O_RDONLY)) < 0)
X {
X perror("w6ps: /dev/kmem");
X exit(1);
X }
X if((swapfd = open("/dev/swap",O_RDONLY)) < 0)
X {
X perror("w6ps: /dev/swap");
X exit(1);
X }
X
X lseek(kmemfd,namelist[XL_V].xl_value,0);
X read(kmemfd,&v,sizeof v);
X
X lseek(kmemfd,namelist[XL_SWPLO].xl_value,0);
X read(kmemfd,&swplo,sizeof swplo);
X
X lseek(kmemfd,namelist[XL_UTSNAME].xl_value,0);
X read(kmemfd,&utsname,sizeof utsname);
X
X lseek(kmemfd,namelist[XL_HZ].xl_value,0);
X read(kmemfd,&hz,sizeof hz);
X
X sprintf(s80,"%s - %s %s %s",utsname.nodename,
X utsname.sysname,utsname.version,utsname.release);
X w6topline(s80);
X
X if(!(procs = (struct proc *)calloc(1,v.v_proc * sizeof(struct proc))))
X {
X fprintf(stderr,"no memory\n");
X exit(1);
X }
X
X if(!(oldprocs = (struct proc *)malloc(v.v_proc * sizeof(struct proc))))
X {
X fprintf(stderr,"no memory\n");
X exit(1);
X }
X noldprocs = nprocs = 0;
X
X init_uid_name_hash();
X
X w6move(PROC_Y,PROC_X);
X w6puts("S USER PID PPID PGRP CPU TIM PRI NI WSIZ TSIZ SSIZ UCPU SCPU TTY CMD");
X w6move(PROC_Y + 1,PROC_X);
X w6puts("- --------- ----- ----- ----- --- --- --- -- ---- ---- ---- ------ ------ --- --");
X get_procs();
X display_line0();
X display_procs(1);
X
X while(1)
X {
X sleep(2);
X get_procs();
X display_line0();
X display_procs(0);
X }
X
X exit(0);
X} /* end of main */
X
X
SHAR_EOF
chmod 0644 w6ps.c || echo "restore of w6ps.c fails"
fi
exit 0
--
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation ...!gatech!emory!tridom!wht
Ker-au'-lo-phon. An 8-foot partial flue-stop, having metal pipes
surmounted by adjustable rings, and with a hole bored near the top
of each pipe, producing a soft and "reedy" tone.
More information about the Alt.sources
mailing list