mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-06-16 12:29:29 +00:00
Regression tests for gsh.
This commit is contained in:
parent
769328325f
commit
7edb4eac39
40
bin/gsh/tests/Makefile
Normal file
40
bin/gsh/tests/Makefile
Normal 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
|
||||
|
26
bin/gsh/tests/callsystem.c
Normal file
26
bin/gsh/tests/callsystem.c
Normal 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
596
bin/gsh/tests/dotests
Normal 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."
|
30
bin/gsh/tests/echoparams.c
Normal file
30
bin/gsh/tests/echoparams.c
Normal 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;
|
||||
}
|
11
bin/gsh/tests/print10params
Normal file
11
bin/gsh/tests/print10params
Normal 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
49
bin/gsh/tests/releasemem
Normal 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
34
bin/gsh/tests/reparse.asm
Normal 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
155
bin/gsh/tests/shellenv.c
Normal 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
10
bin/gsh/tests/singletc
Normal 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
446
bin/gsh/tests/test.list
Normal 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
466
bin/gsh/tests/testfork.c
Normal 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
28
bin/gsh/tests/testjobs
Normal 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
29
bin/gsh/tests/testjobs2
Normal 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
|
Loading…
Reference in New Issue
Block a user