SPS (Show Process Status) Part 1 of 2
sources-request at panda.UUCP
sources-request at panda.UUCP
Tue Dec 3 09:48:55 AEST 1985
Mod.sources: Volume 3, Issue 56
Submitted by: seismo!mcvax!cernvax!hslrswi!robert (Robert Ward)
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# main.c
# mktree.c
# needed.c
# openfiles.c
# percentmem.c
# prcmd.c
# prcpu.c
# prheader.c
# printall.c
# printproc.c
# prsummary.c
# readstatus.c
# selectproc.c
# selecttty.c
# sps.h
# termwidth.c
# ttystatus.c
# waitingfor.c
# This archive created: Mon Dec 2 18:41:14 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'main.c'" '(2626 characters)'
if test -f 'main.c'
then
echo shar: will not over-write existing file "'main.c'"
else
sed 's/^X//' << \SHAR_EOF > 'main.c'
# include "sps.h"
# include "flags.h"
# include <h/text.h>
# include <stdio.h>
/* SPS - Show Process Status */
/* J. R. Ward - Hasler AG Bern - 24 May 1985 */
main ( argc,argv )
int argc ;
char **argv ;
{
register struct process *plist ;
register struct process *process ;
register struct text *text ;
int flinfo ;
extern struct flags Flg ;
extern struct info Info ;
extern int Flmem ;
extern int Flkmem ;
extern int Flswap ;
char *getcore() ;
struct process *needed(), *mktree() ;
/* Renice as fast as possible for root (Suggested by Gregorio!mogul) */
if ( !getuid() )
(void)nice( -40 ) ;
/* Decode the flag arguments */
flagdecode( argc, argv ) ;
/* Determine the terminal width */
if ( !Flg.flg_w && !Flg.flg_N && !Flg.flg_i )
termwidth() ;
/* Open the cpu physical memory, kernel virtual memory and swap device*/
if ( Flg.flg_k )
{
Flmem = openfile( Flg.flg_k ) ;
Flkmem = Flmem ;
}
else
{
Flmem = openfile( FILE_MEM ) ;
Flkmem = openfile( FILE_KMEM ) ;
if ( !Flg.flg_o )
Flswap = openfile( FILE_SWAP ) ;
}
if ( Flg.flg_i )
{ /* -i flag for info file initialisation */
initialise() ;
exit( 0 ) ;
}
/* Read the information file */
flinfo = openfile( Flg.flg_j ? Flg.flg_j : FILE_INFO ) ;
if ( read( flinfo, (char*)&Info, sizeof( struct info ) )
!= sizeof( struct info ) )
{
fprintf( stderr, "sps - Can't read info file %s",
Flg.flg_j ? Flg.flg_j : FILE_INFO ) ;
sysperror() ;
}
(void)close( flinfo ) ;
/* Find current tty status */
ttystatus() ;
/* Now that we know the available ttys, decode the flags */
flagsetup() ;
process = (struct process*)getcore(Info.i_nproc*sizeof(struct process));
text = (struct text*)getcore( Info.i_ntext * sizeof( struct text ) ) ;
do
{ /* Read current process and text status */
readstatus( process, text ) ;
/* Select those processes to be listed */
plist = needed( process, text ) ;
/* Form a tree of listed processes */
plist = mktree( process, plist ) ;
if ( !Flg.flg_N )
{ /* Print the processes */
prheader() ;
printall( plist, 0 ) ;
}
prsummary() ;
(void)fflush( stdout ) ;
if ( Flg.flg_r )
{ /* If repeating, again get tty status */
ttystatus() ;
if ( Flg.flg_rdelay )
# ifdef BSD42
sleep( Flg.flg_rdelay ) ;
# else
sleep( (int)Flg.flg_rdelay ) ;
# endif
}
} while ( Flg.flg_r ) ;
exit( 0 ) ;
}
SHAR_EOF
if test 2626 -ne "`wc -c < 'main.c'`"
then
echo shar: error transmitting "'main.c'" '(should have been 2626 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mktree.c'" '(1626 characters)'
if test -f 'mktree.c'
then
echo shar: will not over-write existing file "'mktree.c'"
else
sed 's/^X//' << \SHAR_EOF > 'mktree.c'
# include "sps.h"
/*
** MKTREE - Sort the needed processes by subtree and at the top by user.
** This procedure takes a list of processes (as returned by needed())
** and returnes a pointer to a sorted list.
*/
struct process *mktree ( process, plist )
struct process *process ;
struct process *plist ;
{
register struct process *p ;
register struct process *pp ;
register struct process *lp ;
struct process *op ;
struct process proot ;
proot.pr_sibling = (struct process*)0 ;
for ( p = plist ; p ; p = p->pr_plink )
{
if ( p->pr_pptr > &process[1] )
{
for ( pp = plist ; pp ; pp = pp->pr_plink )
{
if ( pp != p->pr_pptr )
continue ;
if ( lp = pp->pr_child )
{ /* Does process have children ? */
op = (struct process*)0 ;
while (lp &&
lp->pr_p.p_pid < p->pr_p.p_pid )
{
op = lp ;
lp=lp->pr_sibling ;
}
if ( op )
{
p->pr_sibling = lp ;
op->pr_sibling = p ;
break ;
}
}
p->pr_sibling = lp ;
pp->pr_child = p ;
break ;
}
if ( pp )
continue ;
}
/* We have a top level process, sort into top level list.
The top level is sorted firstly by user-id and then
by process-id. */
lp = &proot ;
pp = lp->pr_sibling ;
while ( pp )
{
if ( p->pr_p.p_uid < pp->pr_p.p_uid )
break ;
if ( p->pr_p.p_uid == pp->pr_p.p_uid
&& p->pr_p.p_pid < pp->pr_p.p_pid )
break ;
lp = pp, pp = pp->pr_sibling ;
}
p->pr_sibling = lp->pr_sibling ;
lp->pr_sibling = p ;
}
return ( proot.pr_sibling ) ;
}
SHAR_EOF
if test 1626 -ne "`wc -c < 'mktree.c'`"
then
echo shar: error transmitting "'mktree.c'" '(should have been 1626 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'needed.c'" '(4455 characters)'
if test -f 'needed.c'
then
echo shar: will not over-write existing file "'needed.c'"
else
sed 's/^X//' << \SHAR_EOF > 'needed.c'
# include "sps.h"
# include "flags.h"
# include <h/text.h>
# include <stdio.h>
/*
** NEEDED - Determine which processes are needed for the printout
** and add these to a list of needed processes.
*/
struct process *needed ( process, text )
register struct process *process ;
struct text *text ;
{
register struct process *p ;
register struct process *plist ;
struct process *lastp ;
int uid ;
extern struct flags Flg ;
extern union userstate User ;
extern struct info Info ;
extern struct ttyline Notty ;
struct ttyline *findtty() ;
char *getcmd() ;
plist = (struct process*)0 ;
lastp = &process[ Info.i_nproc ] ;
/* Normalise internal pointers from kernel addresses. For each kmem
address in the `proc' and `text' structures, we convert that
address for our own internal use. */
for ( p = process ; p < lastp ; p++ )
{
if ( !p->pr_p.p_stat )
continue ;
/* Normalise internal text pointers */
if ( p->pr_p.p_textp )
p->pr_p.p_textp = &text[p->pr_p.p_textp - Info.i_text0];
/* Normalise internal linked list of processes */
p->pr_plink = p->pr_p.p_link ?
&process[ p->pr_p.p_link - Info.i_proc0 ] :
(struct process*)0 ;
/* Normalise internal parent pointers */
p->pr_pptr = p->pr_p.p_pptr ?
&process[ p->pr_p.p_pptr - Info.i_proc0 ] :
(struct process*)0 ;
/* Check for valid parent pointers */
if ( !p->pr_pptr )
{
p->pr_pptr = process ;
continue ;
}
if ( p->pr_pptr < process || p->pr_pptr >= lastp )
{
fprintf( stderr, "sps - process %d has bad pptr\n",
p->pr_p.p_pid ) ;
p->pr_pptr = process ;
}
}
/* For each process, see if it is a candidate for selection.
If so, retrieve its command arguments and upage information. */
uid = getuid() ;
for ( p = process ; p < lastp ; p++ )
{
if ( !p->pr_p.p_stat )
continue ;
/* Count processes and sizes */
summarise( p ) ;
/* Select the given processes. Bear in mind that selection
of processes based on the `F' and `T' flags must be
postponed until the upage is accessed. */
if ( !Flg.flg_F && !Flg.flg_T && !selectproc( p, process, uid ))
continue ;
/* Try to find the process' command arguments. Accessing the
arguments also involves retrieving the upage. */
p->pr_cmd = getcmd( p ) ;
/* If the upage was found successfully, use this information */
if ( p->pr_upag )
{
# ifdef BSD42
p->pr_rself = User.u_us.u_ru ;
p->pr_rchild = User.u_us.u_cru ;
# else
p->pr_vself = User.u_us.u_vm ;
p->pr_vchild = User.u_us.u_cvm ;
# endif
p->pr_tty = findtty( p ) ;
p->pr_files = filecount() ;
}
else
p->pr_tty = &Notty ;
/* Select on the basis of the `F' and `T' flags */
if ( Flg.flg_F
&& !(p->pr_p.p_pgrp && p->pr_p.p_pgrp == p->pr_tty->l_pgrp) )
continue ;
if ( Flg.flg_T && !selecttty( p ) )
continue ;
/* Arrive here with a selected process. Add this to the
linked list of needed processes. */
p->pr_plink = plist ;
plist = p ;
p->pr_child = (struct process*)0 ;
p->pr_sibling = (struct process*)0 ;
}
return ( plist ) ;
}
/* SUMMARISE - Summarises the given process into the `Summary' structure */
/*
** SHOULD ACCOUNT HERE FOR THE SIZE OF LOADED PAGE TABLES, BUT WE DON'T REALLY
** KNOW THEIR RESIDENT SIZES.
*/
summarise ( p )
register struct process *p ;
{
register struct text *tp ;
int busy ;
extern struct summary Summary ;
Summary.sm_ntotal++ ;
if ( p->pr_p.p_stat == SZOMB )
return ;
/* Firstly, account for processes */
Summary.sm_ktotal += p->pr_p.p_dsize + p->pr_p.p_ssize ;
Summary.sm_kloaded += p->pr_p.p_rssize ;
Summary.sm_kswapped += p->pr_p.p_swrss ;
if ( p->pr_p.p_flag & SLOAD )
Summary.sm_nloaded++ ;
else
Summary.sm_nswapped++ ;
busy = (p->pr_p.p_stat == SRUN) || (p->pr_p.p_stat==SSLEEP
&& (p->pr_p.p_pri<PZERO && p->pr_p.p_pid > MSPID) ) ;
if ( busy )
{
Summary.sm_nbusy++ ;
Summary.sm_kbusy += p->pr_p.p_dsize + p->pr_p.p_ssize ;
}
/* Now account for their texts */
if ( !(tp = p->pr_p.p_textp) || !tp->x_count )
return ;
Summary.sm_ktotal += tp->x_size ;
Summary.sm_kloaded += tp->x_rssize ;
Summary.sm_kswapped += tp->x_swrss ;
if ( busy )
Summary.sm_kbusy += tp->x_size ;
tp->x_count = 0 ;
}
SHAR_EOF
if test 4455 -ne "`wc -c < 'needed.c'`"
then
echo shar: error transmitting "'needed.c'" '(should have been 4455 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'openfiles.c'" '(2626 characters)'
if test -f 'openfiles.c'
then
echo shar: will not over-write existing file "'openfiles.c'"
else
sed 's/^X//' << \SHAR_EOF > 'openfiles.c'
# include <stdio.h>
# include "sps.h"
# include "flags.h"
/* Miscellaneous procedures */
/* OPENFILE - Opens the named file */
openfile ( name )
char *name ;
{
register int fd ;
if ( (fd = open( name, 0 )) >= 0 )
return ( fd ) ;
fprintf( stderr, "sps - Can't open %s", name ) ;
sysperror() ;
/* NOTREACHED */
}
/* MEMSEEK - Seek on a special file */
memseek ( fd, pos )
int fd ;
long pos ;
{
extern int errno ;
extern struct flags Flg ;
long lseek() ;
errno = 0 ;
if ( Flg.flg_k )
pos &= 0x7fffffff ;
(void)lseek( fd, pos, 0 ) ;
if ( errno )
{
fprintf( stderr, "sps - Seek failed" ) ;
sysperror() ;
}
}
/* SWSEEK - Seek on the swap device */
swseek ( pos )
long pos ;
{
extern int Flswap ;
extern int errno ;
long lseek() ;
errno = 0 ;
(void)lseek( Flswap, pos, 0 ) ;
if ( errno )
{
fprintf( stderr, "sps - Seek failed" ) ;
sysperror() ;
}
}
# ifdef lint
int errno ;
int sys_nerr ;
char *sys_errlist[] ;
# endif
/* SYSPERROR - Reports a system defined error msg and then exits gracefully */
sysperror ()
{
extern int errno ;
extern int sys_nerr ;
extern char *sys_errlist[] ;
if ( 0 < errno && errno < sys_nerr )
fprintf( stderr, " : %s", sys_errlist[errno] ) ;
(void)fputc( '\n', stderr ) ;
exit( 1 ) ;
}
/* STRSAVE - Store a string in core for later use. */
char *strsave ( cp )
register char *cp ;
{
register char *chp ;
char *getcore(), *strcpy() ;
chp = getcore( strlen( cp ) + 1 ) ;
(void)strcpy( chp, cp ) ;
return ( chp ) ;
}
/* GETCORE - Allocate and return a pointer to the asked for amount of core */
char *getcore ( size )
register int size ;
{
register char *chp ;
char *malloc() ;
if ( chp = malloc( (unsigned)size ) )
return ( chp ) ;
fprintf( stderr, "sps - Out of core" ) ;
sysperror() ;
/* NOTREACHED */
}
union flaglist *getflgsp ( argc )
register int argc ;
{
char *getcore() ;
return ( (union flaglist*)getcore( sizeof( union flaglist )*argc ) ) ;
}
/* PREXIT - Print an error message and exit */
/* VARARGS1 */
/* ARGSUSED */
prexit ( fmt, args )
char *fmt ;
{
_doprnt( fmt, &args, stderr ) ;
exit( 1 ) ;
}
SHAR_EOF
if test 2626 -ne "`wc -c < 'openfiles.c'`"
then
echo shar: error transmitting "'openfiles.c'" '(should have been 2626 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'percentmem.c'" '(823 characters)'
if test -f 'percentmem.c'
then
echo shar: will not over-write existing file "'percentmem.c'"
else
sed 's/^X//' << \SHAR_EOF > 'percentmem.c'
# include "sps.h"
# include <h/text.h>
# ifdef BSD42
# include <machine/pte.h>
# else
# include <h/pte.h>
# include <h/vmparam.h>
# endif
# include <h/vmmac.h>
/* PERCENTMEM - Returns the percentage of real memory used by this process */
double percentmem ( p )
register struct process *p ;
{
register struct text *tp ;
int szptudot ;
double fracmem ;
extern struct info Info ;
tp = p->pr_p.p_textp ;
if ( !(p->pr_p.p_flag & SLOAD) || !tp )
return ( 0.0 ) ;
szptudot = UPAGES + clrnd( ctopt( p->pr_p.p_dsize + p->pr_p.p_ssize ) );
fracmem = ( (double)p->pr_p.p_rssize + szptudot ) / CLSIZE ;
if ( tp->x_ccount )
fracmem += ((double)tp->x_rssize)/CLSIZE/tp->x_ccount ;
return ( 100.0 * fracmem / (double)Info.i_ecmx ) ;
}
SHAR_EOF
if test 823 -ne "`wc -c < 'percentmem.c'`"
then
echo shar: error transmitting "'percentmem.c'" '(should have been 823 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'prcmd.c'" '(709 characters)'
if test -f 'prcmd.c'
then
echo shar: will not over-write existing file "'prcmd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'prcmd.c'
# include "sps.h"
# include "flags.h"
/* PRCMD - Prints the command arguments according to the switches */
prcmd ( p, lpad, width )
register struct process *p ;
int lpad ;
int width ;
{
extern struct flags Flg ;
extern unsigned Termwidth ;
printf( "%*d ", lpad, p->pr_p.p_pid ) ;
if ( Flg.flg_f )
{
printf( "%5d ", p->pr_p.p_ppid ) ;
width -= 6 ;
}
if ( Flg.flg_g )
{
printf( "%5d ", p->pr_p.p_pgrp ) ;
width -= 6 ;
}
width += Termwidth ;
if ( Flg.flg_w )
printf( "%s\n", p->pr_cmd ) ;
else if ( width > 0 )
printf( "%-.*s\n", width, p->pr_cmd ) ;
if ( p->pr_csaved )
free( p->pr_cmd ) ;
}
SHAR_EOF
if test 709 -ne "`wc -c < 'prcmd.c'`"
then
echo shar: error transmitting "'prcmd.c'" '(should have been 709 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'prcpu.c'" '(1538 characters)'
if test -f 'prcpu.c'
then
echo shar: will not over-write existing file "'prcpu.c'"
else
sed 's/^X//' << \SHAR_EOF > 'prcpu.c'
# include "sps.h"
# ifdef BSD42
/* PRCPU - Print cpu time */
prcpu ( time, utime )
register time_t time ;
time_t utime ;
{
time += utime / 1000000 ;
utime %= 1000000 ;
if ( time < 0L )
{ /* Ignore negative times */
printf( " " ) ;
return ;
}
if ( time < 60L*10L )
{ /* Print as seconds if less than 1000 seconds */
printf( "%3d.%1d", (int)time, (int)utime/100000 ) ;
return ;
}
/* Print as minutes if less than 10 hours ; print as hours if less than
10 days, else print as days. */
if ( time < 60L*60L*10L )
printf( "%3D M", time/60L ) ;
else if ( time < 24L*60L*60L*10L )
printf( "%3D H", time/60L/60L ) ;
else
printf( "%3D D", time/60L/60L/24L ) ;
}
# else
/* PRCPU - Print cpu time */
prcpu ( time )
register time_t time ;
{
extern struct info Info ;
if ( time < 0L )
{ /* Ignore negative times */
printf( " " ) ;
return ;
}
if ( time < Info.i_hz*60L*10L )
{ /* Less than 10 minutes */
printf( "%3D.%1D", time/Info.i_hz,
(time % Info.i_hz / (Info.i_hz/10L)) ) ;
return ;
}
/* If less than 10 hours, print as minutes */
time /= Info.i_hz ;
/* Print as minutes if less than 10 hours ; print as hours if less than
10 days, else print as days. */
if ( time < 60L*60L*10L )
printf( "%3D M", time/60L ) ;
else if ( time < 24L*60L*60L*10L )
printf( "%3D H", time/60L/60L ) ;
else
printf( "%3D D", time/60L/60L/24L ) ;
}
# endif
SHAR_EOF
if test 1538 -ne "`wc -c < 'prcpu.c'`"
then
echo shar: error transmitting "'prcpu.c'" '(should have been 1538 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'prheader.c'" '(438 characters)'
if test -f 'prheader.c'
then
echo shar: will not over-write existing file "'prheader.c'"
else
sed 's/^X//' << \SHAR_EOF > 'prheader.c'
# include "sps.h"
# include "flags.h"
/* PRHEADER - Print a header according to the switches */
prheader ()
{
extern struct flags Flg ;
printf( "Ty User %s Proc#", Flg.flg_v ?
" Status Fl Nice Virtual Resident %M Time Child %C" :
Flg.flg_d ?
" Files PageFaults Swap BlockI/O Kbytsecs" : "" ) ;
if ( Flg.flg_f )
printf( " Ppid#" ) ;
if ( Flg.flg_g )
printf( " Pgrp#" ) ;
printf( " Command\n" ) ;
}
SHAR_EOF
if test 438 -ne "`wc -c < 'prheader.c'`"
then
echo shar: error transmitting "'prheader.c'" '(should have been 438 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'printall.c'" '(430 characters)'
if test -f 'printall.c'
then
echo shar: will not over-write existing file "'printall.c'"
else
sed 's/^X//' << \SHAR_EOF > 'printall.c'
# include <stdio.h>
# include "sps.h"
/* PRINTALL - Recursively print the process tree. */
printall ( p, md )
register struct process *p ;
register int md ;
{
while ( p )
{ /* Print this process */
printproc( p, md ) ;
(void)fflush( stdout ) ;
/* Print child processes */
printall( p->pr_child, md+1 ) ;
/* Print brother processes */
p = p->pr_sibling ;
}
}
SHAR_EOF
if test 430 -ne "`wc -c < 'printall.c'`"
then
echo shar: error transmitting "'printall.c'" '(should have been 430 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'printproc.c'" '(5844 characters)'
if test -f 'printproc.c'
then
echo shar: will not over-write existing file "'printproc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'printproc.c'
# include "sps.h"
# include "flags.h"
# include <h/text.h>
/* PRINTPROC - Pretty print a process according to the switches. */
printproc ( p, md )
register struct process *p ;
int md ;
{
register char *chp ;
register struct text *tp ;
register struct hashtab *hp ;
char chbuf[10] ;
time_t time ;
time_t chtime ;
# ifdef BSD42
time_t utime ;
time_t uchtime ;
# endif
extern short Lastuid, Lastpgrp ;
extern struct flags Flg ;
char *waitingfor() ;
struct hashtab *hashuid() ;
double percentmem() ;
/* List tty name and foreground/background/detached information */
printf( "%2.2s%c", p->pr_tty->l_name,
!p->pr_p.p_pgrp ? ' ' :
# ifdef SDETACH
p->pr_p.p_flag & SDETACH ? '_' :
# endif
p->pr_p.p_pgrp == p->pr_tty->l_pgrp ? '.' : ' ' ) ;
hp = hashuid( p->pr_p.p_uid ) ;
if ( !md )
{ /* If a top-level process, list the user name */
if ( hp )
printf( "%-8.8s ", hp->h_uname ) ;
else
printf( "user%-4.4d ", p->pr_p.p_uid ) ;
}
else
{ /* Usually list an asterisk for a child process */
md = md > 8 ? 8 : md ;
printf( "%*s%c", md, "",
p->pr_p.p_pgrp == Lastpgrp ? '|' : '*' ) ;
/* But beware of setuid processes */
md = 8 - md ;
if ( p->pr_p.p_uid == Lastuid )
printf( "%-*.*s", md, md, "" ) ;
else if ( hp )
printf( "%-*.*s", md, md, hp->h_uname ) ;
else
{
md -= 4 ;
printf( "user%-*.*d", md, md, p->pr_p.p_uid ) ;
}
}
Lastuid = p->pr_p.p_uid ;
Lastpgrp = p->pr_p.p_pgrp ;
if ( Flg.flg_d )
{ /* List disc I/O and paging information */
if ( !p->pr_upag || p->pr_p.p_stat == SZOMB )
{
prcmd( p, 49, -63 ) ;
return ;
}
printf( "%2d %8d+%8d %4d %8d %8D ",
p->pr_files,
# ifdef BSD42
p->pr_rself.ru_majflt,
p->pr_rself.ru_minflt,
p->pr_rself.ru_nswap,
p->pr_rself.ru_inblock + p->pr_rself.ru_oublock,
KBYTES( p->pr_rself.ru_idrss + p->pr_rself.ru_isrss
+ p->pr_rself.ru_ixrss ) ) ;
# else
p->pr_vself.vm_majflt,
p->pr_vself.vm_minflt,
p->pr_vself.vm_nswap,
p->pr_vself.vm_inblk + p->pr_vself.vm_oublk,
KBYTES( (p->pr_vself.vm_idsrss
+ p->pr_vself.vm_ixrss) / Info.i_hz ) ) ;
# endif
prcmd( p, 5, -63 ) ;
return ;
}
if ( !Flg.flg_v )
{ /* Not verbose so just list command arguments */
prcmd( p, 5, -19 ) ;
return ;
}
/* Arrive here if being verbose ; list cpu information */
switch ( p->pr_p.p_stat )
{
case SSLEEP :
case SWAIT :
case SIDL :
/* Determine why a process should be in a wait state */
chp = waitingfor( p ) ;
break ;
case SRUN :
chp = "run" ;
break ;
case SZOMB :
chp = "exit" ;
break ;
case SSTOP :
chp = "stop" ;
break ;
}
/* If the process is loaded, list the status information in capitals */
printf( "%-6.6s ", p->pr_p.p_flag & SLOAD ?
(capitals( chp, chbuf ), chbuf) : chp ) ;
/* List process flags */
printf( "%c%c%c", p->pr_p.p_flag & SSYS ? 'U' :
p->pr_p.p_flag & STRC ? 'T' : ' ',
p->pr_p.p_flag & SVFORK ? 'V' :
p->pr_p.p_flag & SPHYSIO ? 'I' : ' ',
p->pr_p.p_flag & SUANOM ? 'A' : ' ' ) ;
/* List process niceness */
if ( p->pr_p.p_nice != NZERO )
printf( "%3d ", p->pr_p.p_nice - NZERO ) ;
else
printf( " " ) ;
if ( p->pr_p.p_stat == SZOMB )
{
prcmd( p, 41, -69 ) ;
return ;
}
/* List process and text virtual sizes */
printf( "%4d", KBYTES( p->pr_p.p_dsize + p->pr_p.p_ssize ) ) ;
if ( tp = p->pr_p.p_textp )
printf( "+%3d ", KBYTES( tp->x_size ) ) ;
else
printf( " " ) ;
/* List process and text real sizes */
printf( "%4d", KBYTES( p->pr_p.p_rssize ) ) ;
if ( tp )
printf( "+%3d %2.0f ", KBYTES( tp->x_rssize ),
percentmem( p ) );
else
printf( " " ) ;
/* List information obtained from the upage. This includes the process
times and command arguments. */
if ( !p->pr_upag )
{
prcmd( p, 20, -69 ) ;
return ;
}
/* List process time information */
# ifdef BSD42
time = Flg.flg_q ? p->pr_rself.ru_utime.tv_sec :
p->pr_rself.ru_utime.tv_sec + p->pr_rself.ru_stime.tv_sec ;
utime = Flg.flg_q ? p->pr_rself.ru_utime.tv_usec :
p->pr_rself.ru_utime.tv_usec + p->pr_rself.ru_stime.tv_usec ;
chtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_sec :
p->pr_rchild.ru_utime.tv_sec + p->pr_rchild.ru_stime.tv_sec ;
uchtime = Flg.flg_q ? p->pr_rchild.ru_utime.tv_usec :
p->pr_rchild.ru_utime.tv_usec + p->pr_rchild.ru_stime.tv_usec ;
prcpu( time, utime ) ;
if ( chtime != 0L )
{
printf( "+" ) ;
prcpu( chtime, uchtime ) ;
}
# else
time = Flg.flg_q ? p->pr_vself.vm_utime :
p->pr_vself.vm_utime + p->pr_vself.vm_stime ;
chtime = Flg.flg_q ? p->pr_vchild.vm_utime :
p->pr_vchild.vm_utime + p->pr_vchild.vm_stime ;
prcpu( time ) ;
if ( chtime != 0L )
{
printf( "+" ) ;
prcpu( chtime ) ;
}
# endif
else
printf( " " ) ;
# ifdef BSD42
if ( time || utime )
# else
if ( time )
# endif
# ifdef SUN
printf( " %2.0f ", (double)p->pr_p.p_pctcpu ) ;
# else
printf( " %2.0f ", p->pr_p.p_pctcpu * 100.0 ) ;
# endif
else
printf( " " ) ;
/* Finally, list the process command arguments. */
prcmd( p, 5, -69 ) ;
}
/* CAPITALS - Converts letters in `chp' to upper-case in buffer `buf'. */
capitals ( chp, buf )
register char *chp ;
register char *buf ;
{
while ( *buf = *chp++ )
{
if ( 'a' <= *buf && *buf <= 'z' )
*buf -= 'a' - 'A' ;
buf++ ;
}
}
SHAR_EOF
if test 5844 -ne "`wc -c < 'printproc.c'`"
then
echo shar: error transmitting "'printproc.c'" '(should have been 5844 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'prsummary.c'" '(632 characters)'
if test -f 'prsummary.c'
then
echo shar: will not over-write existing file "'prsummary.c'"
else
sed 's/^X//' << \SHAR_EOF > 'prsummary.c'
# include "sps.h"
/* PRSUMMARY - Print the summarising information */
prsummary ()
{
extern struct summary Summary ;
printf(
"%D (%Dk) processes, %D (%Dk) busy, %D (%Dk) loaded, %D (%Dk) swapped\n",
Summary.sm_ntotal, KBYTES( Summary.sm_ktotal ),
Summary.sm_nbusy, KBYTES( Summary.sm_kbusy ),
Summary.sm_nloaded, KBYTES( Summary.sm_kloaded ),
Summary.sm_nswapped, KBYTES( Summary.sm_kswapped ) ) ;
Summary.sm_ntotal = 0L ;
Summary.sm_ktotal = 0L ;
Summary.sm_nbusy = 0L ;
Summary.sm_kbusy = 0L ;
Summary.sm_nloaded = 0L ;
Summary.sm_kloaded = 0L ;
Summary.sm_nswapped = 0L ;
Summary.sm_kswapped = 0L ;
}
SHAR_EOF
if test 632 -ne "`wc -c < 'prsummary.c'`"
then
echo shar: error transmitting "'prsummary.c'" '(should have been 632 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'readstatus.c'" '(1170 characters)'
if test -f 'readstatus.c'
then
echo shar: will not over-write existing file "'readstatus.c'"
else
sed 's/^X//' << \SHAR_EOF > 'readstatus.c'
# include "sps.h"
# include <h/text.h>
/* READSTATUS - Reads the kernel memory for current processes and texts */
readstatus ( process, text )
register struct process *process ;
struct text *text ;
{
register struct proc *p ;
register struct proc *p0 ;
register struct process *pr ;
extern struct info Info ;
extern int Flkmem ;
char *getcore() ;
/* Read current text information */
memseek( Flkmem, (long)Info.i_text0 ) ;
if ( read( Flkmem, (char*)text, Info.i_ntext * sizeof( struct text ) )
!= Info.i_ntext * sizeof( struct text ) )
prexit( "sps - Can't read system text table\n" ) ;
/* Read current process information */
p0 = (struct proc*)getcore( sizeof( struct proc )*Info.i_nproc ) ;
memseek( Flkmem, (long)Info.i_proc0 ) ;
if ( read( Flkmem, (char*)p0, Info.i_nproc * sizeof( struct proc ) )
!= Info.i_nproc * sizeof( struct proc ) )
prexit( "sps - Can't read system process table\n" ) ;
/* Copy process information into our own array */
for ( p = p0, pr = process ; pr < &process[ Info.i_nproc ] ; p++, pr++ )
pr->pr_p = *p ;
free( (char*)p0 ) ;
}
SHAR_EOF
if test 1170 -ne "`wc -c < 'readstatus.c'`"
then
echo shar: error transmitting "'readstatus.c'" '(should have been 1170 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'selectproc.c'" '(1587 characters)'
if test -f 'selectproc.c'
then
echo shar: will not over-write existing file "'selectproc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'selectproc.c'
# include "sps.h"
# include "flags.h"
/*
** SELECTPROC - Given a process structure, this procedure decides whether
** the process is a candidate for printing.
*/
selectproc ( p, process, thisuid )
register struct process *p ;
register struct process *process ;
int thisuid ;
{
register union flaglist *fp ;
register struct process *pp ;
extern struct flags Flg ;
/* Flg.flg_AZ is an internal flag set if one of flags `A' to `Z'
was specified. If this is not set, a process is listed only
if it or one of its ancestors belongs to the invoking user. */
if ( !Flg.flg_AZ )
for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
if ( thisuid == pp->pr_p.p_uid )
return ( 1 ) ;
if ( Flg.flg_A )
return ( 1 ) ;
if ( Flg.flg_P )
for ( fp = Flg.flg_Plist ; fp->f_pid >= 0 ; fp++ )
if ( fp->f_pid == p->pr_p.p_pid )
return ( 1 ) ;
if ( Flg.flg_U )
for ( pp = p ; pp > &process[1] ; pp = pp->pr_pptr )
for ( fp = Flg.flg_Ulist ; fp->f_uid >= 0 ; fp++ )
if ( fp->f_uid == pp->pr_p.p_uid )
return ( 1 ) ;
switch ( p->pr_p.p_stat )
{
case SRUN :
if ( Flg.flg_B )
return ( 1 ) ;
break ;
case SSLEEP :
if ( Flg.flg_B
&& p->pr_p.p_pri < PZERO && p->pr_p.p_pid > MSPID )
return ( 1 ) ;
case SWAIT :
case SIDL :
if ( Flg.flg_W )
return ( 1 ) ;
break ;
case SSTOP :
if ( Flg.flg_S )
return ( 1 ) ;
break ;
case SZOMB :
if ( Flg.flg_Z )
return ( 1 ) ;
break ;
default :
break ;
}
return ( 0 ) ;
}
SHAR_EOF
if test 1587 -ne "`wc -c < 'selectproc.c'`"
then
echo shar: error transmitting "'selectproc.c'" '(should have been 1587 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'selecttty.c'" '(368 characters)'
if test -f 'selecttty.c'
then
echo shar: will not over-write existing file "'selecttty.c'"
else
sed 's/^X//' << \SHAR_EOF > 'selecttty.c'
# include "sps.h"
# include "flags.h"
/* SELECTTTY - Decides whether this process is interesting for its tty */
selecttty ( p )
register struct process *p ;
{
register union flaglist *fp ;
extern struct flags Flg ;
for ( fp = Flg.flg_Tlist ; fp->f_ttyline ; fp++ )
if ( fp->f_ttyline == p->pr_tty )
return ( 1 ) ;
return ( 0 ) ;
}
SHAR_EOF
if test 368 -ne "`wc -c < 'selecttty.c'`"
then
echo shar: error transmitting "'selecttty.c'" '(should have been 368 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'sps.h'" '(6468 characters)'
if test -f 'sps.h'
then
echo shar: will not over-write existing file "'sps.h'"
else
sed 's/^X//' << \SHAR_EOF > 'sps.h'
# include <h/param.h>
# include <h/dir.h>
# include <h/user.h>
# include <h/proc.h>
/*
** Maximum # of users to be considered. (Should probably be
** approximately double the # of users in /etc/passwd.)
*/
# define MAXUSERID 100
/* Maximum # ttys to be considered ... */
# define MAXTTYS 60
/* Maximum user name length ... */
# define UNAMELEN 8
/* Maximum process-id not to be considered busy ... */
# define MSPID 2
/* # of wait states defined in the `struct info' ... */
# define NWAITSTATE 36
/* Convert clicks to kbytes ... */
# ifdef SUN
# define KBYTES( size ) ((size) << 1)
# else
# define KBYTES( size ) ((size) >> (10 - PGSHIFT))
# endif
/* Standard files to be examined ... */
# define FILE_MEM "/dev/mem" /* System physical memory */
# define FILE_KMEM "/dev/kmem" /* Kernel virtual memory */
# define FILE_SWAP "/dev/drum" /* Swap/paging device */
# define FILE_DEV "/dev" /* Directory of tty entries */
# define FILE_SYMBOL "/vmunix" /* Symbol file for nlist() */
# define FILE_INFO "/etc/spsinfo" /* Sps information file */
/* Structure to hold necessary information concerning a tty ... */
struct ttyline
{
struct tty *l_addr ; /* Ptr to tty struct in kmem */
unsigned short l_pgrp ; /* Tty process group */
char l_name[2] ; /* Tty character name */
dev_t l_dev ; /* Tty device # */
} ;
/* Structure holding a single hash table entry ... */
struct hashtab
{
unsigned short h_uid ; /* Uid of user entry */
char h_uname[ UNAMELEN ] ; /* Corresponding name */
} ;
/*
** Format of the standard information file maintained by sps.
** This structure is filled in at initialisation time and then is read back
** in whenever sps is invoked.
** Note that the pointer variables in this structure refer to
** kernel virtual addresses, not addresses within sps.
** These variable are typed as such so that pointer arithmetic
** on the kernel addresses will work correctly.
*/
struct info
{ /* Kernel values determining process, tty and upage info ... */
struct proc *i_proc0 ; /* address of process table */
int i_nproc ; /* length of process table */
struct text *i_text0 ; /* address of text table */
int i_ntext ; /* length of text table */
struct inode *i_inode0 ; /* address of inode table */
int i_ninode ; /* length of inode table */
struct buf *i_swbuf0 ; /* address of swap buffers */
int i_nswbuf ; /* # swap buffers */
struct buf *i_buf0 ; /* address of i/o buffers */
int i_nbuf ; /* # i/o buffers */
int i_ecmx ; /* max physical memory address*/
struct pte *i_usrptmap ; /* page table map */
struct pte *i_usrpt ; /* page table map */
struct cdevsw *i_cdevsw ; /* device switch to find ttys */
# ifdef BSD42
struct quota *i_quota0 ; /* disc quota structures */
int i_nquota ; /* # quota structures */
int i_dmmin ; /* The start of the disc map */
int i_dmmax ; /* The end of the disc map */
struct mbuf *i_mbutl ; /* Start of mbuf area */
# else
int i_hz ; /* Clock rate */
# endif
# ifdef CHAOS
caddr_t i_Chconntab ; /* Chaos connection table */
# endif
/* Kernel addresses are associated with process wait states ... */
caddr_t i_waitstate[ NWAITSTATE ] ;
/* User names, stored in a hash table ... */
struct hashtab i_hnames[ MAXUSERID ] ;
/* Tty device info ... */
struct ttyline i_ttyline[ MAXTTYS ] ;
} ;
/*
** The symbol structure cross-references values read from the kernel with
** their place in the info structure, and if such a value is associated with
** a process wait state or not.
*/
struct symbol
{
char *s_kname ; /* Kernel symbol name */
char s_indirect ; /* Value requires indirection */
caddr_t *s_info ; /* Corresponding info address */
char *s_wait ; /* Reason for wait, if any */
} ;
/* The `user' structure obtained from /dev/mem or /dev/swap ... */
union userstate
{
struct user u_us ;
char u_pg[ UPAGES ][ NBPG ] ;
} ;
/* Information concerning each process filled from /dev/kmem ... */
struct process
{
struct proc pr_p ; /* struct proc from /dev/kmem */
struct process *pr_plink ; /* Normalised ptrs from above */
struct process *pr_sibling ; /* Ptr to sibling process */
struct process *pr_child ; /* Ptr to child process */
struct process *pr_pptr ; /* Ptr to parent process */
# ifdef BSD42
struct rusage pr_rself ; /* Read from upage for self */
struct rusage pr_rchild ; /* ... and the children */
# else
struct vtimes pr_vself ; /* Read from upage for self */
struct vtimes pr_vchild ; /* ... and the children */
# endif
int pr_files ; /* # open files */
struct ttyline *pr_tty ; /* Associated tty information */
char *pr_cmd ; /* Command args, from upage */
int pr_upag:1 ; /* Upage was obtained */
int pr_csaved:1 ; /* Cmd args saved by malloc() */
} ;
/* Structure to hold summarising information ... */
struct summary
{
long sm_ntotal ; /* Total # processes */
long sm_ktotal ; /* Total virtual memory */
long sm_nbusy ; /* # busy processes */
long sm_kbusy ; /* Busy virtual memory */
long sm_nloaded ; /* # loaded processes */
long sm_kloaded ; /* Active resident memory */
long sm_nswapped ; /* # swapped processes */
long sm_kswapped ; /* Size totally swapped out */
} ;
SHAR_EOF
if test 6468 -ne "`wc -c < 'sps.h'`"
then
echo shar: error transmitting "'sps.h'" '(should have been 6468 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'termwidth.c'" '(490 characters)'
if test -f 'termwidth.c'
then
echo shar: will not over-write existing file "'termwidth.c'"
else
sed 's/^X//' << \SHAR_EOF > 'termwidth.c'
/*
** TERMWIDTH - Sets the external variable `Termwidth' to the # of columns
** on the terminal.
*/
termwidth ()
{
register char *termtype ;
register int twidth ;
char buf[ 1025 ] ;
extern unsigned Termwidth ;
char *getenv() ;
Termwidth = 80 ;
if ( !(termtype = getenv( "TERM" )) )
return ;
if ( tgetent( buf, termtype ) != 1 )
return ;
twidth = tgetnum( "co" ) ;
if ( twidth > 40 )
Termwidth = twidth ;
}
SHAR_EOF
if test 490 -ne "`wc -c < 'termwidth.c'`"
then
echo shar: error transmitting "'termwidth.c'" '(should have been 490 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ttystatus.c'" '(2883 characters)'
if test -f 'ttystatus.c'
then
echo shar: will not over-write existing file "'ttystatus.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ttystatus.c'
# include "sps.h"
# include "flags.h"
# include <stdio.h>
# include <h/tty.h>
# ifdef CHAOS
# include <chunix/chsys.h>
# include <chaos/chaos.h>
# endif
/*
** TTYSTATUS - Reads the kernel memory for tty structures of active processes.
** The addresses of the associated struct ttys of /dev/kmem are kept in the
** info structure. Here we use those addresses to access the structures.
** Actually, we are mostly interested just in the process group of each tty.
*/
ttystatus ()
{
register struct ttyline *lp ;
struct tty tty ;
extern struct flags Flg ;
extern struct info Info ;
extern int Flkmem ;
if ( Flg.flg_y )
printf( "Ty Dev Addr Rawq Canq Outq Pgrp\n" ) ;
lp = Info.i_ttyline ;
# ifdef CHAOS
while ( lp->l_name[0] && lp->l_name[0] != 'C' )
# else
while ( lp->l_name[0] )
# endif
{
memseek( Flkmem, (long)lp->l_addr ) ;
if ( read( Flkmem, (char*)&tty, sizeof( struct tty ) )
!= sizeof( struct tty ) )
{
fprintf( stderr,
"sps - Can't read struct tty for tty%.2s\n",
lp->l_name ) ;
lp->l_pgrp = 0 ;
lp++ ;
continue ;
}
lp->l_pgrp = tty.t_pgrp ;
prtty( lp, &tty ) ;
lp++ ;
}
# ifdef CHAOS
chaosttys( lp ) ;
# endif
}
/* PRTTY - Print out the tty structure */
prtty ( lp, tty )
register struct ttyline *lp ;
register struct tty *tty ;
{
extern struct flags Flg ;
if ( !Flg.flg_y )
return ;
printf( "%-2.2s %2d,%2d 0x%08x %4d %4d %4d %5d\n",
lp->l_name,
major( lp->l_dev ),
minor( lp->l_dev ),
lp->l_addr,
tty->t_rawq.c_cc,
tty->t_canq.c_cc,
tty->t_outq.c_cc,
tty->t_pgrp ) ;
}
# ifdef CHAOS
/* CHAOSTTYS - Finds ttys attached to the Chaos net */
chaosttys ( lp )
register struct ttyline *lp ;
{
register struct connection **cnp ;
register int i ;
struct tty tty ;
struct connection *conntab[CHNCONNS] ;
struct connection conn ;
extern struct info Info ;
extern int Flkmem ;
memseek( Flkmem, (long)Info.i_Chconntab ) ;
(void)read( Flkmem, (char*)conntab, sizeof( conntab ) ) ;
for ( i = 0, cnp = conntab ; cnp < &conntab[CHNCONNS] ; i++, cnp++ )
{
if ( !*cnp )
continue ;
memseek( Flkmem, (long)*cnp ) ;
(void)read( Flkmem, (char*)&conn, sizeof( struct connection ) );
if ( !(conn.cn_flags & CHTTY) )
continue ;
memseek( Flkmem, (long)conn.cn_ttyp ) ;
(void)read( Flkmem, (char*)&tty, sizeof( struct tty ) ) ;
if ( lp >= &Info.i_ttyline[MAXTTYS] )
prexit( "sps - Too many chaos ttys\n" ) ;
lp->l_addr = conn.cn_ttyp ;
lp->l_pgrp = tty.t_pgrp ;
lp->l_dev = tty.t_dev ;
lp->l_name[0] = 'C' ;
lp->l_name[1] = i < 10 ? '0'+i : i-10 <= 'z'-'a' ? i-10+'a' :
i-10-('z'-'a')+'A' ;
prtty( lp, &tty ) ;
lp++ ;
}
}
# endif
SHAR_EOF
if test 2883 -ne "`wc -c < 'ttystatus.c'`"
then
echo shar: error transmitting "'ttystatus.c'" '(should have been 2883 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'waitingfor.c'" '(5822 characters)'
if test -f 'waitingfor.c'
then
echo shar: will not over-write existing file "'waitingfor.c'"
else
sed 's/^X//' << \SHAR_EOF > 'waitingfor.c'
# include "sps.h"
# include <h/tty.h>
# include <h/text.h>
# ifdef SUN
# include <h/vnode.h>
# include <ufs/inode.h>
# else
# include <h/inode.h>
# endif
# include <h/buf.h>
# ifdef BSD42
# include <h/quota.h>
# include <h/mbuf.h>
# include <h/socket.h>
# include <h/socketvar.h>
# endif
/* 1 if `w' is in the address range defined by `a1' and `a2' ... */
# define INRANGE( w, a1, a2 ) \
( (caddr_t)(a1) <= (w) && (w) < (caddr_t)(a2) )
/* WAITINGFOR - Determine what a process is waiting for and describe it. */
char *waitingfor ( p )
struct process *p ;
{
register caddr_t w ;
register struct ttyline *lp ;
register struct symbol *s ;
register char *cp ;
# ifdef BSD42
struct socket sc ;
# endif
static char wbuf[ 8 ] ;
extern struct info Info ;
extern struct symbol Symbollist[] ;
char *sprintf() ;
w = p->pr_p.p_wchan ;
if ( !w )
return ( "null" ) ;
/* Waiting for a child process, alternatively in a vfork() ? */
if ( INRANGE( w, Info.i_proc0, &Info.i_proc0[ Info.i_nproc ] ) )
return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
/* Waiting for a page to be brought in ? */
if ( INRANGE( w, Info.i_swbuf0, &Info.i_swbuf0[ Info.i_nswbuf ] ) )
return ( "swap" ) ;
/* Waiting for discio through a block device to complete ? */
if ( INRANGE( w, Info.i_buf0, &Info.i_buf0[ Info.i_nbuf ] ) )
/* SHOULD ACTUALLY READ AS "blkio" BUT "discio" IS WHAT
IS GENERALLY MEANT HERE. */
return ( "discio" ) ;
/* Waiting for a text page to be brought in ? */
if ( INRANGE( w, Info.i_text0, &Info.i_text0[ Info.i_ntext ] ) )
return ( "swtext" ) ;
# ifdef BSD42
/* Waiting for an event associated with the quota system ? */
if ( INRANGE( w, Info.i_quota0, &Info.i_quota0[ Info.i_nquota ] ) )
return ( "quota" ) ;
# endif
/* Waiting for tty I/O ? If so, find which tty it is */
for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
if ( INRANGE( w, &lp->l_addr[0], &lp->l_addr[1] ) )
{
switch ( w - (int)lp->l_addr )
{
case (int)&((struct tty*)0)->t_rawq :
/* Read from a tty or slave pty */
cp = "rtty??" ;
break ;
case (int)&((struct tty*)0)->t_outq :
/* Write to a tty or slave pty */
cp = "wtty??" ;
break ;
case (int)&((struct tty*)0)->t_state :
/* Tty not open */
cp = "otty??" ;
break ;
case (int)&((struct tty*)0)->t_outq.c_cf :
/* Read from a controller pty */
cp = "rpty??" ;
break ;
case (int)&((struct tty*)0)->t_rawq.c_cf :
/* Write to a controller pty */
cp = "wpty??" ;
break ;
default :
cp = "?tty??" ;
break ;
}
cp[4] = lp->l_name[0] ;
cp[5] = lp->l_name[1] ;
return ( cp ) ;
}
/* Waiting for an inode ? */
if ( INRANGE( w, Info.i_inode0, &Info.i_inode0[ Info.i_ninode ] ) )
switch ( ((int)w - (int)Info.i_inode0) % sizeof( struct inode ))
{
# ifdef BSD42
# ifndef SUN
case (int)&((struct inode*)0)->i_exlockc :
/* Exclusive lock on this inode */
return ( "exlock" ) ;
case (int)&((struct inode*)0)->i_shlockc :
/* Shared lock on this inode */
return ( "shlock" ) ;
# endif
# else
case 1 :
return ( "wpipe" ) ;
case 2 :
return ( "rpipe" ) ;
case (int)&((struct inode*)0)->i_un.i_group.g_datq :
return ( "rmux" ) ;
# endif
default :
/* Inode probably locked */
return ( "inode" ) ;
}
# ifdef BSD42
/* Waiting for a structure inside an mbuf ? If so, try to find why */
if ( INRANGE( w, Info.i_mbutl,
&Info.i_mbutl[ NMBCLUSTERS * CLBYTES / sizeof( struct mbuf ) ] ) )
switch ( ((int)w - (int)Info.i_mbutl) % sizeof( struct mbuf )
- (int)&((struct mbuf*)0)->m_dat[0] )
{
case (int)&((struct socket*)0)->so_timeo :
/* Socket timeout event */
return ( "socket" ) ;
case (int)&((struct socket*)0)->so_rcv.sb_cc :
/* Read from an empty socket. Here we actually
attempt to determine whether the socket
structure in question really does refer to
a socket, or whether it is in fact a pipe
in disguise. */
return ( getsocket( (struct socket*)(w
- (int)&((struct socket*)0)->so_rcv.sb_cc),
&sc )
&& sc.so_type == SOCK_STREAM
&& !sc.so_rcv.sb_hiwat
&& !sc.so_rcv.sb_mbmax
&& (sc.so_state
& (SS_ISCONNECTED|SS_CANTRCVMORE))
? "rpipe" : "rsockt" ) ;
case (int)&((struct socket*)0)->so_snd.sb_cc :
/* Write to a full socket. Again, we try
to determine whether or not this is a
real socket or a pipe. */
return ( getsocket( (struct socket*)(w
- (int)&((struct socket*)0)->so_snd.sb_cc),
&sc )
&& sc.so_type == SOCK_STREAM
&& sc.so_rcv.sb_hiwat == 2048
&& sc.so_rcv.sb_mbmax == 4096
&& (sc.so_state
& (SS_ISCONNECTED|SS_CANTSENDMORE))
? "wpipe" : "wsockt" ) ;
default :
/* Other mbuf event */
return ( "mbuf" ) ;
}
# endif
/* Look in the symbol table for known wait addresses. */
for ( s = Symbollist ; s->s_kname ; s++ )
if ( s->s_wait && w == *s->s_info )
return ( s->s_wait ) ;
/* No reason for the wait state has been found.
Return the wait channel as a hexadecimal address. */
# ifdef SUN
(void)sprintf( wbuf, "x%05x", w ) ;
# else
(void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
# endif
return ( wbuf ) ;
}
# ifdef BSD42
/*
** GETSOCKET - Reads a `struct socket' from the kernel virtual memory address
** identified by `ks' into the buffer `s'.
*/
getsocket ( ks, s )
struct socket *ks ;
struct socket *s ;
{
extern int Flkmem ;
memseek( Flkmem, (long)ks ) ;
return ( read( Flkmem, (char*)s, sizeof( struct socket ) )
== sizeof( struct socket ) ) ;
}
# endif
SHAR_EOF
if test 5822 -ne "`wc -c < 'waitingfor.c'`"
then
echo shar: error transmitting "'waitingfor.c'" '(should have been 5822 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Mod.sources
mailing list