Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!cmcl2!yale!husc6!panda!genrad!decvax!decwrl!sun!imagen!auspyr!joe From: joe@auspyr.UUCP (Joe Angelo) Newsgroups: comp.unix.wizards,comp.unix.questions Subject: Re: Access to user process info. Message-ID: <31@auspyr.UUCP> Date: Mon, 5-Jan-87 14:53:02 EST Article-I.D.: auspyr.31 Posted: Mon Jan 5 14:53:02 1987 Date-Received: Mon, 5-Jan-87 23:24:08 EST References: <1327@brl-adm.ARPA> <165@hqda-ai.UUCP> <263@spectrix.UUCP> <413@hadron.UUCP> Organization: Austec, Inc., San Jose, CA. USA Lines: 229 Summary: Looking up _proc on sysIII Xref: mnetor comp.unix.wizards:505 comp.unix.questions:532 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#include #include #include #include #include #include #include #include #include #include /* ** 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 ^^ there you {styx,necntc,sdencore,dlb,cbosgd,amdahl,ptsfa,dana}!aussjo!joe are ..." {styx,necntc,sdencore,dlb,imagen,gould}!auspyr!joe