Regression tests for gsh.

This commit is contained in:
tribby 1999-11-30 20:28:24 +00:00
parent 769328325f
commit 7edb4eac39
13 changed files with 1920 additions and 0 deletions

40
bin/gsh/tests/Makefile Normal file
View File

@ -0,0 +1,40 @@
#
# This makefile is intended for use with dmake(1) on Apple IIGS
# $Id: Makefile,v 1.1 1999/11/30 20:28:24 tribby Exp $
#
# Created by Dave Tribby (beginning June 1998)
# This makefile creates the simple test programs used for gsh testing.
# These two programs are used directly by the dotests command script:
# echoparams echo parameters passed from command line;
# uses reparse.asm assembly language subroutine
# callsystem call the system() library subroutine
#
# The remaining two programs can be run to verify the system
# shellenv print information on the shell environment
# testfork use fork/_execve/wait/kill the way gsh does
# Make sure lint is turned on
CFLAGS += -w
all: echoparams callsystem shellenv testfork
# echoparams has a helper subroutine named reparse.
echoparams.o: echoparams.c
reparse.o: reparse.asm
echoparams: echoparams.c reparse.asm
17/occ -o echoparams.o -i -w -a0 -c echoparams.c
17/occ -o reparse.o -i -w -a0 -c reparse.asm
17/occ -o echoparams echoparams.o reparse.o
rm -f echoparams.root echoparams.o reparse.root reparse.o
clean:
rm -f *.o
rm -f *.root
clobber: clean
rm -f echoparams callsystem shellenv testfork

View File

