Reposting of SPS for 4.[12]bsd Vaxen - Shar 4 of 4
Robert Ward
robert at hslrswi.UUCP
Thu Jul 11 12:36:20 AEST 1985
Send comments, suggestions, bug reports, bug fixes, etc. to -
Robert Ward, Hasler AG, Abt. 34, Belpstrasse 23, CH-3000 Bern 14, Switzerland.
(... mcvax!cernvax!hslrswi!robert).
*******************************************************************************
This is a sh(1) archive.
In order to extract the contents of this shar, use an editor to place
the contents of this file from the dotted line onwards into a second,
temporary file. Then run sh on that second file.
--------------------------------- C U T --- H E R E ---------------------------
#! /bin/sh
echo Extracting printproc.c
cat > printproc.c << '---END-OF-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
printf( " %2.0f ", p->pr_p.p_pctcpu * 100.0 ) ;
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++ ;
}
}
---END-OF-printproc.c---
echo Extracting prsummary.c
cat > prsummary.c << '---END-OF-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 ;
}
---END-OF-prsummary.c---
echo Extracting readstatus.c
cat > readstatus.c << '---END-OF-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 ) ;
}
---END-OF-readstatus.c---
echo Extracting selectproc.c
cat > selectproc.c << '---END-OF-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 ) ;
}
---END-OF-selectproc.c---
echo Extracting selecttty.c
cat > selecttty.c << '---END-OF-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 ) ;
}
---END-OF-selecttty.c---
echo Extracting sps.h
cat > sps.h << '---END-OF-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 50
/* 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 35
/* Convert clicks to kbytes ... */
# define KBYTES( size ) ((size) >> (10 - PGSHIFT))
/* 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 */
} ;
---END-OF-sps.h---
echo Extracting termwidth.c
cat > termwidth.c << '---END-OF-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 ;
}
---END-OF-termwidth.c---
echo Extracting ttystatus.c
cat > ttystatus.c << '---END-OF-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
---END-OF-ttystatus.c---
echo Extracting waitingfor.c
cat > waitingfor.c << '---END-OF-waitingfor.c---'
# include "sps.h"
# include <h/tty.h>
# include <h/text.h>
# include <h/inode.h>
# 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
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" ) ;
# 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. */
(void)sprintf( wbuf, "x%05x", w - 0x80000000 ) ;
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
---END-OF-waitingfor.c---
More information about the Comp.sources.unix
mailing list