SPS (Show Process Status) Part 1 of 2
sources-request at panda.UUCP
sources-request at panda.UUCP
Tue Dec 3 09:47:23 AEST 1985
Mod.sources: Volume 3, Issue 55
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:
# README2
# README
# Makefile.4.1
# Makefile.4.2
# Makefile.sun
# filecount.c
# findtty.c
# flagdecode.c
# flags.h
# flagsetup.c
# getcmd.c
# getupage.c
# globals1.c
# globals2.c
# hashuid.c
# initialise.c
# initsymbols.c
# inittty.c
# This archive created: Mon Dec 2 18:40:56 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README2'" '(3050 characters)'
if test -f 'README2'
then
echo shar: will not over-write existing file "'README2'"
else
sed 's/^X//' << \SHAR_EOF > 'README2'
SPS - Show Process Status
===========================
XSPS is a intended to be used as a replacement for the standard ps(1)
program. Its advantages over ps(1) are that it shows more useful
information and that it is faster.
XSPS is currently implemented for 4.1 and 4.2bsd Unix on Vaxen and for
XSun's 4.2bsd/Release 2. (I also have a somewhat older implementation
for V7 on a PDP-11 as well as Unisoft Version 1.3 on a MC68000 if you
are interested).
XSPS displays wait channels symbolically, rather than as hexadecimal
addresses. If you wish to teach sps about a new sort of device, you
must add an entry in the symbol table (globals2.c) as well as
increasing the size of that table (NWAITSTATE in sps.h).
XSPS sorts processes before listing them. The order reflects the
relationship of the processes. A child process is listed underneath its
corresponding parent and is indented to depict the exact relationship.
XSPS also indicates setuid processes.
XSPS displays such values as the resident and virtual sizes of system
processes. It accepts a whole range of options to control the output.
By default, SPS lists information about one's own processes. Other
options instruct it to be verbose (the "v" option), to list all the
command arguments of a process (the "w" option) or to list the
environment strings of that process (the "e" option). Similarly, there
are options to control which processes are to be displayed. The "a"
option tells it to describe all processes and the "b" option tells it
to describe "busy" processes, which is useful if you wish to find out
what is loading your system. There are also options to select the
output according to user, controlling tty or process number.
XSPS keeps its information in an information file. By default, this is
/etc/spsinfo. This means that it can avoid having to do an expensive
nlist() operation each time it is run. It must be reinitialised (with
the "i" option) if new users are added to /etc/passwd or if a new
version of /vmunix is installed.
To compile SPS, unbundle the four shell archive files. Check that the
define statements in sps.h are large enough for your system (You may
need to alter MAXTTYS). Then compile it using the appropriate
Makefile. Initialise it by typing "sps i" (ignore any error messages at
this stage) and then test it out by typing "sps va". That should make
XSPS list verbose information about every process currently active. If
that works, use the appropriate Makefile to install it.
XSend all bug reports, fixes, comments and suggestions to Robert Ward at -
******************************************************************************
Robert Ward,
Hasler AG, Murtenstrasse 137a, CH-3008 Bern, Switzerland
Tel.: (031) - 65 23 19
Uucp: ... {seismo,decvax,ukc, ... }!mcvax!cernvax!hslrswi!robert
Bitnet: hslrswi!robert at cernvax.bitnet
Arpa: hslrswi!robert%cernvax.bitnet at WISCVM.ARPA
Edunet: hslrswi!robert%cernvax.bitnet at UCBJADE.Berkeley.EDU
******************************************************************************
SHAR_EOF
if test 3050 -ne "`wc -c < 'README2'`"
then
echo shar: error transmitting "'README2'" '(should have been 3050 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'README'" '(1226 characters)'
if test -f 'README'
then
echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
SPS - Show Process Status
=========================
To compile, install and test, type the following commands (as super-user):
% make # Compile SPS
% make install # Install SPS into /bin/sps
% sps i # Initialise SPS
% sps va # Run SPS
********************************************************************************
The files in this directory are for the 4.[12]BSD / VAX-11 version of SPS.
Compiler options are as follows -
-DCHAOS if the Chaos network is incorporated into 4.xbsd
-DTRACE for testing/debugging purposes
-DBSD42 compile SPS for 4.2bsd.
Otherwise, SPS is compiled for 4.1bsd.
********************************************************************************
If you want to tell SPS about a new type of device, then add a new line to
the symbol table (see globals2.c),after ensuring that there is sufficient
room in the `info' structure. (NWAITSTATE may need to be increased in sps.h).
********************************************************************************
XSPS understands if the size of internal kernel tables are changed under VMUNIX,
but must be recompiled if major modifications are made to the kernel.
SHAR_EOF
if test 1226 -ne "`wc -c < 'README'`"
then
echo shar: error transmitting "'README'" '(should have been 1226 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile.4.1'" '(882 characters)'
if test -f 'Makefile.4.1'
then
echo shar: will not over-write existing file "'Makefile.4.1'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile.4.1'
# Makefile for SPS (4.1BSD UNIX Version)
PROG = sps
OBJS = filecount.o findtty.o flagdecode.o flagsetup.o \
getcmd.o getupage.o globals1.o globals2.o hashuid.o \
initialise.o initsymbols.o inittty.o main.o mktree.o \
needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
prheader.o printall.o printproc.o prsummary.o readstatus.o \
selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
INCS = sps.h
LIBS = -ltermlib
CFLAGS = -I/usr/src/sys -DCHAOS
all: $(PROG)
X.c.o:
cc $(CFLAGS) -c -O -R $<
globals1.o waitingfor.o:
cc $(CFLAGS) -c -O $<
$(OBJS): $(INCS)
$(PROG): $(OBJS)
cc -o $@ $(OBJS) $(LIBS)
install: $(PROG)
strip $(PROG)
mv $(PROG) /bin/$(PROG)
/etc/chown root /bin/$(PROG)
chmod 4711 /bin/$(PROG)
lint:
lint -x -b $(CFLAGS) *.c
clean:
rm -f $(OBJS) $(PROG)
SHAR_EOF
if test 882 -ne "`wc -c < 'Makefile.4.1'`"
then
echo shar: error transmitting "'Makefile.4.1'" '(should have been 882 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile.4.2'" '(853 characters)'
if test -f 'Makefile.4.2'
then
echo shar: will not over-write existing file "'Makefile.4.2'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile.4.2'
# Makefile for SPS (4.2BSD UNIX Version)
PROG = sps
OBJS = filecount.o findtty.o flagdecode.o flagsetup.o \
getcmd.o getupage.o globals1.o globals2.o hashuid.o \
initialise.o initsymbols.o inittty.o main.o mktree.o \
needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
prheader.o printall.o printproc.o prsummary.o readstatus.o \
selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
INCS = sps.h
CC = cc
CFLAGS = -DBSD42 -I/sys
LIBS = -ltermlib
all: $(PROG)
X.c.o:
$(CC) $(CFLAGS) -c -O -R $<
globals1.o waitingfor.o:
$(CC) $(CFLAGS) -c -O $<
$(OBJS): $(INCS)
$(PROG): $(OBJS)
$(CC) -o $@ $(OBJS) $(LIBS)
install: $(PROG)
strip $(PROG)
mv $(PROG) /bin/$(PROG)
/etc/chown root /bin/$(PROG)
lint:
lint -x -b $(CFLAGS) *.c
clean:
rm -f $(OBJS) $(PROG)
SHAR_EOF
if test 853 -ne "`wc -c < 'Makefile.4.2'`"
then
echo shar: error transmitting "'Makefile.4.2'" '(should have been 853 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile.sun'" '(863 characters)'
if test -f 'Makefile.sun'
then
echo shar: will not over-write existing file "'Makefile.sun'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile.sun'
# Makefile for SPS (Sun 4.2BSD UNIX Version)
PROG = sps
OBJS = filecount.o findtty.o flagdecode.o flagsetup.o \
getcmd.o getupage.o globals1.o globals2.o hashuid.o \
initialise.o initsymbols.o inittty.o main.o mktree.o \
needed.o openfiles.o percentmem.o prcmd.o prcpu.o \
prheader.o printall.o printproc.o prsummary.o readstatus.o \
selectproc.o selecttty.o termwidth.o ttystatus.o waitingfor.o
INCS = sps.h
CC = cc
CFLAGS = -DSUN -DBSD42 -I/sys
LIBS = -ltermlib
all: $(PROG)
X.c.o:
$(CC) $(CFLAGS) -c -O -R $<
globals1.o waitingfor.o:
$(CC) $(CFLAGS) -c -O $<
$(OBJS): $(INCS)
$(PROG): $(OBJS)
$(CC) -o $@ $(OBJS) $(LIBS)
install: $(PROG)
strip $(PROG)
mv $(PROG) /bin/$(PROG)
/etc/chown root /bin/$(PROG)
lint:
lint -x -b $(CFLAGS) *.c
clean:
rm -f $(OBJS) $(PROG)
SHAR_EOF
if test 863 -ne "`wc -c < 'Makefile.sun'`"
then
echo shar: error transmitting "'Makefile.sun'" '(should have been 863 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'filecount.c'" '(351 characters)'
if test -f 'filecount.c'
then
echo shar: will not over-write existing file "'filecount.c'"
else
sed 's/^X//' << \SHAR_EOF > 'filecount.c'
# include "sps.h"
/* FILECOUNT - Counts the # open files for the current process */
filecount ()
{
register int i ;
register struct file **f ;
register int count ;
extern union userstate User ;
count = 0 ;
for ( i = 0, f = User.u_us.u_ofile ; i < NOFILE ; i++ )
if ( *f++ )
count++ ;
return ( count ) ;
}
SHAR_EOF
if test 351 -ne "`wc -c < 'filecount.c'`"
then
echo shar: error transmitting "'filecount.c'" '(should have been 351 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'findtty.c'" '(505 characters)'
if test -f 'findtty.c'
then
echo shar: will not over-write existing file "'findtty.c'"
else
sed 's/^X//' << \SHAR_EOF > 'findtty.c'
# include "sps.h"
# include <h/tty.h>
/* FINDTTY - Attempts to determine to which tty a process is connected */
struct ttyline *findtty ( p )
register struct process *p ;
{
register struct ttyline *lp ;
extern struct info Info ;
extern struct ttyline Notty ;
extern union userstate User ;
if ( !p->pr_p.p_pgrp )
return ( &Notty ) ;
for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
if ( lp->l_dev == User.u_us.u_ttyd )
return ( lp ) ;
return ( &Notty ) ;
}
SHAR_EOF
if test 505 -ne "`wc -c < 'findtty.c'`"
then
echo shar: error transmitting "'findtty.c'" '(should have been 505 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'flagdecode.c'" '(5436 characters)'
if test -f 'flagdecode.c'
then
echo shar: will not over-write existing file "'flagdecode.c'"
else
sed 's/^X//' << \SHAR_EOF > 'flagdecode.c'
# include "sps.h"
# include "flags.h"
/* FLAGDECODE - Looks at the argument list and sets various internal switches */
flagdecode ( argc, argv )
register int argc ;
register char **argv ;
{
register char *chp ;
union flaglist *plist ;
union flaglist *tlist ;
union flaglist *ulist ;
static char usage[] =
"sps - Unknown option %s\nUsage - sps [ -defgijkoqrsvwyABFNPSTUWZ ][ process|tty|user ] ...\n";
union flaglist *getflgsp() ;
extern struct flags Flg ;
plist = tlist = ulist = (union flaglist*)0 ;
for ( argv++ ; --argc ; argv++ )
{
chp = *argv ;
while ( *chp )
switch ( *chp++ )
{
case '-' :
/* Separation character */
continue ;
case 'd' :
case 'D' :
/* List disc orientated information */
Flg.flg_d = 1 ;
Flg.flg_v = 0 ;
continue ;
case 'e' :
case 'E' :
/* List environment strings */
Flg.flg_e = 1 ;
continue ;
case 'f' :
/* List the father's process id */
Flg.flg_f = 1 ;
continue ;
case 'g' :
case 'G' :
/* List the process group id */
Flg.flg_g = 1 ;
continue ;
case 'i' :
case 'I' :
/* Initialise (super-user only) */
Flg.flg_i = 1 ;
continue ;
case 'j' :
case 'J' :
/* The next argument specifies the
name of the information file */
if ( argc <= 1 )
prexit(
"sps - Name of an information file expected after `-j' flag\n" ) ;
argc-- ;
Flg.flg_j = *++argv ;
continue ;
case 'k' :
case 'K' :
/* Use a disc file such as /vmcore
rather than /dev/{k}mem for
accessing kernel data. The next
argument specifies the file name. */
if ( argc <= 1 )
prexit(
"sps - Name of a memory dump file expected after `-k' flag\n" ) ;
argc-- ;
Flg.flg_k = *++argv ;
Flg.flg_o = 1 ;
continue ;
case 'l' :
case 'v' :
case 'L' :
case 'V' :
/* Verbose output */
Flg.flg_d = 0 ;
Flg.flg_v = 1 ;
continue ;
case 'o' :
case 'O' :
/* Avoid looking at the swap device */
Flg.flg_o = 1 ;
continue ;
case 'q' :
case 'Q' :
/* Show only the user time, not the
user + system times together. */
Flg.flg_q = 1 ;
continue ;
case 'r' :
case 'R' :
/* Repeat output every n seconds.
The next argument specifies n which
defaults to 5 if omitted. */
Flg.flg_r = 1 ;
if ( argc > 1 )
{
if ( **++argv >= '0'
&& **argv <= '9' )
{
argc-- ;
Flg.flg_rdelay
= atoi( *argv ) ;
continue ;
}
argv-- ;
}
Flg.flg_rdelay = 0 ;
continue ;
case 's' :
/* Next argument specifies a symbol
file rather than the default
/vmunix. */
if ( argc <= 1 )
prexit(
"sps - Name of a symbol file expected after `-s' flag\n" ) ;
argc-- ;
Flg.flg_s = *++argv ;
continue ;
case 'w' :
/* Wide output, exceeding 79 columns */
Flg.flg_w = 1 ;
continue ;
case 'y' :
case 'Y' :
/* List current tty information */
Flg.flg_y = 1 ;
continue ;
case 'a' :
case 'A' :
/* List all processes */
Flg.flg_AZ = 1 ;
Flg.flg_A = 1 ;
continue ;
case 'b' :
case 'B' :
/* List only busy processes */
Flg.flg_AZ = 1 ;
Flg.flg_B = 1 ;
continue ;
case 'F' :
/* List only foreground processes */
Flg.flg_AZ = 1 ;
Flg.flg_F = 1 ;
continue ;
case 'n' :
case 'N' :
/* No processes, just the summary line*/
Flg.flg_AZ = 1 ;
Flg.flg_N = 1 ;
continue ;
case 'p' :
case 'P' :
/* List only the given process ids */
Flg.flg_AZ = 1 ;
Flg.flg_P = 1 ;
if ( !plist )
plist=Flg.flg_Plist=getflgsp( argc );
while ( argc > 1 )
{
if ( **++argv == '-' )
{
--argv ;
break ;
}
--argc ;
plist->f_chp = *argv ;
(++plist)->f_chp = (char*)0 ;
}
continue ;
case 'S' :
/* List only stopped processes */
Flg.flg_AZ = 1 ;
Flg.flg_S = 1 ;
continue ;
case 't' :
case 'T' :
/* List only processes attached to the
specified terminals */
Flg.flg_AZ = 1 ;
Flg.flg_T = 1 ;
if ( !tlist )
tlist=Flg.flg_Tlist=getflgsp( argc );
while ( argc > 1 )
{
if ( **++argv == '-' )
{
--argv ;
break ;
}
--argc ;
tlist->f_chp = *argv ;
(++tlist)->f_chp = (char*)0 ;
}
continue ;
case 'u' :
case 'U' :
/* List only processes belonging to the
specified users */
Flg.flg_AZ = 1 ;
Flg.flg_U = 1 ;
if ( !ulist )
ulist=Flg.flg_Ulist=getflgsp( argc );
while ( argc > 1 )
{
if ( **++argv == '-' )
{
--argv ;
break ;
}
--argc ;
ulist->f_chp = *argv ;
(++ulist)->f_chp = (char*)0 ;
}
continue ;
case 'W' :
/* List only waiting processes */
Flg.flg_AZ = 1 ;
Flg.flg_W = 1 ;
continue ;
case 'z' :
case 'Z' :
/* List only zombie processes */
Flg.flg_AZ = 1 ;
Flg.flg_Z = 1 ;
continue ;
default :
prexit( usage, *argv ) ;
/* NOTREACHED */
}
}
}
SHAR_EOF
if test 5436 -ne "`wc -c < 'flagdecode.c'`"
then
echo shar: error transmitting "'flagdecode.c'" '(should have been 5436 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'flags.h'" '(2488 characters)'
if test -f 'flags.h'
then
echo shar: will not over-write existing file "'flags.h'"
else
sed 's/^X//' << \SHAR_EOF > 'flags.h'
/* Structure holding information specified in the option list ... */
union flaglist
{
char *f_chp ; /* Option specified as string */
int f_uid ; /* Numerical user id */
int f_pid ; /* Numerical process id */
struct ttyline *f_ttyline ; /* Specified tty */
} ;
/* Structure holding global information specifed by arg list options ... */
struct flags
{
int flg_d:1 ; /* disc orientated output */
int flg_e:1 ; /* print environment string */
int flg_f:1 ; /* print process father # */
int flg_g:1 ; /* print process group # */
int flg_i:1 ; /* initialise sps */
char *flg_j ; /* Use this as the info file */
char *flg_k ; /* Use this as the {k}mem file*/
int flg_o:1 ; /* avoid the swap device */
int flg_q:1 ; /* show user time only */
int flg_r:1 ; /* repeat output */
unsigned flg_rdelay ; /* ... with this much delay */
char *flg_s ; /* Use this as the symbol file*/
int flg_v:1 ; /* print verbose listing */
int flg_w:1 ; /* print wide output */
int flg_y:1 ; /* print tty information */
int flg_A:1 ; /* print all processes */
int flg_B:1 ; /* print busy processes */
int flg_F:1 ; /* print foreground processes */
int flg_N:1 ; /* print no processes */
int flg_P:1 ; /* print specified process #'s*/
int flg_S:1 ; /* print stopped processes */
int flg_T:1 ; /* print procs for given ttys */
int flg_U:1 ; /* print procs for given users*/
int flg_W:1 ; /* print waiting processes */
int flg_Z:1 ; /* print zombie processes */
int flg_AZ:1 ; /* One of A to Z was specified*/
union flaglist *flg_Plist ; /* List of specified processes*/
union flaglist *flg_Tlist ; /* List of specified ttys */
union flaglist *flg_Ulist ; /* List of specified users */
} ;
SHAR_EOF
if test 2488 -ne "`wc -c < 'flags.h'`"
then
echo shar: error transmitting "'flags.h'" '(should have been 2488 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'flagsetup.c'" '(2182 characters)'
if test -f 'flagsetup.c'
then
echo shar: will not over-write existing file "'flagsetup.c'"
else
sed 's/^X//' << \SHAR_EOF > 'flagsetup.c'
# include "sps.h"
# include "flags.h"
# include <h/tty.h>
/*
** FLAGSETUP - Replaces any users or processes specified by flagdecode()
** with numerical equivalents. The lists are terminated by negative values.
** or null pointers. Ttystatus() must have been previously called to
** initialise the Info structure with chaos tty values.
*/
flagsetup ()
{
register union flaglist *fp ;
register char *chp ;
register int i ;
register struct ttyline *lp ;
int found ;
extern struct flags Flg ;
extern struct info Info ;
/* Look for specified users */
if ( Flg.flg_U )
{
if ( !Flg.flg_Ulist->f_chp )
prexit( "sps - User name was expected after -u flag\n");
for ( fp = Flg.flg_Ulist ; chp = fp->f_chp ; fp++ )
{
found = 0 ;
for ( i = 0 ; i < MAXUSERID ; i++ )
if ( !strncmp( chp, Info.i_hnames[i].h_uname,
UNAMELEN ) )
{
fp->f_uid = Info.i_hnames[i].h_uid ;
found = 1 ;
break ;
}
if ( !found )
prexit( "sps - Unknown user: %s\n", chp ) ;
}
fp->f_uid = -1 ;
}
/* Look for specified process ids */
if ( Flg.flg_P )
{
if ( !Flg.flg_Plist->f_chp )
prexit(
"sps - Process id was expected after -p flag\n" ) ;
for ( fp = Flg.flg_Plist ; chp = fp->f_chp ; fp++ )
{
if ( chp[0] < '0' || chp[0] > '9' )
prexit( "sps - Bad process id: %s\n", chp ) ;
fp->f_pid = atoi( chp ) ;
}
fp->f_pid = -1 ;
}
/* Look for specified ttys */
if ( !Flg.flg_T )
return ;
if ( !Flg.flg_Tlist->f_chp )
prexit( "sps - Tty name was expected after -t flag\n" ) ;
for ( fp = Flg.flg_Tlist ; chp = fp->f_chp ; fp++ )
{ /* Under VMUNIX, all ttys have two character names.
Thus, a flag of the form `t 8' should be expanded to
become `t 08'. */
if ( !chp[1] )
chp[1] = chp[0], chp[0] = '0' ;
found = 0 ;
for ( lp = Info.i_ttyline ; lp->l_name[0] ; lp++ )
if ( !strncmp( chp, lp->l_name, 2 ) )
{
fp->f_ttyline = lp ;
found = 1 ;
break ;
}
if ( !found )
prexit( "sps - Unknown tty name: %.2s\n", chp ) ;
}
fp->f_ttyline = (struct ttyline*)0 ;
}
SHAR_EOF
if test 2182 -ne "`wc -c < 'flagsetup.c'`"
then
echo shar: error transmitting "'flagsetup.c'" '(should have been 2182 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getcmd.c'" '(4815 characters)'
if test -f 'getcmd.c'
then
echo shar: will not over-write existing file "'getcmd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'getcmd.c'
# include "sps.h"
# include "flags.h"
# include <h/vm.h>
# ifdef BSD42
# include <machine/pte.h>
# else
# include <h/pte.h>
# endif
/*
** GETCMD - Returns a character string read from a process' upage.
** This character string should represent the arguments to the current process.
*/
char *getcmd ( p )
register struct process *p ;
{
register int *ip ;
register char *cp ;
register char *cp0 ;
unsigned nbad ;
struct dblock db ;
struct pte ptetbl[ UPAGES + CLSIZE ] ;
union
{
char a_argc[ CLSIZE * NBPG ] ;
int a_argi[ CLSIZE * NBPG / sizeof( int ) ] ;
} argbuf ;
extern struct flags Flg ;
extern union userstate User ;
extern int Flmem, Flswap ;
char *strcat(), *strncpy(), *strsave() ;
p->pr_csaved = 0 ;
p->pr_upag = 0 ;
if ( p->pr_p.p_stat == SZOMB )
return ( "** Exit **" ) ;
if ( !(p->pr_p.p_flag & SLOAD) && Flg.flg_o )
return ( "** Swapped out **" ) ;
/* Find the process' upage */
if ( !getupage( p, ptetbl ) )
return ( "** No upage **" ) ;
/* Is this a system process ? */
if ( p->pr_p.p_flag & SSYS )
switch ( p->pr_p.p_pid )
{
case 0 :
p->pr_upag = 1 ;
return ( "Unix Swapper" ) ;
case 2 :
p->pr_upag = 1 ;
return ( "Unix Pager" ) ;
default :
break ;
}
/* Look at the top of the upage to locate the command arguments.
The page is loaded if the process itself is loaded and the pte
contains is marked as valid. */
if ( (p->pr_p.p_flag & SLOAD)
&& !ptetbl[0].pg_fod && ptetbl[0].pg_pfnum )
{ /* If the page is loaded, read the arguments from
physical memory. */
memseek( Flmem, (long)ctob( ptetbl[0].pg_pfnum ) ) ;
if ( read( Flmem, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
return ( "** Memory read error **" ) ;
}
else
{ /* Otherwise the page is on the swap device */
vstodb( 0, ctod( CLSIZE ), &User.u_us.u_smap, &db, 1 ) ;
# ifdef BSD42
swseek( (long)dtob( db.db_base ) ) ;
# else
swseek( (long)ctob( db.db_base ) ) ;
# endif
if ( Flg.flg_o )
return ( "** Swapped page **" ) ;
if ( read( Flswap, argbuf.a_argc, CLSIZE*NBPG ) != CLSIZE*NBPG )
return ( "** Swap device read error **" ) ;
}
/* Look down until the end of command arguments is found. */
p->pr_upag = 1 ;
p->pr_csaved = 1 ;
ip = &argbuf.a_argi[ CLSIZE*NBPG / sizeof( int ) ] ;
ip -= 2 ;
while ( *--ip )
if ( ip == &argbuf.a_argi[0] )
goto getsysargs ;
/* Process the command arguments, looking for nulls and unprintable
characters. */
cp0 = (char*)(ip + 1) ;
if ( !*cp0 )
cp0++ ;
if ( *cp0 )
{
nbad = 0 ;
for ( cp = cp0 ; cp < &argbuf.a_argc[ CLSIZE*NBPG ] ; cp++ )
{
*cp &= 0177 ;
if ( !*cp )
{ /* Replace nulls with spaces */
*cp = ' ' ;
continue ;
}
if ( *cp < ' ' || *cp == 0177 )
{ /* Replace control characters with ?'s */
if ( ++nbad > 5 )
{
*cp++ = ' ' ;
break ;
}
*cp = '?' ;
continue ;
}
if ( !Flg.flg_e && *cp == '=' )
{ /* Break on an `=' if we are not interested
in the environment strings. */
*cp = '\0' ;
while ( cp > cp0 && *--cp != ' ' )
*cp = '\0' ;
break ;
}
}
while ( *--cp == ' ' )
*cp = '\0' ;
return ( strsave( cp0 ) ) ;
}
getsysargs :
/* If the command arguments cannot be accessed from the user's memory
space, get the command name from the system's idea of what the
name should be. */
argbuf.a_argc[0] = '(' ;
(void)strncpy( &argbuf.a_argc[1], User.u_us.u_comm,
sizeof( User.u_us.u_comm ) ) ;
(void)strcat( &argbuf.a_argc[0], ")" ) ;
return ( strsave( argbuf.a_argc ) ) ;
}
/*
** VSTODB - Given a base/size pair in virtual swap area,
** return a physical base/size pair which is the
** (largest) initial, physically contiguous block.
/* This code is stolen from the kernel file /sys/sys/vm_drum.c.
*/
vstodb ( vsbase, vssize, dmp, dbp, rev )
register int vsbase ;
register int vssize;
struct dmap *dmp ;
register struct dblock *dbp ;
int rev ;
{
register int blk ;
register swblk_t *ip ;
# ifdef BSD42
extern struct info Info ;
# endif
# ifdef BSD42
blk = Info.i_dmmin ;
# else
blk = DMMIN ;
# endif
ip = dmp->dm_map ;
while ( vsbase >= blk )
{
vsbase -= blk ;
# ifdef BSD42
if ( blk < Info.i_dmmax )
# else
if ( blk < DMMAX )
# endif
blk *= 2 ;
ip++ ;
}
dbp->db_size = vssize < blk - vsbase ? vssize : blk - vsbase ;
dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
}
SHAR_EOF
if test 4815 -ne "`wc -c < 'getcmd.c'`"
then
echo shar: error transmitting "'getcmd.c'" '(should have been 4815 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getupage.c'" '(2971 characters)'
if test -f 'getupage.c'
then
echo shar: will not over-write existing file "'getupage.c'"
else
sed 's/^X//' << \SHAR_EOF > 'getupage.c'
# include "sps.h"
# include <h/vm.h>
# ifdef BSD42
# include <machine/pte.h>
# else
# include <h/pte.h>
# endif
# include <stdio.h>
/*
** GETUPAGE - Reads the upage for the specified process as well as sufficient
** page tables entries for reading the command arguments. The pte's are read
** into the argument `ptetbl'. The upage is read into the external variable
** `User'. This procedure returns 1 if the upage was successfully read.
*/
# define usrpt (Info.i_usrpt)
getupage ( p, ptetbl )
register struct process *p ;
register struct pte *ptetbl ;
{
register int i ;
register int ncl ;
struct pte pte ;
extern struct info Info ;
extern union userstate User ;
extern int Flmem, Flkmem, Flswap ;
/* If the process is not loaded, look for the upage on the swap device*/
if ( !(p->pr_p.p_flag & SLOAD) )
{
# ifdef BSD42
swseek( (long)dtob( p->pr_p.p_swaddr ) ) ;
# else
swseek( (long)ctob( p->pr_p.p_swaddr ) ) ;
# endif
# ifdef SUN
if ( read( Flswap, (char*)&User.u_us, sizeof( union userstate ))
!= sizeof( union userstate ) )
# else
if ( read( Flswap, (char*)&User.u_us, sizeof( struct user ) )
!= sizeof( struct user ) )
# endif
{
fprintf( stderr,
"sps - Can't read upage of process %d\n",
p->pr_p.p_pid ) ;
return ( 0 ) ;
}
return ( 1 ) ;
}
/* The process is loaded. Locate the process pte's by reading
the pte of their base address from system virtual address space. */
memseek( Flkmem, (long)&Info.i_usrptmap[ btokmx(p->pr_p.p_p0br)
+ p->pr_p.p_szpt-1 ] ) ;
if ( read( Flkmem, (char*)&pte, sizeof( struct pte ) )
!= sizeof( struct pte ) )
{
fprintf( stderr,
"sps - Can't read indir pte for upage of process %d\n",
p->pr_p.p_pid ) ;
return ( 0 ) ;
}
/* Now read the process' pte's from physical memory. We need to access
sufficient pte's for the upage and for the command arguments. */
memseek( Flmem, (long)ctob( pte.pg_pfnum+1 )
- (UPAGES+CLSIZE)*sizeof( struct pte ) ) ;
if ( read( Flmem, (char*)ptetbl, (UPAGES+CLSIZE)*sizeof( struct pte ) )
!= (UPAGES+CLSIZE)*sizeof( struct pte ) )
{
fprintf( stderr, "sps - Can't read page table of process %d\n",
p->pr_p.p_pid ) ;
return ( 0 ) ;
}
/* Now we can read the pages belonging to the upage.
Here we read in an entire click at one go. */
ncl = (sizeof( struct user ) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE) ;
while ( --ncl >= 0 )
{
i = ncl * CLSIZE ;
memseek( Flmem, (long)ctob( ptetbl[ CLSIZE+i ].pg_pfnum ) ) ;
if ( read( Flmem, User.u_pg[i], CLSIZE*NBPG ) != CLSIZE*NBPG )
{
fprintf( stderr,
"sps - Can't read page 0x%x of process %d\n",
ptetbl[ CLSIZE+i ].pg_pfnum, p->pr_p.p_pid ) ;
return ( 0 ) ;
}
}
return ( 1 ) ;
}
SHAR_EOF
if test 2971 -ne "`wc -c < 'getupage.c'`"
then
echo shar: error transmitting "'getupage.c'" '(should have been 2971 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'globals1.c'" '(720 characters)'
if test -f 'globals1.c'
then
echo shar: will not over-write existing file "'globals1.c'"
else
sed 's/^X//' << \SHAR_EOF > 'globals1.c'
# include "sps.h"
# include "flags.h"
/* Read/Write Variables global to the code of sps */
struct info Info ; /* Information structure */
struct flags Flg ; /* Flag options */
struct summary Summary ; /* Summary of processes */
union userstate User ; /* Upage of one process */
int Flmem, Flkmem, Flswap ; /* File descriptors */
unsigned Termwidth ; /* Width of output device */
short Lastpgrp ; /* Last process pgrp printed */
short Lastuid ; /* Last process uid printed */
SHAR_EOF
if test 720 -ne "`wc -c < 'globals1.c'`"
then
echo shar: error transmitting "'globals1.c'" '(should have been 720 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'globals2.c'" '(5240 characters)'
if test -f 'globals2.c'
then
echo shar: will not over-write existing file "'globals2.c'"
else
sed 's/^X//' << \SHAR_EOF > 'globals2.c'
# include "sps.h"
/* Read Only variables, global to the code of sps ... */
/* Null ttyline device ... */
struct ttyline Notty = { 0, 0, " ", 0 } ;
/*
** The symbol table. For each address read from the kernel during
** initialisation, this table shows the following:
** i. the name of that symbol within the kernel ;
** ii. whether an extra indirection is needed through the kernel,
** i.e. whether the value of that symbol should be obtained
** rather than its address.
** iii. where the obtained value/address is placed in the Info structure ;
** iv. whether the obtained value is associated with a reason for
** a process wait state.
*/
/* The order of entries in this table is unimportant. */
extern struct info Info ;
struct symbol Symbollist[] =
{
/* Kernel addresses required in order to access process,
tty and upage information. All these addresses should be
located in the symbol file during initialisation. */
{ "_proc", 1, (caddr_t*)&Info.i_proc0, (char*)0 },
{ "_nproc", 1, (caddr_t*)&Info.i_nproc, (char*)0 },
{ "_text", 1, (caddr_t*)&Info.i_text0, (char*)0 },
{ "_ntext", 1, (caddr_t*)&Info.i_ntext, (char*)0 },
{ "_inode", 1, (caddr_t*)&Info.i_inode0, (char*)0 },
{ "_ninode", 1, (caddr_t*)&Info.i_ninode, (char*)0 },
{ "_swbuf", 1, (caddr_t*)&Info.i_swbuf0, (char*)0 },
{ "_nswbuf", 1, (caddr_t*)&Info.i_nswbuf, (char*)0 },
{ "_buf", 1, (caddr_t*)&Info.i_buf0, (char*)0 },
{ "_nbuf", 1, (caddr_t*)&Info.i_nbuf, (char*)0 },
{ "_ecmx", 1, (caddr_t*)&Info.i_ecmx, (char*)0 },
{ "_Usrptmap", 0, (caddr_t*)&Info.i_usrptmap, (char*)0 },
{ "_usrpt", 0, (caddr_t*)&Info.i_usrpt, (char*)0 },
{ "_cdevsw", 0, (caddr_t*)&Info.i_cdevsw, (char*)0 },
# ifdef BSD42
{ "_quota", 1, (caddr_t*)&Info.i_quota0, (char*)0 },
{ "_nquota", 1, (caddr_t*)&Info.i_nquota, (char*)0 },
{ "_dmmin", 1, (caddr_t*)&Info.i_dmmin, (char*)0 },
{ "_dmmax", 1, (caddr_t*)&Info.i_dmmax, (char*)0 },
{ "_mbutl", 0, (caddr_t*)&Info.i_mbutl, (char*)0 },
# else
{ "_hz", 1, (caddr_t*)&Info.i_hz, (char*)0 },
# endif
# ifdef CHAOS
{ "_Chconntab", 0, &Info.i_Chconntab, (char*)0 },
# endif
/* Kernel addresses associated with process wait states.
It is not important if some of these addresses are unresolved
at initialisation. */
{ "_fltab", 0, &Info.i_waitstate[0], "floppy" },
{ "_tu", 0, &Info.i_waitstate[1], "tu58" },
{ "_bfreelist", 0, &Info.i_waitstate[2], "buffer" },
{ "_lp_softc", 0, &Info.i_waitstate[3], "printr" },
{ "_lbolt", 0, &Info.i_waitstate[4], "lbolt" },
{ "_runin", 0, &Info.i_waitstate[5], "runin" },
{ "_runout", 0, &Info.i_waitstate[6], "runout" },
{ "_ipc", 0, &Info.i_waitstate[7], "ptrace" },
{ "_u", 0, &Info.i_waitstate[8], "pause" },
{ "_freemem", 0, &Info.i_waitstate[9], "freemm" },
{ "_kernelmap", 0, &Info.i_waitstate[10], "kermap" },
{ "_cwaiting", 0, &Info.i_waitstate[11], "cwait" },
{ "_rhpbuf", 0, &Info.i_waitstate[12], "rhpbuf" },
{ "_rhtbuf", 0, &Info.i_waitstate[13], "rhtbuf" },
{ "_ridcbuf", 0, &Info.i_waitstate[14], "ridcbf" },
{ "_rikbuf", 0, &Info.i_waitstate[15], "rikbuf" },
{ "_rmtbuf", 0, &Info.i_waitstate[16], "rmtbuf" },
{ "_rrkbuf", 0, &Info.i_waitstate[17], "rrkbuf" },
{ "_rrlbuf", 0, &Info.i_waitstate[18], "rrlbuf" },
{ "_rrxbuf", 0, &Info.i_waitstate[19], "rrxbuf" },
{ "_rswbuf", 0, &Info.i_waitstate[20], "rswbuf" },
{ "_rtmbuf", 0, &Info.i_waitstate[21], "rtmbuf" },
{ "_rtsbuf", 0, &Info.i_waitstate[22], "rtsbuf" },
{ "_rudbuf", 0, &Info.i_waitstate[23], "rudbuf" },
{ "_rupbuf", 0, &Info.i_waitstate[24], "rupbuf" },
{ "_rutbuf", 0, &Info.i_waitstate[25], "rutbuf" },
{ "_rvabuf", 0, &Info.i_waitstate[26], "rvabuf" },
{ "_rvpbuf", 0, &Info.i_waitstate[27], "rvpbuf" },
{ "_chtbuf", 0, &Info.i_waitstate[28], "chtbuf" },
{ "_cmtbuf", 0, &Info.i_waitstate[29], "cmtbuf" },
{ "_ctmbuf", 0, &Info.i_waitstate[30], "ctmbuf" },
{ "_ctsbuf", 0, &Info.i_waitstate[31], "ctsbuf" },
{ "_cutbuf", 0, &Info.i_waitstate[32], "cutbuf" },
# ifdef BSD42
{ "_selwait", 0, &Info.i_waitstate[33], "select" },
# endif
# ifdef CHAOS
{ "_Chrfclist", 0, &Info.i_waitstate[34], "chrfc" },
# endif
# ifdef SUN
{ "_async_bufhead", 0, &Info.i_waitstate[35], "async" },
# endif
{ (char*)0, 0, (caddr_t*)0, (char*)0 }
} ;
SHAR_EOF
if test 5240 -ne "`wc -c < 'globals2.c'`"
then
echo shar: error transmitting "'globals2.c'" '(should have been 5240 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'hashuid.c'" '(1421 characters)'
if test -f 'hashuid.c'
then
echo shar: will not over-write existing file "'hashuid.c'"
else
sed 's/^X//' << \SHAR_EOF > 'hashuid.c'
# include "sps.h"
/* The hashing functions themselves ... */
# define HASHFN1( a ) (((a)*91 + 17) % MAXUSERID)
# define HASHFN2( a ) (((a) + 47) % MAXUSERID)
/*
** HASHUID - Returns a pointer to a slot in the hash table that corresponds
** to the hash table entry for `uid'. It returns a null pointer if there is
** no such slot.
*/
struct hashtab *hashuid ( uid )
int uid ;
{
register struct hashtab *hp ;
register int i ;
register int j ;
extern struct info Info ;
j = HASHFN1( uid ) ;
for ( i = 0 ; i < MAXUSERID ; i++ )
{
hp = &Info.i_hnames[ j ] ;
if ( !hp->h_uname[0] )
return ( (struct hashtab*)0 ) ;
if ( hp->h_uid == uid )
return ( hp ) ;
j = HASHFN2( j ) ;
}
return ( (struct hashtab*)0 ) ;
}
/*
** HASHNEXT - Returns a pointer to the next slot in the hash table that
** may be use for storing information for `uid'. It returns a null pointer
** if there are no more free slots available.
*/
struct hashtab *hashnext ( uid )
int uid ;
{
register struct hashtab *hp ;
register int i ;
register int j ;
extern struct info Info ;
j = HASHFN1( uid ) ;
for ( i = 0 ; i < MAXUSERID ; i++ )
{
hp = &Info.i_hnames[ j ] ;
if ( !hp->h_uname[0] )
return ( hp ) ;
j = HASHFN2( j ) ;
}
return ( (struct hashtab*)0 ) ;
}
SHAR_EOF
if test 1421 -ne "`wc -c < 'hashuid.c'`"
then
echo shar: error transmitting "'hashuid.c'" '(should have been 1421 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'initialise.c'" '(1905 characters)'
if test -f 'initialise.c'
then
echo shar: will not over-write existing file "'initialise.c'"
else
sed 's/^X//' << \SHAR_EOF > 'initialise.c'
# include "sps.h"
# include "flags.h"
# include <pwd.h>
# include <stdio.h>
/*
** INITIALISE - Called to reset the `Info' structure with new kernel
** addresses and user and tty information.
*/
initialise ()
{
register FILE *fd ;
char *fileinfo ;
extern struct flags Flg ;
extern struct info Info ;
FILE *fopen() ;
fileinfo = Flg.flg_j ? Flg.flg_j : FILE_INFO ;
/* Read kernel addresses */
initsymbols() ;
/* Read user names */
initusers() ;
(void)umask( ~0644 ) ;
if ( !(fd = fopen( fileinfo, "w" )) )
{
fprintf( stderr, "sps - Can't create info file %s", fileinfo ) ;
sysperror() ;
}
/* Find tty addresses */
inittty() ;
if ( fwrite( (char*)&Info, sizeof( struct info ), 1, fd ) != 1 )
{
fprintf( stderr, "sps - Can't write info file %s", fileinfo ) ;
sysperror() ;
exit( 1 ) ;
}
(void)fclose( fd ) ;
printf( "sps is initialised\n" ) ;
}
/* INITUSERS - Read the passwd file and fill in the user name arrays */
initusers ()
{
register struct passwd *pw ;
register struct hashtab *hp ;
struct passwd *getpwent() ;
char *strncpy() ;
struct hashtab *hashuid(), *hashnext() ;
while ( pw = getpwent() )
{ /* For each user in the passwd file, first see if that uid
has been already allocated in the hash table. */
if ( hp = hashuid( pw->pw_uid ) )
{
fprintf( stderr,
"sps - Names %s and %s conflict in passwd file for uid %d\n",
hp->h_uname, pw->pw_name, pw->pw_uid ) ;
continue ;
}
/* Try to find a free slot in the hash table and fill it. */
if ( !(hp = hashnext( pw->pw_uid )) )
prexit( "sps - Too many users in passwd file\n" ) ;
hp->h_uid = pw->pw_uid ;
(void)strncpy( hp->h_uname, pw->pw_name, UNAMELEN ) ;
}
(void)endpwent() ;
}
SHAR_EOF
if test 1905 -ne "`wc -c < 'initialise.c'`"
then
echo shar: error transmitting "'initialise.c'" '(should have been 1905 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'initsymbols.c'" '(2994 characters)'
if test -f 'initsymbols.c'
then
echo shar: will not over-write existing file "'initsymbols.c'"
else
sed 's/^X//' << \SHAR_EOF > 'initsymbols.c'
# include "sps.h"
# include "flags.h"
# ifdef BSD42
# include <sys/file.h>
# endif
# include <nlist.h>
# include <stdio.h>
/* INITSYMBOLS - Reads kmem values into the Info structure */
/*
** THIS CODE COPIES KMEM VALUES INTO THE INFO STRUCTURE ASSUMING THAT
** VALUES READ FROM THE KERNEL HAVE TYPE CADDR_T. THEREFORE, WE ARE
** MAKING THE DUBIOUS ASSUMPTION THAT INTS, POINTERS AND CADDR_T's
** HAVE IDENTICAL SIZES.
*/
initsymbols ()
{
register struct nlist *np ;
register struct symbol *s ;
register struct nlist *np0 ;
char *filesymbol ;
extern int Flkmem ;
extern struct flags Flg ;
extern struct symbol Symbollist[] ;
extern struct info Info ;
char *getcore() ;
char *strncpy() ;
filesymbol = Flg.flg_s ? Flg.flg_s : FILE_SYMBOL ;
/* Find the length of the symbol table */
for ( s = Symbollist ; s->s_kname ; s++ )
;
/* Construct an nlist structure by copying names from the symbol table*/
np0 = (struct nlist*)getcore( (s-Symbollist+1)*sizeof( struct nlist ) );
for ( s = Symbollist, np = np0 ; s->s_kname ; s++, np++ )
{
np->n_name = s->s_kname ;
np[1].n_name = (char*)0 ;
np->n_value = 0 ;
}
# ifdef BSD42
if ( access( filesymbol, R_OK ) < 0 )
# else
if ( access( filesymbol, 4 ) < 0 )
# endif
{
fprintf( stderr, "sps - Can't open symbol file %s", filesymbol);
sysperror() ;
}
/* Get kernel addresses */
nlist( filesymbol, np0 ) ;
if ( np0[0].n_value == -1 )
{
fprintf( stderr, "sps - Can't read symbol file %s", filesymbol);
sysperror() ;
}
for ( s = Symbollist, np = np0 ; s->s_kname ; s++, np++ )
{
if ( !np->n_value )
{
fprintf( stderr, "sps - Can't find symbol %s in %s",
np->n_name, filesymbol ) ;
/* Assume this error to be unimportant if the address
is only associated with a process wait state.
This may happen if the system has been configured
without a particular device. */
fprintf( stderr, &Info.i_waitstate[ 0 ] <= s->s_info
&& s->s_info < &Info.i_waitstate[ NWAITSTATE ]
? " (error is not serious)\n"
: " (ERROR MAY BE SERIOUS)\n" ) ;
*s->s_info = (caddr_t)0 ;
continue ;
}
/* If no indirection is required, just copy the obtained value
into the `Info' structure. */
if ( !s->s_indirect )
{
/* DUBIOUS ASSUMPTION THAT KMEM VALUE HAS SIZE OF A CADDR_T */
*s->s_info = (caddr_t)np->n_value ;
continue ;
}
/* Otherwise one level of indirection is required. Using the
obtained address, look again in the kernel for the value */
memseek( Flkmem, (long)np->n_value ) ;
/* DUBIOUS ASSUMPTION THAT KMEM VALUE HAS SIZE OF A CADDR_T */
(void)read( Flkmem, (char*)s->s_info, sizeof(caddr_t) ) ;
}
free( (char*)np0 ) ;
}
SHAR_EOF
if test 2994 -ne "`wc -c < 'initsymbols.c'`"
then
echo shar: error transmitting "'initsymbols.c'" '(should have been 2994 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'inittty.c'" '(3544 characters)'
if test -f 'inittty.c'
then
echo shar: will not over-write existing file "'inittty.c'"
else
sed 's/^X//' << \SHAR_EOF > 'inittty.c'
# include "sps.h"
# include <h/conf.h>
# include <h/tty.h>
# include <sys/stat.h>
# include <stdio.h>
/* INITTTY - Initialise the tty part of the info structure */
inittty ()
{
register struct ttyline *lp ;
# ifdef BSD42
register struct direct *dp ;
DIR *dfd ;
# else
struct direct dir ;
FILE *dfd ;
# endif
struct stat statbuf ;
static char filedev[] = FILE_DEV ;
extern struct info Info ;
extern int Flkmem ;
# ifdef BSD42
DIR *opendir() ;
struct direct *readdir() ;
# else
FILE *fopen() ;
# endif
lp = Info.i_ttyline ;
# ifdef BSD42
if ( !(dfd = opendir( filedev )) )
# else
if ( !(dfd = fopen( filedev, "r" )) )
# endif
prexit( "Can't open %s\n", filedev ) ;
if ( chdir( filedev ) < 0 )
prexit( "sps - Can't chdir to %s\n", filedev ) ;
# ifdef BSD42
/* Read all entries in the device directory, looking for ttys */
while ( dp = readdir( dfd ) )
{ /* Skip entries that do not match "tty" or "console" */
if ( strncmp( "tty", dp->d_name, 3 )
&& strcmp( "console", dp->d_name ) )
continue ;
/* Skip "tty" itself */
if ( dp->d_namlen == 3 )
continue ;
# ifdef CHAOS
/* Skip chaos ttys ; they are accessed during ttystatus() */
if ( dp->d_namelen > 3 &&
dp->d_name[ sizeof( "tty" ) - 1 ] == 'C' )
continue ;
# endif
if ( lp >= &Info.i_ttyline[ MAXTTYS ] )
prexit( "sps - Too many ttys in %s\n", filedev ) ;
/* Copy the tty name into the information entry */
if ( !strcmp( dp->d_name, "console" ) )
{
lp->l_name[0] = 'c' ;
lp->l_name[1] = 'o' ;
}
else
{
lp->l_name[0] = dp->d_name[3] ;
lp->l_name[1] = dp->d_name[4] ;
}
/* Ensure that this tty is actually a valid character device */
if ( stat( dp->d_name, &statbuf ) < 0 )
continue ;
# else
/* Read all entries in the device directory, looking for ttys */
while ( fread( (char*)&dir, sizeof( struct direct ), 1, dfd ) == 1 )
{ /* Skip entries that do not match "tty" or "console" */
if ( strncmp( "tty", dir.d_name, 3 )
&& strcmp( "console", dir.d_name ) )
continue ;
/* Skip "tty" itself */
if ( dir.d_name[3] == '\0' )
continue ;
# ifdef CHAOS
/* Skip chaos ttys ; they are accessed during ttystatus() */
if ( dir.d_name[ sizeof( "tty" ) - 1 ] == 'C' )
continue ;
# endif
if ( lp >= &Info.i_ttyline[ MAXTTYS ] )
prexit( "sps - Too many ttys in %s\n", filedev ) ;
/* Copy the tty name into the information entry */
if ( !strcmp( dir.d_name, "console" ) )
{
lp->l_name[0] = 'c' ;
lp->l_name[1] = 'o' ;
}
else
{
lp->l_name[0] = dir.d_name[3] ;
lp->l_name[1] = dir.d_name[4] ;
}
/* Ensure that this tty is actually a valid character device */
if ( stat( dir.d_name, &statbuf ) < 0 )
continue ;
# endif
if ( (statbuf.st_mode & S_IFMT) != S_IFCHR )
continue ;
/* Find the device # of the tty and the address of its
associated struct tty in /dev/kmem. */
lp->l_dev = statbuf.st_rdev ;
memseek( Flkmem,
(long)&Info.i_cdevsw[ major( statbuf.st_rdev ) ].d_ttys ) ;
if ( read( Flkmem, (char*)&lp->l_addr, sizeof( lp->l_addr ) )
!= sizeof( lp->l_addr ) )
{
fprintf( stderr, "sps - Can't read struct tty for %s\n",
# ifdef BSD42
dp->d_name ) ;
# else
dir.d_name ) ;
# endif
continue ;
}
lp->l_addr += (int)minor( statbuf.st_rdev ) ;
lp++ ;
}
# ifdef BSD42
(void)closedir( dfd ) ;
# else
(void)fclose( dfd ) ;
# endif
}
SHAR_EOF
if test 3544 -ne "`wc -c < 'inittty.c'`"
then
echo shar: error transmitting "'inittty.c'" '(should have been 3544 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Mod.sources
mailing list