@ -0,0 +1,26 @@
/*
* callsystem.c: see what happens when system() is called
*
* Written by Dave Tribby to test gsh * June 1998
* $Id: callsystem.c,v 1.1 1999/11/30 20:28:24 tribby Exp $
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i, rtnval;
printf("Test of system() function\n");
*argv++;
if (argc == 1) {
rtnval = system((char *)0L);
printf(" Null parameter returns value of %d\n", rtnval);
}
else for (i = 1; i < argc; i++) {
rtnval = system(*argv);
printf(" `%s` returns value = %d\n", *argv,rtnval);
*argv++;
}
return rtnval;
}

596
bin/gsh/tests/dotests Normal file
View File

@ -0,0 +1,596 @@
# Test gsh built-in commands
# Written by Dave Tribby beginning June 1998
# $Id: dotests,v 1.1 1999/11/30 20:28:24 tribby Exp $
# -----------------------------------------------------------------------
# Support commands that must be available (usually in tests directory)
# echoparams echo parameters passed from command line;
# uses reparse.asm assembly language subroutine
# callsystem call the system() library subroutine
# Support exec files that must be available (usually in tests directory)
# prin10params prints $0 through $10
# singletc execute a single test and compare results
# releasemem releases most gsh memory; use with debug mem mgr
#
# Additional job control tests that cannot be part of this file are
# found in testjobs and testjobs2.
#
# Output comparison files are read from the directory specified within this
# script by variable $cmpout (/src/gno/bin/gsh/tests/bi.out/). NOTE: the
# hash.list file needs updating when contents of /bin and /usr/bin changes.
# -----------------------------------------------------------------------
# NOTE: $PATH might be messed up, so use full path for sed
set SED=/usr/bin/sed
# Clean up the alias environment, so results are consistent
# A. Generate the cleanup aliases command file
set tmpcmd=/tmp/cleanalias
alias | $SED -e 's/:.*//' -e 's/^/unalias /' > $tmpcmd
# B. Run the cleanup command
echo -n "Removing all aliases..."
source $tmpcmd
echo
# Clean up the variable environment, so results are consistent
# A. Generate the cleanup variables command file
set tmpcmd=/tmp/cleanenv
set | $SED -e '/TERM/d' -e 's/ = .*//' -e 's/^/unset /' > $tmpcmd
# B. Run the cleanup command
echo -n "Removing environment variables..."
source $tmpcmd
echo
# Add back a few environment variables
# Location of shell to be tested
set objdir /obj/gno/bin/gsh
setenv SHELL=$objdir/gsh
setenv USER=test
set testdir=/src/gno/bin/gsh/tests
setenv HOME=$testdir
setenv PATH "$objdir"
set PATH "$testdir $PATH /bin /usr/bin"
export PATH
rehash
# Directories for holding test output and comparison output
setenv cmpdir=$testdir/bi.out
setenv outdir=/tmp/bi.out
# Use either cmp or diff for comparing files
setenv compare="diff"
setenv compare="cmp"
# Create directory under /tmp to hold results
# GNO's rm command is no longer implemented under the cp command
set RM="/bin/rm"
# Create directory under /tmp to hold results
echo -n "Removing output directory $outdir..."
$RM -rf $outdir/*
rmdir $outdir
echo
mkdir $outdir
echo " = = = = = Start of $SHELL built-in tests = = = = ="
echo ""
# Use clear at beginning
setenv testcmd="clear"
echo "Test: $testcmd"
$testcmd
echo " Completion status for $testcmd = $status"
echo ""
# There should be no aliases at this point
setenv testcmd="alias"
setenv listfile="$testcmd.0.list"
singletc
# Add a few aliases back in
echo "Adding aliases for ls and mv"
alias ls 'ls -l'
alias mv 'cp -p mv'
setenv testcmd="alias"
setenv listfile="$testcmd.list"
singletc
setenv testcmd="alias"
setenv testarg="newcmd date"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
unset testarg
setenv testcmd="unalias"
setenv testarg="newcmd"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
unset testarg
setenv testcmd="which"
setenv testarg="ls"
setenv listfile="$testcmd.0.list"
singletc
setenv testcmd="unalias"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
setenv testcmd="which"
setenv listfile="$testcmd.list"
singletc
unset testarg
setenv testcmd="echo"
echo "Test: $testcmd"
setenv listfile="$testcmd.list"
echo '\- - - - - - - - - - E C H O T E S T S - - - - - - - - - -' > $outdir/$listfile
echo >> $outdir/$listfile
echo Testing whether the echo command inserts an extra space: >> $outdir/$listfile
echo -n "There should be no space between ->" >> $outdir/$listfile
echo "<- the '->' and '<-'" >> $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
set testcmd=sed
echo "Test: $testcmd and redirected stdin/stdout"
setenv infile="${testcmd}0.in"
setenv listfile1="${testcmd}1.list"
echo "This is a test" > $outdir/$infile
echo "This is another test" >> $outdir/$infile
$testcmd -e's/test/success/' < $outdir/$infile > $outdir/$listfile1
$compare $cmpdir/$listfile1 $outdir/$listfile1
echo " comparison status = $status for $listfile1"
echo ""
setenv listfile2="${testcmd}2.list"
echo "Test: $testcmd and pipes"
cat $outdir/$infile | $testcmd -e's/test/success/' | cat > $outdir/$listfile2
$compare $cmpdir/$listfile1 $outdir/$listfile2
echo " comparison status = $status for $listfile2"
echo ""
setenv testcmd="commands"
setenv listfile="$testcmd.list"
singletc
setenv testcmd="export"
setenv testcmd="set"
setenv listfile="$testcmd.list"
singletc
## NOTE: need to clean up prefixes so results are consistent
# NOTE: since prefix is a non-forked built-in command, it must be
# executed from a new shell to capture its output
setenv testcmd="$SHELL"
setenv testarg="-f prefix"
setenv listfile="prefix.list"
singletc
unset testarg
setenv testcmd="pushd"
setenv testarg="$cmpdir"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
unset testarg
setenv testcmd="dirs"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
unset testarg
setenv testcmd="cd"
setenv testarg="$outdir"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
unset testarg
# NOTE: since pwd is a non-forked built-in command, it must be
# executed from a new shell to capture its output
setenv testcmd="$SHELL"
setenv testarg="-f pwd"
setenv listfile="pwd.list"
singletc
unset testarg
setenv testcmd="chdir"
setenv testarg="/bin"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
unset testarg
setenv testcmd="$SHELL"
setenv testarg="-f pwd"
setenv listfile="pwd.2.list"
singletc
unset testarg
setenv testcmd="popd"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
unset testarg
## NOTE: may need shorter path so results are consistent,
## but also need access to /bin and /usr/bin commands.
setenv testcmd="rehash"
echo "Test: $testcmd $testarg"
$testcmd $testarg
echo " Completion status = $status"
## Comparison file hash.list may need to be replaced, depending upon
## changes to contents of /bin/ and /usr/bin/ directories.
setenv testcmd="hash"
setenv listfile="$testcmd.list"
singletc
# Create two commands by the same name in different directories
setenv testcmd="pathtst"
echo "echo This is test command number 1" > /tmp/$testcmd
chtyp -l exec /tmp/$testcmd
echo "echo This is test command number 2" > $outdir/$testcmd
chtyp -l exec $outdir/$testcmd
# Add those directories to $PATH (holding onto the old $PATH)
setenv holdpath="$PATH"
setenv PATH="/tmp $outdir $PATH"
rehash
setenv listfile="$testcmd.1.list"
singletc
# Reorder the search of $PATH and try again
setenv OLDPATHMODE=1
rehash
setenv testarg="with OLDPATHMODE set"
setenv listfile="$testcmd.2.list"
singletc
unset testarg
# Reset environment so $PATH acts in the expected way
setenv PATH="$holdpath"
unset OLDPATHMODE
unset holdpath
rehash
$RM /tmp/$testcmd $outdir/$testcmd
setenv testcmd="unhash"
# Job control: see separate file "testjobs", which must be sourced.
setenv testcmd="bg"
setenv testcmd="fg"
setenv testcmd="kill"
setenv testcmd="stop"
setenv testcmd="jobs"
# Cannot test output from these...just status
setenv testcmd="tset"
echo "Test: $testcmd"
$testcmd
echo " Completion status = $status"
echo ""
setenv testcmd="setdebug"
setenv testarg="-pathtrace"
echo "Test: $testcmd"
$testcmd $testarg
echo " Completion status = $status"
echo ""
unset testarg
setenv testcmd="bindkey"
setenv testcmd="history"
echo "Test: $testcmd"
$testcmd
echo " Completion status = $status"
setenv testcmd="ps"
echo "Test: $testcmd"
$testcmd
echo " Completion status = $status"
echo ""
# These have been tested enough through other uses
setenv testcmd="source"
setenv testcmd="unset"
setenv testcmd="setenv"
# Cannot figure how to test these...
setenv testcmd="exit"
setenv testcmd="edit"
# Create a gsh execution file with a forked command in it and execute
# it two different ways. (From "cmdtest")
echo
echo "= = Testing execution file with forked commands = = = = = = = "
set tmpcmd=/tmp/testcmds
echo -n > $tmpcmd
chtyp -l exec $tmpcmd
set echo_cmd="/bin/echo"
set ps_cmd="/bin/ps -l"
echo "$echo_cmd $ps_cmd" >> $tmpcmd
echo "$ps_cmd" >> $tmpcmd
# Execute the command
echo -n "= = Executing as a command: "
$tmpcmd
# Source the command
echo -n "= = Sourcing the command: "
source $tmpcmd
echo "= = Execution files did not hang: test successful! = = = = = ="
echo
echo " = = = = = Start of $SHELL commandline expansion tests = = = ="
echo
setenv home=/src/gno/bin/gsh/tests
setenv listfile="tilde.list"
echo 'Test: echo ~/ ~:'
echo ~/ ~: > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
setenv listfile="glob.list"
echo 'ls *.c bad*name dot*'
ls *.c bad*name dot* > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
setenv listfile="multi.list"
echo 'Test: multiple commands separated by ";"'
set t_num=0
set t_num=1 ; echo "Test variable has been set to $t_num" > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
unset t_num
setenv listfile="semi.list"
echo 'Test: semicolons within quoted parameters'
echoparams "This ; will" 'see if ; are confusing' > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
setenv listfile="null.list"
echo 'Test: null parameters'
echoparams "Parameter #1" "" p3 '' "Last param" > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
# Next two commands operate with KEEPQUOTE environment variable set
setenv listfile=keep.list
echo 'Test: keep single quotes around parameters'
setenv KEEPQUOTE=1
echoparams 'Parameter #1' "" p3 '' "Last param" > $outdir/$listfile
echo " Completion status = $status"
unset KEEPQUOTE
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
setenv listfile=keep2.list
echo 'Test: keep single quotes around parameters, again'
setenv KEEPQUOTE=1
echoparams '{ print "Hello, world" }' filename > $outdir/$listfile
echo " Completion status = $status"
unset KEEPQUOTE
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
# Ensure that $0 - $10 are created appropriately
setenv testcmd="print10params"
setenv listfile="print10.list"
echo "Test: $testcmd"
$testcmd p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo
echo
echo " = = = = = = Start of $SHELL system() interface tests = = = = ="
echo
setenv listfile="nullsys.list"
echo 'Test: call system() with null parameter'
callsystem "" > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""
set sys_cmd "ps"
echo "Test: concurrent execution of $sys_cmd"
callsystem "$sys_cmd" & ; callsystem "$sys_cmd"
echo
set sys_cmd "/bin/ps -l"
echo "Test: concurrent execution of $sys_cmd"
callsystem "$sys_cmd" & ; callsystem "$sys_cmd"
echo
set sys_cmd "pwd"
echo "Test: concurrent execution of $sys_cmd"
callsystem "$sys_cmd" & ; callsystem "$sys_cmd"
echo
set sys_cmd "rehash"
echo "Test: concurrent execution of $sys_cmd"
callsystem "$sys_cmd" & ; callsystem "$sys_cmd"
echo
set sys_cmd "hash"
echo "Test: concurrent execution of $sys_cmd"
callsystem "$sys_cmd" & ; callsystem "$sys_cmd"
echo
echo "= = = Execution did not hang: test successful! = = = = ="
echo
echo " = = = = = $SHELL commands' usage strings and status test = = = ="
echo
# Non-forked commands
bg a b c
echo " Completion status = $status (expected 1)"
chdir a b c
echo " Completion status = $status (expected 1)"
cd a b c
echo " Completion status = $status (expected 1)"
clear a b c
echo " Completion status = $status (expected 1)"
export
echo " Completion status = $status (expected 1)"
fg a b c
echo " Completion status = $status (expected 1)"
jobs a b c
echo " Completion status = $status (expected 1)"
kill a b c
echo " Completion status = $status (expected 1)"
popd a b c
echo " Completion status = $status (expected 1)"
prefix a b c
echo " Completion status = $status (expected 1)"
pushd a b c
echo " Completion status = $status (expected 1)"
pwd a b c
echo " Completion status = $status (expected 1)"
rehash a b c
echo " Completion status = $status (expected 1)"
stop a b c
echo " Completion status = $status (expected 1)"
tset a b c
echo " Completion status = $status (expected 1)"
unalias
echo " Completion status = $status (expected 1)"
unhash a b c
echo " Completion status = $status (expected 1)"
unset
echo " Completion status = $status (expected 1)"
# Forked commands
commands a b b
echo " Completion status = $status (expected 1)"
setdebug a b c
echo " Completion status = $status (expected 1)"
dirs a b c
echo " Completion status = $status (expected 1)"
hash a b c
echo " Completion status = $status (expected 1)"
ps a b c
echo " Completion status = $status (expected 1)"
set -x
echo " Completion status = $status (expected 1)"
setenv -x
echo " Completion status = $status (expected 1)"
bindkey a b c
echo " Completion status = $status (expected 1)"
echo -x
echo " Completion status = $status (expected 1)"
history a b c
echo " Completion status = $status (expected 1)"
which
echo " Completion status = $status (expected 1)"
edit
echo " Completion status = $status (expected 1)"
echo
echo " = = = = = End of $SHELL tests = = = = ="
echo
echo "Note: To test job control commands, source testjobs and testjobs2."

View File

@ -0,0 +1,30 @@
/*
* echoparams: echo the arguments passed as parameters
*
* Written by Dave Tribby to test gsh * June 1998
* $Id: echoparams.c,v 1.1 1999/11/30 20:28:24 tribby Exp $
*/
#include <stdio.h>
#include <orca.h>
/* Interface to subroutine that re-parses parameters */
extern int reparse(char *argv[], char *commandline);
int main(int argc, char *argv[])
{
int i;
int argc1;
char **argv1;
printf("Command line: %s\n", commandline());
for (i = 0; i < argc; i++)
printf(" parameter %2d: '%s'\n", i,*argv++);
printf("Reparsing...\n");
argc1 = reparse(&argv1, commandline());
for (i = 0; i < argc1; i++)
printf(" parameter %2d: '%s'\n", i,*argv1++);
return 0;
}

