home *** CD-ROM | disk | FTP | other *** search
- From: robert@olsen.UUCP (Robert Ward)
- Newsgroups: alt.sources
- Subject: SPS for SunOS4.1 and DEC 3100's - Shar 3 of 3
- Message-ID: <201@frey.UUCP>
- Date: 19 Nov 90 15:44:49 GMT
-
-
- #!/bin/sh
- #
- # This is a shar (shell archive) file.
- # In order to extract the contents of this archive, remove everything
- # above the "#!/bin/sh" line. Then execute the remaining file with
- # /bin/sh. The following file(s) will be extracted:
- # percentmem.c
- # prcmd.c
- # prcpu.c
- # prheader.c
- # printall.c
- # printproc.c
- # prsummary.c
- # readstatus.c
- # selectproc.c
- # selecttty.c
- # sps.h
- # sps.l
- # stream.c
- # termwidth.c
- # ttystatus.c
- # vmstat.c
- # waitingfor.c
- #
- #
- # This archive was generated on Mon Aug 6 17:54:08 MET DST 1990
- #
- #
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if [ -f 'percentmem.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "percentmem.c"
- exit 2
- fi
- echo x - percentmem.c
- sed -e 's/^X//' > percentmem.c << '---END-OF-percentmem.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)percentmem.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# ifndef SUNOS40
- X# include <h/text.h>
- X# endif
- X# ifdef BSD42
- X# include <machine/pte.h>
- X# else
- X# include <h/pte.h>
- X# include <h/vmparam.h>
- X# endif
- X# include <h/vmmac.h>
- X
- X/* PERCENTMEM - Returns the percentage of real memory used by this process */
- Xdouble percentmem ( p )
- X
- Xregister struct process *p ;
- X
- X{
- X# ifndef SUNOS40
- X register struct text *tp ;
- X# endif
- X int szptudot ;
- X double fracmem ;
- X extern struct info Info ;
- X
- X# ifdef SUNOS40
- X if ( !(p->pr_p.p_flag & SLOAD) )
- X return ( 0.0 ) ;
- X szptudot = UPAGES ;
- X fracmem = ( (double)p->pr_p.p_rssize + szptudot ) ;
- X# else
- X tp = p->pr_p.p_textp ;
- X if ( !(p->pr_p.p_flag & SLOAD) || !tp )
- X return ( 0.0 ) ;
- X szptudot = UPAGES + clrnd( ctopt( p->pr_p.p_dsize + p->pr_p.p_ssize ) );
- X fracmem = ( (double)p->pr_p.p_rssize + szptudot ) / CLSIZE ;
- X if ( tp->x_ccount )
- X fracmem += ((double)tp->x_rssize)/CLSIZE/tp->x_ccount ;
- X# endif
- X return ( 100.0 * fracmem / (double)Info.i_ecmx ) ;
- X}
- ---END-OF-percentmem.c---
- LEN=`wc -c < percentmem.c`
- if [ $LEN != 1112 ] ; then
- echo shar: File "percentmem.c" was $LEN, should have been 1112 bytes
- fi
- if [ -f 'prcmd.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "prcmd.c"
- exit 2
- fi
- echo x - prcmd.c
- sed -e 's/^X//' > prcmd.c << '---END-OF-prcmd.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)prcmd.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X
- X/* PRCMD - Prints the command arguments according to the switches */
- Xprcmd ( p, lpad, width )
- X
- Xregister struct process *p ;
- Xint lpad ;
- Xint width ;
- X
- X{
- X extern struct flags Flg ;
- X extern unsigned Termwidth ;
- X
- X printf( "%*d ", lpad, p->pr_p.p_pid ) ;
- X if ( Flg.flg_f )
- X {
- X printf( "%5d ", p->pr_p.p_ppid ) ;
- X width -= 6 ;
- X }
- X if ( Flg.flg_g )
- X {
- X printf( "%5d ", p->pr_p.p_pgrp ) ;
- X width -= 6 ;
- X }
- X width += Termwidth ;
- X if ( Flg.flg_w )
- X printf( "%s\n", p->pr_cmd ) ;
- X else if ( width > 0 )
- X printf( "%-.*s\n", width, p->pr_cmd ) ;
- X if ( p->pr_csaved )
- X free( p->pr_cmd ) ;
- X}
- ---END-OF-prcmd.c---
- LEN=`wc -c < prcmd.c`
- if [ $LEN != 785 ] ; then
- echo shar: File "prcmd.c" was $LEN, should have been 785 bytes
- fi
- if [ -f 'prcpu.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "prcpu.c"
- exit 2
- fi
- echo x - prcpu.c
- sed -e 's/^X//' > prcpu.c << '---END-OF-prcpu.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)prcpu.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X
- X# ifdef BSD42
- X
- X/* PRCPU - Print cpu time */
- Xprcpu ( time, utime )
- X
- Xregister time_t time ;
- Xtime_t utime ;
- X
- X{
- X time += utime / 1000000 ;
- X utime %= 1000000 ;
- X if ( time < 0L )
- X { /* Ignore negative times */
- X printf( " " ) ;
- X return ;
- X }
- X if ( time < 60L*10L )
- X { /* Print as seconds if less than 1000 seconds */
- X printf( "%3d.%1d", (int)time, (int)utime/100000 ) ;
- X return ;
- X }
- X /* Print as minutes if less than 10 hours ; print as hours if less than
- X 10 days, else print as days. */
- X if ( time < 60L*60L*10L )
- X printf( "%3D M", time/60L ) ;
- X else if ( time < 24L*60L*60L*10L )
- X printf( "%3D H", time/60L/60L ) ;
- X else
- X printf( "%3D D", time/60L/60L/24L ) ;
- X}
- X
- X# else
- X
- X/* PRCPU - Print cpu time */
- Xprcpu ( time )
- X
- Xregister time_t time ;
- X
- X{
- X extern struct info Info ;
- X
- X if ( time < 0L )
- X { /* Ignore negative times */
- X printf( " " ) ;
- X return ;
- X }
- X if ( time < Info.i_hz*60L*10L )
- X { /* Less than 10 minutes */
- X printf( "%3D.%1D", time/Info.i_hz,
- X (time % Info.i_hz / (Info.i_hz/10L)) ) ;
- X return ;
- X }
- X /* If less than 10 hours, print as minutes */
- X time /= Info.i_hz ;
- X /* Print as minutes if less than 10 hours ; print as hours if less than
- X 10 days, else print as days. */
- X if ( time < 60L*60L*10L )
- X printf( "%3D M", time/60L ) ;
- X else if ( time < 24L*60L*60L*10L )
- X printf( "%3D H", time/60L/60L ) ;
- X else
- X printf( "%3D D", time/60L/60L/24L ) ;
- X}
- X
- X# endif
- ---END-OF-prcpu.c---
- LEN=`wc -c < prcpu.c`
- if [ $LEN != 1614 ] ; then
- echo shar: File "prcpu.c" was $LEN, should have been 1614 bytes
- fi
- if [ -f 'prheader.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "prheader.c"
- exit 2
- fi
- echo x - prheader.c
- sed -e 's/^X//' > prheader.c << '---END-OF-prheader.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)prheader.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X
- X/* PRHEADER - Print a header according to the switches */
- Xprheader ()
- X{
- X extern struct flags Flg ;
- X
- X printf( "Ty User %s Proc#", Flg.flg_v ?
- X# ifdef SUNOS40
- X# ifdef OLDSTATS
- X " Status Fl Nice Virt Res %M Time Child %C" :
- X# else
- X " Status Fl Nice Prv Shr Res %M Time Child %C" :
- X# endif
- X# else
- X " Status Fl Nice Virtual Resident %M Time Child %C" :
- X# endif
- X Flg.flg_d ?
- X " Files PageFaults Swap BlockI/O Kbytsecs" : "" ) ;
- X if ( Flg.flg_f )
- X printf( " Ppid#" ) ;
- X if ( Flg.flg_g )
- X printf( " Pgrp#" ) ;
- X printf( " Command\n" ) ;
- X}
- ---END-OF-prheader.c---
- LEN=`wc -c < prheader.c`
- if [ $LEN != 683 ] ; then
- echo shar: File "prheader.c" was $LEN, should have been 683 bytes
- fi
- if [ -f 'printall.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "printall.c"
- exit 2
- fi
- echo x - printall.c
- sed -e 's/^X//' > printall.c << '---END-OF-printall.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)printall.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include <stdio.h>
- X# include "sps.h"
- X
- X/* PRINTALL - Recursively print the process tree. */
- Xprintall ( p, md )
- X
- Xregister struct process *p ;
- Xregister int md ;
- X
- X{
- X while ( p )
- X { /* Print this process */
- X printproc( p, md ) ;
- X (void)fflush( stdout ) ;
- X /* Print child processes */
- X printall( p->pr_child, md+1 ) ;
- X /* Print brother processes */
- X p = p->pr_sibling ;
- X }
- X}
- ---END-OF-printall.c---
- LEN=`wc -c < printall.c`
- if [ $LEN != 509 ] ; then
- echo shar: File "printall.c" was $LEN, should have been 509 bytes
- fi
- if [ -f 'printproc.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "printproc.c"
- exit 2
- fi
- echo x - printproc.c
- sed -e 's/^X//' > printproc.c << '---END-OF-printproc.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)printproc.c 1.2\t8/2/90" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X# ifndef SUNOS40
- X# include <h/text.h>
- X# endif
- X
- X# ifdef SUNOS40
- X# ifdef OLDSTATS
- X# define OFFSET 8
- X# else
- X# define OFFSET 3
- X# endif
- X# else
- X# define OFFSET 0
- X# endif
- X
- X/* PRINTPROC - Pretty print a process according to the switches. */
- Xprintproc ( p, md )
- X
- Xregister struct process *p ;
- Xint md ;
- X
- X{
- X register char *chp ;
- X# ifndef SUNOS40
- X register struct text *tp ;
- X# endif
- X register struct hashtab *hp ;
- X char chbuf[10] ;
- X time_t time ;
- X time_t chtime ;
- X# ifdef BSD42
- X time_t utime ;
- X time_t uchtime ;
- X# endif
- X extern short Lastuid, Lastpgrp ;
- X extern struct flags Flg ;
- X char *waitingfor() ;
- X struct hashtab *hashuid() ;
- X double percentmem() ;
- X
- X /* List tty name and foreground/background/detached information */
- X printf( "%2.2s%c", p->pr_tty->l_name,
- X# ifdef SDETACH
- X !p->pr_p.p_pgrp ? ' ' : p->pr_p.p_flag & SDETACH ? '_' :
- X p->pr_p.p_pgrp == p->pr_tty->l_pgrp ? '.' : ' ' ) ;
- X# else
- X !p->pr_p.p_pgrp || p->pr_p.p_pgrp != p->pr_tty->l_pgrp ?
- X# ifdef SPGLDR
- X p->pr_p.p_flag & SPGLDR ? '-' :
- X# endif
- X ' ' :
- X# ifdef SPGLDR
- X p->pr_p.p_flag & SPGLDR ? '+' :
- X# endif
- X '.' ) ;
- X# endif
- X hp = hashuid( (int)p->pr_p.p_uid ) ;
- X if ( !md )
- X { /* If a top-level process, list the user name */
- X if ( hp )
- X printf( "%-8.8s ", hp->h_uname ) ;
- X else
- X printf( "user%-4.4d ", p->pr_p.p_uid ) ;
- X }
- X else
- X { /* Usually list an asterisk for a child process */
- X md = md > 8 ? 8 : md ;
- X printf( "%*s%c", md, "",
- X p->pr_p.p_pgrp == Lastpgrp ? '|' : '*' ) ;
- X /* But beware of setuid processes */
- X md = 8 - md ;
- X if ( p->pr_p.p_uid == Lastuid )
- X printf( "%-*.*s", md, md, "" ) ;
- X else if ( hp )
- X printf( "%-*.*s", md, md, hp->h_uname ) ;
- X else
- X {
- X md -= 4 ;
- X printf( "user%-*.*d", md, md, p->pr_p.p_uid ) ;
- X }
- X }
- X Lastuid = p->pr_p.p_uid ;
- X Lastpgrp = p->pr_p.p_pgrp ;
- X if ( Flg.flg_d )
- X { /* List disc I/O and paging information */
- X if ( !p->pr_upag || p->pr_p.p_stat == SZOMB )
- X {
- X prcmd( p, 49, -63 ) ;
- X return ;
- X }
- X printf( "%2d %8d+%8d %4d %8d %8D ",
- X p->pr_files,
- X# ifdef BSD42
- X p->pr_rself.ru_majflt,
- X p->pr_rself.ru_minflt,
- X p->pr_rself.ru_nswap,
- X p->pr_rself.ru_inblock + p->pr_rself.ru_oublock,
- X KBYTES( p->pr_rself.ru_idrss + p->pr_rself.ru_isrss
- X + p->pr_rself.ru_ixrss ) ) ;
- X# else
- X p->pr_vself.vm_majflt,
- X p->pr_vself.vm_minflt,
- X p->pr_vself.vm_nswap,
- X p->pr_vself.vm_inblk + p->pr_vself.vm_oublk,
- X KBYTES( (p->pr_vself.vm_idsrss
- X + p->pr_vself.vm_ixrss) / Info.i_hz ) ) ;
- X# endif
- X prcmd( p, 5, -63 ) ;
- X return ;
- X }
- X if ( !Flg.flg_v )
- X { /* Not verbose so just list command arguments */
- X prcmd( p, 5, -19 ) ;
- X return ;
- X }
- X /* Arrive here if being verbose ; list cpu information */
- X switch ( p->pr_p.p_stat )
- X {
- X case SSLEEP :
- X case SWAIT :
- X case SIDL :
- X /* Determine why a process should be in a wait state */
- X chp = waitingfor( p ) ;
- X break ;
- X case SRUN :
- X chp = "run" ;
- X break ;
- X case SZOMB :
- X chp = "exit" ;
- X break ;
- X case SSTOP :
- X chp = "stop" ;
- X break ;
- X }
- X /* If the process is loaded, list the status information in capitals */
- X printf( "%-6.6s ", p->pr_p.p_flag & SLOAD ?
- X (capitals( chp, chbuf ), chbuf) : chp ) ;
- X /* List process flags */
- X printf( "%c%c%c", p->pr_p.p_flag & SSYS ? 'U' :
- X p->pr_p.p_flag & STRC ? 'T' : ' ',
- X p->pr_p.p_flag & SVFORK ? 'V' :
- X p->pr_p.p_flag & SPHYSIO ? 'I' : ' ',
- X p->pr_p.p_flag & SUANOM ? 'A' :
- X p->pr_p.p_flag & SSEQL ? 'S' : ' ' ) ;
- X /* List process niceness */
- X if ( p->pr_p.p_nice != NZERO )
- X printf( "%3d ", p->pr_p.p_nice - NZERO ) ;
- X else
- X printf( " " ) ;
- X if ( p->pr_p.p_stat == SZOMB )
- X {
- X prcmd( p, 41 - OFFSET, OFFSET - 69 ) ;
- X return ;
- X }
- X# ifdef SUNOS40
- X# ifdef OLDSTATS
- X /* List process virtual and real sizes */
- X printf( "%4d", KBYTES( p->pr_p.p_dsize + p->pr_p.p_ssize ) ) ;
- X# else
- X /* List process private and shared virtual and real sizes */
- X printf("%4d", KBYTES( p->pr_private ) ) ;
- X printf("+%4d", KBYTES( p->pr_shared ) ) ;
- X# endif
- X printf( " %4d", KBYTES( p->pr_p.p_rssize ) ) ;
- X# else
- X /* List process and text virtual sizes */
- X printf( "%4d", KBYTES( p->pr_p.p_dsize + p->pr_p.p_ssize ) ) ;
- X if ( tp = p->pr_p.p_textp )
- X printf( "+%3d ", KBYTES( tp->x_size ) ) ;
- X else
- X printf( " " ) ;
- X /* List process and text real sizes */
- X printf( "%4d", KBYTES( p->pr_p.p_rssize ) ) ;
- X if ( tp )
- X printf( "+%3d", KBYTES( tp->x_rssize ) ) ;
- X else
- X printf( " " ) ;
- X# endif
- X printf( " %2.0f ", percentmem( p ) ) ;
- X /* List information obtained from the upage. This includes the process
- X times and command arguments. */
- X if ( !p->pr_upag )
- X {
- X prcmd( p, 20, OFFSET - 69 ) ;
- X return ;
- X }
- X /* List process time information */
- X# ifdef BSD42
- X time = Flg.flg_q ? p->pr_rself.ru_utime.tv_sec :
- X p->pr_rself.ru_utime.tv_sec + p->pr_rself.ru_stime.tv_sec ;
- X utime = Flg.flg_q ? p->pr_rself.ru_utime.tv_usec :
- X p->pr_rself.ru_utime.tv_usec + p->pr_rself.ru_stime.tv_usec ;
- X chtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_sec :
- X p->pr_rchild.ru_utime.tv_sec + p->pr_rchild.ru_stime.tv_sec ;
- X uchtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_usec :
- X p->pr_rchild.ru_utime.tv_usec + p->pr_rchild.ru_stime.tv_usec ;
- X prcpu( time, utime ) ;
- X if ( chtime != 0L )
- X {
- X printf( "+" ) ;
- X prcpu( chtime, uchtime ) ;
- X }
- X# else
- X time = Flg.flg_q ? p->pr_vself.vm_utime :
- X p->pr_vself.vm_utime + p->pr_vself.vm_stime ;
- X chtime = Flg.flg_q ? p->pr_vchild.vm_utime :
- X p->pr_vchild.vm_utime + p->pr_vchild.vm_stime ;
- X prcpu( time ) ;
- X if ( chtime != 0L )
- X {
- X printf( "+" ) ;
- X prcpu( chtime ) ;
- X }
- X# endif
- X else
- X printf( " " ) ;
- X# ifdef BSD42
- X if ( time || utime )
- X# else
- X if ( time )
- X# endif
- X# ifdef SUN
- X printf( " %2.0f ", (double)p->pr_p.p_pctcpu * 100.0/FSCALE ) ;
- X# else
- X# ifdef DEC3100
- X printf( " %2.0f ", p->pr_p.p_pctcpu ) ;
- X# else
- X printf( " %2.0f ", p->pr_p.p_pctcpu * 100.0 ) ;
- X# endif DEC3100
- X# endif SUN
- X else
- X printf( " " ) ;
- X /* Finally, list the process command arguments. */
- X prcmd( p, 5, OFFSET - 69 ) ;
- X}
- X
- X/* CAPITALS - Converts letters in `chp' to upper-case in buffer `buf'. */
- Xcapitals ( chp, buf )
- X
- Xregister char *chp ;
- Xregister char *buf ;
- X
- X{
- X while ( *buf = *chp++ )
- X {
- X if ( 'a' <= *buf && *buf <= 'z' )
- X *buf -= 'a' - 'A' ;
- X buf++ ;
- X }
- X}
- ---END-OF-printproc.c---
- LEN=`wc -c < printproc.c`
- if [ $LEN != 6875 ] ; then
- echo shar: File "printproc.c" was $LEN, should have been 6875 bytes
- fi
- if [ -f 'prsummary.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "prsummary.c"
- exit 2
- fi
- echo x - prsummary.c
- sed -e 's/^X//' > prsummary.c << '---END-OF-prsummary.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)prsummary.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X
- X/* PRSUMMARY - Print the summarising information */
- Xprsummary ()
- X{
- X extern struct summary Summary ;
- X
- X printf(
- X"%D (%Dk) processes, %D (%Dk) busy, %D (%Dk) loaded, %D (%Dk) swapped\n",
- X Summary.sm_ntotal, KBYTES( Summary.sm_ktotal ),
- X Summary.sm_nbusy, KBYTES( Summary.sm_kbusy ),
- X Summary.sm_nloaded, KBYTES( Summary.sm_kloaded ),
- X Summary.sm_nswapped, KBYTES( Summary.sm_kswapped ) ) ;
- X Summary.sm_ntotal = 0L ;
- X Summary.sm_ktotal = 0L ;
- X Summary.sm_nbusy = 0L ;
- X Summary.sm_kbusy = 0L ;
- X Summary.sm_nloaded = 0L ;
- X Summary.sm_kloaded = 0L ;
- X Summary.sm_nswapped = 0L ;
- X Summary.sm_kswapped = 0L ;
- X}
- ---END-OF-prsummary.c---
- LEN=`wc -c < prsummary.c`
- if [ $LEN != 712 ] ; then
- echo shar: File "prsummary.c" was $LEN, should have been 712 bytes
- fi
- if [ -f 'readstatus.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "readstatus.c"
- exit 2
- fi
- echo x - readstatus.c
- sed -e 's/^X//' > readstatus.c << '---END-OF-readstatus.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)readstatus.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# ifndef SUNOS40
- X# include <h/text.h>
- X# endif
- X
- X/* READSTATUS - Reads the kernel memory for current processes and texts */
- X# ifdef SUNOS40
- Xreadstatus ( process )
- X
- Xregister struct process *process ;
- X
- X# else
- X
- Xreadstatus ( process, text )
- X
- Xregister struct process *process ;
- Xstruct text *text ;
- X
- X# endif
- X{
- X register struct proc *p ;
- X register struct proc *p0 ;
- X register struct process *pr ;
- X int size ;
- X extern struct info Info ;
- X char *getcore() ;
- X
- X# ifndef SUNOS40
- X /* Read current text information */
- X size = Info.i_ntext * sizeof( struct text ) ;
- X if ( getkmem( (long)Info.i_text0, (char*)text, size ) != size )
- X prexit( "sps - Can't read system text table\n" ) ;
- X# endif
- X /* Read current process information */
- X size = Info.i_nproc * sizeof( struct proc ) ;
- X p0 = (struct proc*)getcore( size ) ;
- X if ( getkmem( (long)Info.i_proc0, (char*)p0, size ) != size )
- X prexit( "sps - Can't read system process table\n" ) ;
- X /* Copy process information into our own array */
- X for ( p = p0, pr = process ; pr < &process[ Info.i_nproc ] ; p++, pr++ )
- X pr->pr_p = *p ;
- X free( (char*)p0 ) ;
- X}
- ---END-OF-readstatus.c---
- LEN=`wc -c < readstatus.c`
- if [ $LEN != 1281 ] ; then
- echo shar: File "readstatus.c" was $LEN, should have been 1281 bytes
- fi
- if [ -f 'selectproc.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "selectproc.c"
- exit 2
- fi
- echo x - selectproc.c
- sed -e 's/^X//' > selectproc.c << '---END-OF-selectproc.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)selectproc.c 1.2\t6/15/90" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X# ifdef USELOGINUID
- X# include <pwd.h>
- X# endif USELOGINUID
- X
- X/*
- X** SELECTPROC - Given a process structure, this procedure decides whether
- X** the process is a candidate for printing.
- X*/
- Xselectproc ( p, process, thisuid )
- X
- Xregister struct process *p ;
- Xregister struct process *process ;
- Xint thisuid ;
- X
- X{
- X register union flaglist *fp ;
- X register struct process *pp ;
- X#ifdef USELOGINUID
- X char *username ;
- X struct passwd *pw ;
- X char *getlogin() ;
- X struct passwd *getpwnam() ;
- X#endif USELOGINUID
- X extern struct flags Flg ;
- X
- X /* Flg.flg_AZ is an internal flag set if one of flags `A' to `Z'
- X was specified. If this is not set, a process is listed only
- X if it or one of its ancestors belongs to the invoking user. */
- X if ( !Flg.flg_AZ )
- X {
- X#ifdef USELOGINUID
- X thisuid = (username = getlogin())
- X && (pw = getpwnam( username )) ? pw->pw_uid : getuid() ;
- X#endif USELOGINUID
- X for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
- X if ( thisuid == pp->pr_p.p_uid )
- X return ( 1 ) ;
- X }
- X if ( Flg.flg_A )
- X return ( 1 ) ;
- X if ( Flg.flg_P )
- X for ( fp = Flg.flg_Plist ; fp->f_pid >= 0 ; fp++ )
- X if ( fp->f_pid == p->pr_p.p_pid )
- X return ( 1 ) ;
- X if ( Flg.flg_U )
- X for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
- X for ( fp = Flg.flg_Ulist ; fp->f_uid >= 0 ; fp++ )
- X if ( fp->f_uid == pp->pr_p.p_uid )
- X return ( 1 ) ;
- X switch ( p->pr_p.p_stat )
- X {
- X case SRUN :
- X if ( Flg.flg_B )
- X# ifdef SUNOS40
- X /* Ignore the idle processes */
- X return ( p->pr_p.p_pid != 3
- X && p->pr_p.p_pid != 4 ) ;
- X# else
- X return ( 1 ) ;
- X# endif SUNOS40
- X break ;
- X case SSLEEP :
- X if ( Flg.flg_B
- X && p->pr_p.p_pri < PZERO && p->pr_p.p_pid > MSPID )
- X# ifdef SUNOS40
- X /* Ignore the idle processes */
- X return ( p->pr_p.p_pid != 3
- X && p->pr_p.p_pid != 4 ) ;
- X# else
- X return ( 1 ) ;
- X# endif SUNOS40
- X case SWAIT :
- X case SIDL :
- X if ( Flg.flg_W )
- X return ( 1 ) ;
- X break ;
- X case SSTOP :
- X if ( Flg.flg_S )
- X return ( 1 ) ;
- X break ;
- X case SZOMB :
- X if ( Flg.flg_Z )
- X return ( 1 ) ;
- X break ;
- X default :
- X break ;
- X }
- X return ( 0 ) ;
- X}
- ---END-OF-selectproc.c---
- LEN=`wc -c < selectproc.c`
- if [ $LEN != 2248 ] ; then
- echo shar: File "selectproc.c" was $LEN, should have been 2248 bytes
- fi
- if [ -f 'selecttty.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "selecttty.c"
- exit 2
- fi
- echo x - selecttty.c
- sed -e 's/^X//' > selecttty.c << '---END-OF-selecttty.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)selecttty.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X
- X/* SELECTTTY - Decides whether this process is interesting for its tty */
- Xselecttty ( p )
- X
- Xregister struct process *p ;
- X
- X{
- X register union flaglist *fp ;
- X extern struct flags Flg ;
- X
- X for ( fp = Flg.flg_Tlist ; fp->f_ttyline ; fp++ )
- X if ( fp->f_ttyline == p->pr_tty )
- X return ( 1 ) ;
- X return ( 0 ) ;
- X}
- ---END-OF-selecttty.c---
- LEN=`wc -c < selecttty.c`
- if [ $LEN != 448 ] ; then
- echo shar: File "selecttty.c" was $LEN, should have been 448 bytes
- fi
- if [ -f 'sps.h' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "sps.h"
- exit 2
- fi
- echo x - sps.h
- sed -e 's/^X//' > sps.h << '---END-OF-sps.h---'
- X# ifndef lint
- Xstatic char SpsHId[] = "@(#)sps.h 1.3\t7/4/90" ;
- X# endif
- X
- X# ifdef SUNOS40
- X# define KERNEL
- X# endif SUNOS40
- X# include <h/param.h>
- X# undef KERNEL
- X# include <h/dir.h>
- X# include <h/user.h>
- X# include <h/proc.h>
- X
- X# ifdef SUNOS40
- X# ifndef BSD43
- X# define BSD43
- X# endif BSD43
- X# endif SUNOS40
- X
- X/*
- X** Maximum # of users to be considered. (Because user names are stored
- X** in a hash table, this should probably be at least double the number
- X** of actual users defined in /etc/passwd or by the Yellow Pages.)
- X*/
- X# define MAXUSERS 100
- X/* Maximum # ttys to be considered, plus 1 for the console ... */
- X# define MAXTTYS 97
- X
- X
- X/* Maximum user name length ... */
- X# define UNAMELEN 8
- X/* Maximum process-id not to be considered busy ... */
- X# define MSPID 2
- X/* # of wait states defined in the `struct info' ... */
- X# ifdef NFS
- X# ifdef SUN
- X# define NWAITSTATE 16
- X# else
- X# define NWAITSTATE 36
- X# endif SUN
- X# else NFS
- X# ifdef ULTRIX20
- X# define NWAITSTATE 36
- X# else ULTRIX20
- X# define NWAITSTATE 35
- X# endif ULTRIX20
- X# endif NFS
- X
- X/* Convert clicks to kbytes ... */
- X# ifndef PGSHIFT
- X# define KBYTES( size ) ((size) << 1)
- X# else PGSHIFT
- X# if PGSHIFT > 10
- X# define KBYTES( size ) ((size) << (PGSHIFT - 10))
- X# else
- X# define KBYTES( size ) ((size) >> (10 - PGSHIFT))
- X# endif
- X# endif PGSHIFT
- X
- X/* Standard files to be examined ... */
- X# define FILE_MEM "/dev/mem" /* System physical memory */
- X# define FILE_KMEM "/dev/kmem" /* Kernel virtual memory */
- X# define FILE_SWAP "/dev/drum" /* Swap/paging device */
- X# define FILE_DEV "/dev" /* Directory of tty entries */
- X# define FILE_SYMBOL "/vmunix" /* Symbol file for nlist() */
- X# define FILE_INFO "/tmp/.spsinfo" /* Sps information file */
- X# define FILE_PASSWD "/etc/passwd" /* User database */
- X
- X/* Structure to hold necessary information concerning a tty ... */
- Xstruct ttyline
- X{
- X char l_name[2] ; /* Tty character name */
- X unsigned short l_pgrp ; /* Tty process group */
- X# ifdef SUNOS40
- X struct streamtab *l_addr ; /* Ptr to streamtab in kmem */
- X struct stdata *l_stdata ; /* Ptr to stdata at runtime */
- X# else SUNOS40
- X struct tty *l_addr ; /* Ptr to tty struct in kmem */
- X# endif SUNOS40
- X dev_t l_dev ; /* Tty device # */
- X} ;
- X
- X/* Structure holding a single hash table entry ... */
- Xstruct hashtab
- X{
- X short h_uid ; /* Uid of user entry */
- X char h_uname[ UNAMELEN ] ; /* Corresponding name */
- X} ;
- X
- X/*
- X** Format of the standard information file maintained by sps.
- X** This structure is filled in at initialisation time and then is read back
- X** in whenever sps is invoked.
- X** Note that the pointer variables in this structure refer to
- X** kernel virtual addresses, not addresses within sps.
- X** These variable are typed as such so that pointer arithmetic
- X** on the kernel addresses will work correctly.
- X*/
- Xstruct info
- X{ /* Kernel values determining process, tty and upage info ... */
- X struct proc *i_proc0 ; /* address of process table */
- X int i_nproc ; /* length of process table */
- X# ifndef SUNOS40
- X struct text *i_text0 ; /* address of text table */
- X# endif SUNOS40
- X int i_ntext ; /* length of text table */
- X# ifdef ULTRIX20
- X struct gnode *i_inode0 ; /* address of inode table */
- X# else ULTRIX20
- X struct inode *i_inode0 ; /* address of inode table */
- X# endif ULTRIX20
- X int i_ninode ; /* length of inode table */
- X int i_ecmx ; /* max physical memory address*/
- X# ifndef SUNOS40
- X struct buf *i_swbuf0 ; /* address of swap buffers */
- X int i_nswbuf ; /* # swap buffers */
- X struct buf *i_buf0 ; /* address of i/o buffers */
- X int i_nbuf ; /* # i/o buffers */
- X struct pte *i_usrptmap ; /* page table map */
- X struct pte *i_usrpt ; /* page table map */
- X# endif SUNOS40
- X struct cdevsw *i_cdevsw ; /* device switch to find ttys */
- X# ifdef BSD42
- X# ifdef NFS
- X struct dquot *i_quota0 ; /* disc quota structures */
- X# else NFS
- X struct quota *i_quota0 ; /* disc quota structures */
- X# endif NFS
- X int i_nquota ; /* # quota structures */
- X int i_dmmin ; /* The start of the disc map */
- X int i_dmmax ; /* The end of the disc map */
- X struct mbuf *i_mbutl ; /* Start of mbuf area */
- X# else BSD42
- X int i_hz ; /* Clock rate */
- X# endif BSD42
- X# ifdef CHAOS
- X caddr_t i_Chconntab ; /* Chaos connection table */
- X# endif
- X /* Kernel addresses are associated with process wait states ... */
- X caddr_t i_waitstate[ NWAITSTATE ] ;
- X /* User names, stored in a hash table ... */
- X struct hashtab i_hnames[ MAXUSERS ] ;
- X /* Tty device info ... */
- X struct ttyline i_ttyline[ MAXTTYS ] ;
- X# ifdef SUNOS40
- X struct seg_ops *i_segvn_ops ; /* ptr to vnode segment ops */
- X struct pty *i_ptybase ;
- X int i_npty ;
- X# ifdef SUNOS41
- X struct strstat *i_strst;
- X struct stdata *i_allstream;
- X# else SUNOS41
- X struct stdata *i_streams ; /* streams list */
- X struct stdata *i_streamsNSTREAMS ;
- X# endif SUNOS41
- X caddr_t i_sysbase ;
- X# endif SUNOS40
- X} ;
- X
- X/*
- X** The symbol structure cross-references values read from the kernel with
- X** their place in the info structure, and if such a value is associated with
- X** a process wait state or not.
- X*/
- Xstruct symbol
- X{
- X char *s_kname ; /* Kernel symbol name */
- X char s_indirect ; /* Value requires indirection */
- X caddr_t *s_info ; /* Corresponding info address */
- X char *s_wait ; /* Reason for wait, if any */
- X} ;
- X
- X/* The `user' structure obtained from /dev/mem or /dev/swap ... */
- Xunion userstate
- X{
- X struct user u_us ;
- X char u_pg[ UPAGES ][ NBPG ] ;
- X} ;
- X
- X/* Information concerning each process filled from /dev/kmem ... */
- Xstruct process
- X{
- X struct proc pr_p ; /* struct proc from /dev/kmem */
- X struct process *pr_plink ; /* Normalised ptrs from above */
- X struct process *pr_sibling ; /* Ptr to sibling process */
- X struct process *pr_child ; /* Ptr to child process */
- X struct process *pr_pptr ; /* Ptr to parent process */
- X# ifdef BSD42
- X struct rusage pr_rself ; /* Read from upage for self */
- X struct rusage pr_rchild ; /* ... and the children */
- X# else BSD42
- X struct vtimes pr_vself ; /* Read from upage for self */
- X struct vtimes pr_vchild ; /* ... and the children */
- X# endif BSD42
- X int pr_files ; /* # open files */
- X struct ttyline *pr_tty ; /* Associated tty information */
- X char *pr_cmd ; /* Command args, from upage */
- X int pr_upag:1 ; /* Upage was obtained */
- X int pr_csaved:1 ; /* Cmd args saved by malloc() */
- X# ifdef SUNOS40
- X unsigned pr_private ; /* private pages */
- X unsigned pr_shared ; /* shared pages */
- X# endif SUNOS40
- X} ;
- X
- X/* Structure to hold summarising information ... */
- Xstruct summary
- X{
- X long sm_ntotal ; /* Total # processes */
- X long sm_ktotal ; /* Total virtual memory */
- X long sm_nbusy ; /* # busy processes */
- X long sm_kbusy ; /* Busy virtual memory */
- X long sm_nloaded ; /* # loaded processes */
- X long sm_kloaded ; /* Active resident memory */
- X long sm_nswapped ; /* # swapped processes */
- X long sm_kswapped ; /* Size totally swapped out */
- X} ;
- ---END-OF-sps.h---
- LEN=`wc -c < sps.h`
- if [ $LEN != 6824 ] ; then
- echo shar: File "sps.h" was $LEN, should have been 6824 bytes
- fi
- if [ -f 'sps.l' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "sps.l"
- exit 2
- fi
- echo x - sps.l
- sed -e 's/^X//' > sps.l << '---END-OF-sps.l---'
- X.if n .pl 66
- X.TH SPS 1
- X.SH NAME
- Xsps \ \ \-\ \ \ show process status
- X.SH SYNOPSIS
- X\fBsps\ \fP \ [ \fB\-cdefgijkoqrslvwyABDFNPSTUWZ\fP ]\ \ [
- X\fIprocess\ .\ .\ .\ | tty\ .\ .\ .\ | user\ .\ .\ .\fP ]
- X.SH DESCRIPTION
- X\fISps\fP reports information concerning system processes.
- XIt shows the current state of any process by
- Xlisting information such as ownership, CPU time usage, memory usage
- Xand disc activity.
- X.PP
- X\fISps\fP should be used in preference to \fIps\fP(1)
- Xbecause it is faster and the output is more comprehensive and more
- Xcomprehensible.
- X.SH OPTIONS
- XBy default, \fIsps\fP prints basic information about one's own processes.
- XThe various options described below select other processes or make
- X\fIsps\fP more verbose.
- X.PP
- XUpper case options select processes to be described.
- XLower case options specify the format of the output.
- XFor instance, the options \fBBv\fP specify that \fIsps\fP
- Xshould list ``busy'' processes in a verbose format.
- XUnless there is any conflict, lower case options may be used
- Xinstead of upper case options, and vice versa.
- X.PP
- XThe following options specify the format of the listed output \-
- X.TP 8
- X\fB\-c\fP
- XUse the system's idea of the command, rather than getting the arguments
- Xfrom user space. While somewhat less informative, this is faster and
- Xmore reliable.
- X.TP
- X\fB\-d\fP
- XList output reflecting how each process affects the
- Xdisc and paging activity of the system.
- X.TP
- X\fB\-e\fP
- XList the environment passed to each process.
- X.TP
- X\fB\-f\fP
- XInclude the process\-id of the parent of each process.
- X.TP
- X\fB\-g\fP
- XInclude the process group of each process.
- X.TP
- X\fB\-o\fP
- XAvoid looking at the swap device (\fB/dev/drum\fP). This tends to make \fIsps\fP
- Xrun faster, although no information concerning swapped processes
- Xcan be obtained.
- X.TP
- X\fB\-q\fP
- XBy default, \fIsps\fP
- Xlists the sum of the user plus system times under the
- X\fITime\fP and \fIChild\fP fields. This option forces \fIsps\fP
- Xto list only the user times.
- X.TP
- X\fB\-r\fP
- XRepeat the output indefinitely.
- XIf the next argument is numeric, \fIsps\fP repeats the output with that
- Xmany seconds delay between each repetition.
- XOtherwise the output is repeated with no delay.
- X.TP
- X\fB\-l\fP
- X.br
- X.ns
- X.TP
- X\fB\-v\fP
- XList additional information in a verbose format. See below.
- X.TP
- X\fB\-w\fP
- XList output in a wide format. This option forces \fIsps\fP
- Xto print all the command arguments, even if doing so extends the output
- Xbeyond one line.
- X.TP
- X\fB\-y\fP
- XShow the status of each terminal line.
- X.PP
- XThe following options specify which processes are to be described \-
- X.TP 8
- X\fB\-A\fP
- XList all processes.
- X.TP
- X\fB\-B\fP
- XList busy processes. A process is considered to be busy
- Xif it is immediately runnable or awaiting a fast event such as disc I/O.
- X.TP
- X\fB\-D\fP
- XList detached processes.
- X.TP
- X\fB\-F\fP
- XList foreground processes.
- X.TP
- X\fB\-N\fP
- XShow no processes at all. Only the summary line is printed.
- X.TP
- X\fB\-P\fP
- XList only processes whose identifiers are specified in the following arguments.
- X.TP
- X\fB\-S\fP
- XList stopped processes.
- X.TP
- X\fB\-T\fP
- XList only processes attached to the following specified terminals.
- X.TP
- X\fB\-U\fP
- XList only processes belonging to the following specified users.
- X.TP
- X\fB\-W\fP
- XList waiting processes.
- X.TP
- X\fB\-Z\fP
- XList zomby (exiting) processes.
- X.PP
- XThe following are miscellaneous options \-
- X.TP 8
- X\fB\-i\fP
- XInitialise \fIsps\fP.
- XThis is necessary if new users are added to the password file,
- Xor if a new version of UNIX is installed.
- XSps builds a new information file summarising pertinent information
- Xread from the password file (\fB/etc/passwd\fP), the executable kernel image
- X(\fB/vmunix\fP) and the directory of tty devices (\fB/dev\fP).
- XSee also the \fB\-j\fP and \fB\-s\fP options.
- X.TP
- X\fB\-j\fP
- XSpecify an information file other than the default (\fB/etc/spsinfo\fP).
- XThe next argument is taken to be the name of a suitable information file.
- XIf the \fB\-i\fP flag is also specified, \fIsps\fP builds a
- Xnew information file with the given name.
- XOtherwise, \fBsps\fP reads previously created summarising information
- Xfrom that file.
- X.TP
- X\fB\-k\fP
- XUse a specific disc file rather than the default physical
- Xmemory (\fB/dev/mem\fP)
- Xand kernel virtual memory (\fB/dev/kmem\fP) files. The next argument is taken
- Xto be the name of a suitable memory dump file.
- XThis flag automatically sets the \fB\-o\fP flag.
- X.TP
- X\fB\-s\fP
- XThis option is used in conjunction with the \fB\-i\fP option.
- XThe next argument is taken to be the name of a suitable kernel executable
- Xfile, rather than the default (\fB/vmunix\fP).
- X\fISps\fP looks at the symbol table of this file to determine
- Xthe virtual addresses of various kernel structures.
- X.SH OUTPUT
- X\fISps\fP produces output in the following fields \-
- X.TP 8
- X\fITy\fP
- XThe terminal identifier to which the process is attached.
- X.IP
- XIf this is followed by an underscore, the process is detached.
- XIf it is followed by a period, the process is running in the foreground.
- XOtherwise the process is running in the background but is still
- Xattached to a terminal.
- X.TP
- X\fIUser\fP
- XThe symbolic name of the process' effective user-id (see \fIexec\fP(2)
- Xand \fIsetuid\fP(2)).
- XThis name is defined by the system password file (\fB/etc/passwd\fP)
- Xwhen \fIsps\fP was last initialised.
- XOtherwise, an asterisk (\fB*\fP) or vertical bar (\fB|\fP) appearing in this
- Xcolumn denotes that the process is an immediate relative of the
- Xpreceding process.
- XA bar is listed, rather than an asterisk, if both processes belong
- Xto the same process group.
- XA user name is listed only if the effective user-id
- Xdiffers from that of the preceding process or if it is a top-level
- Xprocess (immediate offspring of process 1).
- X.TP
- X\fIProc#\fP
- XThe unique process identifier.
- X.TP
- X\fIPpid#\fP
- XThe process-id of the process' parent.
- X.TP
- X\fIPgrp#\fP
- XThe process group to which the process belongs.
- X.TP
- X\fICommand\fP
- XThe command arguments obtained from the process' own address space.
- X(If the command name appears in parentheses, \fIsps\fP
- Xwas unable to locate the arguments in user space and so reports
- Xthe system's idea of the command name.)
- X.PP
- XThe following additional fields are listed when \fIsps\fP
- Xis invoked with one of the \fB\-l\fP or \fB\-v\fP options \-
- X.TP 8
- X\fIStatus\fP
- XThe process' current state.
- XIf this field is listed in upper-case letters, the process is currently
- Xloaded in real memory space ; otherwise it has been swapped out.
- XThe status field may contain one of the following descriptions \-
- X.RS 8
- X.TP 16
- X\fIrun\fP
- XThe process can be run immediately.
- X.TP
- X\fIstop\fP
- XThe process is stopped. See \fIsigvec\fP(2).
- X.TP
- X\fIexit\fP
- XThe process is a zomby.
- X.RE
- X.IP
- XAny other entry in the status field indicates the process is
- Xwaiting for some external event to occur.
- XThis is usually for one of the reasons listed below.
- X(If \fIsps\fP does not know why a process is waiting, it lists
- Xthe hexadecimal address of the process' wait channel,
- Xwith the initial 80000000 trimmed off.)
- XA process may be waiting for one of the following reasons \-
- X.RS 8
- X.TP 16
- X\fIchild\fP
- XThe process is waiting for a child to terminate. See \fIwait\fP(2).
- X.TP
- X\fIpause\fP
- XWaiting for a signal to be received. See \fIsigpause\fP(2).
- X.TP
- X\fIswap\fP
- XWaiting for a page to be swapped in.
- X.TP
- X\fIrswbuf\fP
- XWaiting for a read from the swap device \fB/dev/drum.\fP
- X.TP
- X\fIdiscio\fP
- XWaiting for a disc read or write operation.
- X(Actually, this means that the process is waiting for an operation
- Xthrough the kernel's I/O buffering mechanism to complete, but \fIdiscio\fP
- Xis what is generally meant here).
- X.TP
- X\fIrpipe\fP
- X.br
- X.ns
- X.TP
- X\fIwpipe\fP
- XWaiting for a read from an empty pipe. Alternatively, the process
- Xis waiting to write to a full pipe. See \fIpipe\fP(2).
- X.TP
- X\fIrsockt\fP
- X.br
- X.ns
- X.TP
- X\fIwsockt\fP
- XWaiting for a read from an empty socket.
- XAlternatively, the process is waiting to write to a full socket (4.[2\-]bsd only).
- X.TP
- X\fIaccept\fP
- XWaiting to accept a stream-based socket connection (4.[2\-]bsd only).
- XSee \fIaccept\fP(2).
- X.TP
- X\fIconnct\fP
- XWaiting to establish a connection through a stream-based socket to a
- Xremote process (4.[2\-]bsd only). See \fIconnect\fP(2).
- X.TP
- X\fIsocket\fP
- XWaiting for some other time-out event on a socket (4.[2\-]bsd only).
- X.TP
- X\fIselect\fP
- XBlocked by a \fIselect\fP(2) system call (4.[2\-]bsd only).
- X.TP
- X\fIrmux\fP
- XWaiting for a read from a multiplexor file (4.1bsd only).
- X.TP
- X\fIinode\fP
- XWaiting for an inode to be allocated or unlocked.
- X.TP
- X\fIexlock\fP
- X.br
- X.ns
- X.TP
- X\fIshlock\fP
- XWaiting for a file to become unlocked. See \fIflock\fP(2).
- X.TP
- X\fIrtty??\fP
- X.br
- X.ns
- X.TP
- X\fIwtty??\fP
- X.br
- X.ns
- X.TP
- X\fIotty??\fP
- XWaiting for a read or write to the specified terminal, or for the terminal
- Xto be switched on. See \fItty\fP(4).
- XAlternatively, waiting for a read or write to the
- Xspecified slave pty device. See \fIpty\fP(4).
- X.TP
- X\fIitty??\fP
- X.br
- X.ns
- XUnder SunOS, waiting perform I/O to an iconified window.
- X.TP
- X\fIrpty??\fP
- X.br
- X.ns
- X.TP
- X\fIwpty??\fP
- XWaiting for a read or write to the specified master pty device.
- XSee \fIpty\fP(4).
- X.TP
- X\fIptrace\fP
- XThis is a parent process tracing its child.
- X.TP
- X\fIvfork\fP
- XThis is a vforking parent process waiting for its child to relinquish
- Xmemory resources. See \fIvfork\fP(2).
- X.TP
- X\fIfloppy\fP
- X.br
- X.ns
- X.TP
- X\fIprintr\fP
- X.br
- X.ns
- X.TP
- X\fIr??buf\fP
- XWaiting for the specified device to complete an I/O operation.
- X.RE
- X.TP 8
- X\fIFl\fP
- XFlags associated with the current state of the process.
- XThese flags may be any of the following \-
- X.RS 8
- X.TP 16
- X\fIU\fP
- XThe process is a UNIX system process.
- X.TP
- X\fIT\fP
- XThe process is being traced or debugged.
- X.TP
- X\fIV\fP
- XThe process is a child currently being vforked. See \fIvfork\fP(2).
- X.TP
- X\fII\fP
- XThe process is undergoing physical I/O.
- X.TP
- X\fIA\fP
- XThe system has detected, or the user has warned of
- Xanomalous paging behaviour. See \fIvadvise\fP(2).
- X.RE
- X.TP 8
- X\fINice\fP
- XThe ``niceness'' of the process. See \fInice\fP(2).
- X.TP
- X\fIVirtual\fP
- XThe virtual memory size of the process in kilobytes.
- XThe first figure indicates the sum of the data and stack segments,
- Xthe second figure that of the text segment.
- X.TP
- X\fIResident\fP
- XThe resident memory size of the process in kilobytes, representing
- Xthe real memory devoted to the process.
- X.TP
- X\fI%M\fP
- XThe percentage of available real memory allocated to this process.
- X.TP
- X\fITime\fP
- XThe total CPU time accumulated by this process.
- X(This is the sum of the system plus user times, unless the \fB\-q\fP
- Xflag is specified in which case only the user time is listed.)
- X.TP
- X\fIChild\fP
- XThe total CPU time accumulated by the process' children.
- X(This is the sum of the system plus user times, unless the \fB\-q\fP
- Xflag is specified.)
- X.TP
- X\fI%C\fP
- XThe percentage of available CPU time devoted to the process.
- XThis figure is a decaying average, computed over the past second.
- X.PP
- XThe following fields are listed when \fIsps\fP is invoked with the
- X\fB\-d\fP option \-
- X.TP 8
- X\fIFiles\fP
- XThe number of open files for this process.
- X.TP
- X\fIPageFaults\fP
- XThe number of major and minor page faults incurred by the process.
- X.TP
- X\fISwap\fP
- XThe number of swaps incurred by the process.
- X.TP
- X\fIBlockI/O\fP
- XThe number of block read or write operations performed
- Xon behalf of the process.
- X.TP
- X\fIKbytesecs\fP
- XThe integral of real memory usage over time.
- XThus, if a process uses 60 kilobytes of real memory for 3 seconds,
- Xthis figure is incremented by 180.
- X.PP
- XThe following fields are listed when \fIsps\fP is invoked with the
- X\fB\-y\fP option \-
- X.TP 8
- X\fIDev\fP
- XThe major and minor device numbers of the terminal.
- X.TP
- X\fIAddr\fP
- XThe virtual address of the associated \fBstruct tty\fP in \fB/dev/kmem\fP.
- X.TP
- X\fIRawq\fP
- X.br
- X.ns
- X.TP
- X\fICanq\fP
- X.br
- X.ns
- X.TP
- X\fIOutq\fP
- XThe number of characters in the terminal I/O queues.
- XThese refer to the raw input queue, the canonical input queue
- Xand the output queue.
- X.TP
- X\fIPgrp\fP
- XThe process group associated with the terminal.
- X.PP
- XAfter listing the requested output, \fIsps\fP prints a summary line.
- XThis indicates the number and total virtual memory size of all processes,
- Xthe number and total virtual size of busy processes,
- Xthe number and real memory size of loaded processes
- Xand the number and real size of swapped processes.
- X.SH DIAGNOSTICS
- X\fISps\fP reports a self-explanatory message if it is given an
- Xinvalid argument list.
- XThe program also complains if it cannot find necessary system information.
- X.PP
- XAt initialisation, \fIsps\fP complains if it cannot find the addresses of
- Xrequisite system structures in the kernel symbol file.
- XThis is usually the case because the system is rarely configured to support
- Xall known devices.
- X\fISps\fP also complains if more than one user shares the same user-id
- Xin the password file (\fB/etc/passwd\fP).
- X.SH EXAMPLES
- X\fBsps vb\fP
- X.PP
- X\fISps\fP describes all busy processes in a verbose manner.
- X.PP
- X\fBsps dtg 9 h1 co\fP
- X.PP
- X\fISps\fP lists processes associated with terminals \fB9\fP,
- X\fBh1\fP and the \fBconsole\fP.
- XThe output reflects the disc activity caused by these processes.
- XThe process group of each process is also included in the output.
- X.PP
- X\fBsps weu robert fred \-r 2\fP
- X.PP
- X\fISps\fP reports processes belonging to the specified users.
- XIt lists the environment as well as all the command arguments in a wide format.
- XThe output is produced indefinitely, with a delay of two seconds between
- Xeach listing.
- X.PP
- X\fBsps is /vmunix.new\fP
- X.PP
- X\fISps\fP is initialised. It reads its symbol information from the
- Xspecified file.
- X.SH FILES
- X.ta 2.5i
- X.nf
- X\fB/dev/console\fP Console
- X\fB/dev/tty??\fP Terminal and pty devices
- X\fB/dev/kmem\fP Kernel virtual memory
- X\fB/dev/mem\fP Physical memory
- X\fB/dev/drum\fP Paging and swap device
- X\fB/etc/passwd\fP Password file
- X\fB/etc/spsinfo\fP Information file
- X\fB/vmunix\fP Symbol file of \fB/dev/kmem\fP addresses
- X\fB/etc/termcap\fP To determine the output terminal width
- X.fi
- X.ta
- X.SH SEE ALSO
- X\fIiostat\fP(1), \fIkill\fP(1), \fIps\fP(1),
- X\fIvmstat\fP(1), \fIexec\fP(2),
- X\fIflock\fP(2), \fInice\fP(2), \fIpause\fP(2), \fIselect\fP(2), \fIsetuid\fP(2),
- X\fIsigvec\fP(2), \fIvadvise\fP(2), \fIvfork\fP(2), \fIwait\fP(2),
- X\fIpty\fP(4),\fItty\fP(4), \fIpstat\fP(8).
- X.SH AUTHORS
- XSeveral. In particular, J. E. Kulp and J. Robert Ward,
- X\fB<robert@olsen.uucp>\fP.
- X.LP
- XNFS changes incorporated by Alexander Dupuy,
- X\fB<dupuy@amsterdam.columbia.edu>\fP
- X.LP
- XSunOS 4.0 implementation by Alexander Dupuy and
- XCharlie Kim \fB<cck@cunixc.cc.columbia.edu>\fP.
- X.LP
- XUltrix 2.\fIx\fP additions incorporated by Rob Lehman at CUUCA.
- X.LP
- XSunOS 4.1 additions incorporated by Sakari Jalovaara, \fB<sja@sirius.hut.fi>\fP.
- X.LP
- XCurrently maintained by J. Robert Ward, \fB<robert@olsen.uu.ch>\fP
- X.SH BUGS
- XBecause the system is continually changing, the information reported by
- X\fIsps\fP is only an approximation to reality.
- XIf invoked by root, \fIsps\fP renices itself to \-20 in an attempt to run as
- Xfast as possible.
- X.PP
- X\fISps\fP recognises the sizes and addresses of internal kernel
- Xtables whenever it is invoked. However, it must be recompiled
- Xif major modifications are made to the kernel.
- X.PP
- X\fISps\fP does not list all the detailed information shown by \fIps\fP(1).
- XNor are all the options supported by \fIps\fP(1) available from \fIsps\fP.
- X.PP
- X\fISps\fP does not understand all the possible
- Xreasons why a process may be sleeping.
- X.PP
- XThe code of \fIsps\fP is inherently machine-dependent and non-portable.
- X.PP
- XThe number of options to \fIsps\fP is ridiculous.
- ---END-OF-sps.l---
- LEN=`wc -c < sps.l`
- if [ $LEN != 15259 ] ; then
- echo shar: File "sps.l" was $LEN, should have been 15259 bytes
- fi
- if [ -f 'stream.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "stream.c"
- exit 2
- fi
- echo x - stream.c
- sed -e 's/^X//' > stream.c << '---END-OF-stream.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)stream.c 1.2\t7/4/90" ;
- X# endif
- X
- X# ifdef SUNOS40
- X# include "sps.h"
- X# include <h/stream.h>
- X# include <h/vnode.h>
- X# ifdef SUNOS41
- X# include <h/strstat.h>
- X# endif
- X
- Xstatic struct stdata *pstreams ;
- Xstatic struct stdata *pstreamsNSTREAMS ;
- X
- Xinit_streams_tab()
- X{
- X int len ;
- X extern struct info Info ;
- X register struct stdata *s ;
- X struct vnode *v ;
- X char *getcore() ;
- X
- X if ( pstreams )
- X /* reinitializing */
- X for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
- X if ( s->sd_vnode != 0 )
- X free( (char*)s->sd_vnode ) ;
- X free( (char*)pstreams ) ;
- X# ifdef SUNOS41
- X /*
- X * In SunOS 4.1, the stream heads are in a linked list. A
- X * `struct strstat' contains the number of active streams; the
- X * variable `allstream' points to an apparently random
- X * position in a doubly linked `struct stdata' chain.
- X *
- X * To find all streams we'll have to scan the chain forwards
- X * AND backwards from `allstream'. `int going_forwards' below
- X * tells which direction we are currently going. Weird.
- X *
- X */
- X
- X {
- X struct strstat strst ;
- X int n ;
- X long addr ;
- X struct stdata *this_stream ;
- X int going_forwards = 1 ;
- X
- X if ( getkmem ((long) Info.i_strst, (char *) &strst,
- X sizeof ( struct strstat )) != sizeof ( struct strstat ))
- X return 0 ;
- X len = strst.stream.use * sizeof( struct stdata ) ;
- X pstreams = (struct stdata *)getcore (len ) ;
- X addr = (long)Info.i_allstream ;
- X this_stream = pstreams ;
- X pstreamsNSTREAMS = pstreams - 1 ;
- X for (n = 0 ; n < strst.stream.use ; n++)
- X {
- X if ( getkmem ( addr, (char *) this_stream,
- X sizeof ( struct stdata ))
- X != sizeof ( struct stdata ))
- X {
- X /*
- X * If we are following the `sd_next' chain we'll
- X * have to start over from the stream pointed to
- X * by Info.i_allstream and scan `sd_prev'
- X * backwards.
- X */
- X if ( going_forwards && n > 0 )
- X {
- X going_forwards = 0 ;
- X addr = (long) pstreams[0].sd_prev ;
- X n--;
- X continue ;
- X }
- X if ( pstreamsNSTREAMS < pstreams )
- X return 0 ;
- X break ;
- X }
- X addr = going_forwards ? (long) this_stream->sd_next :
- X (long) this_stream->sd_prev ;
- X this_stream++ ;
- X pstreamsNSTREAMS++ ;
- X }
- X }
- X# else SUNOS41
- X len = ((Info.i_streamsNSTREAMS - Info.i_streams) + 1)
- X * sizeof( struct stdata ) ;
- X pstreams = (struct stdata *)getcore( len ) ;
- X pstreamsNSTREAMS = pstreams + (len / sizeof( struct stdata ) ) ;
- X if ( getkmem( (long)Info.i_streams, (char *)pstreams, len ) != len )
- X return( 0 ) ;
- X# endif SUNOS41
- X
- X for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
- X if ( s->sd_vnode != 0 )
- X {
- X if ( ( v = (struct vnode*)getcore( sizeof( *v ) ) )
- X && getkmem( (long)s->sd_vnode, (char*)v, sizeof( *v ) )
- X == sizeof( *v ) )
- X {
- X s->sd_vnode = v ;
- X continue ;
- X }
- X
- X s->sd_vnode = 0 ;
- X }
- X return( 1 ) ;
- X}
- X
- X
- X# ifdef SUNOS41
- Xstruct sess *find_session ( addr )
- X
- Xstruct sess *addr ;
- X
- X{
- X /*
- X * SunOS 4.1 seems to store controlling tty's in a "struct
- X * sess" which is accessible as p->p_sessp. Another layer
- X * of indirection to wade through...
- X *
- X * To make this a tiny bit faster, I'll store sessions in a
- X * linked list as I read them in with getkmem; subsequent
- X * calls to find_session() check the cache.
- X */
- X
- X struct sps_sess {
- X struct sess sess ;
- X struct sess *addr ;
- X struct sps_sess *next ;
- X };
- X
- X static struct sps_sess *sessions ; /* Cache of known sessions*/
- X register struct sps_sess *s ;
- X
- X /* Try to find the session in the cache */
- X for ( s = sessions ; s ; s = s->next )
- X if ( s->addr == addr )
- X return &s->sess ;
- X /* Not found; get it from kmem and put it in the cache */
- X s = (struct sps_sess *)getcore( sizeof ( struct sps_sess ) ) ;
- X if ( getkmem ((long) addr, (char *) &s->sess,
- X sizeof ( struct sess )) != sizeof ( struct sess ) )
- X return 0 ;
- X s->addr = addr ;
- X s->next = sessions ;
- X sessions = s ;
- X return &s->sess ;
- X}
- X# endif SUNOS41
- X
- Xstruct stdata *getstdata ( st, dev )
- X
- Xstruct streamtab *st ;
- Xdev_t dev ;
- X
- X{
- X register struct stdata *s ;
- X
- X for ( s = pstreams ; s <= pstreamsNSTREAMS ; s++ )
- X if ( s->sd_strtab == st && s->sd_vnode
- X && s->sd_vnode->v_rdev == dev )
- X return( s ) ;
- X return( 0 ) ;
- X}
- X
- X/* 1 if `w' is in the address range defined by `a1' and `a2' ... */
- X# define INRANGE( w, a1, a2 ) \
- X ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
- X
- Xchar *gettty ( lp, w )
- X
- Xregister struct ttyline *lp ;
- Xcaddr_t w ;
- X
- X{
- X struct stdata *s ;
- X struct queue *q ;
- X struct queue qq[2] ;
- X char *cp = 0 ;
- X
- X if ( ( s = lp->l_stdata ) == 0 )
- X return( 0 ) ;
- X
- X q = s->sd_wrq ; /* get write queue (only queue_t in stdata) */
- X do
- X {
- X if ( INRANGE( w, RD( q ), q ) )
- X { /* check read queue */
- X cp = "rtty??" ;
- X break ;
- X }
- X if ( INRANGE( w, q, WR ( q ) ) )
- X { /* check write queue */
- X cp = "wtty??" ;
- X break ;
- X }
- X /* check queue private data structures - useful??? */
- X if ( getkmem( (long)RD( q ), (char*)qq, sizeof( qq ) )
- X != sizeof( qq ) )
- X break ;
- X if ( INRANGE( w, qq[0].q_ptr, qq[0].q_ptr + 1 ) )
- X {
- X cp = "r?ty??" ;
- X }
- X if ( INRANGE( w, qq[1].q_ptr, qq[1].q_ptr + 1 ) )
- X {
- X cp = "w?ty??" ;
- X }
- X q = qq[1].q_next ;
- X }
- X while ( q ) ;
- X if ( cp )
- X {
- X cp[4] = lp->l_name[0] ;
- X cp[5] = lp->l_name[1] ;
- X return( cp ) ;
- X }
- X return( 0 ) ; /* chain down list? */
- X}
- X# endif SUNOS40
- X
- ---END-OF-stream.c---
- LEN=`wc -c < stream.c`
- if [ $LEN != 5425 ] ; then
- echo shar: File "stream.c" was $LEN, should have been 5425 bytes
- fi
- if [ -f 'termwidth.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "termwidth.c"
- exit 2
- fi
- echo x - termwidth.c
- sed -e 's/^X//' > termwidth.c << '---END-OF-termwidth.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)termwidth.c 1.3\t8/6/90" ;
- X# endif
- X
- X# include <sys/ioctl.h>
- X
- X/*
- X** TERMWIDTH - Sets the external variable `Termwidth' to the # of columns
- X** on the terminal.
- X*/
- Xtermwidth ()
- X{
- X register char *termtype ;
- X register int twidth ;
- X# ifdef TIOCGWINSZ
- X struct winsize w ;
- X# else
- X# ifdef TIOCGSIZE
- X struct ttysize w ;
- X# endif
- X# endif
- X char buf[ 1025 ] ;
- X extern unsigned Termwidth ;
- X char *getenv() ;
- X
- X# ifdef TIOCGWINSZ
- X w.ws_col = 0 ;
- X if ( !ioctl( 0, TIOCGWINSZ, &w ) && w.ws_col )
- X {
- X Termwidth = w.ws_col ;
- X return ;
- X }
- X# else
- X# ifdef TIOCGSIZE
- X w.ts_cols = 0 ;
- X if ( !ioctl( 0, TIOCGSIZE, &w ) && w.ts_cols )
- X {
- X Termwidth = w.ts_cols ;
- X return ;
- X }
- X# endif
- X# endif
- X Termwidth = 80 ;
- X if ( !(termtype = getenv( "TERM" )) )
- X return ;
- X if ( tgetent( buf, termtype ) != 1 )
- X return ;
- X twidth = tgetnum( "co" ) ;
- X if ( twidth > 40 )
- X Termwidth = twidth ;
- X}
- ---END-OF-termwidth.c---
- LEN=`wc -c < termwidth.c`
- if [ $LEN != 978 ] ; then
- echo shar: File "termwidth.c" was $LEN, should have been 978 bytes
- fi
- if [ -f 'ttystatus.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "ttystatus.c"
- exit 2
- fi
- echo x - ttystatus.c
- sed -e 's/^X//' > ttystatus.c << '---END-OF-ttystatus.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)ttystatus.c 1.1\t10/1/88" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X# include <stdio.h>
- X# include <h/ioctl.h>
- X# ifdef SUNOS40
- X# include <h/stream.h>
- X# else
- X# include <h/tty.h>
- X# endif
- X# ifdef CHAOS
- X# include <chunix/chsys.h>
- X# include <chaos/chaos.h>
- X# endif
- X
- X/*
- X** TTYSTATUS - Reads the kernel memory for tty structures of active processes.
- X** The addresses of the associated struct ttys of /dev/kmem are kept in the
- X** info structure. Here we use those addresses to access the structures.
- X** Actually, we are mostly interested just in the process group of each tty.
- X*/
- Xttystatus ()
- X{
- X register struct ttyline *lp ;
- X# ifdef SUNOS40
- X struct stdata *stdata ;
- X extern struct stdata *getstdata() ;
- X# else
- X struct tty tty ;
- X# endif
- X extern struct flags Flg ;
- X extern struct info Info ;
- X# ifndef KVM
- X extern int Flkmem ;
- X# endif
- X
- X# ifdef SUNOS40
- X if ( !init_streams_tab() )
- X fprintf( stderr, "can't read streams table\n" ) ;
- X# endif
- X
- X if ( Flg.flg_y )
- X# ifdef SUNOS40
- X printf( "Ty Dev Addr Pgrp\n" ) ;
- X# else
- X printf( "Ty Dev Addr Rawq Canq Outq Pgrp\n" ) ;
- X# endif
- X lp = Info.i_ttyline ;
- X# ifdef CHAOS
- X while ( lp->l_name[0] && lp->l_name[0] != 'C' )
- X# else
- X while ( lp->l_name[0] )
- X# endif
- X {
- X# ifdef SUNOS40
- X if ( stdata = getstdata ( lp->l_addr, lp->l_dev ) )
- X {
- X lp->l_stdata = stdata ;
- X lp->l_pgrp = stdata->sd_pgrp ;
- X prstr( lp, stdata ) ;
- X }
- X else
- X lp->l_pgrp = 0 ;
- X lp++ ;
- X# else
- X if ( getkmem( (long)lp->l_addr, (char*)&tty, sizeof( tty ) )
- X != sizeof( struct tty ) )
- X {
- X fprintf( stderr,
- X "sps - Can't read struct tty for tty%.2s\n",
- X lp->l_name ) ;
- X lp->l_pgrp = 0 ;
- X lp++ ;
- X continue ;
- X }
- X lp->l_pgrp = tty.t_pgrp ;
- X prtty( lp, &tty ) ;
- X lp++ ;
- X# endif
- X }
- X# ifdef CHAOS
- X chaosttys( lp ) ;
- X# endif
- X}
- X
- X# ifdef SUNOS40
- X
- X/* PRSTR - Print out the stdata structure */
- Xprstr ( lp, stdata )
- X
- Xregister struct ttyline *lp ;
- Xregister struct stdata *stdata ;
- X
- X{
- X extern struct flags Flg ;
- X
- X if ( !Flg.flg_y )
- X return ;
- X printf( "%-2.2s %2d,%2d 0x%08x %5d\n",
- X lp->l_name,
- X major( lp->l_dev ),
- X minor( lp->l_dev ),
- X lp->l_addr,
- X stdata->sd_pgrp ) ;
- X}
- X
- X# else
- X
- X/* PRTTY - Print out the tty structure */
- Xprtty ( lp, tty )
- X
- Xregister struct ttyline *lp ;
- Xregister struct tty *tty ;
- X
- X{
- X extern struct flags Flg ;
- X
- X if ( !Flg.flg_y )
- X return ;
- X printf( "%-2.2s %2d,%2d 0x%08x %4d %4d %4d %5d\n",
- X lp->l_name,
- X major( lp->l_dev ),
- X minor( lp->l_dev ),
- X lp->l_addr,
- X tty->t_rawq.c_cc,
- X tty->t_canq.c_cc,
- X tty->t_outq.c_cc,
- X tty->t_pgrp ) ;
- X}
- X
- X# endif
- X
- X# ifdef CHAOS
- X
- X/* CHAOSTTYS - Finds ttys attached to the Chaos net */
- Xchaosttys ( lp )
- X
- Xregister struct ttyline *lp ;
- X
- X{
- X register struct connection **cnp ;
- X register int i ;
- X struct tty tty ;
- X struct connection *conntab[CHNCONNS] ;
- X struct connection conn ;
- X extern struct info Info ;
- X extern int Flkmem ;
- X
- X (void)getkmem( (long)Info.i_Chconntab, (char*)conntab,
- X sizeof( conntab ) ) ;
- X for ( i = 0, cnp = conntab ; cnp < &conntab[CHNCONNS] ; i++, cnp++ )
- X {
- X if ( !*cnp )
- X continue ;
- X (void)getkmem( (long)*cnp, (char*)&conn, sizeof( conn ) ) ;
- X if ( !(conn.cn_flags & CHTTY) )
- X continue ;
- X (void)getkmem( (long)conn.cn_ttyp, (char*)&tty, sizeof( tty ) ) ;
- X if ( lp >= &Info.i_ttyline[MAXTTYS] )
- X prexit( "sps - Too many chaos ttys\n" ) ;
- X lp->l_addr = conn.cn_ttyp ;
- X lp->l_pgrp = tty.t_pgrp ;
- X lp->l_dev = tty.t_dev ;
- X lp->l_name[0] = 'C' ;
- X lp->l_name[1] = i < 10 ? '0'+i : i-10 <= 'z'-'a' ? i-10+'a' :
- X i-10-('z'-'a')+'A' ;
- X prtty( lp, &tty ) ;
- X lp++ ;
- X }
- X}
- X
- X# endif
- ---END-OF-ttystatus.c---
- LEN=`wc -c < ttystatus.c`
- if [ $LEN != 3826 ] ; then
- echo shar: File "ttystatus.c" was $LEN, should have been 3826 bytes
- fi
- if [ -f 'vmstat.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "vmstat.c"
- exit 2
- fi
- echo x - vmstat.c
- sed -e 's/^X//' > vmstat.c << '---END-OF-vmstat.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)vmstat.c 1.1\t10/1/88" ;
- X# endif
- X
- X# ifdef SUNOS40
- X# ifndef OLDSTATS
- X# include "sps.h"
- X# include <h/mman.h>
- X# include <vm/hat.h>
- X# include <vm/as.h>
- X# include <vm/seg.h>
- X# include <vm/seg_vn.h>
- X
- Xseg_count ( p )
- X
- Xstruct process *p ;
- X
- X{
- X extern struct info Info ;
- X struct as as ; /* address space */
- X struct seg seg ; /* segment in addr space */
- X struct segvn_data vn_data ;
- X unsigned private = 0 ;
- X unsigned shared = 0 ;
- X
- X p->pr_private = 0 ;
- X p->pr_shared = 0 ;
- X
- X if ( getkmem( (long)p->pr_p.p_as, &as, sizeof( as ) ) != sizeof( as ) )
- X return( -1 ) ;
- X seg.s_next = as.a_segs ; /* setup for loop */
- X do
- X {
- X if ( ( getkmem( seg.s_next, &seg, sizeof( seg ) ) )
- X != sizeof( seg ) )
- X break ;
- X if ( seg.s_as != p->pr_p.p_as )
- X continue ; /* invalid segment */
- X if ( seg.s_ops != Info.i_segvn_ops )
- X { /* mapped device is "shared" */
- X shared += seg.s_size ;
- X continue ;
- X }
- X if ( getkmem( (long)seg.s_data, &vn_data, sizeof( vn_data ) )
- X != sizeof( vn_data ) )
- X continue ;
- X /*
- X * If a segment has an anonymous mapping, it is in the swap
- X * area. If it is also MAP_PRIVATE, we consider it "private"
- X * (even though it may be shared between parent and child after
- X * a fork() call). Segments without an anonymous mapping are
- X * considered to be "shared". [Should we worry about swap
- X * space reserved for copy-on-write shared segments?]
- X */
- X
- X if ( vn_data.amp && (vn_data.type & MAP_TYPE) == MAP_PRIVATE )
- X private += seg.s_size ;
- X else
- X shared += seg.s_size ;
- X }
- X while ( seg.s_next != as.a_segs ) ;
- X
- X# define BYTETOPAGE(x) (((x)+(PAGESIZE-1))>>PGSHIFT)
- X
- X p->pr_private = BYTETOPAGE( private ) ;
- X p->pr_shared = BYTETOPAGE( shared ) ;
- X p->pr_p.p_rssize = as.a_rss ; /* update count of resident pages */
- X return( 0 ) ;
- X}
- X# endif
- X# endif
- ---END-OF-vmstat.c---
- LEN=`wc -c < vmstat.c`
- if [ $LEN != 1902 ] ; then
- echo shar: File "vmstat.c" was $LEN, should have been 1902 bytes
- fi
- if [ -f 'waitingfor.c' -a "${1}" != "-c" ] ; then
- echo shar: Won\'t overwrite existing file "waitingfor.c"
- exit 2
- fi
- echo x - waitingfor.c
- sed -e 's/^X//' > waitingfor.c << '---END-OF-waitingfor.c---'
- X# ifndef lint
- Xstatic char SccsId[] = "@(#)waitingfor.c 1.5\t8/6/90" ;
- X# endif
- X
- X# include "sps.h"
- X# ifndef SUNOS40
- X# include <h/text.h>
- X# endif SUNOS40
- X
- X# ifdef NFS
- X# ifdef DEC3100
- X# include <h/gnode.h>
- X# include <h/inode.h>
- X# else DEC3100
- X# include <h/vnode.h>
- X# include <ufs/inode.h>
- X# endif DEC3100
- X# else
- X# include <h/inode.h>
- X# endif NFS
- X
- X# include <h/ioctl.h>
- X# ifdef SUNOS40
- X# include <h/stream.h>
- X# include <h/tty.h>
- X# include <h/ptyvar.h>
- X# else SUNOS40
- X# include <h/tty.h>
- X# endif SUNOS40
- X
- X# include <h/buf.h>
- X# ifdef BSD42
- X# ifdef NFS
- X# ifndef NOQUOTA
- X# ifdef DEC3100
- X# include <h/quota.h>
- X# else
- X# include <ufs/quota.h>
- X# endif DEC3100
- X# endif NOQUOTA
- X# else NFS
- X# include <h/quota.h>
- X# endif NFS
- X# include <h/mbuf.h>
- X# include <h/socket.h>
- X# include <h/socketvar.h>
- X# endif BSD42
- X
- X/* 1 if `w' is in the address range defined by `a1' and `a2' ... */
- X# define INRANGE( w, a1, a2 ) \
- X ( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
- X
- X/* NFS changes incorporated by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
- X
- X/* WAITINGFOR - Determine what a process is waiting for and describe it. */
- Xchar *waitingfor ( p )
- X
- Xstruct process *p ;
- X
- X{
- X register caddr_t w ;
- X register struct ttyline *lp ;
- X register struct symbol *s ;
- X register char *cp ;
- X# ifdef BSD42
- X struct socket sc ;
- X# endif
- X int rc ;
- X static char wbuf[ 8 ] ;
- X extern struct info Info ;
- X extern struct symbol Symbollist[] ;
- X char *sprintf() ;
- X# ifdef SUNOS40
- X char *gettty() ;
- X# endif
- X
- X w = p->pr_p.p_wchan ;
- X if ( !w )
- X return ( "null" ) ;
- X /* Waiting for a child process, alternatively in a vfork() ? */
- X if ( INRANGE( w, Info.i_proc0, &Info.i_proc0[ Info.i_nproc ] ) )
- X return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
- X# ifndef SUNOS40
- X /* Waiting for a page to be brought in ? */
- X if ( INRANGE( w, Info.i_swbuf0, &Info.i_swbuf0[ Info.i_nswbuf ] ) )
- X return ( "swap" ) ;
- X /* Waiting for discio through a block device to complete ? */
- X if ( INRANGE( w, Info.i_buf0, &Info.i_buf0[ Info.i_nbuf ] ) )
- X /* SHOULD ACTUALLY READ AS "blkio" BUT "discio" IS WHAT
- X IS GENERALLY MEANT HERE. */
- X return ( "discio" ) ;
- X /* Waiting for a text page to be brought in ? */
- X if ( INRANGE( w, Info.i_text0, &Info.i_text0[ Info.i_ntext ] ) )
- X return ( "swtext" ) ;
- X# endif SUNOS40
- X
- X# ifdef BSD42
- X# ifndef NOQUOTA
- X /* Waiting for an event associated with the quota system ? */
- X if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
- X return ( "quota" ) ;
- X# endif NOQUOTA
- X# endif BSD42
- X
- X# ifndef SUNOS41
- X /* Sorry, I don't know how to do this...
- X * I kinda think that SunOS 4.1 allocates inode
- X * buffer entries dynamically. Maybe it could be
- X * possible to read in all "struct file"s and
- X * compare each file.f_data to the wait channel. ++sja
- X */
- X /* Waiting for an inode ? */
- X if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
- X# ifdef ULTRIX20
- X switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct gnode ))
- X# else
- X switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
- X# endif ULTRIX20
- X {
- X# ifdef BSD42
- X# ifdef NFS
- X case (int)&((struct inode*)0)->i_vnode.v_exlockc :
- X /* Exclusive lock on this inode */
- X return ( "exlock" ) ;
- X case (int)&((struct inode*)0)->i_vnode.v_shlockc :
- X /* Shared lock on this inode */
- X return ( "shlock" ) ;
- X# else NFS
- X# ifdef ULTRIX20
- X# ifndef DEC3100
- X /* Compile this code with gcc if you want to run it
- X properly. The DEC compiler can't handle this. */
- X case (int)&((struct gnode*)0)->g_exlockc :
- X /* Exclusive lock on this inode */
- X return ( "exlock" ) ;
- X case (int)&((struct gnode*)0)->g_shlockc :
- X /* Shared lock on this inode */
- X return ( "shlock" ) ;
- X case (int)&((struct gnode*)0)->g_frcnt :
- X /* Open fifo with no readers */
- X return ( "wfifo" ) ;
- X case (int)&((struct gnode*)0)->g_fwcnt :
- X /* Open fifo with no writers */
- X return ( "rfifo" ) ;
- X# endif DEC3100
- X# else ULTRIX20
- X case (int)&((struct inode*)0)->i_exlockc :
- X /* Exclusive lock on this inode */
- X return ( "exlock" ) ;
- X case (int)&((struct inode*)0)->i_shlockc :
- X /* Shared lock on this inode */
- X return ( "shlock" ) ;
- X# endif ULTRIX20
- X# endif NFS
- X# else BSD42
- X case 1 :
- X return ( "wpipe" ) ;
- X case 2 :
- X return ( "rpipe" ) ;
- X case (int)&((struct inode*)0)->i_un.i_group.g_datq :
- X return ( "rmux" ) ;
- X# endif BSD42
- X default :
- X /* Inode probably locked */
- X return ( "inode" ) ;
- X }
- X# endif SUNOS41
- X
- X# if defined(BSD42) && (defined(SUNOS40) || defined(NMBCLUSTERS))
- X /* Waiting for a structure inside an mbuf ? If so, try to find why */
- X# ifdef SUNOS40
- X if ( INRANGE( w, Info.i_mbutl,
- X &Info.i_mbutl[ MBPOOLBYTES / sizeof( struct mbuf ) ] ) )
- X# else
- X if ( INRANGE( w, Info.i_mbutl,
- X &Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
- X# endif SUNOS40
- X switch ( ((int)w - (int)Info.i_mbutl) % sizeof( struct mbuf )
- X - (int)&((struct mbuf*)0)->m_dat[0] )
- X {
- X case (int)&((struct socket*)0)->so_timeo :
- X /* Socket timeout event - Guess why */
- X rc = getsocket( (struct socket*)(w
- X - (int)&((struct socket*)0)->so_timeo),
- X &sc ) ;
- X return ( rc && (sc.so_state & SS_ISCONNECTING)
- X ? "connct"
- X : rc && ((sc.so_options & SO_ACCEPTCONN)
- X && !sc.so_qlen)
- X ? "accept" : "socket" ) ;
- X case (int)&((struct socket*)0)->so_rcv.sb_cc :
- X /* Read from an empty socket. Here we actually
- X attempt to determine whether the socket
- X structure in question really does refer to
- X a socket, or whether it is in fact a pipe
- X in disguise. */
- X return ( getsocket( (struct socket*)(w
- X - (int)&((struct socket*)0)->so_rcv.sb_cc),
- X &sc )
- X && sc.so_type == SOCK_STREAM
- X# ifdef BSD43
- X && ((sc.so_state
- X & (SS_ISCONNECTED|SS_CANTSENDMORE))
- X == (SS_ISCONNECTED|SS_CANTSENDMORE))
- X# else
- X && !sc.so_rcv.sb_hiwat
- X && !sc.so_rcv.sb_mbmax
- X && (sc.so_state
- X & (SS_ISCONNECTED|SS_CANTRCVMORE))
- X# endif BSD43
- X ? "rpipe" : "rsockt" ) ;
- X case (int)&((struct socket*)0)->so_snd.sb_cc :
- X /* Write to a full socket. Again, we try
- X to determine whether or not this is a
- X real socket or a pipe. */
- X return ( getsocket( (struct socket*)(w
- X - (int)&((struct socket*)0)->so_snd.sb_cc),
- X &sc )
- X# ifdef BSD43
- X && sc.so_type == SOCK_STREAM
- X && ((sc.so_state
- X & (SS_ISCONNECTED|SS_CANTRCVMORE))
- X == (SS_ISCONNECTED|SS_CANTRCVMORE))
- X# else
- X && sc.so_rcv.sb_hiwat == 2048
- X && sc.so_rcv.sb_mbmax == 4096
- X && (sc.so_state
- X & (SS_ISCONNECTED|SS_CANTSENDMORE))
- X# endif BSD43
- X ? "wpipe" : "wsockt" ) ;
- X default :
- X /* Other mbuf event */
- X return ( "mbuf" ) ;
- X }
- X# endif BSD42
- X
- X# ifdef SUNOS41
- X if ( w == (caddr_t)p->pr_p.p_uarea )
- X return ( "pause" ) ;
- X# endif SUNOS41
- X /* Look in the symbol table for known wait addresses. */
- X for ( s = Symbollist ; s->s_kname ; s++ )
- X if ( s->s_wait && w == *s->s_info )
- X return ( s->s_wait ) ;
- X
- X# ifdef SUNOS40
- X /* Have to check for ptys in a funny sort of way */
- X if ( INRANGE( w, Info.i_ptybase, &Info.i_ptybase[ Info.i_npty ] ) )
- X {
- X switch ( ((int)w - (int)Info.i_ptybase) % sizeof( struct pty ) )
- X {
- X case (int)&((struct pty*)0)->pt_flags :
- X cp = "opty??" ;
- X break ;
- X case (int)&((struct pty*)0)->pt_ttycommon.t_writeq :
- X cp = "spty??" ;
- X break ;
- X default :
- X cp = "?pty??" ;
- X }
- X /* by the conventional naming, anyhow */
- X cp[4] = 'p' + (((int)w - (int)Info.i_ptybase)
- X / sizeof( struct pty )) / 16 ;
- X if ( ( cp[5] = '0' + (((int) w - (int)Info.i_ptybase)
- X / sizeof( struct pty )) % 16 ) > '9' )
- X cp[5] += 'a' - '9' - 1 ;
- X return( cp ) ;
- X }
- X /* Check for ttys last, since there may be a lot of them. */
- X if ( p->pr_tty != 0 )
- X if ( cp = gettty( p->pr_tty, w ) )
- X return( cp ) ;
- X for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
- X if ( cp = gettty( lp, w ) )
- X return( cp ) ;
- X# else SUNOS40
- X /* Waiting for tty I/O ? If so, find which tty it is */
- X for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
- X if ( INRANGE( w, &lp->l_addr[0], &lp->l_addr[1] ) )
- X {
- X# ifdef DEC3100
- X /* Cretinous DEC compiler can't handle case
- X constructs like the following ... */
- X cp = "?tty??" ;
- X# else DEC3100
- X switch ( (int)w - (int)lp->l_addr )
- X {
- X case (int)&((struct tty*)0)->t_rawq :
- X /* Read from a tty or slave pty */
- X cp = "rtty??" ;
- X break ;
- X case (int)&((struct tty*)0)->t_outq :
- X /* Write to a tty or slave pty */
- X cp = "wtty??" ;
- X break ;
- X case (int)&((struct tty*)0)->t_canq :
- X /* Waiting for icon to be opened */
- X cp = "itty??" ;
- X break ;
- X case (int)&((struct tty*)0)->t_state :
- X /* Tty not open */
- X cp = "otty??" ;
- X break ;
- X case (int)&((struct tty*)0)->t_outq.c_cf :
- X /* Read from a controller pty */
- X cp = "rpty??" ;
- X break ;
- X case (int)&((struct tty*)0)->t_rawq.c_cf :
- X /* Write to a controller pty */
- X cp = "wpty??" ;
- X break ;
- X default :
- X cp = "?tty??" ;
- X break ;
- X }
- X# endif DEC3100
- X cp[4] = lp->l_name[0] ;
- X cp[5] = lp->l_name[1] ;
- X return ( cp ) ;
- X }
- X# endif SUNOS40
- X
- X /* No reason for the wait state has been found.
- X Return the wait channel as a hexadecimal address. */
- X# ifdef SUN
- X (void)sprintf( wbuf, "x%05x", w - KERNELBASE ) ;
- X# else
- X (void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
- X# endif
- X return ( wbuf ) ;
- X}
- X
- X
- X# ifdef BSD42
- X/*
- X** GETSOCKET - Reads a `struct socket' from the kernel virtual memory address
- X** identified by `ks' into the buffer `s'.
- X*/
- Xgetsocket ( ks, s )
- X
- Xstruct socket *ks ;
- Xstruct socket *s ;
- X
- X{
- X return ( getkmem( (long)ks, (char*)s, sizeof( struct socket ) )
- X == sizeof( struct socket ) ) ;
- X}
- X# endif BSD42
- ---END-OF-waitingfor.c---
- LEN=`wc -c < waitingfor.c`
- if [ $LEN != 9904 ] ; then
- echo shar: File "waitingfor.c" was $LEN, should have been 9904 bytes
- fi
- exit 0
-