v19i009: A reimplmentation of the System V shell, Patch1

131 views
Skip to first unread message

Rich Salz

unread,
May 31, 1989, 5:37:51 PM5/31/89
to
Submitted-by: k...@june.cs.washington.edu (Kenneth Almquist)
Posting-number: Volume 19, Issue 9
Archive-name: ash/patch1


Ash blows up if you create more than four jobs.

Also attached is a config script. If you've already compiled ash,
you can skip this.

Kenneth Almquist


echo extracting jobs.pch
cat > jobs.pch <<\!
*** jobs.28 Fri Apr 21 06:25:53 1989
--- jobs.c Fri Apr 21 06:28:52 1989
***************
*** 412,437 ****
union node *node;
{
int i;
! struct job *jp;

for (i = njobs, jp = jobtab ; ; jp++) {
! if (--i < 0) {
INTOFF;
! if (njobs == 0) {
! jobtab = ckmalloc(4 * sizeof jobtab[0]);
! } else {
! jp = ckmalloc((njobs + 4) * sizeof jobtab[0]);
! bcopy(jobtab, jp, njobs * sizeof jp[0]);
! ckfree(jobtab);
! jobtab = jp;
! }
! jp = jobtab + njobs;
! for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0);
INTON;
! break;
! }
! if (jp->used == 0)
! break;
}
INTOFF;
jp->state = 0;
--- 412,448 ----
union node *node;
{
int i;
! struct job *jp, *jp2;
! struct job *newtab;

for (i = njobs, jp = jobtab ; ; jp++) {
! if (--i < 0) {
INTOFF;
! if (njobs == 0) {
! jobtab = ckmalloc(4 * sizeof jobtab[0]);
! } else {
! newtab = ckmalloc((njobs + 4) * sizeof newtab[0]);
! bcopy(jobtab, newtab, njobs * sizeof newtab[0]);
! jp = jobtab;
! jp2 = newtab;
! for (i = njobs ; --i >= 0 ; ) {
! if (jp->ps == &jp->ps0)
! jp2->ps = &jp2->ps0;
! jp++;
! jp2++;
! }
! ckfree(jobtab);
! jobtab = newtab;
! }
! jp = jobtab + njobs;
! njobs += 4;
! jp2 = jp;
! for (i = 4 ; --i >= 0 ; (jp2++)->used = 0);
INTON;
! break;
! }
! if (jp->used == 0)
! break;
}
INTOFF;
jp->state = 0;
EOF
echo extracting README.CONFIG
cat > README.CONFIG <<\!
The config shell procedure is used to configure ash to reflect the
properties of your system. It will create shell.h for you and edit
the makefile to reflect your choice of C compiler. To run it, type
"sh config" and answer the questions that it asks you.
Kenneth Almquist
!
if test `wc -c < README.CONFIG` -ne 279
then echo 'README.CONFIG is the wrong size'
fi

echo extracting config
cat > config << 'EOF'
: Create shell.h $#Use_sh_not_csh
: Based on code by Larry Wall.

: Copyright 1989 by Kenneth Almquist. All rights reserved.
: This file is part of ash, which is distributed under the terms specified
: by the Ash General Public License. See the file named LICENSE.

: sanity checks
PATH="/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/new:/usr/new/bin:/usr/nbin:$PATH"

if test ! -t 0; then
echo "Say 'sh config', not 'sh < config'"
exit 1
fi

echo "Config program for ash."
echo " "

libpth='/usr/lib /usr/local/lib /lib'
rmlist=
include=/usr/include
fastread=

: some greps do not return status, grrr.
echo "grimblepritz" >temp
if grep blurfldyick temp >/dev/null 2>&1 ; then
contains=contains
elif grep grimblepritz temp >/dev/null 2>&1 ; then
contains=grep
else
contains=contains
fi
rm -f temp
: the following should work in any shell
case "$contains" in
contains*)
echo " "
echo "AGH! Grep doesn't return a status. Attempting remedial action."
cat >contains <<'EOSS'
grep "$1" "$2" >greptemp && cat greptemp && test -s greptemp
EOSS
chmod +x contains
rmlist="$rmlist contains greptemp"
;;
esac

: first determine how to suppress newline on echo command
echo "Checking echo to see how to suppress newlines..."
(echo "hi there\c" ; echo " ") >temp
if $contains c temp >/dev/null 2>&1 ; then
echo "...using -n."
n='-n'
c=''
else
cat <<'EOM'
...using \c
EOM
n=''
c='\c'
fi
echo $n "Type carriage return to continue. Your cursor should be here-->$c"
read ans
rm -f temp

