32V/usr/src/cmd/ps.c

Compare this file to the similar file:
Show the results in this format:

/*
 *	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);
}