dusan@osupyr.UUCP (Dusan Nedeljkovic) (12/18/86)
Briefly: I need to get access to information about a certain (or more generally, ALL) processes that are active and bound to a terminal. (I also have read access to all pertinent files.) Machine: Pyramid 90x running BSD Unix 4.2 I've sent news out about this, and have gotten conflicting suggestions...some people say to access <sys/user.h> in /dev/kmem and /vmunix -- but I've had no success with this; still others say that I am on the wrong track, because this information varies across machines so that it can't be done using the structures in <sys/user.h>. I guess, what I'm really asking is how the unix utility "w" gets its information from the system about active processes. To refresh your memory, I've included some sample "w" output: User tty login@ idle JCPU PCPU what dusan ttyi02 7:24pm 1:06 28 w alden ttyi03 5:29pm 2 7:03 22 emacs /etc/termcap gae ttyi17 7:45pm 8 8 rn How does "w" get all this useful info? I can't imagine that it doesn't use <sys/user.h>, etc. Any info would be GREATLY appreciated. Thanks in advance. Dusan. (Ohio State Univ. -- Math/Sciences Computer Lab) ( Columbus, OH 43210 ) * dusan%osupyr.uucp@osu-eddie.uucp * * cbatt!osupyr!dusan * -- Dusan. (Ohio State Univ. -- Math/Sciences Computer Lab) ( Columbus, OH 43210 ) * dusan%osupyr.uucp@osu-eddie.uucp * * cbatt!osupyr!dusan *
mouse@mcgill-vision.UUCP (der Mouse) (12/21/86)
In article <99@osupyr.UUCP>, dusan@osupyr.UUCP (Dusan Nedeljkovic) writes: > Briefly: I need to get access to information about a certain (or > more generally, ALL) processes that are active and bound to a > terminal. I would recommend creating a pipe and forking ps. > I guess, what I'm really asking is how the unix utility "w" gets its > information from the system about active processes. You mention that some people say to use <sys/user.h> and /vmunix and /dev/kmem, others say that you can't because it varies across machines and <sys/user.h> doesn't have enough info. Both are right. This is normally done in a machine- and system-specific manner using include files such as <sys/user.h> and <sys/proc.h> (and others, depending on the system). > To refresh your memory, I've included some sample "w" output: > User tty login@ idle JCPU PCPU what > dusan ttyi02 7:24pm 1:06 28 w > alden ttyi03 5:29pm 2 7:03 22 emacs /etc/termcap > gae ttyi17 7:45pm 8 8 rn > How does "w" get all this useful info? I can't imagine that > it doesn't use <sys/user.h>, etc. I can't speak for a Pyramid, but on a 4/[23] VAX, it gets User, tty, and login@ from /etc/utmp Idle time by groveling through the tty driver structures via /dev/kmem and the appropriate include files (I think) JCPU and PCPU from the user and proc structs - <sys/user.h> and <sys/proc.h> what from the process' argv[] vector - it's stored in the process' address space, which w knows how to fetch from /dev/mem or /dev/drum as necessary (more include files) Really, forking ps is most likely the simplest, easiest, least buggy solution (if your ps can be made to produce the information you want). der Mouse USA: {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse think!mosart!mcgill-vision!mouse Europe: mcvax!decvax!utcsri!mcgill-vision!mouse ARPAnet: think!mosart!mcgill-vision!mouse@harvard.harvard.edu
michael@orcisi.UUCP (12/22/86)
> In article <99@osupyr.UUCP>, dusan@osupyr.UUCP (Dusan Nedeljkovic) writes: > > Briefly: I need to get access to information about a certain (or > > more generally, ALL) processes that are active and bound to a > > terminal. There was a public-domain version of a ps-like program called "sps" that was posted some time ago. It might give you some pointers (no pun intended).
jsdy@hadron.UUCP (Joseph S. D. Yao) (01/04/87)
I can't give you off the top of my head any tricks to make sure that all the data you get is consistent. However, First you read the elements of the proc table. There are NPROC of them: this is found in int nproc in /vmunix or /dev/kmem. The proc structures tell where in memory or page space one can find the user memory, including the _u structure; and the _u structure tells which tty the process is attached to. You get the addresses out of /vmunix using nlist(), and then read them from /dev/kmem. Or from /dev/proc, if you are lucky enough to have it ... -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP} jsdy@hadron.COM (not yet domainised)
joe@auspyr.UUCP (Joe Angelo) (01/05/87)
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
dennis@rlgvax.UUCP (Dennis Bednar) (01/15/87)
In article <587@mcgill-vision.UUCP>, mouse@mcgill-vision.UUCP (der Mouse) writes: > In article <99@osupyr.UUCP>, dusan@osupyr.UUCP (Dusan Nedeljkovic) writes: > > Briefly: I need to get access to information about a certain (or > > more generally, ALL) processes that are active and bound to a > > terminal. If you have the fuser(1M) command, it will do what you need. It works nicely. Given the output of fuser (the numerical process ids), you can get more information by running: ps -p25645 assuming the output of of fuser had been 25646. -- -Dennis Bednar {decvax,ihnp4,harpo,allegra}!seismo!rlgvax!dennis UUCP