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.wizards
mailing list