home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-08 | 43.1 KB | 1,526 lines |
- Newsgroups: comp.sources.unix
- From: robert@olsen.ch (Robert Ward)
- Subject: v26i026: sps3 - show process status, Part03/03
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: robert@olsen.ch (Robert Ward)
- Posting-Number: Volume 26, Issue 26
- Archive-Name: sps3/part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 3)."
- # Contents: getcmd.c printproc.c sps.1 waitingfor.c
- # Wrapped by vixie@cognition.pa.dec.com on Sat May 9 22:30:50 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'getcmd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'getcmd.c'\"
- else
- echo shar: Extracting \"'getcmd.c'\" \(7639 characters\)
- sed "s/^X//" >'getcmd.c' <<'END_OF_FILE'
- X# ifndef lint
- static char SccsId[] = "@(#)getcmd.c 1.8\t6/26/91" ;
- X# endif
- X
- X# include "sps.h"
- X# include "flags.h"
- X# ifdef KVM
- X# include <kvm.h>
- X# include <ctype.h>
- X# else
- X# include <h/vm.h>
- X# ifdef BSD42
- X# include <machine/pte.h>
- X# else BSD42
- X# include <h/pte.h>
- X# endif BSD42
- X# endif KVM
- X
- X/*
- X** GETCMD - Returns a character string read from a process' upage.
- X** This character string should represent the arguments to the current process.
- X*/
- char *getcmd ( p )
- X
- register struct process *p ;
- X
- X{
- X# ifdef KVM
- X char **ap ;
- X char *cp ;
- X char *sp ;
- X int spsize ;
- X char **argv ;
- X char **env ;
- X extern kvm_t *Flkvm ;
- X# else
- X register int *ip ;
- X register char *cp ;
- X register char *cp0 ;
- X struct dblock db ;
- X struct pte ptetbl[ UPAGES + CLSIZE ] ;
- X extern int Flmem, Flswap ;
- X# endif
- X unsigned nbad ;
- X union
- X {
- X char a_argc[ CLSIZE * NBPG ] ;
- X int a_argi[ CLSIZE * NBPG / sizeof( int ) ] ;
- X } argbuf ;
- X extern struct flags Flg ;
- X extern union userstate User ;
- X char *strcat(), *strncpy(), *strsave() ;
- X
- X p->pr_csaved = 0 ;
- X p->pr_upag = 0 ;
- X if ( p->pr_p.p_stat == SZOMB )
- X return ( "** Exit **" ) ;
- X# ifdef ULTRIX40
- X if ( !(p->pr_p.p_sched & SLOAD) && Flg.flg_o )
- X# else
- X if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o )
- X# endif
- X return ( "** Swapped out **" ) ;
- X /* Find the process' upage */
- X# ifdef KVM
- X if ( !getupage( p ) )
- X# else
- X if ( !getupage( p, ptetbl ) )
- X# endif
- X return ( "** No upage **" ) ;
- X p->pr_upag = 1 ;
- X /* Is this a system process ? */
- X# ifdef ULTRIX40
- X if ( p->pr_p.p_type & SSYS )
- X# else
- X if ( p->pr_p.p_flag & SSYS )
- X# endif
- X switch ( p->pr_p.p_pid )
- X {
- X case 0 :
- X return ( "Unix Swapper" ) ;
- X case 2 :
- X return ( "Unix Pager" ) ;
- X# ifdef SUNOS40
- X case 3 :
- X case 4 :
- X return ( "Unix Idle" ) ;
- X# endif
- X default :
- X break ;
- X }
- X# ifdef ULTRIX40
- X /* Reading the command arguments doesn't work on the DEC 3100 so
- X we resort to this kludge until one day it does. */
- X if ( 1 )
- X# else ULTRIX40
- X if ( Flg.flg_c )
- X# endif ULTRIX40
- X {
- X p->pr_csaved = 1 ;
- X (void)strncpy( argbuf.a_argc, User.u_us.u_comm,
- X sizeof( User.u_us.u_comm ) ) ;
- X argbuf.a_argc[ sizeof ( User.u_us.u_comm ) ] = '\0' ;
- X return ( strsave( argbuf.a_argc ) ) ;
- X }
- X
- X
- X# ifdef KVM
- X spsize = sizeof( argbuf ) - 2 ;
- X if ( kvm_getcmd( Flkvm, &p->pr_p, &User.u_us, &argv,
- X Flg.flg_e ? &env : (char ***)NULL ) < 0 || argv == NULL )
- X goto getsysargs ;
- X p->pr_csaved = 1 ;
- X sp = argbuf.a_argc ;
- X nbad = 0 ;
- X ap = argv ;
- X while ( ap && *ap )
- X {
- X /* Copy one string from argv or env */
- X cp = *ap++ ;
- X while ( cp && *cp )
- X if ( isprint( *cp ) )
- X /* Be careful not to overrun allocated array.
- X Fix provided by Matti E Aarnio
- X <mea@nic.funet.fi> */
- X if ( --spsize > 0 )
- X *sp++ = *cp++ ;
- X else
- X ++cp ;
- X else
- X {
- X /* Replace control characters with ?'s */
- X if ( ++nbad > 5 )
- X {
- X if ( --spsize > 0 )
- X *sp++ = ' ' ;
- X break ;
- X }
- X if ( --spsize > 0 )
- X *sp++ = '?' ;
- X cp++ ;
- X }
- X if (--spsize > 0)
- X *sp++ = ' ' ;
- X /* Check if at end of argv and user wants to see env */
- X if ( ap && *ap == 0 && Flg.flg_e && argv != 0 )
- X {
- X free( (char *) argv ) ;
- X argv = NULL ;
- X ap = env ;
- X if ( ap == NULL )
- X break ;
- X }
- X }
- X if ( Flg.flg_e )
- X free( (char*)env ) ;
- X while ( *--sp == ' ' )
- X *sp = '\0' ;
- X return ( strsave( argbuf.a_argc ) ) ;
- X# else
- X /* Fix by Alexander Dupuy <dupuy@amsterdam.columbia.edu> */
- X /* Check for lack of stack, jack! (Sun 3.0 biod's) */
- X if (User.u_us.u_ssize == 0)
- X goto getsysargs ;
- X /* Look at the top of the upage to locate the command arguments.
- X The page is loaded if the process itself is loaded and the pte
- X contains is marked as valid. */
- X# ifdef ULTRIX40
- X if ( (p->pr_p.p_sched & SLOAD)
- X# else
- X if ( (p->pr_p.p_flag & SLOAD)
- X# endif
- X && !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
- X { /* If the page is loaded, read the arguments from
- X physical memory. */
- X memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
- X if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
- X return ( "** Memory read error **" ) ;
- X }
- X else
- X { /* Otherwise the page is on the swap device */
- X# ifdef ULTRIX40
- X vstodb( 0, ctod( CLSIZE ),&p->pr_p.p_smap, &db, 1 ) ;
- X# else
- X vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
- X# endif
- X# ifdef BSD42
- X swseek( (long)dtob( db.db_base ) ) ;
- X# else
- X swseek( (long)ctob( db.db_base ) ) ;
- X# endif
- X if ( Flg.flg_o )
- X return ( "** Swapped page **" ) ;
- X if ( read( Flswap, (char *)argbuf.a_argc, CLSIZE*NBPG )
- X != CLSIZE*NBPG )
- X return ( "** Swap device read error **" ) ;
- X }
- X /* Look down until the end of command arguments is found. */
- X ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
- X ip -= 2 ;
- X while ( *--ip )
- X if ( ip == &argbuf.a_argi[0] )
- X goto getsysargs ;
- X p->pr_csaved = 1 ;
- X /* Process the command arguments, looking for nulls and unprintable
- X characters. */
- X cp0 = (char*)(ip + 1) ;
- X if ( !*cp0 )
- X cp0++ ;
- X if ( *cp0 )
- X {
- X nbad = 0 ;
- X for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
- X {
- X *cp &= 0177 ;
- X if ( !*cp )
- X { /* Replace nulls with spaces */
- X *cp = ' ' ;
- X continue ;
- X }
- X if ( *cp < ' ' || *cp == 0177 )
- X { /* Replace control characters with ?'s */
- X if ( ++nbad > 5 )
- X {
- X *cp++ = ' ' ;
- X break ;
- X }
- X *cp = '?' ;
- X continue ;
- X }
- X if ( !Flg.flg_e && *cp == '=' )
- X { /* Break on an `=' if we are not interested
- X in the environment strings. */
- X *cp = '\0' ;
- X while ( cp > cp0 && *--cp != ' ' )
- X *cp = '\0' ;
- X break ;
- X }
- X }
- X while ( *--cp == ' ' )
- X *cp = '\0' ;
- X return ( strsave( cp0 ) ) ;
- X }
- X# endif KVM
- getsysargs :
- X /* If the command arguments cannot be accessed from the user's memory
- X space, get the command name from the system's idea of what the
- X name should be. */
- X p->pr_csaved = 1 ;
- X argbuf.a_argc[0] = '(' ;
- X (void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
- X sizeof( User.u_us.u_comm ) ) ;
- X argbuf.a_argc[ sizeof ( User.u_us.u_comm ) + 1 ] = '\0' ;
- X (void)strcat( &argbuf.a_argc[0], ")" ) ;
- X return ( strsave( argbuf.a_argc ) ) ;
- X}
- X
- X# ifndef KVM
- X/*
- X** VSTODB - Given a base/size pair in virtual swap area,
- X** return a physical base/size pair which is the
- X** (largest) initial, physically contiguous block.
- X/* This code is stolen from the kernel file /sys/sys/vm_drum.c.
- X*/
- vstodb ( vsbase, vssize, dmp, dbp, rev )
- X
- register int vsbase ;
- register int vssize;
- struct dmap *dmp ;
- register struct dblock *dbp ;
- int rev ;
- X
- X{
- X register int blk ;
- X register swblk_t *ip ;
- X# ifdef BSD42
- X extern struct info Info ;
- X# endif
- X# ifndef ULTRIX40
- X# ifdef BSD42
- X blk = Info.i_dmmin ;
- X# else
- X blk = DMMIN ;
- X# endif
- X ip = dmp->dm_map ;
- X while ( vsbase >= blk )
- X {
- X vsbase -= blk ;
- X# ifdef BSD42
- X if ( blk < Info.i_dmmax )
- X# else
- X if ( blk < DMMAX )
- X# endif
- X blk *= 2 ;
- X ip++ ;
- X }
- X# else ULTRIX40
- X blk = Info.i_swapfrag ;
- X ip = dmp->dm_map ;
- X ip += (vsbase/blk) ;
- X vsbase %= blk;
- X# endif ULTRIX40
- X
- X dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
- X dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
- X}
- X# endif
- END_OF_FILE
- if test 7639 -ne `wc -c <'getcmd.c'`; then
- echo shar: \"'getcmd.c'\" unpacked with wrong size!
- fi
- # end of 'getcmd.c'
- fi
- if test -f 'printproc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'printproc.c'\"
- else
- echo shar: Extracting \"'printproc.c'\" \(7216 characters\)
- sed "s/^X//" >'printproc.c' <<'END_OF_FILE'
- X# ifndef lint
- static char SccsId[] = "@(#)printproc.c 1.4\t12/4/91" ;
- 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. */
- printproc ( p, md )
- X
- register struct process *p ;
- int 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# ifdef ULTRIX40
- X printf( "%-6.6s ", p->pr_p.p_sched & SLOAD ?
- X# else
- X printf( "%-6.6s ", p->pr_p.p_flag & SLOAD ?
- X# endif
- X (capitals( chp, chbuf ), chbuf) : chp ) ;
- X /* List process flags */
- X# ifdef ULTRIX40
- X printf( "%c%c%c", p->pr_p.p_type & SSYS ? 'U' :
- X p->pr_p.p_trace & STRC ? 'T' : ' ',
- X p->pr_p.p_vm & SVFORK ? 'V' :
- X p->pr_p.p_vm & SPHYSIO ? 'I' : ' ',
- X p->pr_p.p_vm & SUANOM ? 'A' :
- X p->pr_p.p_vm & SSEQL ? 'S' : ' ' ) ;
- X# else
- 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# endif
- 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 ULTRIX40
- X printf( " %2.0f ", p->pr_p.p_pctcpu ) ;
- X# else
- X printf( " %2.0f ", p->pr_p.p_pctcpu * 100.0 ) ;
- X# endif ULTRIX40
- 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'. */
- capitals ( chp, buf )
- X
- register char *chp ;
- register 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_FILE
- if test 7216 -ne `wc -c <'printproc.c'`; then
- echo shar: \"'printproc.c'\" unpacked with wrong size!
- fi
- # end of 'printproc.c'
- fi
- if test -f 'sps.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sps.1'\"
- else
- echo shar: Extracting \"'sps.1'\" \(15346 characters\)
- sed "s/^X//" >'sps.1' <<'END_OF_FILE'
- X.if n .pl 66
- X.TH SPS 1
- X.SH NAME
- sps \ \ \-\ \ \ 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.
- It shows the current state of any process by
- listing information such as ownership, CPU time usage, memory usage
- and disc activity.
- X.PP
- X\fISps\fP should be used in preference to \fIps\fP(1)
- because it is faster and the output is more comprehensive and more
- comprehensible.
- X.SH OPTIONS
- By default, \fIsps\fP prints basic information about one's own processes.
- The various options described below select other processes or make
- X\fIsps\fP more verbose.
- X.PP
- Upper case options select processes to be described.
- Lower case options specify the format of the output.
- XFor instance, the options \fBBv\fP specify that \fIsps\fP
- should list ``busy'' processes in a verbose format.
- Unless there is any conflict, lower case options may be used
- instead of upper case options, and vice versa.
- X.PP
- The following options specify the format of the listed output \-
- X.TP 8
- X\fB\-c\fP
- Use the system's idea of the command, rather than getting the arguments
- from user space. While somewhat less informative, this is faster and
- more reliable.
- X.TP
- X\fB\-d\fP
- List output reflecting how each process affects the
- disc and paging activity of the system.
- X.TP
- X\fB\-e\fP
- List the environment passed to each process.
- X.TP
- X\fB\-f\fP
- Include the process\-id of the parent of each process.
- X.TP
- X\fB\-g\fP
- Include the process group of each process.
- X.TP
- X\fB\-o\fP
- Avoid looking at the swap device (\fB/dev/drum\fP). This tends to make \fIsps\fP
- run faster, although no information concerning swapped processes
- can be obtained.
- X.TP
- X\fB\-q\fP
- By default, \fIsps\fP
- lists the sum of the user plus system times under the
- X\fITime\fP and \fIChild\fP fields. This option forces \fIsps\fP
- to list only the user times.
- X.TP
- X\fB\-r\fP
- Repeat the output indefinitely.
- If the next argument is numeric, \fIsps\fP repeats the output with that
- many seconds delay between each repetition.
- Otherwise the output is repeated with no delay.
- X.TP
- X\fB\-l\fP
- X.br
- X.ns
- X.TP
- X\fB\-v\fP
- List additional information in a verbose format. See below.
- X.TP
- X\fB\-w\fP
- List output in a wide format. This option forces \fIsps\fP
- to print all the command arguments, even if doing so extends the output
- beyond one line.
- X.TP
- X\fB\-y\fP
- Show the status of each terminal line.
- X.PP
- The following options specify which processes are to be described \-
- X.TP 8
- X\fB\-A\fP
- List all processes.
- X.TP
- X\fB\-B\fP
- List busy processes. A process is considered to be busy
- if it is immediately runnable or awaiting a fast event such as disc I/O.
- X.TP
- X\fB\-D\fP
- List detached processes.
- X.TP
- X\fB\-F\fP
- List foreground processes.
- X.TP
- X\fB\-N\fP
- Show no processes at all. Only the summary line is printed.
- X.TP
- X\fB\-P\fP
- List only processes whose identifiers are specified in the following arguments.
- X.TP
- X\fB\-S\fP
- List stopped processes.
- X.TP
- X\fB\-T\fP
- List only processes attached to the following specified terminals.
- X.TP
- X\fB\-U\fP
- List only processes belonging to the following specified users.
- X.TP
- X\fB\-W\fP
- List waiting processes.
- X.TP
- X\fB\-Z\fP
- List zomby (exiting) processes.
- X.PP
- The following are miscellaneous options \-
- X.TP 8
- X\fB\-i\fP
- Initialise \fIsps\fP.
- This is necessary if new users are added to the password file,
- or if a new version of UNIX is installed.
- Sps builds a new information file summarising pertinent information
- read 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).
- See also the \fB\-j\fP and \fB\-s\fP options.
- X.TP
- X\fB\-j\fP
- Specify an information file other than the default (\fB/etc/spsinfo\fP).
- The next argument is taken to be the name of a suitable information file.
- If the \fB\-i\fP flag is also specified, \fIsps\fP builds a
- new information file with the given name.
- Otherwise, \fBsps\fP reads previously created summarising information
- from that file.
- X.TP
- X\fB\-k\fP
- Use a specific disc file rather than the default physical
- memory (\fB/dev/mem\fP)
- and kernel virtual memory (\fB/dev/kmem\fP) files. The next argument is taken
- to be the name of a suitable memory dump file.
- This flag automatically sets the \fB\-o\fP flag.
- X.TP
- X\fB\-s\fP
- This option is used in conjunction with the \fB\-i\fP option.
- The next argument is taken to be the name of a suitable kernel executable
- file, rather than the default (\fB/vmunix\fP).
- X\fISps\fP looks at the symbol table of this file to determine
- the virtual addresses of various kernel structures.
- X.SH OUTPUT
- X\fISps\fP produces output in the following fields \-
- X.TP 8
- X\fITy\fP
- The terminal identifier to which the process is attached.
- X.IP
- If this is followed by an underscore, the process is detached.
- If it is followed by a period, the process is running in the foreground.
- Otherwise the process is running in the background but is still
- attached to a terminal.
- X.TP
- X\fIUser\fP
- The symbolic name of the process' effective user-id (see \fIexec\fP(2)
- and \fIsetuid\fP(2)).
- This name is defined by the system password file (\fB/etc/passwd\fP)
- when \fIsps\fP was last initialised.
- Otherwise, an asterisk (\fB*\fP) or vertical bar (\fB|\fP) appearing in this
- column denotes that the process is an immediate relative of the
- preceding process.
- A bar is listed, rather than an asterisk, if both processes belong
- to the same process group.
- A user name is listed only if the effective user-id
- differs from that of the preceding process or if it is a top-level
- process (immediate offspring of process 1).
- X.TP
- X\fIProc#\fP
- The unique process identifier.
- X.TP
- X\fIPpid#\fP
- The process-id of the process' parent.
- X.TP
- X\fIPgrp#\fP
- The process group to which the process belongs.
- X.TP
- X\fICommand\fP
- The command arguments obtained from the process' own address space.
- X(If the command name appears in parentheses, \fIsps\fP
- was unable to locate the arguments in user space and so reports
- the system's idea of the command name.)
- X.PP
- The following additional fields are listed when \fIsps\fP
- is invoked with one of the \fB\-l\fP or \fB\-v\fP options \-
- X.TP 8
- X\fIStatus\fP
- The process' current state.
- If this field is listed in upper-case letters, the process is currently
- loaded in real memory space ; otherwise it has been swapped out.
- The status field may contain one of the following descriptions \-
- X.RS 8
- X.TP 16
- X\fIrun\fP
- The process can be run immediately.
- X.TP
- X\fIstop\fP
- The process is stopped. See \fIsigvec\fP(2).
- X.TP
- X\fIexit\fP
- The process is a zomby.
- X.RE
- X.IP
- Any other entry in the status field indicates the process is
- waiting for some external event to occur.
- This is usually for one of the reasons listed below.
- X(If \fIsps\fP does not know why a process is waiting, it lists
- the hexadecimal address of the process' wait channel,
- with the initial 80000000 trimmed off.)
- A process may be waiting for one of the following reasons \-
- X.RS 8
- X.TP 16
- X\fIchild\fP
- The process is waiting for a child to terminate. See \fIwait\fP(2).
- X.TP
- X\fIpause\fP
- Waiting for a signal to be received. See \fIsigpause\fP(2).
- X.TP
- X\fIswap\fP
- Waiting for a page to be swapped in.
- X.TP
- X\fIrswbuf\fP
- Waiting for a read from the swap device \fB/dev/drum.\fP
- X.TP
- X\fIdiscio\fP
- Waiting for a disc read or write operation.
- X(Actually, this means that the process is waiting for an operation
- through the kernel's I/O buffering mechanism to complete, but \fIdiscio\fP
- is what is generally meant here).
- X.TP
- X\fIrpipe\fP
- X.br
- X.ns
- X.TP
- X\fIwpipe\fP
- Waiting for a read from an empty pipe. Alternatively, the process
- is 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
- Waiting for a read from an empty socket.
- Alternatively, the process is waiting to write to a full socket (4.[2\-]bsd only).
- X.TP
- X\fIaccept\fP
- Waiting to accept a stream-based socket connection (4.[2\-]bsd only).
- See \fIaccept\fP(2).
- X.TP
- X\fIconnct\fP
- Waiting to establish a connection through a stream-based socket to a
- remote process (4.[2\-]bsd only). See \fIconnect\fP(2).
- X.TP
- X\fIsocket\fP
- Waiting for some other time-out event on a socket (4.[2\-]bsd only).
- X.TP
- X\fIselect\fP
- Blocked by a \fIselect\fP(2) system call (4.[2\-]bsd only).
- X.TP
- X\fIrmux\fP
- Waiting for a read from a multiplexor file (4.1bsd only).
- X.TP
- X\fIinode\fP
- Waiting for an inode to be allocated or unlocked.
- X.TP
- X\fIexlock\fP
- X.br
- X.ns
- X.TP
- X\fIshlock\fP
- Waiting 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
- Waiting for a read or write to the specified terminal, or for the terminal
- to be switched on. See \fItty\fP(4).
- Alternatively, waiting for a read or write to the
- specified slave pty device. See \fIpty\fP(4).
- X.TP
- X\fIitty??\fP
- X.br
- X.ns
- Under SunOS, waiting perform I/O to an iconified window.
- X.TP
- X\fIrpty??\fP
- X.br
- X.ns
- X.TP
- X\fIwpty??\fP
- Waiting for a read or write to the specified master pty device.
- See \fIpty\fP(4).
- X.TP
- X\fIptrace\fP
- This is a parent process tracing its child.
- X.TP
- X\fIvfork\fP
- This is a vforking parent process waiting for its child to relinquish
- memory 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
- Waiting 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.
- These flags may be any of the following \-
- X.RS 8
- X.TP 16
- X\fIU\fP
- The process is a UNIX system process.
- X.TP
- X\fIT\fP
- The process is being traced or debugged.
- X.TP
- X\fIV\fP
- The process is a child currently being vforked. See \fIvfork\fP(2).
- X.TP
- X\fII\fP
- The process is undergoing physical I/O.
- X.TP
- X\fIA\fP
- The system has detected, or the user has warned of
- anomalous paging behaviour. See \fIvadvise\fP(2).
- X.RE
- X.TP 8
- X\fINice\fP
- The ``niceness'' of the process. See \fInice\fP(2).
- X.TP
- X\fIVirtual\fP
- The virtual memory size of the process in kilobytes.
- The first figure indicates the sum of the data and stack segments,
- the second figure that of the text segment.
- X.TP
- X\fIResident\fP
- The resident memory size of the process in kilobytes, representing
- the real memory devoted to the process.
- X.TP
- X\fI%M\fP
- The percentage of available real memory allocated to this process.
- X.TP
- X\fITime\fP
- The total CPU time accumulated by this process.
- X(This is the sum of the system plus user times, unless the \fB\-q\fP
- flag is specified in which case only the user time is listed.)
- X.TP
- X\fIChild\fP
- The total CPU time accumulated by the process' children.
- X(This is the sum of the system plus user times, unless the \fB\-q\fP
- flag is specified.)
- X.TP
- X\fI%C\fP
- The percentage of available CPU time devoted to the process.
- This figure is a decaying average, computed over the past second.
- X.PP
- The following fields are listed when \fIsps\fP is invoked with the
- X\fB\-d\fP option \-
- X.TP 8
- X\fIFiles\fP
- The number of open files for this process.
- X.TP
- X\fIPageFaults\fP
- The number of major and minor page faults incurred by the process.
- X.TP
- X\fISwap\fP
- The number of swaps incurred by the process.
- X.TP
- X\fIBlockI/O\fP
- The number of block read or write operations performed
- on behalf of the process.
- X.TP
- X\fIKbytesecs\fP
- The integral of real memory usage over time.
- Thus, if a process uses 60 kilobytes of real memory for 3 seconds,
- this figure is incremented by 180.
- X.PP
- The following fields are listed when \fIsps\fP is invoked with the
- X\fB\-y\fP option \-
- X.TP 8
- X\fIDev\fP
- The major and minor device numbers of the terminal.
- X.TP
- X\fIAddr\fP
- The 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
- The number of characters in the terminal I/O queues.
- These refer to the raw input queue, the canonical input queue
- and the output queue.
- X.TP
- X\fIPgrp\fP
- The process group associated with the terminal.
- X.PP
- After listing the requested output, \fIsps\fP prints a summary line.
- This indicates the number and total virtual memory size of all processes,
- the number and total virtual size of busy processes,
- the number and real memory size of loaded processes
- and the number and real size of swapped processes.
- X.SH DIAGNOSTICS
- X\fISps\fP reports a self-explanatory message if it is given an
- invalid argument list.
- The program also complains if it cannot find necessary system information.
- X.PP
- At initialisation, \fIsps\fP complains if it cannot find the addresses of
- requisite system structures in the kernel symbol file.
- This is usually the case because the system is rarely configured to support
- all known devices.
- X\fISps\fP also complains if more than one user shares the same user-id
- in 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.
- The output reflects the disc activity caused by these processes.
- The 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.
- It lists the environment as well as all the command arguments in a wide format.
- The output is produced indefinitely, with a delay of two seconds between
- each listing.
- X.PP
- X\fBsps is /vmunix.new\fP
- X.PP
- X\fISps\fP is initialised. It reads its symbol information from the
- specified 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
- Several. In particular, J. E. Kulp and J. Robert Ward,
- X\fB<robert@olsen.uucp>\fP.
- X.LP
- NFS changes incorporated by Alexander Dupuy,
- X\fB<dupuy@amsterdam.columbia.edu>\fP
- X.LP
- SunOS 4.0 implementation by Alexander Dupuy and
- Charlie Kim \fB<cck@cunixc.cc.columbia.edu>\fP.
- X.LP
- Ultrix 2.\fIx\fP additions incorporated by Rob Lehman at CUUCA.
- X.LP
- SunOS 4.1 additions incorporated by Sakari Jalovaara, \fB<sja@sirius.hut.fi>\fP.
- X.LP
- Ultrix 4.0 additions incorporated by Stefano Diomedi,
- X\fB<sdiomedi@tecsiel.it>\fP.
- X.LP
- Currently maintained by J. Robert Ward, \fB<robert@olsen.uu.ch>\fP
- X.SH BUGS
- Because the system is continually changing, the information reported by
- X\fIsps\fP is only an approximation to reality.
- If invoked by root, \fIsps\fP renices itself to \-20 in an attempt to run as
- fast as possible.
- X.PP
- X\fISps\fP recognises the sizes and addresses of internal kernel
- tables whenever it is invoked. However, it must be recompiled
- if major modifications are made to the kernel.
- X.PP
- X\fISps\fP does not list all the detailed information shown by \fIps\fP(1).
- Nor are all the options supported by \fIps\fP(1) available from \fIsps\fP.
- X.PP
- X\fISps\fP does not understand all the possible
- reasons why a process may be sleeping.
- X.PP
- The code of \fIsps\fP is inherently machine-dependent and non-portable.
- X.PP
- The number of options to \fIsps\fP is ridiculous.
- END_OF_FILE
- if test 15346 -ne `wc -c <'sps.1'`; then
- echo shar: \"'sps.1'\" unpacked with wrong size!
- fi
- # end of 'sps.1'
- fi
- if test -f 'waitingfor.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'waitingfor.c'\"
- else
- echo shar: Extracting \"'waitingfor.c'\" \(10012 characters\)
- sed "s/^X//" >'waitingfor.c' <<'END_OF_FILE'
- X# ifndef lint
- static char SccsId[] = "@(#)waitingfor.c 1.7\t12/4/91" ;
- X# endif
- X
- X# include "sps.h"
- X# ifndef SUNOS40
- X# include <h/text.h>
- X# endif SUNOS40
- X
- X# ifdef NFS
- X# ifdef ULTRIX40
- X# include <h/gnode.h>
- X# include <h/inode.h>
- X# else ULTRIX40
- X# include <h/vnode.h>
- X# include <ufs/inode.h>
- X# endif ULTRIX40
- 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 ULTRIX40
- X# include <h/quota.h>
- X# else
- X# include <ufs/quota.h>
- X# endif ULTRIX40
- 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. */
- char *waitingfor ( p )
- X
- struct 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# ifdef ULTRIX40
- X return ( p->pr_p.p_vm & SNOVM ? "vfork" : "child" ) ;
- X# else
- X return ( p->pr_p.p_flag & SNOVM ? "vfork" : "child" ) ;
- X# endif ULTRIX40
- 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 ULTRIX40
- 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 ULTRIX40
- 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 ULTRIX40
- X /* Cretinous DEC compiler can't handle case
- X constructs like the following ... */
- X cp = "?tty??" ;
- X# else ULTRIX40
- 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 ULTRIX40
- 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*/
- getsocket ( ks, s )
- X
- struct socket *ks ;
- struct socket *s ;
- X
- X{
- X return ( getkmem( (long)ks, (char*)s, sizeof( struct socket ) )
- X == sizeof( struct socket ) ) ;
- X}
- X# endif BSD42
- END_OF_FILE
- if test 10012 -ne `wc -c <'waitingfor.c'`; then
- echo shar: \"'waitingfor.c'\" unpacked with wrong size!
- fi
- # end of 'waitingfor.c'
- fi
- echo shar: End of archive 3 \(of 3\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-