AUSAM/source/S/ps.c

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

#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;
}