View File

@ -0,0 +1,11 @@
echo "p0 = $0"
echo "p1 = $1"
echo "p2 = $2"
echo "p3 = $3"
echo "p4 = $4"
echo "p5 = $5"
echo "p6 = $6"
echo "p7 = $7"
echo "p8 = $8"
echo "p9 = $9"
echo "p10 = $10"

49
bin/gsh/tests/releasemem Normal file
View File

@ -0,0 +1,49 @@
# Release as much memory as possible from current invocation of gsh.
# This is only useful when using the debug version of memory routines
# found in mmdebug.asm, because the normal memory routines hold on to
# allocated memory for reuse. The steps for using this to check for
# memory leaks:
# - link gsh with debug memory management routines
# - execute that version (it will be much slower than normal)
# - perform activities with the debug gsh
# - source this file
# - get memory manager ID of the debug gsh (via ps, for example)
# - using the NiftyList NDA, list memory allocated by MMID+$0D00;
# for example, if MMID=1009 enter the NiftyList command
# 1D09id
# There should be several blocks of size $400, plus blocks for
# strings holding the current directory, the current command,
# and the name of the history file. All other allocated memory
# is suspicious. (If a gsh command is killed, its memory will
# probably be left allocated.)
# Written by Dave Tribby (November 1998)
# $Id: releasemem,v 1.1 1999/11/30 20:28:24 tribby Exp $
echo " = = = = = Releasing gsh allocated memory = = = = ="
echo " Note: This command should be sourced, not executed"
echo
# NOTE: $PATH might be messed up, so use full path for sed and cat
set SED=/usr/bin/sed
set CAT=/bin/cat
echo -n "Removing all aliases..."
# A. Generate the cleanup aliases command file
set tmpcmd=/tmp/cleanalias
alias | $SED -e 's/:.*//' -e 's/^/unalias /' > $tmpcmd
# B. Run the cleanup command
source $tmpcmd
echo
echo -n "Releasing hash table memory..."
unhash
echo
echo -n "Removing directory stack..."
dirs | $SED -e's/[^ ]* [^ ]*/popd; /' > $tmpcmd
source $tmpcmd
echo -n "Reduce the history to 1 (minimum)"
setenv HISTORY=1
echo
echo "=> Manually enter any command for final release of history memory"

34
bin/gsh/tests/reparse.asm Normal file
View File

@ -0,0 +1,34 @@
* -------------------------------------------------------------------
*
* Example of routine to re-parse the commandline arguments to
* recognize both " and ' as quote characters.
*
* Written by Dave Tribby beginning November 1999
*
* Summary: extern int reparse(char *argv[], char *commandline);
*
* Method: call the GNO routine ~GNO_PARSEARG.
*
* -------------------------------------------------------------------
dummy START ; This segment ends up in .root
END
case on
reparse START
; NOTE: ~GNO_PARSEARG expects commandline parameter to be the "raw"
; value passed by the shell, so it skips the first 8 characters.
; Need to adjust pointer back 8 bytes.
lda $8,s ; Get commandline parameter, low-order word.
sec
sbc #8 ; Subtract 8.
sta $8,s
lda $a,s ; Adjust high-order word, if necessary.
sbc #0
sta $a,s
jml >~GNO_PARSEARG ; Let ~GNO_PARSEARG handle the rest.
END

