Bell 32V development
[unix-history] / usr / src / cmd / ps.c
/*
* ps - process status
* examine and print certain things about processes
*/
#include <stdio.h>
#include <a.out.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/tty.h>
#include <sys/dir.h>
#include <sys/user.h>
struct nlist nl[] = {
{ "_proc" },
{ "_swapdev" },
{ "_swplo" },
{ 0 },
};
struct proc mproc;
union {
struct user yy;
int xx[128][UPAGES];
} zz;
#define u zz.yy
int chkpid;
int retcode=1;
int lflg;
int kflg;
int xflg;
char *tptr;
char *gettty();
int aflg;
int pagetbl[128];
int mem;
int swmem;
int swap;
daddr_t swplo;
int ndev;
struct devl {
char dname[DIRSIZ];
dev_t dev;
} devl[256];
char *coref, *memf;
main(argc, argv)
char **argv;
{
int i;
char *ap;
int uid, puid;
if (argc>1) {
ap = argv[1];
while (*ap) switch (*ap++) {
case 'a':
aflg++;
break;
case 't':
if(*ap)
tptr = ap;
aflg++;
if (*tptr == '?')
xflg++;
break;
case 'x':
xflg++;
break;
case '-':
break;
case 'l':
lflg++;
break;
case 'k':
kflg++;
break;
default:
chkpid=atoi(--ap);
*ap = '\0';
break;
}
}
if(chdir("/dev") < 0) {
fprintf(stderr, "Can't change to /dev\n");
done(1);
}
nlist(argc>2? argv[2]:"/unix", nl);
if (nl[0].n_type==0) {
fprintf(stderr, "No namelist\n");
done(1);
}
coref = "/dev/kmem";
memf = "/dev/mem";
if(kflg) {
coref = "/usr/sys/core";
memf = coref;
nl[0].n_value = (char *)((int)nl[0].n_value & 0x7fffffff);
nl[1].n_value = (char *)((int)nl[1].n_value & 0x7fffffff);
nl[2].n_value = (char *)((int)nl[2].n_value & 0x7fffffff);
}
if ((mem = open(coref, 0)) < 0) {
fprintf(stderr, "No kmem\n");
done(1);
}
if((swmem = open(memf, 0)) < 0) {
fprintf(stderr, "No mem\n");
done(1);
}
/*
* read mem to find swap dev.
*/
lseek(mem, (long)nl[1].n_value, 0);
read(mem, &nl[1].n_value, sizeof(nl[1].n_value));
/*
* Find base of swap
*/
lseek(mem, (long)nl[2].n_value, 0);
read(mem, &swplo, sizeof(swplo));
/*
* Locate proc table
*/
lseek(mem, (long)nl[0].n_value, 0);
getdev();
uid = getuid();
if (lflg)
printf(" F S UID PID PPID CPU PRI NICE ADDR SZ WCHAN TTY TIME COMMAND\n"); else
if (chkpid==0) printf(" PID TTY TIME COMMAND\n");
for (i=0; i<NPROC; i++) {
read(mem, &mproc, sizeof mproc);
if (mproc.p_stat==0)
continue;
if (mproc.p_pgrp==0 && xflg==0 && mproc.p_uid==0)
continue;
puid = mproc.p_uid;
if ((uid != puid && aflg==0) ||
(chkpid!=0 && chkpid!=mproc.p_pid))
continue;
if(prcom(puid)) {
printf("\n");
retcode=0;
}
}
done(retcode);
}
getdev()
{
#include <sys/stat.h>
register FILE *df;
struct stat sbuf;
struct direct dbuf;
if ((df = fopen("/dev", "r")) == NULL) {
fprintf(stderr, "Can't open /dev\n");
done(1);
}
ndev = 0;
while (fread(&dbuf, sizeof(dbuf), 1, df) == 1) {
if(dbuf.d_ino == 0)
continue;
if(stat(dbuf.d_name, &sbuf) < 0)
continue;
if ((sbuf.st_mode&S_IFMT) != S_IFCHR)
continue;
strcpy(devl[ndev].dname, dbuf.d_name);
devl[ndev].dev = sbuf.st_rdev;
ndev++;
}
fclose(df);
if ((swap = open("/dev/swap", 0)) < 0) {
fprintf(stderr, "Can't open /dev/swap\n");
done(1);
}
}
prcom(puid)
{
int abuf[128];
long addr;
int mf;
register int *ip;
register char *cp, *cp1;
long tm;
int c, nbad;
register char *tp;
if ((mproc.p_flag& (SLOAD | SSPART)) == 0) {
addr = (mproc.p_swaddr+swplo)<<9;
mf = swap;
lseek(mf, addr, 0);
if (read(mf, &u, sizeof(u)) != sizeof(u))
return(0);
} else {
for(c=0; c<UPAGES; c++) {
lseek(swmem,mproc.p_addr[c]<<9,0);
if (read(swmem,((int *)&u)+128*c,512) != 512) /* get u page */
return(0);
}
}
tp = gettty();
if (tptr && strcmpn(tptr, tp, 2))
return(0);
if (lflg) {
printf("%3o %c%4d", 0377 & mproc.p_flag,
"0SWRIZT"[mproc.p_stat], puid);
}
printf("%6u", mproc.p_pid);
if (lflg) {
printf("%6u%4d%4d%5d%8x%4d", mproc.p_ppid, mproc.p_cpu&0377,
mproc.p_pri,
mproc.p_nice,
mproc.p_addr[0], mproc.p_size);
if (mproc.p_wchan)
printf("%9x", mproc.p_wchan); else
printf(" ");
}
printf(" %-2.2s", tp);
if (mproc.p_stat==SZOMB) {
printf(" <defunct>");
return(1);
}
tm = (u.u_utime + u.u_stime + 30)/60;
printf(" %2ld:", tm/60);
tm %= 60;
printf(tm<10?"0%ld":"%ld", tm);
if (0 && lflg==0) { /* 0 == old tflg (print long times) */
tm = (u.u_cstime + 30)/60;
printf(" %2ld:", tm/60);
tm %= 60;
printf(tm<10?"0%ld":"%ld", tm);
tm = (u.u_cutime + 30)/60;
printf(" %2ld:", tm/60);
tm %= 60;
printf(tm<10?"0%ld":"%ld", tm);
}
if (mproc.p_pid == 0) {
printf(" swapper");
return(1);
}
c = mproc.p_size - btoc(512);
if ((mproc.p_flag & SLOAD) == 0) {
addr += ctob(c);
lseek(mf, addr, 0);
if (read(mf, abuf, sizeof(abuf)) != sizeof(abuf))
return(1);
} else {
if (u.u_pcb.pcb_szpt<1 || u.u_pcb.pcb_szpt>20)
return(1);
c = ctob((u.u_ptable[u.u_pcb.pcb_szpt-1] & 0x1fffff));
lseek(swmem,c,0);
if (read(swmem,pagetbl,512) != 512) /* get last page table */
return(1);
lseek(swmem,ctob((pagetbl[127] & 0x1fffff)),0);
if (read(swmem,abuf,sizeof(abuf)) != sizeof(abuf))
return(1);
}
abuf[128] = 0;
for (ip = &abuf[126]; ip > abuf;) {
if (*--ip == -1 || *ip == 0) {
cp = (char *)(ip+1);
if (*cp==0)
cp++;
nbad = 0;
for (cp1 = cp; cp1 < (char *)&abuf[128]; cp1++) {
c = *cp1&0177;
if (c==0)
*cp1 = ' ';
else if (c < ' ' || c > 0176) {
if (++nbad >= 5) {
*cp1++ = ' ';
break;
}
*cp1 = '?';
} else if (c=='=') {
*cp1 = 0;
while (cp1>cp && *--cp1!=' ')
*cp1 = 0;
break;
}
}
while (*--cp1==' ')
*cp1 = 0;
printf(lflg?" %.30s":" %.60s", cp);
return(1);
}
}
return(1);
}
char *
gettty()
{
register i;
register char *p;
if (u.u_ttyp==0)
return("?");
for (i=0; i<ndev; i++) {
if (devl[i].dev == u.u_ttyd) {
p = devl[i].dname;
if (p[0]=='t' && p[1]=='t' && p[2]=='y')
p += 3;
return(p);
}
}
return("?");
}
done(exitno)
{
exit(exitno);
}