: now set up to do reads with possible shell escape and default assignment
cat <<EOSC >myread
case "\$fastread" in
yes) ans=''; echo " " ;;
*) ans='!';;
esac
while expr "X\$ans" : "X!" >/dev/null; do
read ans
case "\$ans" in
!)
sh
echo " "
echo $n "\$rp $c"
;;
!*)
set \`expr "X\$ans" : "X!\(.*\)\$"\`
sh -c "\$*"
echo " "
echo $n "\$rp $c"
;;
esac
done
rp='Your answer:'
case "\$ans" in
'') ans="\$dflt";;
esac
EOSC

: general instructions
cat <<EOH

This installation shell script will examine your system and ask you questions
to determine how ash should be installed. If you get stuck on a question,
you may use a ! shell escape to start a subshell or execute a command. Many
of the questions will have default answers in square brackets--typing carriage
return will give you the default.

If this shell script doesn't work for some reason, you will have to create
shell.h by hand. This isn't too hard to do; sample versions of shell.h for
for Berkeley UNIX and System V are included in the distribution. Also, if
you make a mistake in answering a question, you can edit shell.h after this
procedure finishes.

EOH
rp="[Type carriage return to continue]"
echo $n "$rp $c"
. ./myread

: get list of predefined functions in a handy place
echo " "
if test -f /lib/libc.a; then
echo "Your C library is in /lib/libc.a. You're normal."
libc=/lib/libc.a
else
libc=
for dir in $libpth ; do
if test -f $dir/libc.a ; then
libc=$dir/libc.a
break
fi
if test -f $dir/clib ; then
libc=$dir/clib
break
fi
if test -f $dir/libc ; then
libc=$dir/libc
break
fi
done
if test $libc ; then
echo "Your C library is in $libc, of all places."
else
cat <<EOM

I can't seem to find your C library. I've looked in the following places:

$libpth

None of these seems to contain your C library. What is the full name
EOM
dflt=None
echo $n "of your C library? $c"
rp='C library full name?'
. ./myread
libc="$ans"
fi
fi
echo " "
echo $n "Extracting names from $libc for later perusal...$c"
nm $libc 2>/dev/null >libc.tmp
sed -n -e 's/^.* [AT] _//p' -e 's/^.* [AT] //p' <libc.tmp >libc.list
if $contains '^printf$' libc.list >/dev/null 2>&1; then
echo "done"
else
sed -n -e 's/^.* D _//p' -e 's/^.* D //p' <libc.tmp >libc.list
$contains '^printf$' libc.list >/dev/null 2>&1 || \
sed -n -e 's/^_//' \
-e 's/^\([a-zA-Z_0-9]*\).*xtern.*text.*/\1/p' <libc.tmp >libc.list
if $contains '^printf$' libc.list >/dev/null 2>&1; then
echo "done"
else
echo " "
echo "nm didn't seem to work right."
echo "Trying ar instead..."
if ar t $libc > libc.tmp; then
sed -e 's/\.o$//' < libc.tmp > libc.list
echo "Ok."
else
echo "ar didn't seem to work right."
echo "Maybe this is a Cray...trying bld instead..."
if bld t $libc | sed -e 's/.*\///' -e 's/\.o:.*$//' > libc.list; then
echo "Ok."
else
echo "That didn't work either. Giving up."
exit 1
fi
fi
fi
fi
rmlist="$rmlist libc.tmp libc.list"

: Locate the /usr/include directory
if test ! -d "$include" ; then
echo " "
echo "Hey, $include doesn't exist on this system!"
echo "I need to know the location of your header files to figure out what type"
echo "of system you are on."
while test true ; do
dflt=None
rp='Where do include files reside on this system?'
echo $n "$rp $c"
. ./myread
include="$ans"
if test ! -d "$ans" ; then
echo "$ans does not exist."
elif test ! -f "$ans/stdio.h" ; then
echo "$ans is a pretty pathetic excuse for an include directory"
echo $n "since it doesn't include stdio.h. Use it anyway? [n] $c"
dflt=n
rp="Include files are in $ans? [$dflt]"
. ./myread
if test "X$ans" = Xy -o "X$ans" = Xyes ; then
break
fi
else
break
fi
done
fi

: make some quick guesses about what we are up against
echo " "
echo $n "Hmm... $c"
if test -f $include/sys/socket.h -a \( -f /usr/bin/ranlib -o -f /usr/ucb/ranlib \) ; then
echo "Looks kind of like a BSD system, but we'll see..."
systype=bsd
elif $contains '^fcntl$' libc.list >/dev/null 2>&1 ; then
echo "Looks kind of like a USG system, but we'll see..."
systype=sys5
else
echo "Looks kind of like a version 7 system, but we'll see..."
systype=v7
fi
if $contains '^vmssystem$' libc.list >/dev/null 2>&1 ; then
cat <<'EOI'
You appear to be running Eunice. Lucky you. I haven't tested ash
under Eunice; let me know if it works.
EOI
eunicefix=unixtovms
eunice=yes
: it so happens the Eunice I know will not run shell scripts in Unix format
else
echo " "
echo "Congratulations. You aren't running Eunice."
eunicefix=':'
eunice=no
fi
if test -f /xenix; then
echo "Actually, this looks more like a XENIX system..."
xenix=yes
else
echo " "
echo "It's not Xenix..."
xenix=no
fi
if test -f /venix; then
echo "Actually, this looks more like a VENIX system..."
venix=yes
else
echo " "
if test "$xenix" = yes; then
: null
else
echo "Nor is it Venix."
fi
venix=yes
fi

: Now determine the C compiler. Default is gcc if present.
dflt=cc
for dir in `echo $PATH | tr : ' '` ; do
if test -f "$dir/gcc" ; then
dflt=gcc
fi
done
echo " "
rp="What is the name of your C compiler? [$dflt]"
echo $n "$rp $c"
. ./myread
cc=$ans

echo " "
if $contains SIGTSTP $include/sys/signal.h >/dev/null 2>&1 ; then
echo "I see you have Berkeley job control."
jobs=1
elif $contains SIGTSTP $include/signal.h >/dev/null 2>&1 ; then
echo "I see you have Berkeley job control."
jobs=1
else
echo "You don't seem to have Berkeley job control. Too bad."
jobs=0
fi

: see if symlink exists
echo " "
if $contains '^symlink$' libc.list >/dev/null 2>&1; then
echo 'Your system has symbolic links.'
symlinks=1
else
echo 'No symbolic links on your system.'
symlinks=0
fi

: test for system V directory routines
echo " "
if test -f $include/dirent.h ; then
echo 'You appear to have the System V directory access routines.'
dirent=1
elif test "$systype" = bsd ; then
echo 'I assume you have the Berkeley directory access routines.'
dirent=0
else
echo "Your system doesn't contain directory access routines, which is"
echo "fine if you have Version 7 format directories."
dirent=0
fi

: Tell user whether atty will be supported
echo " "
if test "$systype" = bsd ; then
echo "Since you are on a BSD system, I'll compile in support for atty."
atty=1
else
echo "Since atty only works on BSD systems, I assume you don't want it."
atty=0
fi

if test $symlinks = 1 -a -d /u ; then
echo " "
echo "You appear to have the /u directory on your system."
if test ! -d /u/root ; then
echo "However, there is no entry for root. If you have questions"
echo "about the /u directory, read the DIFFERENCES file."
fi
udir=0
else
if test $symlinks = 1 ; then
cat <<\!

By convention, the home directory of a user is referred to using the
name /u/user. Since you have symbolic links on your system, you can
create /u and place symbolic links in it pointing to the home directories
of the users of the system. However, ash does contain code to replace
/u/user with the name of the home directory of the user, and you can use
this code instead of creating /u if you want to.
!
dflt=n
else
cat <<\!

By convention, the home directory of a user is referred to using the
name /u/user. Unfortunately, the /u directory is typically implemented
using symbolic links, which your system appears not to have. To support
systems like yours, ash contains code to replace /u/user with the name
of the home directory of the user.
!
dflt=y
fi
udir=unset
while test $udir = unset ; do
rp="Do you want ash to include this code? [$dflt]"
echo $n "$rp $c"
. ./myread
case "$ans" in
y*) udir=1 ;;
n*) udir=0 ;;
*) echo "Please answer 'y' or 'n'" ;;
esac
done
fi

echo " "
echo "Now let's test out your C compiler..."

cat > ctemp1.c <<\!
main() {
#ifdef __STDC__
exit(0);
#else
exit(1);
#endif
}

verylongname1() {
return 1;
}
!
cat > ctemp2.c <<\!
verylongname2() {
return 2;
}
!
if $cc -c ctemp1.c ctemp2.c ; then
:
else
echo "What's with your compiler? I'm giving up!"
rm -f myread $rmlist
exit 1
fi
if $cc -o ctemp ctemp1.o ctemp2.o >/dev/null 2>&1 ; then
echo 'Good, your C compiler understands long names.'
shortnames=0
else
cat <<\!
Your C compiler appears to truncate external identifiers, so we will
have to make sure all global identifiers are unique when truncated to
six characters.
!
shortnames=1
$cc -o ctemp ctemp1.o
fi

: if not ansi C, check for volatile support
if ./ctemp ; then
echo "Your C compiler claims to be ANSI, so I'll assume it understands volatile"
volatile=ansi
else
cat > ctemp2.c <<\!
main() {
volatile int x;
x = 0;
return x;
}
!
echo " "
if $cc -c ctemp2.c >/dev/null 2>&1 ; then
echo "Your C compiler accepts the volatile keyword even though it's not ANSI."
volatile=yes
else
echo "Your C compiler doesn't have (and presumably doesn't need) the"
echo "volatile keyword."
volatile=no
fi
fi
rm -f ctemp1.c ctemp2.c ctemp1.o ctemp2.o ctemp

echo " "
if test "`(cd //; pwd)`" = / ; then
echo "You appear to have a fairly normal UNIX file system."
else
cat <<\!
Your file system appears to interpret // at the start of a file name
differently from a single slash at the start of the file name, which
will probably cause the pwd command to malfunction. This problem hasn't
been fixed because the writer of ash (Kenneth Almquist) doesn't have
access to any systems that behave this way. You can probably get a
version of pwd for your system in return for a description of how your
system interprets file names and a promise to test out the code. In
!
echo $n "the mean time, type return to continue...$c"
rp="Type return to continue:"
. myread
fi


: Now create shell.h
echo " "
echo $n "Creating shell.h...$c"

cat > shell.h <<\!
/*
* Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
* This file is part of ash, which is distributed under the terms specified
* by the Ash General Public License. See the file named LICENSE.
*/

/*
* The follow should be set to reflect the type of system you have:
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
* SYMLINKS -> 1 if your system includes symbolic links, 0 otherwise.
* DIRENT -> 1 if your system has the SVR3 directory(3X) routines.
* UDIR -> 1 if you want the shell to simulate the /u directory.
* ATTY -> 1 to include code for atty(1).
* SHORTNAMES -> 1 if your linker cannot handle long names.
* define BSD if you are running 4.2 BSD or later.
* define SYSV if you are running under System V.
* define DEBUG to turn on debugging.
*
* When debugging is on, debugging info will be written to $HOME/trace and
* a quit signal will generate a core dump.
*/


!
echo "#define JOBS $jobs" >>shell.h
echo "#define SYMLINKS $symlinks" >>shell.h
echo "#define DIRENT $dirent" >>shell.h
echo "#define UDIR $udir" >>shell.h
echo "#define ATTY $atty" >>shell.h
echo "#define SHORTNAMES $shortnames" >>shell.h
if test $systype = bsd ; then
echo "#define BSD" >>shell.h
else
echo "/* #define BSD */" >>shell.h
fi
if test $systype = sys5 ; then
echo "#define SYSV" >>shell.h
else
echo "/* #define SYSV */" >>shell.h
fi
cat >> shell.h <<\!
/* #define DEBUG */

#if SHORTNAMES
#include "shortnames.h"
#endif


#ifdef __STDC__
typedef void *pointer;
#ifndef NULL
#define NULL (void *)0
#endif
#else /* not __STDC__ */
#define const
!
if test $volatile = yes ; then
echo "/* #define volatile */" >>shell.h
else
echo "#define volatile" >>shell.h
fi
cat >> shell.h <<\!
typedef char *pointer;
#ifndef NULL
#define NULL 0
#endif
#endif /* __STDC__ */
#ifdef __GNUC__ /* Gcc lets us declare that functions don't return */
#define noreturn volatile
#else
#define noreturn
#endif
#define STATIC /* empty */
#define MKINIT /* empty */

extern char nullstr[1]; /* null string */


#ifdef DEBUG
#define TRACE(param) trace param
#else
#define TRACE(param)
#endif
!
echo done

: Now update the makefile
echo " "
echo "Editing makefile to reflect your choice of C compiler..."

chmod u+w makefile
ed - makefile <<!
/^#*CC=/s/.*/CC=$cc/p
w
q
!
echo done

echo " "
echo "Edit shell.h by hand if you want to make any changes."
echo "Then run make."

rm -f myread $rmlist
EOF
if test `wc -c < config` -ne 14098
then echo 'config is the wrong size'
fi
chmod +x config

echo 'Archive unpacked'
exit 0
--
Please send comp.sources.unix-related mail to rs...@uunet.uu.net.

Reply all
Reply to author
Forward
0 new messages