155
bin/gsh/tests/shellenv.c Normal file
View File

@ -0,0 +1,155 @@
/*
* shellenv: print information on the shell environment
*
* Written by Dave Tribby to test gsh * June 1998
* $Id: shellenv.c,v 1.1 1999/11/30 20:28:24 tribby Exp $
*/
#include <stdlib.h>
#include <stdio.h>
#include <shell.h>
#include <types.h>
/* VersionGS parameter block */
VersionGSPB vers_pb = {1};
/* GetLInfoGS parameter block */
ResultBuf255Ptr sFilePtr = NULL;
ResultBuf255Ptr dFilePtr = NULL;
ResultBuf255Ptr paramsPtr = NULL;
ResultBuf255Ptr iStringPtr = NULL;
GetLInfoGSPB get_li_pb = {11};
/* GetLangGS paramater block */
GetLangGSPB get_l_pb = {1};
/* DirectionGS parameter block */
DirectionGSPB dir_pb = {2};
char *devnm[3]={"stdin ", "stdout", "stderr"};
char *devdir[3]={"Console", "Printer", "Disk file"};
/* Cleanup routine at end: deallocate buffers */
void cleanup(void)
{
if (get_li_pb.sFile) {
free(get_li_pb.sFile);
get_li_pb.sFile = NULL;
}
if (get_li_pb.dFile) {
free(get_li_pb.dFile);
get_li_pb.dFile = NULL;
}
if (get_li_pb.parms) {
free(get_li_pb.parms);
get_li_pb.parms = NULL;
}
if (get_li_pb.iString) {
free(get_li_pb.iString);
get_li_pb.iString = NULL;
}
}
/* Allocate memory for a GS/OS result buffer */
ResultBuf255Ptr allocate_buf(Word numbytes)
{
ResultBuf255Ptr hold_ptr;
if ( (hold_ptr = (ResultBuf255Ptr) malloc(numbytes+1)) == 0) {
printf("Error allocating %u bytes of memory\n");
exit (1);
}
hold_ptr->bufSize = 1024;
return hold_ptr;
}
/* Print information about a buffer */
void print_buf_info(char *title, ResultBuf255Ptr buf_ptr)
{
char *end_str;
/* Calculate address beyond end of string */
end_str = buf_ptr->bufString.text + buf_ptr->bufString.length;
/* Terminate the string with a null character */
*end_str = '\0';
printf("Buffer for %s: size = %u\n%s\n\n",
title, buf_ptr->bufString.length, buf_ptr->bufString.text);
}
/* Print information about option flags */
void print_flag_info(unsigned long flags)
{
char ch='A';
unsigned long testpos=0x80000000;
printf("%08lX:", flags);
while (ch <= 'Z') {
if (testpos & flags) printf(" %c",ch);
ch++;
testpos = testpos >> 1;
}
}
int main(int argc, char *argv[])
{
int i;
printf("=< S H E L L E N V I R O N M E N T R E P O R T >=\n");
atexit(cleanup);
VersionGS(&vers_pb);
printf("Shell version: ");
for (i=0; i<4; i++) putchar(vers_pb.version[i]);
putchar('\n');
printf("Edit/Compile/Link environment:\n");
get_li_pb.sFile = allocate_buf(1024);
get_li_pb.dFile = allocate_buf(255);
get_li_pb.parms = allocate_buf(255);
get_li_pb.iString = allocate_buf(1024);
GetLInfoGS(&get_li_pb);
print_buf_info("Source file", (ResultBuf255Ptr) get_li_pb.sFile);
print_buf_info("Destination file", (ResultBuf255Ptr) get_li_pb.dFile);
print_buf_info("Parameter List", (ResultBuf255Ptr) get_li_pb.parms);
print_buf_info("Command specific", (ResultBuf255Ptr) get_li_pb.iString);
printf("Error level: Maximum = %d, Found = %d\n",
get_li_pb.merr, get_li_pb.merrf);
printf("Operations flag = %08X Keep flag = %d\n",
get_li_pb.lops, get_li_pb.kflag);
printf("Flags: -");
print_flag_info(get_li_pb.mFlags);
printf(" +");
print_flag_info(get_li_pb.pFlags);
putchar('\n');
printf("Displacement into file: %ld\n", get_li_pb.org);
GetLangGS(&get_l_pb);
printf("Current language number = %d (", get_l_pb.lang);
switch(get_l_pb.lang) {
case 0: printf("ProDOS");
break;
case 1: printf("text");
break;
case 3: printf("ASM65816");
break;
case 5: printf("ORCA/Pascal");
break;
case 6: printf("EXEC");
break;
case 8: printf("ORCA/C");
break;
default: printf("?");
}
printf(")\n");
printf("I/O Redirection:\n");
for (i=0; i<3; i++) {
dir_pb.device = i;
DirectionGS(&dir_pb);
printf(" %d: %s direction = %d", i,devnm[i],dir_pb.direct);
if (dir_pb.direct < 3) printf(" (%s)", devdir[dir_pb.direct]);
putchar('\n');
}
return 0;
}

10
bin/gsh/tests/singletc Normal file
View File

@ -0,0 +1,10 @@
# Run one test and compare results.
# Before calling, set $testcmd, $testarg, $listfile
echo "Test: $testcmd $testarg"
$testcmd $testarg > $outdir/$listfile
echo " Completion status = $status"
echo "Checking results against control file (no differences expected)"
$compare $cmpdir/$listfile $outdir/$listfile
echo " comparison status = $status for $listfile"
echo ""

446
bin/gsh/tests/test.list Normal file
View File

