Access to user process info.

Joe Angelo joe at auspyr.UUCP
Tue Jan 6 05:53:02 AEST 1987


Looking up the process and user tables can be rots of fun.
Course, it's different on EVERY version of UNIX and the likes.
Ucb source programs w.c and ps.c are alot of help, but I don't 
think anyone is likely to post them ... I've enclosed a small
program to read the proc table and the user table -- programs
works on an NEC MS190 running SYSIII Unix and I assure you
it will not work on any other computer ... (That's why I didn't
post it in net.sources) ... But perhaps you can get an idea or
two from the program.

I'm working on a version of "ps with specified options (pss)",
a version of ps where the arguments specify the data fields you
want printed ... eg: pss '-UpPNC' will print only USERNAME,
PROCID, PPROCID, NAME_IN_USER_TABEL, and CPU time ... I'm trying
to make the program work on ALL version of UNIX/xenix. In about
20 years I'll post it ...

Anyways, hope this helps,

--- sloppy code follows, cut here and burn below portion of crt --

/*
** psmask.c -- print process table and process masks
**
** portion of this code MAY look like ucb/att code,
** since i've read it all a million times, there is a MINOR
** chance that my subconsience mind has been warped ...
**
*/
char	*DOIT();
#include <stdio.h>
#include <a.out.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/var.h>
#include <ctype.h>
#include <utmp.h>
#include <time.h>
#include <sys/stat.h>

/*
** assign tty major/minor numbers to a name, 
** forget looking them up in /dev, takes too long ...
*/

struct	{
	int	maj;
	int	min;
	char	*name;
}	TTY[] = {
	0,0,"co", 0,1,"01", 0,2,"02", 0,3,"03", 5,0,"h0",
	5,1,"h1", 5,2,"h2", 5,3,"h3", 5,4,"h4", 5,5,"h5",
	5,6,"h6", 5,7,"h7", 5,8,"h8", 5,9,"h9", 5,10,"ha",
	5,11,"hb", 5,12,"hc", 5,13,"hd", 5,14,"he", 5,15,"hf",
	5,16,"hg", 5,17,"hh", 5,18,"hi", 5,19,"hj", 5,20,"hk",
	5,21,"hl", 5,22,"hm", 5,23,"hn", 5,24,"ho", 5,25,"hp",
	5,26,"hq", 5,27,"hr", 5,28,"hs", 5,29,"ht", 5,30,"hu",
	5,31,"hv", 99,99,"nothing"
};

/*
** user table 
*/
struct	user	u;
/*
** process table
*/
struct	proc	p;
/*
** tuneable varaible table
*/
struct	var	v;
/*
** what symbols too look for in kernel a.out file
*/
struct	nlist	nl[  ] = {
	{ "_v" },
	{ "_proc" },
	{ "_swplo" }
};

#define	N_VARS		0
#define	N_PROC		1
#define	N_SWAPLO	2
int	file;

main()
{
	int	mem, swap, kmem, j, dead, alive, onswap, k, mn, mj;
	char	tty[4];
	long	addr;
	daddr_t	swplo;
	char	comm[50];
	char	ar[300];

	/*
	** get real addresses of kernel symbols
	*/
	nlist("/unix",nl);
	/*
	** open all things large and small
	*/
	if( (swap=open("/dev/swap",0)) == -1) {
		printf("No swap.\n"); 
		exit(-1);
	}
	if( (kmem=open("/dev/mem",0)) == -1) {
		printf("No kmem.\n"); 
		exit(-1);
	}
	if( (mem=open("/dev/mem",0)) == -1) {
		printf("No mem.\n"); 
		exit(-1);
	}

	/*
	** seek to and read var table
	*/
	lseek(kmem,(long)nl[ N_VARS ].n_value<<1,0);
	read(kmem,(char *)&v,sizeof(v));

	/* find base of swap */
	lseek(kmem,(long)nl[ N_SWAPLO ].n_value<<1,0);
	read(kmem,(char *)&swplo,sizeof(swplo));

	/* position to start of process table */
	lseek(kmem,(long)nl[ N_PROC ].n_value<<1,0);

	printf("    PID  PPID UID  GID TT MSK LIMIT  COMMAND\n");

	/* loop through process table */
	for(j=0; j< v.v_proc;++j) {

		/* read process entry */
		read(kmem,(char *)&p,sizeof(p));
		if( p.p_flag & SLOAD == 0) {
			/* information is out on swap */
			addr = ctow(p.p_addr + swplo);
			file = swap;
			onswap = 1;
		} else {
			addr = ctow((long) p.p_addr);
			file = mem;
			onswap = 0;
		}

		/* locate and read user entry */
		lseek(file,(long)addr<<1,0);
		read(file,(char *)&u,sizeof(u));

		/* interesting process ? */
		if( p.p_pid == 0) 
			++dead;
		else {
			++alive;

			/* get command name */
			strncpy(comm,u.u_comm,14);
			comm[14] = '\0';

			/* get args */
			addr += ctow( (long)u.u_dsize) + ctow((long)USIZE);
			lseek(file,addr<<1,0);
			strcpy(ar,DOIT(&comm));
			ar[41] = '\0';

			/* compare devive number of tty to tty table */
			mn = minor(u.u_ttyd);
			mj = major(u.u_ttyd);
			strcpy(tty,"??");
			for( k = 0; k <= 35; ++k) {
				if((TTY[k].min == mn) && (TTY[k].maj == mj)) {
					strcpy(tty,TTY[k].name);
					break;
				}
			}
			
			if( onswap) 
				putchar('s');
			else
				putchar(' ');
			putchar(' ');
			printf("%5d %5d %3d %4d %2s %03o %5ld  %s\n",
				p.p_pid, p.p_ppid, p.p_uid, u.u_gid, tty,
				u.u_cmask,u.u_limit, ar);
		}
	}
}
char *DOIT(was)
char	*was;
{
	int	nbad, c;
	char	*cp1, *cp2, *cp;
	char	**abuf[BSIZE/sizeof(char **)];

	if( read(file,(char *)abuf,sizeof(abuf)) != sizeof(abuf))
		return(was);
	cp = (char *) ((char *)abuf + 10);	
	nbad = 0;
	for(cp1=cp2=cp ; cp1 < (char *)(&abuf[BSIZE/sizeof(char **)])  ; cp1++) {
		c = *cp1 & 0177;
		if (c == 0) {
			*cp1 = ' ';
			cp2 = cp1 ;
		}
		else if ( c < ' ' || c > '~') {
			if (++nbad >=3) {
				*cp1-- = ' ';
				break ;
			}
			*cp1 = '?' ;
		}
		if (c == '=') {
			*cp2 = 0;
			break ;
		}
	}
	if ( nbad >= 3 || *cp == '\0' || cp1 >= (char *)(&abuf[BSIZE/sizeof(char **)]))
		return(was);
	return(cp);
}
-- 
"No matter      Joe Angelo, Sr. Sys. Engineer @ Austec, Inc. [408] 279-5533
where you go,   ^^ A True Klingon <TK0> ^^
there you       {styx,necntc,sdencore,dlb,cbosgd,amdahl,ptsfa,dana}!aussjo!joe
are ..."        {styx,necntc,sdencore,dlb,imagen,gould}!auspyr!joe



More information about the Comp.unix.questions mailing list