AUSAM/source/S/ps.c
#define AUSAM
/*
*
* aug '77 Chris M, Ian J
*
* consolidated ps
* faster - gprocs - print time - no k flag -
* better defintion of a & t flags
*
* nov '77 Ian J
*
* introduce 'c' and 'p' flags
* 'c' => print sum of child usr+sys times
* 'p' => print sum of usr+sys times
* 'cp' => print sum of child & parant times
* default is 'p'
* also check locations 54&56 for non-zero
* if so this long indicates clock tics since
* clock initialized. print this info atop listing.
* allow 'u' and 's' flags
* 'u' => print user time only
* 's' => print system time only
* 'us' => (default) print sum of user and system times
*
*/
/*
* ps - process status
* examine and print certain things about processes
*/
#include <param.h>
#include <proc.h>
#include <tty.h>
#include <user.h>
struct proc proc[NPROC];
int ttydev;
struct user u;
char partab[1];
int lflg;
int zflg;
int cflg;
int pflg;
int uflg;
int sflg;
int xflg;
int tflg;
int gflg;
int titflg;
int aflg;
int mem; /* file desc. for kernal memory space */
int swap; /* file desc. for swap area */
char ltty[64]; /* char id's for desired terminals */
char *ptty ltty; /* limit of id's for ltty */
int ndev;
char devc[65]; /* last character of tty name from dev */
int devl[65]; /* corresponding major/minor number */
int devt[65];
struct {
long pusr;
long psys;
long cusr;
long csys;
} tbuf;
struct ibuf {
char idevmin, idevmaj;
int inum;
int iflags;
#ifdef AUSAM
unsigned iuid;
#endif
char inl;
#ifndef AUSAM
char iuid;
char igid;
#endif
char isize0;
int isize;
int iaddr[8];
long ictime;
long imtime;
#ifndef AUSAM
int fill;
#endif
};
#define RSIZE 32
#define usagerr { printf("\n\t ps [-][alxcpuszt[c]]\n"); done(-1); }
main(argc, argv)
char **argv;
{
struct proc *p;
int nproc, b;
register int i, c, n;
char *ap, *comname;
long comtime;
unsigned uid, puid;
long tics;
double temp;
extern fout;
titflg = 1; /* no title yet printed */
fout = dup(1);
if ( argc > 2 ) usagerr;
if (argc > 1) {
ap = argv[1];
while (*ap) switch (*ap++) {
case 'a':
aflg++;
break;
case 't':
tflg++;
if( *ap ) *ptty++ = *ap++;
break;
case 'g':
gflg++;
break;
case 'x':
xflg++;
break;
case 'l':
lflg++;
break;
case 'z':
zflg++;
break;
case 'c':
cflg++;
break;
case 'p':
pflg++;
break;
case 's':
sflg++;
break;
case 'u':
uflg++;
break;
case '-':
break;
default:
usagerr;
}
}
if( (cflg==0)&&(pflg==0) ) pflg++;
if( (uflg==0)&&(sflg==0) ) uflg++, sflg++;;
if(chdir("/dev") < 0) {
printf("Chdir /dev failed\n");
done(-1);
}
if ((mem = open("mem", 0)) <= 0) {
printf("No mem\n");
done(-1);
}
getdev();
#ifndef AUSAM
uid = getuid();
#endif
#ifdef AUSAM
uid = getreal();
#endif
if((swap = open("swap",0)) < 0)
printf("No swap\n");
if( (nproc=gprocs(proc)) > NPROC ) {
printf(" tell a guru to re-compile PS.C \n");
done(-1);
}
if ( zflg ) {
seek(mem,054,0); read(mem,&tics,4);
if( tics ) {
ptime(tics);
printf(" since boot");
i = proc[0].p_addr;
c = i>>3;
i = (i&07)<<6;
i =+ &(0->u_utime);
seek(mem, c, 3);
seek(mem, i, 1);
read(mem,&tbuf,sizeof tbuf); /* get times for system process */
temp = tbuf.pusr + tbuf.psys + tbuf.cusr + tbuf.csys;
temp = 100 * temp / tics + 0.5;
printf("\n %2.0f%% idle time\n",temp);
}
}
for (i=0; i<nproc; i++) {
if (proc[i].p_stat==0)
continue;
if (proc[i].p_ttyp==0) {
if (xflg==0)
continue;
c = '?';
} else {
for(c=0; c<ndev; c++)
if(devt[c] == proc[i].p_ttyp) {
c = devc[c];
goto out;
}
seek(mem, &((proc[i].p_ttyp)->t_dev), 0);
read(mem, &ttydev, 2);
for(c=0; c<ndev; c++)
if(devl[c] == ttydev) {
devt[c] = proc[i].p_ttyp;
c = devc[c];
goto out;
}
c = '?';
out:;
}
#ifndef AUSAM
puid = proc[i].p_uid & 0377;
#endif
#ifdef AUSAM
puid = proc[i].p_uid;
#endif
/*
* four possibilities of which process's to look at:
*
* a=0 a=1
*
* t=0 all terminals all terminals
* own processes all processes
*
* t=1 own terminal own terminal *
* own processes all processes
*
* *note: default is own terminal but maybe the named
* terminal
*/
if( aflg ) {
if( tflg && destty(c) ) continue;
} else {
if( uid != puid ) continue;
else if( tflg && destty(c) ) continue;
}
if( (comname=getcom(i,&comtime)) == 0 ) continue;
if( titflg )
if(lflg) {
#ifndef AUSAM
printf("TTY F S UID PID PRI ADDR SZ WCHAN TIME COMMAND\n");
#endif
#ifdef AUSAM
printf("TTY F S UID PID PRI ADDR SZ WCHAN TIME COMMAND\n");
#endif
} else printf("%s PID TIME COMMAND\n",tflg==1 ? " " : "TTY");
titflg = 0;
if ( lflg || tflg!=1 || destty(c) )
{ putchar(c); putchar(':'); }
else if( tflg == 0 )
{ putchar(' '); putchar(' '); }
if (lflg) {
#ifndef AUSAM
printf("%3o %c%4d", proc[i].p_flag,
#endif
#ifdef AUSAM
printf("%3o %c%5d", proc[i].p_flag,
#endif
"0SWRIZT"[proc[i].p_stat], puid);
}
printf("%6l", proc[i].p_pid);
if (lflg) {
if( proc[i].p_nice == 0) c = ' ';
else if(proc[i].p_nice > 0) c = '+';
else c = '-';
printf("%4d%c%6o%4d", proc[i].p_pri, c, proc[i].p_addr,
(proc[i].p_size+7)>>3);
if (proc[i].p_wchan)
printf("%7o", proc[i].p_wchan); else
printf(" ");
}
ptime( comtime ); /* output time used */
printf(lflg?" %.17s\n":" %.62s\n", comname);
}
if( titflg ) printf("no procs found\n");
done(0);
}
getdev()
{
register struct {
int dir_ino;
char dir_n[14];
} *p;
register i, c;
int f;
int mdev;
char *dbuf = &proc;
int sdbuf = sizeof proc;
int sbuf[20];
if( (f = open("."))<0 ) {
printf("cannot open /dev\n");
done(-1);
}
c = 0;
if( ptty == ltty ) {
fstat( 0, sbuf);
mdev = sbuf->iaddr[0];
}
loop:
if( (i = read(f, dbuf, sdbuf))<=0 ) {
close(f);
ndev = c;
return;
}
for(p = dbuf; p < &dbuf[i]; p++) {
if(p->dir_ino == 0)
continue;
if(p->dir_n[0] == 't' &&
p->dir_n[1] == 't' &&
p->dir_n[2] == 'y' &&
p->dir_n[4] == 0 &&
p->dir_n[3] != 0) {
if(stat(p->dir_n, sbuf) < 0)
continue;
devc[c] = p->dir_n[3];
devl[c] = sbuf->iaddr[0];
if( (mdev == devl[c]) && (ptty==ltty) )
*ptty++ = devc[c];
c++;
continue;
}
}
goto loop;
}
getcom(i,comtime)
int i;
long *comtime;
{
int baddr, laddr, mf;
register int *ip,cp;
register char *cp1;
int c, nbad;
long ct;
static char stbuf[513];
*comtime = -1;
if( proc[i].p_stat==SZOMB ) return("<defunct>");
baddr = 0;
laddr = 0;
if (proc[i].p_flag&SLOAD) {
laddr = proc[i].p_addr;
mf = mem;
} else {
baddr = proc[i].p_addr;
if((mf = swap) < 0)
return("<??>");
}
baddr =+ laddr>>3;
laddr = (laddr&07)<<6;
seek(mf, baddr, 3);
laddr =+ &(0->u_utime);
seek(mf,laddr,1);
read(mf,&tbuf,sizeof tbuf);
if(!uflg) tbuf.pusr = tbuf.cusr = 0;
if(!sflg) tbuf.psys = tbuf.csys = 0;
if(pflg) ct = tbuf.pusr+tbuf.psys; else ct=0;
if(cflg) ct =+ tbuf.cusr+tbuf.csys;
*comtime = ct; /* save accumulated time for later printout */
if( i == 0 ) return("UNIX");
baddr = 0; laddr = 0;
if(proc[i].p_flag & SLOAD)
laddr = proc[i].p_addr;
else
baddr = proc[i].p_addr;
laddr =+ proc[i].p_size - 8;
baddr =+ laddr>>3;
laddr = (laddr&07) << 6;
seek(mf,baddr,3);
cp = laddr;
if(mf == mem) /* less reading */
cp =+ 512-RSIZE;
seek(mf,cp,1);
cp =- laddr;
ip = &stbuf[512];
do {
read(mf,stbuf + cp,( mf == mem ? RSIZE : 512));
while(ip > (stbuf + cp))
if( *--ip == -1) goto found;
seek(mf, -(RSIZE<<1), 1);
cp =- RSIZE;
} while( cp >= 0);
return("");
found: cp1 = ++ip;
nbad = 0;
for (; cp1 < &stbuf[512]; cp1++) {
c = *cp1;
if (c==0)
*cp1 = ' ';
else if (c < ' ' || c > 0176) {
if (++nbad >= 5) {
*cp1++ = ' ';
break;
}
*cp1 = '?';
}
}
while (*--cp1==' ') *cp1 = 0;
{
char *q,*p;
q = "getty"; p = ip;
while( *q++ == *p++ ) if( (*q==0) && (*p==' ') && (gflg==0) ) return(0);
if( i>1 ) {
q = "init"; p = ip;
while( *q++ == *p++ ) if( (*q==0) && (*p==0) && (gflg==0) ) return(0);
}
}
return(ip);
}
ptime(tics)
long tics;
{
struct {
int hiword;
int loword;
};
if( tics<0 )
{
printf(" ");
}
else
{
register divn,sepc,trac,cp;
divn = 100;
sepc = '.'; trac = 's'; /* sss.ss seconds */
if(tics > 15000)
{
sepc = 'm'; /* xxxmxxs minutes */
tics = tics / 50; divn = 60;
if(tics > 18000)
{
sepc = 'h';trac = 'm'; /* xxxhxxm hours */
tics = tics / 60;
if(tics > 7200)
{
sepc = 'd'; trac = 'h'; /* xxxdxxh */
tics = tics/60;
divn = 24;
}
}
}
else tics = tics * 2;
cp = tics.loword;
printf(" %3l%c%c%c%c", cp/divn, sepc,
(cp%divn)/10 + '0', (cp%divn)%10 + '0', trac);
}
}
done(cc)
{
flush();
exit(cc);
}
destty( c )
register c;
{
char *p = ptty;
char *q = ltty;
while( q < p )
if( *q++ == c ) return 0;
return 1;
}