@ -0,0 +1,446 @@
Script started on: Fri Nov 26 21:55:46 1999
Executing gshrc from directory /H2/NewDev
[61] tests=> dotests ; exit
Removing all aliases...
Removing environment variables...
hashed 118 files
Removing output directory /tmp/bi.out...
= = = = = Start of /obj/gno/bin/gsh/gsh built-in tests = = = = =
Test: clear
Completion status for clear = 0
Test: alias
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for alias.0.list
Adding aliases for ls and mv
Test: alias
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for alias.list
Test: alias newcmd date
Completion status = 0
Test: unalias newcmd
Completion status = 0
Test: which ls
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for which.0.list
Test: unalias ls
Completion status = 0
Test: which ls
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for which.list
Test: echo
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for echo.list
Test: sed and redirected stdin/stdout
comparison status = 0 for sed1.list
Test: sed and pipes
comparison status = 0 for sed2.list
Test: commands
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for commands.list
Test: set
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for set.list
Test: /obj/gno/bin/gsh/gsh -f prefix
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for prefix.list
Test: pushd /src/gno/bin/gsh/tests/bi.out
~/bi.out ~
Completion status = 0
Test: dirs
~/bi.out ~
Completion status = 0
Test: cd /tmp/bi.out
Completion status = 0
Test: /obj/gno/bin/gsh/gsh -f pwd
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for pwd.list
Test: chdir /bin
Completion status = 0
Test: /obj/gno/bin/gsh/gsh -f pwd
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for pwd.2.list
Test: popd
~
Completion status = 0
Test: rehash
hashed 118 files
Completion status = 0
Test: hash
Completion status = 0
Checking results against control file (no differences expected)
[datafork] /src/gno/bin/gsh/tests/bi.out/hash.list differ: /tmp/bi.out/hash.list char 18, line 1
comparison status = 1 for hash.list
hashed 121 files
Test: pathtst
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for pathtst.1.list
hashed 121 files
Test: pathtst with OLDPATHMODE set
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for pathtst.2.list
hashed 118 files
Test: tset
Completion status = 0
Test: setdebug
Completion status = 0
Test: history
1: less ../Makefile
2: pushd /src/gno
3: fgrep clean *.mk
4: more binrules.mk
5: popd
6: edit Makefile
7: dmake -u clean
8: dmake -n clean
9: dmake -n clobber
10: ls
11: dmake clobber
12: ls
13: ls *.c
14: more testfork.c
15: ls
16: edit dotests
17: more shellenv.c
18: ls *.c
19: ll calls*
20: edit Makefile *.c
21: ll
22: more cmdtest4fr
23: rm cmdtest4fr
24: more cmdtestmul
25: rm cmdtestmul
26: ls
27: more dotests
28: ls
29: edit dotests
30: chtyp -l exec dotests
31: edit dotests
32: ll
33: more fulltests.mul
34: more /var/tmp/test.list
35: edit /var/tmp/test.list
36: ls
37: more releasemem
38: ls
39: more singletc
40: fgrep singletc dotests
41: edit dotests
42: ls
43: more smallbi
44: ls
45: more testedit
46: ll test*
47: edit Makefile
48: clrff
49: clrff
50: ls
51: mkdir extra
52: mv singletc testedit extra/
53: ls -n
54: mv fulltests.mul extra/
55: more cmdtest
56: mv cmdtest extra/
57: ls
58: dmake clean
59: dmake clobber
60: exit
61: dotests ; exit
Completion status = 0
Test: ps
ID STATE TT MMID UID TIME COMMAND
1 ready co 1002 0000 23:12 NullProcess
2 paused nu 1004 0000 0:01 init
3 blocked nu 1003 0000 0:00 syslogd
382 paused co 1006 0000 0:22 -gsh
539 waiting co 1005 0000 0:00 /src/gno/build.tools/fulltests
548 paused 07 1011 0000 0:05 gsh
547 waiting 06 1010 0000 0:00 script /tmp/rawlist
549 ready 06 100F 0000 2:34 forked child of script /tmp/rawlist
558 ready 07 1008 0000 0:14 dotests
820 running 07 1012 0000 0:00 forked child of dotests
Completion status = 0
= = Testing execution file with forked commands = = = = = = =
= = Executing as a command: /bin/ps -l
ID PPID PGRP STATE TT MMID USER TIME COMMAND
1 1 00 ready co 1002 0000 23:12 NullProcess
2 1 02 paused 00 1004 0000 00:01 init
3 2 02 blocked 00 1003 0000 00:00 syslogd
382 2 04 paused co 1006 0000 00:22 -gsh
539 382 03 waitsigch co 1005 0000 00:00 /src/gno/build.tools/fullte...
548 547 06 paused 07 1011 0000 00:05 gsh
547 539 03 waitsigch 06 1010 0000 00:00 script /tmp/rawlist
549 547 03 ready 06 100F 0000 02:38 forked child of process 547
558 548 05 waitsigch 07 1008 0000 00:14 dotests
838 558 05 waitsigch 07 1012 0000 00:00 /tmp/testcmds
840 838 05 running 07 100D 0000 00:00 /bin/ps -l
= = Sourcing the command: /bin/ps -l
ID PPID PGRP STATE TT MMID USER TIME COMMAND
1 1 00 ready co 1002 0000 23:12 NullProcess
2 1 02 paused 00 1004 0000 00:01 init
3 2 02 blocked 00 1003 0000 00:00 syslogd
382 2 04 paused co 1006 0000 00:22 -gsh
539 382 03 waitsigch co 1005 0000 00:00 /src/gno/build.tools/fullte...
548 547 06 paused 07 1011 0000 00:05 gsh
547 539 03 waitsigch 06 1010 0000 00:00 script /tmp/rawlist
549 547 03 ready 06 100F 0000 02:39 forked child of process 547
558 548 05 paused 07 1008 0000 00:15 dotests
843 558 07 running 07 100D 0000 00:00 /bin/ps -l
= = Execution files did not hang: test successful! = = = = = =
= = = = = Start of /obj/gno/bin/gsh/gsh commandline expansion tests = = = =
Test: echo ~/ ~:
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for tilde.list
ls *.c bad*name dot*
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for glob.list
Test: multiple commands separated by ";"
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for multi.list
Test: semicolons within quoted parameters
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for semi.list
Test: null parameters
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for null.list
Test: keep single quotes around parameters
" Completion status = 0"
Checking results against control file (no differences expected)
comparison status = 0 for keep.list
Test: keep single quotes around parameters, again
" Completion status = 0"
Checking results against control file (no differences expected)
comparison status = 0 for keep2.list
Test: print10params
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for print10.list
= = = = = = Start of /obj/gno/bin/gsh/gsh system() interface tests = = = = =
Test: call system() with null parameter
Completion status = 0
Checking results against control file (no differences expected)
comparison status = 0 for nullsys.list
Test: concurrent execution of ps
Test of system() function
ID STATE TT MMID UID TIME COMMAND
1 ready co 1002 0000 23:12 NullProcess
2 paused nu 1004 0000 0:01 init
3 blocked nu 1003 0000 0:00 syslogd
382 paused co 1006 0000 0:22 -gsh
539 waiting co 1005 0000 0:00 /src/gno/build.tools/fulltests
548 paused 07 1011 0000 0:05 gsh
547 waiting 06 1010 0000 0:00 script /tmp/rawlist
549 ready 06 100F 0000 2:58 forked child of script /tmp/rawlist
558 ready 07 1008 0000 0:18 dotests
942 ready 07 1013 0000 0:00 callsystem ps
943 running 07 1012 0000 0:00 forked child of callsystem ps
944 ready 07 1015 0000 0:00 callsystem ps
Test of system() function
`ps` returns value = 0
ID STATE TT MMID UID TIME COMMAND
1 ready co 1002 0000 23:12 NullProcess
2 paused nu 1004 0000 0:01 init
3 blocked nu 1003 0000 0:00 syslogd
382 paused co 1006 0000 0:22 -gsh
539 waiting co 1005 0000 0:00 /src/gno/build.tools/fulltests
548 paused 07 1011 0000 0:05 gsh
547 waiting 06 1010 0000 0:00 script /tmp/rawlist
549 ready 06 100F 0000 2:59 forked child of script /tmp/rawlist
558 waiting 07 1008 0000 0:18 dotests
945 running 07 1012 0000 0:00 forked child of callsystem ps
944 waiting 07 1015 0000 0:00 callsystem ps
`ps` returns value = 0
Test: concurrent execution of /bin/ps -l
Test of system() function
ID PPID PGRP STATE TT MMID USER TIME COMMAND
1 1 00 ready co 1002 0000 23:12 NullProcess
2 1 02 paused 00 1004 0000 00:01 init
3 2 02 blocked 00 1003 0000 00:00 syslogd
Test of system() function
382 2 04 paused co 1006 0000 00:22 -gsh
539 382 03 waitsigch co 1005 0000 00:00 /src/gno/build.tools/fullte...
548 547 06 paused 07 1011 0000 00:05 gsh
547 539 03 waitsigch 06 1010 0000 00:00 script /tmp/rawlist
549 547 03 ready 06 100F 0000 03:00 forked child of process 547
558 548 05 waitsigch 07 1008 0000 00:19 dotests
949 558 07 waitsigch 07 1013 0000 00:00 callsystem "/bin/ps -l"
950 949 07 running 07 100D 0000 00:00 /bin/ps -l
951 558 05 ready 07 1014 0000 00:00 callsystem "/bin/ps -l"
ID PPID PGRP STATE TT MMID USER TIME COMMAND
1 1 00 ready co 1002 0000 23:12 NullProcess
2 1 02 paused 00 1004 0000 00:01 init
952 951 05 ready 07 1015 0000 00:00 /bin/ps -l
3 2 02 blocked 00 1003 0000 00:00 syslogd
382 2 04 paused co 1006 0000 00:22 -gsh
`/bin/ps -l` returns value = 0
539 382 03 waitsigch co 1005 0000 00:00 /src/gno/build.tools/fullte...
548 547 06 paused 07 1011 0000 00:05 gsh
547 539 03 waitsigch 06 1010 0000 00:00 script /tmp/rawlist
549 547 03 ready 06 100F 0000 03:00 forked child of process 547
558 548 05 waitsigch 07 1008 0000 00:19 dotests
951 558 05 waitsigch 07 1014 0000 00:00 callsystem "/bin/ps -l"
952 951 05 running 07 1015 0000 00:00 /bin/ps -l
`/bin/ps -l` returns value = 0
Test: concurrent execution of pwd
Test of system() function
:src:gno:bin:gsh:tests:
`pwd` returns value = 0
Test of system() function
:src:gno:bin:gsh:tests:
`pwd` returns value = 0
Test: concurrent execution of rehash
Test of system() function
hashed 118 files
`rehash` returns value = 0
Test of system() function
hashed 118 files
`rehash` returns value = 0
Test: concurrent execution of hash
Test of system() function
apropos ctags gsh.r pwd testjobs
aroff cut gsh0 rcp testjobs2
asml date gsh10 releasemem time
assemble day head removerez touch
aw30 describe help rlogin tr
awk df hostname rm true
basename diff init rmdir udl
binprint dirname install rsh uname
callsystem dmake kill script uncompress
cat dotests last sed uniq
catrez du launch setvers unshar
center echo less shellenv uptime
chmod echoparams link singletc vi
chtyp egrep logger sleep wall
cksum false ls split wc
Test of system() function
cmp fgrep lseg strings whatis
cmpl fmt man stty whereis
coff freeze mkdir su who
colcrt ftp more sum whois
compile getvers nroff tail yankit
compress grep passwd tar yes
copycat gsh print10params tee
cp gsh.debug ps test
cpp gsh.nodebug purge testfork
`hash` returns value = 0
apropos ctags gsh.r pwd testjobs
aroff cut gsh0 rcp testjobs2
asml date gsh10 releasemem time
assemble day head removerez touch
aw30 describe help rlogin tr
awk df hostname rm true
basename diff init rmdir udl
binprint dirname install rsh uname
callsystem dmake kill script uncompress
cat dotests last sed uniq
catrez du launch setvers unshar
center echo less shellenv uptime
chmod echoparams link singletc vi
chtyp egrep logger sleep wall
cksum false ls split wc
cmp fgrep lseg strings whatis
cmpl fmt man stty whereis
coff freeze mkdir su who
colcrt ftp more sum whois
compile getvers nroff tail yankit
compress grep passwd tar yes
copycat gsh print10params tee
cp gsh.debug ps test
cpp gsh.nodebug purge testfork
`hash` returns value = 0
= = = Execution did not hang: test successful! = = = = =
= = = = = /obj/gno/bin/gsh/gsh commands' usage strings and status test = = = =
Usage: bg [%job | pid]
Completion status = 1 (expected 1)
Usage: chdir [pathname]
Completion status = 1 (expected 1)
Usage: cd [pathname]
Completion status = 1 (expected 1)
Usage: clear
Completion status = 1 (expected 1)
Usage: export var ...
Completion status = 1 (expected 1)
Usage: fg [%job | pid]
Completion status = 1 (expected 1)
Usage: jobs [-l]
Completion status = 1 (expected 1)
kill: No such job or pid.
Completion status = 1 (expected 1)
Usage: popd [+n]
Completion status = 1 (expected 1)
Usage: prefix prefixnum prefixname
Completion status = 1 (expected 1)
usage: pushd [+n | dir]
Completion status = 1 (expected 1)
Usage: pwd
Completion status = 1 (expected 1)
Usage: rehash
Completion status = 1 (expected 1)
Usage: stop [%job | pid]
Completion status = 1 (expected 1)
Usage: tset
Completion status = 1 (expected 1)
Usage: unalias name ...
Completion status = 1 (expected 1)
Usage: unhash
Completion status = 1 (expected 1)
Usage: unset var ...
Completion status = 1 (expected 1)
Usage: commands
Completion status = 1 (expected 1)
Usage: setdebug (value | [+|-]flag ... )
Flags: gsostrace - Trace GS/OS calls
gsosblocks - Trace GS/OS parameter blocks
gsoserrors - Trace GS/OS errors
pathtrace - Trace GS/OS pathnames
sigtrace - Trace signals
systrace - Trace system calls
breakpoint - Coded brk instructions
Completion status = 1 (expected 1)
usage: dirs [-l]
Completion status = 1 (expected 1)
Usage: hash
Completion status = 1 (expected 1)
Usage: ps
Completion status = 1 (expected 1)
Usage:
set - displays all variables
set ... [var] - displays the value of var
set [var value]... - sets var to value
set [var=value]... - sets var to value
Completion status = 1 (expected 1)
Usage:
set - displays all variables
set ... [var] - displays the value of var
set [var value]... - sets var to value
set [var=value]... - sets var to value
Completion status = 1 (expected 1)
Usage: bindkey [-l] function string
Completion status = 1 (expected 1)
Usage: echo [-n] [strings...]
Completion status = 1 (expected 1)
Usage: history
Completion status = 1 (expected 1)
Usage: which [file ...]
Completion status = 1 (expected 1)
edit: no filename specified
Completion status = 1 (expected 1)
= = = = = End of /obj/gno/bin/gsh/gsh tests = = = = =
Note: To test job control commands, source testjobs and testjobs2.
Script done on: Fri Nov 26 22:04:34 1999

