home *** CD-ROM | disk | FTP | other *** search
- Subject: v19i009: A reimplmentation of the System V shell, Patch1
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: ka@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
-