Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion v19i009: A reimplmentation of the System V shell, Patch1
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Rich Salz  
View profile  
 More options May 31 1989, 5:37 pm
Newsgroups: comp.sources.unix
From: rs...@bbn.com (Rich Salz)
Date: 31 May 89 21:37:51 GMT
Local: Wed, May 31 1989 5:37 pm
Subject: v19i009: A reimplmentation of the System V shell, Patch1
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.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.