466
bin/gsh/tests/testfork.c Normal file
View File

@ -0,0 +1,466 @@
/*
* testfork: See how fork/_execve/wait/kill interact
*
* Written by Dave Tribby to test gsh * Oct 1998
*/
#define INCLUDE_WAIT
#define INCLUDE_PWAIT
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <orca.h>
int fork_mutex = 0; /* Mutual exclusion during fork */
int event_mutex = 0; /* Mutual exclusion while adding an event */
int wait_in_handler = 0; /* Should wait() be called in sig handler? */
int root_pid; /* Root program's pid */
int child1_pid; /* Child program's pid */
/* Values to be passed to _execve() */
char *progname;
char *cmdline;
/* Default values for _execve() if none are provided on command line */
char *d_progname="/bin/ps";
char *d_cmdline="/bin/ps -l";
/* ---------- Data and code for handling program events ----------*/
/* Structure for recording program events */
typedef struct {
int pid;
int verb;
int v1,v2;
} EventRec;
EventRec *prog_events; /* Pointer to array of events */
int num_events=0, max_events; /* Current # of events and maximum */
/* Values for verb in event record */
enum { e_start, e_fork, e_forkmc, e_exec, e_exfail, e_sigp0, e_sigp1,
e_wait, e_kill, e_getsig, e_noproc, e_end };
char *e_name[] ={"Start", "Fork child pid =", "Fork mutex count =",
"_execve", "_execve failed", "Calling sigpause",
"Sigpause returned", "Wait returns child",
"Kill returns", "Receive signal", "Process not found!", "End"};
/*
* Add a program event
*/
#pragma databank 1
void add_event(int pid, int verb, int v1, int v2)
{
EventRec *p;
/* Lock the event mutual exclusion key */
/* -------------------------------------------------
asm {
phb
phk
plb
lda #1
test: tsb event_mutex
beq alldone
cop 0x7f
bra test
alldone: plb
}
---------------------------------------------------- */
if (num_events >= max_events ) {
prog_events = realloc((char *)prog_events, 64*sizeof(EventRec));
max_events += 64;
}
p = &(prog_events[num_events]);
p->pid = pid;
p->verb = verb;
p->v1 = v1;
p->v2 = v2;
num_events++;
/* Unlock the event mutual exclusion key */
event_mutex = 0;
}
#pragma databank 0
/*
* Print program event records
*/
void print_events(void)
{
int i;
EventRec *p;
p = prog_events;
for (i=0; i < num_events; i++) {
printf("%3d: %4d %s", i, p->pid, e_name[p->verb]);
switch (p->verb) {
case e_getsig:
case e_fork:
case e_forkmc:
printf(" %d", p->v1);
break;
case e_wait:
case e_kill:
printf(" pid %d status = 0x%04X",
p->v1,p->v2);
break;
}
printf("\n");
p++;
}
}
/* ---------- Data and code for handling process list ----------*/
#define MAX_SIG 33
/* Linked list for each invocation of this program sharing the same space */
struct ProgListRec {
struct ProgListRec *next;
int pid;
int *sig_rcv;
} ProgListRec;
typedef struct ProgListRec ProgListRec;
ProgListRec *plist_head = NULL;
/*
* Clear the signal received array
*/
#pragma databank 1
void clear_sig_flags(int *sig_array)
{
int sig_num;
for (sig_num = 0; sig_num < MAX_SIG; sig_num++) {
sig_array[sig_num] = 0;
}
}
#pragma databank 0
/*
* Create a new entry in the process list
*/
#pragma databank 1
void new_process_entry(int pid)
{
ProgListRec *new;
new = malloc(sizeof(ProgListRec));
new->pid = pid;
new->sig_rcv = malloc(MAX_SIG*sizeof(int));
clear_sig_flags(new->sig_rcv);
new->next = plist_head;
plist_head = new;
}
#pragma databank 0
#pragma databank 1
ProgListRec *find_process_entry(int my_pid)
{
ProgListRec *plist;
/* Find process list entry and set signal received bit */
plist = plist_head;
while (plist && plist->pid != my_pid) {
plist = plist->next;
}
if (!plist) {
add_event(my_pid, e_noproc, 0, 0);
}
return plist;
}
#pragma databank 0
/*
* Print process list
*/
#pragma databank 1
void print_proc_list(void)
{
ProgListRec *plist;
int signum;
plist = plist_head;
while (plist) {
printf("Process # %d received signals:", plist->pid);
for (signum = 1; signum < MAX_SIG; signum++) {
if (plist->sig_rcv[signum])
printf(" %d", signum);
}
printf("\n");
plist = plist->next;
}
}
#pragma databank 0
/* ---------------------------------------------------------------*/
/*
* Entry point for forked process to schedule "progname"
*/
#pragma databank 1
void prog_exec(void)
{
int child_pid;
int my_pid;
/* Get process id */
my_pid = getpid();
fork_mutex = 0;
add_event(my_pid, e_exec, 0, 0);
child_pid = _execve(progname,cmdline);
add_event(my_pid, e_exfail, 0, 0);
}
#pragma databank 0
/*
* Signal handler
*/
#pragma databank 1
void SigHandler(int sig, int code)
{
pid_t wpid;
union wait status;
int my_pid;
ProgListRec *pentry;
/* Get process id */
my_pid = getpid();
add_event(my_pid, e_getsig, sig, code);
/* Find process list entry and set signal received bit */
if (pentry = find_process_entry(my_pid)) {
pentry->sig_rcv[sig] = 1;
}
switch (sig) {
case SIGCHLD:
if (wait_in_handler) {
/* Get child's completion status */
wpid = wait(&status);
add_event(my_pid, e_wait, wpid, status.w_status);
}
/* Make sure parent isn't waiting on mutex */
fork_mutex = 0;
break;
case SIGUSR1: /* User-defined signal 1 */
if (my_pid == root_pid)
kill(child1_pid,SIGUSR2);
break;
case SIGUSR2: /* User-defined signal 2 */
break;
case SIGHUP: /* Hang-up */
case SIGTERM: /* Kill or hang-up */
fprintf(stderr, "...bye!...\n");
exit(1);
}
}
#pragma databank 0
/*
* Establish signal handlers
*/
#pragma databank 1
void set_sig_handler(void)
{
signal(SIGINT, SigHandler);
signal(SIGTERM, SigHandler);
signal(SIGHUP, SigHandler);
signal(SIGTSTP, SigHandler);
signal(SIGCHLD, SigHandler);
signal(SIGUSR1, SigHandler);
signal(SIGUSR2, SigHandler);
}
#pragma databank 0
/*
* Wait for foreground process to finish up
*/
#pragma databank 1
void pwait(void)
{
long oldmask;
int my_pid;
ProgListRec *pentry;
/* Get process id */
my_pid = getpid();
/* Wait for signal */
pentry = find_process_entry(my_pid);
while (!pentry->sig_rcv[SIGCHLD]) {
add_event(my_pid, e_sigp0, 0, 0);
sigpause(0);
add_event(my_pid, e_sigp1, 0, 0);
}
}
#pragma databank 0
/*
* Invoke a child program
*/
#pragma databank 1
int invoke(void *addr)
{
int my_pid;
int child_pid;
int mutex_count = 0;
my_pid = getpid();
fork_mutex = 1;
child_pid = fork(addr);
add_event(my_pid, e_fork, child_pid, 0);
while (fork_mutex) {
asm {
cop 0x7f
}
mutex_count++;
}
add_event(my_pid, e_forkmc, mutex_count, 0);
return child_pid;
}
#pragma databank 0
/*
* Do process startup stuff, and invoke the proper child
*/
#pragma databank 1
void command(int pid, void *addr)
{
long oldmask;
int child_pid;
int kill_stat;
/* Temporarially block reception of all signals */
oldmask = sigblock(-1L);
/* Invoke the appropriate child process */
child_pid = invoke(addr);
/* Enable the signal handlers for current process */
set_sig_handler();
/* Create process entry for this process */
new_process_entry(pid);
/* Restore previous signal mask */
sigsetmask(oldmask);
/* If this is the child, let parent know we're here */
if (pid != root_pid)
kill(root_pid,SIGUSR1);
/* If child process is still running, wait for it to complete */
kill_stat = kill(child_pid,0);
add_event(pid, e_kill, child_pid, kill_stat);
if (!kill_stat) {
pwait();
}
}
#pragma databank 0
/*
* Forked child of root process starts here
*/
int process2(void)
#pragma databank 1
{
child1_pid = getpid();
add_event(child1_pid, e_start, 0, 0);
command(child1_pid,&prog_exec);
add_event(child1_pid, e_end, 0, 0);
return 1;
}
#pragma databank 0
/*
* Main program starts here
*/
int main(int argc, char *argv[])
{
pid_t wpid;
union wait status;
int argnum;
root_pid = getpid();
max_events = 64;
if (!(prog_events = malloc(64*sizeof(EventRec)))) {
fprintf(stderr, "ERROR: cannot malloc %d bytes\n",
64*sizeof(EventRec));
exit(1);
}
/* Print listing of events and process list when program terminates */
atexit(print_events);
atexit(print_proc_list);
/* Set value of grandchild program to be executed */
if (argc <= 1) {
/* Use default if nothing provided in arguments */
progname = d_progname;
cmdline = d_cmdline;
}
else {
progname = argv[1];
/* Command line for _execve() is root program's */
/* cmd line without the original program name. */
cmdline = commandline();
while (*cmdline && *cmdline != ' ') cmdline++;
while (*cmdline && *cmdline == ' ') cmdline++;
}
/* Record that we made it through startup */
add_event(root_pid, e_start, 0, 0);
#ifdef INCLUDE_WAIT
/* This section of code does a simple wait */
wait_in_handler = 0;
signal(SIGCHLD, SigHandler);
invoke(&prog_exec);
wpid = wait(&status);
add_event(root_pid, e_wait, wpid, status.w_status);
#endif
#ifdef INCLUDE_PWAIT
/* This section of code does a more complex wait two levels deep */
wait_in_handler = 1;
command(root_pid,&process2);
#endif
add_event(root_pid, e_end, 0, 0);
return 0;
}

28
bin/gsh/tests/testjobs Normal file
View File

@ -0,0 +1,28 @@
# Test gsh built-in job commands
# Written by Dave Tribby (December 1998)
# $Id: testjobs,v 1.1 1999/11/30 20:28:24 tribby Exp $
# This shell exec file must be sourced rather than run
echo " = = = = = Test of $SHELL job control"
echo ""
echo "NOTE: $0 must be sourced rather than run; otherwise it kills itself!"
echo ""
/bin/sleep 15 &
/bin/sleep 5 &
echo
echo "Should show two jobs"
jobs
echo
echo "Kill the first job"
kill %1
echo
echo "There should now only be one job"
jobs
echo
echo "Wait on the final job"
fg

29
bin/gsh/tests/testjobs2 Normal file
View File

@ -0,0 +1,29 @@
# Test gsh built-in job commands
# Written by Dave Tribby (December 1998)
# $Id: testjobs2,v 1.1 1999/11/30 20:28:24 tribby Exp $
# This shell exec file must be sourced rather than run
echo " = = = = = Test of $SHELL job control"
echo ""
echo "NOTE: $0 must be sourced rather than run; otherwise it kills itself!"
echo ""
/bin/sleep 15 &
echo
echo "Should show one job"
jobs
echo
echo "Kill the first job"
kill %1
/bin/sleep 5 &
echo
echo "There should now be another job"
jobs
echo
echo "Wait on the final job"
fg