Public Domain Korn Shell - Part.01 of 7

USENET Administration netnews at netcom.UUCP
Wed Dec 12 22:34:39 AEST 1990


The following seven shar files are the public domain Korn Shell attributed to:

	Eric Gisin, egisin at math.UWaterloo.CA (or Waterloo.EDU)

... however he was not reachable via email for any updates or status of
this work.  So, we provide you with what we have.
I don't recall how we got it originally.  We do not actually use this
ksh here at NetCom, as it is incomplete (only emacs-style line editing),
and we have an authentic ksh already.  However, if you don't have ksh and
know emacs, this might be fun to have around.

First is the src/ReadMe file, to let you know what you're getting into,
followed by the first shar.  These files may not be organized in the best
possible way.  "No warrenties expressed or implied" -- use at your own risk.
------------------------------------------------------------------------------
[from src/ReadMe:]


		Public Domain KornShell

	Quick installation notes for PD KornShell

PD KornShell can be installed on
4.2+ BSD systems, System V, and POSIX-compatable systems.
The makefiles all define _BSD, change this to _SYSV, or _POSIX.
The makefiles also contain CC=gcc, delete this if you don't have GNU C.
The ksh makefile also contains some options,
including JOBS (BSD/POSIX job control) and EDIT (emacs command editing).

PD KornShell assumes you have standard C (ANSI) and POSIX header files and functions.
Since you probably don't, they are provided in the "std" directory.

The Alpha test version will probably come as two tar files.
std.tar contains standard C and POSIX emulation and
must be extracted into a directory called std.
ksh.tar contains the ksh source and should be extracted
into a directory called src or ksh.

See std/ReadMe and install it. Only then can you make ksh in the "src" directory.

To clear up questions about the origin of this shell,
this shell is NOT based on the "Minix shell".
It is based on Charles Forsyth's public domain V7 shell,
which he later contributed to Minix.

I have permission directly from Charles Forsyth to use his shell.

	Eric Gisin, egisin at math.UWaterloo.CA (or Waterloo.EDU)

	Things to do
- add sxt-based job control (see Brown's contribution on the Usenix 87 tape).
- add arrays and variable attributes.
- add MAILPATH and CDPATH.
- add vi editing mode (apparently someone has a PD version).
- add new features described in Korn's book.

	Machines ported to
VAX, 68000, 80386

	OS's ported to
BSD 4.2, BSD 4.3 (with and without YP and NFS
Sys V.3
------------------------------------------------------------------------------
[end of src/ReadMe]

#!/bin/sh
# This is ksh-pd, a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 12/12/1990 11:19 UTC by netnews at netcom
# Source directory /usr/source/cmd/ksh
#
# existing files will NOT be overwritten unless -c is specified
# This format requires very little intelligence at unshar time.
# "if test", "echo", "true", and "sed" may be needed.
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   1599 -r--r--r-- src/ReadMe
#  27500 -rw-r--r-- src/ksh.1
#   1388 -rw-r--r-- src/Makefile
#   6459 -rw-r--r-- src/sh.h
#   3406 -rw-r--r-- src/table.h
#   1991 -rw-r--r-- src/expand.h
#   2669 -rw-r--r-- src/lex.h
#   3598 -rw-r--r-- src/tree.h
#    596 -rw-r--r-- src/tty.h
#    615 -rw-r--r-- src/version.c
#   7299 -rw-r--r-- src/main.c
#   6290 -rw-r--r-- src/misc.c
#   2734 -rw-r--r-- src/trap.c
#   4501 -rw-r--r-- src/alloc.c
#   3153 -rw-r--r-- src/io.c
#   9196 -rw-r--r-- src/syn.c
#  10858 -rw-r--r-- src/lex.c
#  27910 -rw-r--r-- src/edit.c
#   5293 -rw-r--r-- src/history.c
#   8213 -rw-r--r-- src/tree.c
#  11948 -rw-r--r-- src/exec.c
#  13924 -rw-r--r-- src/jobs.c
#   8915 -rw-r--r-- src/c_sh.c
#   8739 -rw-r--r-- src/c_ksh.c
#   6994 -rw-r--r-- src/c_test.c
#   2996 -rw-r--r-- src/getopts.c
#   2823 -rw-r--r-- src/ulimit.c
#  10509 -rw-r--r-- src/var.c
#   3724 -rw-r--r-- src/table.c
#  13524 -rw-r--r-- src/eval.c
#   4414 -rw-r--r-- src/expr.c
#   2945 -rw-r--r-- ReadMe
#   1060 -rw-r--r-- posix/Makefile
#   1037 -rw-r--r-- posix/dirent.C
#    880 -rw-r--r-- posix/dirent.H
#     87 -rw-r--r-- posix/dirent.h
#    430 -rw-r--r-- posix/fcntl.c
#    435 -rw-r--r-- posix/fcntl.h
#   1369 -rw-r--r-- posix/io.h
#   1126 -rw-r--r-- posix/times.c
#    459 -rw-r--r-- posix/unistd.c
#    782 -rw-r--r-- posix/unistd.h
#    274 -rw-r--r-- posix/time.h
#    355 -rw-r--r-- posix/times.h
#    935 -rw-r--r-- posix/wait.h
#    799 -rw-r--r-- posix/fixincludes
#   1592 -rw-r--r-- stdc/Makefile
#   4940 -rw-r--r-- stdc/vprintf.c
#    566 -rw-r--r-- stdc/stddef.h
#    300 -rw-r--r-- stdc/stdio.c
#   3946 -rw-r--r-- stdc/stdio.h
#   2290 -rw-r--r-- stdc/stdio.h_std
#   1104 -rw-r--r-- stdc/stdlib.h
#   1310 -rw-r--r-- stdc/string.h
#    322 -rw-r--r-- stdc/strcat.c
#    795 -rw-r--r-- stdc/sprintf.c
#    930 -rw-r--r-- stdc/time.h
#    228 -rw-r--r-- stdc/memcpy.c
#   1044 -rw-r--r-- stdc/setvbuf.c
#    735 -rw-r--r-- stdc/clock.c
#    369 -rw-r--r-- stdc/types.h
#    845 -rw-r--r-- stdc/limits.h
#    619 -rw-r--r-- stdc/stdarg.h
#    357 -rw-r--r-- stdc/strcmp.s
#    161 -rw-r--r-- stdc/strcpy.s
#    225 -rw-r--r-- stdc/memchr.c
#    358 -rw-r--r-- stdc/memcmp.c
#    336 -rw-r--r-- stdc/memmove.c
#    196 -rw-r--r-- stdc/memset.c
#    732 -rw-r--r-- stdc/fprintf.c
#   1108 -rw-r--r-- stdc/strtok.c
#    423 -rw-r--r-- stdc/strchr.c
#    758 -rw-r--r-- stdc/strcmp.c
#    278 -rw-r--r-- stdc/strcpy.c
#    467 -rw-r--r-- stdc/strcspn.c
#    326 -rw-r--r-- stdc/strerror.c
#    241 -rw-r--r-- stdc/strlen.c
#    427 -rw-r--r-- stdc/strncat.c
#    778 -rw-r--r-- stdc/strncmp.c
#    410 -rw-r--r-- stdc/strncpy.c
#    427 -rw-r--r-- stdc/strpbrk.c
#    415 -rw-r--r-- stdc/strrchr.c
#    483 -rw-r--r-- stdc/strspn.c
#    595 -rw-r--r-- stdc/strstr.c
#
# ============= src/ReadMe ==============
if test ! -d 'src'; then
    echo 'x - creating directory src'
    mkdir 'src'
fi
if test -f 'src/ReadMe' -a X"$1" != X"-c"; then
	echo 'x - skipping src/ReadMe (File already exists)'
else
echo 'x - extracting src/ReadMe (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/ReadMe' &&
X		Public Domain KornShell
X
X	Quick installation notes for PD KornShell
X
XPD KornShell can be installed on
X4.2+ BSD systems, System V, and POSIX-compatable systems.
XThe makefiles all define _BSD, change this to _SYSV, or _POSIX.
XThe makefiles also contain CC=gcc, delete this if you don't have GNU C.
XThe ksh makefile also contains some options,
Xincluding JOBS (BSD/POSIX job control) and EDIT (emacs command editing).
X
XPD KornShell assumes you have standard C (ANSI) and POSIX header files and functions.
XSince you probably don't, they are provided in the "std" directory.
X
XThe Alpha test version will probably come as two tar files.
Xstd.tar contains standard C and POSIX emulation and
Xmust be extracted into a directory called std.
Xksh.tar contains the ksh source and should be extracted
Xinto a directory called src or ksh.
X
XSee std/ReadMe and install it. Only then can you make ksh in the "src" directory.
X
XTo clear up questions about the origin of this shell,
Xthis shell is NOT based on the "Minix shell".
XIt is based on Charles Forsyth's public domain V7 shell,
Xwhich he later contributed to Minix.
X
XI have permission directly from Charles Forsyth to use his shell.
X
X	Eric Gisin, egisin at math.UWaterloo.CA (or Waterloo.EDU)
X
X	Things to do
X- add sxt-based job control (see Brown's contribution on the Usenix 87 tape).
X- add arrays and variable attributes.
X- add MAILPATH and CDPATH.
X- add vi editing mode (apparently someone has a PD version).
X- add new features described in Korn's book.
X
X	Machines ported to
XVAX, 68000, 80386
X
X	OS's ported to
XBSD 4.2, BSD 4.3 (with and without YP and NFS
XSys V.3
SHAR_EOF
true || echo 'restore of src/ReadMe failed'
fi
# ============= src/ksh.1 ==============
if test -f 'src/ksh.1' -a X"$1" != X"-c"; then
	echo 'x - skipping src/ksh.1 (File already exists)'
else
echo 'x - extracting src/ksh.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/ksh.1' &&
X.\" $Header: /tmp/egisin/src/RCS/ksh.1,v 3.1 88/11/22 10:44:17 egisin Exp $
X.nr OJ 1 \" Job Control
X.nr OE 1 \" Command Editing
X.nr OB 1 \" BSD enhanced ulimit options
X.ds OK [\|
X.ds CK \|]
X.TH KSH 1 "January 1988"
X.SH NAME
Xksh \- Bourne / Korn Shell (Public Domain)
X.SH SYNOPSIS
X\fBksh\fP
X[\fB\-st\fP] [\fB\-c\fP \fIcommand\fP]
X[\fIfile\fP [\fIargument ...\fP]]
X.SH INTRODUCTION
XThis document only summarizes the System V, release 2 shell features.
XAll of the System V features except for "restricted mode"
Xand the CDPATH and MAIL* variables are implemented.
XSee also the BUGS section.
X.LP
XFeatures of the Korn shell are described in more detail.
XOnly a subset of the Korn shell features are currently implemented.
X.SH DESCRIPTION
X.SS Command syntax
XThe ``#'' character begins a one-line comment,
Xunless the ``#'' occurs inside a word.
XThe tokens ``;'', ``|'', ``&'', ``;;'', ``||'', ``&&'', ``('', and ``)''
Xstand by themselves.
XA \fIword\fP is a sequence of any other non-whitespace characters,
Xwhich may also contain quoted strings
X(quote character are ``\''', ``"'', ``\`'',
Xor a matching ``${ }'' or ``$( )'' pair).
XA \fIname\fP is an unquoted word made up of letters, digits, or ``_''.
XAny number of whitespace characters (space and tab) may separate words and tokens.
X.LP
XIn the following syntax, { ... }? indicates an optional thing,
X{ ... }* indicates zero or more repetitions, { ... | ... } indicates alternatives.
X.de S
X.br
X\\$1
X.br
X..
X.IP statement:
X.S "\fB(\fP list \fB)\fP"
X.S "\fB{\fP list \fB;\fP \fB}\fP"
X.S "\fBfor\fP name { \fBin\fP { word }* }? \fBdo\fP list \fB;\fP \fBdone\fP"
X.S "{ \fBwhile\fP | \fBuntil\fP } list \fB;\fP \fBdo\fP list \fB;\fP \fBdone\fP"
X.S "\fBif\fP list \fB;\fP \fBthen\fP list \fB;\fP { \fBelif\fP list \fB;\fP \fBthen\fP list \fB;\fP }* { \fBelse\fP list \fB;\fP }?\fBfi\fP"
X.S "\fBcase\fP name \fBin\fP { \fB(\fP word { \fB|\fP word } \fB)\fP list \fB;;\fP }* \fBesac\fP"
X.S "\fBfunction\fP name \fB{\fP list \fB;\fP \fB}\fP"
X.S "name \fB() {\fP list \fB;\fP \fB}\fP"
X.S "\fBtime\fP pipe"
XThe opening parenthesis of the pattern is optional. 
XRedirection may occur at the beginning or end of a statement.
X.IP command:
X.S "{ name=word }* { word }*"
XRedirection may occur anywhere in a command.
X.IP list:
X.S "cond"
X.S "cond \fB;\fP list"
X.S "cond \fB&\fP list"
X.IP cond:
X.S "pipe"
X.S "pipe \fB&&\fP cond"
X.S "pipe \fB||\fP cond"
X.IP pipe:
X.S "statement { \fB|\fP statement }*"
X.SS Alias expansion
XAlias expansion occurs when the first word of a statement is a defined alias,
Xexcept when that alias is already being expanded.
XIt also occurs after the expansion of an alias whose definition ends with a space.
X.SS Shell variables
XThe following standard special variables exist:
X\fB!\fP, \fB#\fP, \fB$\fP, \fB\-\fP, \fB?\fP.
X.IP CDPATH
XNot yet implemented.
X.IP ENV
XIf this variable is set at start-up
X(after any profile files are executed),
Xthe expanded value is used as shell start-up file.
XIt typically contains function and alias definitions.
X.IP FCEDIT
XThe editor used by the \fIfc\fP command.
X.IP IFS
X\fIInternal field separator\fP,
Xused during substitution and the \fIread\fP command.
X.IP HOME
XThe default directory for the \fIcd\fP command.
X.IP "MAIL MAILCHECK MAILPATH"
XNot yet implemented.
X.IP PATH
XThe search path for executable commands and \fB.\fP'd files.
X.IP "PS1 PS2"
X\fBPS1\fP is the primary prompt for interactive shells.
XDollar substitution is performed, and \fB!\fP is replaced
Xwith the command number (see \fIfc\fP).
X.IP "PWD OLDPWD"
XThe current and previous working directories.
X.IP SECONDS
XThe number of seconds since the shell was started.
X.SS Substitution
XIn addition to the System Vr2 substitutions,
Xthe following are available.
X.IP "$(command)"
XLike `command`, but no escapes are recognized.
X.IP "$(<file)"
XEquivalent to $(cat file), but without forking.
X.IP "${#var}"
XThe length of the string value of \fIvar\fP,
Xor the number of arguments if \fIvar\fP is \fB*\fP or \fB@\fP.
X.IP "${var#pattern} ${var##pattern}"
XIf \fIpattern\fP matches the beginning of the value of \fIvar\fP,
Xthe matched text is deleted from the result of substitution.
XA single \fB#\fP results in the shortest match,
Xtwo \fB#\fP's results in the longest match.
X.IP "${var%pattern} ${var%%pattern}"
XLike \fB#\fP substition, but deleting from the end of the value.
X.SS Expressions
XExpressions can be used with the \fBlet\fP command,
Xas numeric arguments to the \fBtest\fP command,
Xand as the value of an assignment to an integer variable.
X.LP
XExpression may contain alpha-numeric variable identifiers and integer constants
Xand may be combined with the following operators.
X[list them]
X.SS Command execution
XAfter evaluation of keyword assignments and arguments,
Xthe type of command is determined.
XA command may execute a shell function, a shell built-in,
Xor an executable file.
X.LP
XAny keyword assignments are then performed according to
Xthe type of command.
XIn function calls assignments are local to the function.
XAssignments in built-in commands marked with a \(dg persist,
Xotherwise they are temporary.
XAssignments in executable commands are exported to the sub-process
Xexecuting the command.
X.LP
XThere are several built-in commands.
X.IP ":"
XOnly expansion and assignment are performed.
XThis is the default if a command has no arguments.
X.IP ". \fIfile\fP"
XExecute the commands in \fIfile\fP without forking.
XThe file is searched in the directories of $PATH.
XPassing arguments is not implemented.
X.IP "alias [\fIname\fB=\fIvalue\fI ...]\fR"
XWithout arguments, \fBalias\fP lists all aliases and their values.
XFor any name without a value, its value is listed.
XAny name with a value defines an alias, see "Alias Expansion" above.
XKorn's tracked aliases are not implemented,
Xbut System V command hashing is (see "hash").
X.IP "break [\fIlevels\fP]"
X.IP "builtin \fIcommand arg ...\fP"
X\fICommand\fP is executed as a built-in command.
X.IP "cd [\fIpath\fP]"
XSet the working directory to \fIpath\fP.
XIf \fIpath\fP is missing, the home directory ($HOME) is used.
XIf \fIpath\fP is \fB\-\fP, the previous working directory is used.
XThe PWD and OLDPWD variables are reset.
XThe System V two argument form is not implemented.
X.IP "continue [\fIlevels\fP]"
X.IP "echo ..."
X\fIEcho\fP is replaced with the alias echo='print' in the Korn shell.
X.IP "eval \fIcommand ...\fP"
X.IP "exec \fIcommand arg ...\fP"
XThe executable command is executed without forking.
XIf no arguments are given, any IO redirection is permanent.
X.IP "exit [\fIstatus\fP]"
X.IP "fc [\fB\-l\fP] [\fB\-n\fP] [\fIfirst\fP [\fIlast\fP]]"
XA simple subset of Korn's ``fix command''.
X\fIFirst\fP and \fIlast\fP select commands.
XCommands can be selected by history number,
Xor a string specifing the most recent command starting with that string.
XThe \fB\-l\fP option lists the command on stdout,
Xand \fB\-n\fP inhibits the default command numbers.
XWithout \fB\-l\fP, the selected commands can be edited by
Xthe \fB$FCEDIT\fP editor, then executed by the shell.
X.IP "\fBfc \-s\fP [\fIold\fB=\fInew\fR] [\fIcommand\fP]"
XRe-execute the selected command (the previous command by default)
Xafter performing the optional substitution of \fIold\fP with \fInew\fP.
XThis non-standard command is usually accessed with the predefined alias r="fc -s".
X.IP "getopts"
XSee the attached manual page.
X.IP "hash [\fB\-r\fP] [\fIname ...\fP]"
XWithout arguments, any hashed executable command pathnames are listed.
XThe \fB\-r\fP flag causes all hashed commands to be removed.
XEach \fIname\fP is searched as if it where a command name
Xand added to the hash table if it is an executable command.
X.IP "kill [\fB\-\fIsignal\fR] \fIprocess\fP ..."
XSend a signal (TERM by default) to the named process.
XThe signal may be specified as a number or a mnemonic from <signal.h>
Xwith the SIG prefix removed.
X.IP "let [\fIexpression ...\fP]"
XEach expression is evaluated, see "Expressions" above.
XA zero status is returned if the last expression evaluates
Xto a non-zero value, otherwise a non-zero status is returned.
X.IP "\fBprint\fP [\fB\-nreu\fIn\fR] [\fIargument ...\fP]"
X\fBPrint\fP prints its arguments on the standard output,
Xseparated by spaces, and terminated with a newline.
XThe \fB\-n\fP option eliminates the newline.
X.IP
XBy default, certain C escapes are translated.
XThese include \eb, \ef, \en, \er, \et, \ev, and \e### (# is an octal digit).
X\ec is equivalent to the \fB\-n\fP option.
XThis expansion may be inhibitted with the \fB\-r\fP option,
Xand may be re-enabled with the addition of the \fB\-e\fP option.
X.IP "read [\fB\-ru\fIn\fR] \fIname ...\fP"
XThe first variable name may be of the form \fIname\fB?\fIprompt\fR.
X.IP "readonly [\fIname ...\fP]"
X.IP "return [\fIstatus\fP]"
X.ta 5n 10n 30n
X.de O
X.br
X\t\\$1\t\\$2\t\\$3
X..
X.IP "set [\fB\(+-\fP\fI[a-z]\fP] [\fB\(+-o\fP \fIkeyword\fP] ..."
XSet (\fB\-\fP) or clear (\fB+\fP) a shell option:
X.O \-a allexport "all new variable are created with export attribute"
X.O \-e errexit "exit on non-zero status [incorrect]"
X.O "" bgnice "background jobs are run with lower priority"
X.if \n(OE \{
X.O "" emacs "BRL emacs-like line editing"\}
X.O "" ignoreeof "shell will not exit of EOF, must use \fIexit\fP"
X.O \-k keyword "variable assignments are recognized anywhere in command"
X.O "" markdirs "[not implemented]"
X.if \n(OJ \{
X.O \-m monitor "job control enabled (default for interactive shell)"\}
X.O \-n noexec "compile input but do not execute (ignored if interactive)"
X.O \-f noglob "don't expand filenames"
X.O \-u nounset "dollar expansion of unset variables is an error"
X.O \-v verbose "echo shell commands on stdout when compiling"
X.O \-h trackall "add command pathnames to hash table"
X.O \-x xtrace "echo simple commands while executing"
X.IP "set [\fB\-\-\fP] \fIarg ...\fP"
XSet shell arguments.
X.IP "shift [\fInumber\fP]"
X.IP "test"
XSee the attached manual page.
X.IP "times"
X.IP "trap [\fIhandler\fP] [\fIsignal ...\fP]"
X.IP "typeset [\fB\(+-irtx\fP] [\fIname\fP[\fB=\fIvalue\fR] ...]"
XIf no arguments are given, lists all variables and their attributes.
X.PP
XIf options but no names are given, lists variables with specified
Xattributes, and their values if unless ``+'' is used.
X.PP
XIf names are given, set the attributes of the named variables.
XVariables may also be assigned a value.
XIf used inside a function, the created variable are local to the function.
X.PP
XThe attributes are as follows.
X.ta 5n 10n
X\t\-i\tThe variable's value is stored as an integer.
X.br
X\t\-x\tThe variable is exported to the enviroment.
X.br
X\t\-r\tThe variable is read-only cannot be reassigned a value.
X.br
X\t\-t\tTrace (not implemented).
X.br
X\t\-f\tList functions instead of variable.
X.\".IP "ulimit [\fB\-f\fP] [\fIvalue\fP]"
X.ds OZ <OZ>
X.IP "\fBulimit\fP \*(OK \fB\-\*(OZ\fP \*(CK \*(OK \fIn\fP \*(CK"
X.RS
X.TP "\w'\fB\-\-\ \ \ 'u"
X.if \n(OB \{.B \-c
XImpose a size limit of
X.I n\^
Xblocks on the size of core dumps.
X.TP
X.B \-d
XImpose a size limit of
X.I n\^
Xblocks on the size of the data area.\}
X.TP
X.B \-f
XImpose a size limit of
X.I n
Xblocks on files written by the shell
Xand its child processes (files of any size may be read).
X.if \n(OB \{.TP
X.B \-m
XImpose a soft limit of
X.I n\^
Xblocks on the size of physical memory.
X.TP
X.B \-t
XImpose a time limit of
X.I n\^
Xseconds to be used by each process.\}
X.PP
XIf no option is given,
X.B \-f
Xis assumed.
XIf
X.I n
Xis omitted, the current limit is printed.
XAs far as
X.B ulimit
Xis concerned, a ``block'' is 512 bytes.
X.PP
XYou may lower your own resource limit,
Xbut only a super-user (see
X.IR su (1M))
Xcan raise a limit.
X.RE
X.IP "umask [\fIvalue\fP]"
X.IP "unalias \fIname ...\fP"
XThe aliases for the given names are removed.
X.IP "unset [\fB\-f\fP] \fIname ...\fP"
X.IP "wait [\fIprocess-id\fP]"
X.IP "whence [\fB\-v\fP] name ..."
XFor each name, the type of command is listed.
XThe \fB\-v\fP flag causes function and alias values to be listed.
X.if \n(OJ \{.SS Job Control
XJob control features are enabled by the
X\fB\-m\fP or \fB\-o monitor\fP flags.
XWhen job control is enabled,
Xbackground commands and foreground commands that have been stopped
X(usually by a
X.SM SIGTSTP
Xsignal generated by typing
X.IR ^Z\^ )
Xare placed into separate individual
X.IR "process groups" .
XThe following commands are used to manipulate these process groups:
X.PP
X.PD 0
X.TP "\w'\fBkill\fP \*(OK \fIjob\fP \*(CK\ \ \ 'u"
X\fBjobs\fP
XDisplay information about the controlled jobs.
XThe job number is given preceeded by a percent sign,
Xfollowed by a plus sign if it is the ``current job'',
Xor by a minus sign if it is the ``previous job'',
Xthen the process group number for the job,
Xthen the command.
X.TP
Xkill [\fB\-\fIsignal\fR] \fIjob\fP ...
XSend a signal (TERM by default) to the named job process group.
X.TP
X\fBfg\fP \*(OK \fIjob\fP \*(CK
XResume the stopped foreground job in the foreground.
XIf the process group
X.I n
Xis not specified then the ``current job'' is resumed.
X.TP
X\fBbg\fP \*(OK \fIjob\fP \*(CK
XResume the stopped foreground job in the background.
XIf the process group
X.I n
Xis not specified then the ``current job'' is resumed.
X.PD
X.PP
XThe \fBfg\fP, \fBbg\fP, \fBkill\fP, and \fBwait\fP commands
Xmay refer to jobs with the following ``percent'' sequences.
XThe percent sign is optional with the fg and bg commands.
X.PP
X.PD 0
X.TP "\w'\fBbg\fP \*(OK \fIn\fP \*(CK\ \ \ 'u"
X.BR %+ ( %\- )
XIf there is a ``current job'' (``previous job''),
Xthen that job is selected.
X.TP
X.BI % n
XIf the specified job number is one of the known jobs,
Xthen that job is selected.
X.TP
X.BI % string
XIf the string matches the initial part of a job's command,
Xthen that job is selected.
X.TP
X.BI %? string
XAs above, but the string may match any portion of the command.
X.PD\}
X.br
X.if \n(OE \{.SS "Interactive Input Line Editing"
XWhen the
X.B emacs
Xoption is set,
Xinteractive input line editing is enabled.
XThis mode is slightly different from the emacs mode in AT&T's KornShell.
XIn this mode various
X.I "editing commands"
X(typically bound to one or more control characters)
Xcause immediate actions without waiting for a new-line.
XSeveral
X.I "editing commands"
Xare bound to particular control characters
Xwhen the shell is invoked;
Xthese bindings can be changed using the following commands:
X.br
X.PP
X.PD 0
X.TP 2i
X\fBbind\fP
XThe current bindings are listed.
X.TP
X\fBbind\fP \*(OK \fIstring\fP \*(CK = \*(OK \fIediting-command\fP \*(CK
XThe specified
X.I "editing command\^"
Xis bound to the given
X.IR string ,
Xwhich should consist of a control character
X(which may be written using ``caret notation'' \fB^\fP\fIx\fP\|),
Xoptionally preceded by one of the two prefix characters.
XFuture input of the
X.I string
Xwill cause the
X.I "editing command\^"
Xto be immediately invoked.
X.br
X.TP
X\fBbind -m\fP \*(OK \fIstring\fP \*(CK = \*(OK \fIsubstitute\fP \*(CK
XThe specified input
X.I string
Xwill afterwards be immediately replaced by the given
X.I substitute
Xstring,
Xwhich may contain
X.IR "editing commands" .
X.PD
X.PP
XThe following
X.I "editing commands"
Xare available;
Xfirst the command name is given
Xfollowed by its default binding (if any)
Xusing caret notation
X(note that the ASCII
X.SM ESC
Xcharacter is written as \s-1^[\s0\|),
Xthen the editing function performed is decribed.
XNote that
X.I "editing command"
Xnames are used only with the
X.B bind
Xcommand.
XFurthermore,
Xmany
X.I "editing commands"
Xare useful only on terminals with a visible cursor.
XThe default bindings were chosen to resemble corresponding EMACS key bindings.
X.br
X.PP
X.PD 0
X.TP "\w'\fBdelete-word-backward\ \ ^W\fP\ \ \ 'u"
X\fBabort\ \ ^G\fP
XUseful as a response to a request for a
X.B search-history
Xpattern in order to abort the search.
X.br
X.TP
X\fBauto-insert\fP
XSimply causes the character to appear as literal input.
X(Most ordinary characters are bound to this.)
X.br
X.TP
X\fBbackward-char\ \ ^B\fP
XMoves the cursor backward one character.
X.br
X.TP
X\fBbackward-word\ \ ^[\|b\fP
XMoves the cursor backward to the beginning of a word;
Xwords are delimited by the current setting of \fB\s-1IFS\s0\fP.
X.br
X.TP
X\fBbeginning-of-line\ \ ^A\fP
XMoves the cursor to the beginning of the input line
X(after the prompt string).
X.br
X.TP
X\fBcomplete\ \ ^[\|^[\fP
XAutomatically completes as much as is unique of the hashed command name
Xor the file name containing the cursor.
XIf the entire remaining command or file name is unique
Xa space is printed after its completion,
Xunless it is a directory name in which case
X.B /
Xis postpended.
XIf there is no hashed command or file name with the current partial word
Xas its prefix,
Xa bell character is output (usually causing a ``beep'').
X.br
X.TP
X\fBcomplete-command\ \ ^X^[\fP
XAutomatically completes as much as is unique of the hashed command name
Xhaving the partial word up to the cursor as its prefix,
Xas in the
X.B complete
Xcommand described above.
XOnly command and function names seen since the last
X.B "hash \-r"
Xcommand are available for completion;
Xthe
X.B "hash"
Xcommand may be used to register additional names.
X.br
X.TP
X\fBcomplete-file\ \ ^X\|^X\fP
XAutomatically completes as much as is unique of the file name
Xhaving the partial word up to the cursor as its prefix,
Xas in the
X.B complete
Xcommand described above.
X.br
X.TP
X\fBdelete-char-backward\ \ ^H\fP
XDeletes the character before the cursor.
X.br
X.TP
X\fBdelete-char-forward\ \ ^D\fP
XDeletes the character after the cursor.
X.br
X.TP
X\fBdelete-word-backward\ \ ^W\fP
XDeletes characters before the cursor back to the beginning of a word.
X.br
X.TP
X\fBdelete-word-forward\ \ ^[\|d\fP
XDeletes characters after the cursor up to the end of a word.
X.br
X.TP
X\fBdown-history\ \ ^N\fP
XScrolls the history buffer forward one line (later).
XEach input line originally starts just after
Xthe last entry in the history buffer,
Xso
X.B down-history
Xis not useful until either
X.B search-history
Xor
X.B up-history
Xhas been performed.
X.br
X.TP
X\fBend-of-line\ \ ^E\fP
XMoves the cursor to the end of the input line.
X.br
X.TP
X\fBeot\ \ ^_\fP
XActs as an end-of-file;
Xthis is useful because edit-mode input
Xdisables normal terminal input canonicalization.
X.br
X.TP
X\fBforward-char\ \ ^F\fP
XMoves the cursor forward one position.
X.br
X.TP
X\fBforward-word\ \ ^[\|f\fP
XMoves the cursor forward to the end of a word.
X.br
X.TP
X\fBkill-line\ \ ^U\fP
XDeletes the entire input line.
X.br
X.TP
X\fBkill-to-eol\ \ ^K\fP
XDeletes the input from the cursor to the end of the line.
X.br
X.TP
X\fBlist\ \ ^[\|?\fP
XPrints a sorted, columnated list of hashed command names or file names
X(if any) that can complete the partial word containing the cursor.
XDirectory names have
X.B /
Xpostpended to them,
Xand executable file names are followed by
X.BR \(** .
X.br
X.TP
X\fBlist-command\ \ ^X\|?\fP
XPrints a sorted, columnated list of hashed command names
X(if any) that can complete the partial word containing the cursor.
X.br
X.TP
X\fBlist-file\fP
XPrints a sorted, columnated list of file names
X(if any) that can complete the partial word containing the cursor.
XFile type indicators are postpended as described under
X.B list
Xabove.
X.br
X.TP
X\fBnewline\ \ ^J\ \fP\fIand\^\fP\fB\ ^M\fP
XCauses the current input line to be processed by the shell.
X(The current cursor position may be anywhere on the line.)
X.br
X.TP
X\fBprefix-1\ \ ^[\fP
XIntroduces a 2-character command sequence.
X.br
X.TP
X\fBprefix-2\ \ ^X\fP
XIntroduces a 2-character command sequence.
X.br
X.TP
X\fBquote\ \ ^^\fP
XThe following character is taken literally
Xrather than as an
X.IR "editing command" .
X.br
X.TP
X\fBredraw\ \ ^L\fP
XReprints the prompt string and the current input line.
X.br
X.TP
X\fBsearch-character\ \ ^]\fP
XSearch forward in the current line for the next keyboard character.
X.br
X.TP
X\fBsearch-history\ \ ^R\fP
XEnter incremental search mode.
XThe internal history list is searched backwards for commands matching the input.
XAn initial ``^'' in the search string anchors the search.
XThe escape key will leave search mode.
XOther commands will be executed after leaving search mode.
XSuccessive
X.B search-history
Xcommands continue searching backward
Xto the next previous occurrence of the pattern.
XThe history buffer retains only a finite number of lines;
Xthe oldest are discarded as necessary.
X.br
X.ie \n(OX \{.TP
X\fBstuff\ \ ^T\fP\}
X.el \{.TP
X\fBstuff\fP\}
XOn systems supporting it,
Xpushes the bound character back onto the terminal input
Xwhere it may receive special processing by the terminal handler.
X.if \n(OX \{This is useful for the BRL
X.B ^T
X``mini-systat'' feature,
Xfor example.\}
X.br
X.TP
X\fBstuff-reset\fP
XActs like
X.BR stuff\^ ,
Xthen aborts input the same as an interrupt.
X.br
X.ie \n(OX \{.TP
X\fBtranspose-chars\fP\}
X.el \{.TP
X\fBtranspose-chars\ \ ^T\fP\}
XExchanges the two characters on either side of the cursor.
X.br
X.TP
X\fBup-history\ \ ^P\fP
XScrolls the history buffer backward one line (earlier).
X.br
X.TP
X\fByank\ \ ^Y\fP
XInserts the most recently killed text string at the current cursor position.
X.br
X.TP
X\fByank-pop\ \ ^[\|y\fP
XImmediately after a
X.BR yank ,
Xreplaces the inserted text string with the
Xnext previous killed text string.
X.PD\}
X.br
X.SH FILES
X~/.profile
X.br
X/etc/profile
X.SH SEE ALSO
XSh(1) on System V or Sun OS.
X.LP
X.I "UNIX Shell Programming,"
XStephan G. Kochan,
XPatrick H. Wood,
XHayden.
X.LP
X.I "KornShell: Command and Programming Language (not yet published),"
XMorris Bolsky and David Korn.
X.SH AUTHORS
XBased on the public domain 7th edition Bourne shell.
X.LP
XSystem V and Korn modifications by Eric Gisin,
Xwith contributions by
XRon Natalie, Arnold Robbins, Doug Gwyn, Erik Baalbergen, AT&T (getopt(3)).
X.SH DIFFERENCES FROM AT&T VERSION
XVi editing mode is not implemented.
XThe \fBselect\fP statement is not implemented.
X"\fBfc \-e \-\fP" is not implemented, use "\fBfc \-s\fP".
XThe variables \fBRANDOM\fP and \fBPPID\fP are not implemented.
XVariable arrays are not implemented.
XVariable attributes other than integer are not implemented.
XThe \fBERR\fP and \fBEXIT\fP traps are not implemented for functions.
XAlias expansion is inhibited at the beginning of an alias definition
Xin the AT&T version.
XKorn evaluates expressions differently [elaborate].
X.SH BUGS
XInteractive shells will occasionally hang while waiting for a job.
X.LP
XThe 8th bit is stripped in emacs mode.
X.LP
XPlease report any other bugs by mail to egisin at Waterloo.EDU or egisin at UWaterloo.CA.
X.TH TEST 1 "January 1988" "Korn shell"
X.ta 30n
X.de X
X.br
X\\$1\t\\$2
X..
X.SH NAME
Xtest \- test condition (Korn and 8th edition)
X.SH SYNOPSIS
X\fBtest\fP \fIexpression\fP
X.br
X\fB[\fP \fIexpression\fP \fB]\fP
X.SH DESCRIPTION
X\fBTest\f evalutates the \fIexpression\fP and returns zero status if true,
Xand non-zero status otherwise.
XIt is normally used as the controlling command of the \fBif\fP and \fBwhile\fP statements.
X.LP
XThe following basic expressions are available.
X.IP
X.X "-r file" "file exists and is readable"
X.X "-w file" "file exists and is writable"
X.X "-x file" "file exists and is executable"
X.X "-f file" "file is a regular file"
X.X "-d file" "file is a directory"
X.X "-c file" "file is a character special device"
X.X "-b file" "file is a block special device"
X.X "-p file" "file is a named pipe"
X.X "-u file" "file mode has setuid bit"
X.X "-g file" "file mode has setgid bit"
X.X "-k file" "file mode has sticky bit"
X.X "-s file" "file is not empty"
X.X "-L file" "file is a symbolic link"
X.X "-S file" "file is a socket"
X.X "file -nt file" "first file is newer than second file"
X.X "file -ot file" "first file is older than second file"
X.X "file -ef file" "first file is the same file as second file"
X.X "-t filedes" "file descriptor is a tty device"
X.IP
X.X "string" "string is not null"
X.X "-z string" "string is null"
X.X "-n string" "string is not null"
X.X "string = string" "strings are equal"
X.X "string != string" "strings are not equal"
X.IP
X.X "number -eq number" "numbers compare equal"
X.X "number -ne number" "numbers compare not equal"
X.X "number -ge number" "numbers compare greater than or equal"
X.X "number -gt number" "numbers compare greater than"
X.X "number -le number" "numbers compare less than or equal"
X.X "number -lt number" "numbers compare less than"
X.LP
XThe above basic expressions may be combined with the following operators.
X.IP
X.X "expr -o expr" "logical or"
X.X "expr -a expr" "logical and"
X.X "! expr" "logical not"
X.X "( expr )" "grouping"
X.SH AUTHOR
XErik Baalbergen. Modified by Arnold Robbins.
X.rn LP P
X.TH GETOPTS 1 "January 1988" "Korn shell"
X.SH NAME
Xgetopts \- parse command options
X.SH SYNOPSIS
X.B getopts
Xoptstring name [arg ...]
X.SH DESCRIPTION
X.I getopts
Xis used by shell procedures
Xto parse positional parameters and to check for legal options.
XIt supports all applicable rules of the command syntax standard
X(see Rules 3-10,
X.IR intro (1)).
XIt should be used in place of the
X.IR getopt (1)
Xcommand.
X(See the
X.BR \s-1WARNING\s0 ,
Xbelow.)
X.PP
X.I optstring
Xmust contain the option letters the command using
X.I getopts
Xwill recognize;
Xif a letter is followed by a colon,
Xthe option is expected to have an argument
Xwhich should be separated from it by white space.
X.PP
XEach time it is invoked,
X.I getopts
Xwill place the next option in the shell variable
X.I name
Xand the index of the next argument to be processed in the shell variable
X.BR \s-1OPTIND\s0 .
XWhenever the shell or a shell procedure is invoked,
X.B \s-1OPTIND\s0
Xis initialized to
X.BR 1 .
X.PP
XWhen an option requires an option-argument,
X.I getopts
Xplaces it in the shell variable
X.BR \s-1OPTARG\s0 .
X.P
XIf an illegal option is encountered,
X.B ?\&
Xwill be placed in
X.IR name .
X.P
XWhen the end of the options is encountered,
X.I getopts
Xexits with a non-zero exit status.
XThe special option
X.RB `` \-\- ''
Xmay be used to delimit the end of the options.
X.P
XBy default,
X.I getopts
Xparses the positional parameters.
XIf extra arguments
X.RI ( arg
X\&...) are given on the
X.I getopts
Xcommand line,
X.I getopts
Xwill parse them instead.
X.PP
XSo all new commands will adhere to the command syntax standard described in
X.IR intro (1),
Xthey should use
X.IR getopts (1)
Xor
X.IR getopt (3C)
Xto parse positional parameters
Xand check for options that are legal for that command
X(see
X.BR \s-1WARNINGS\s0 ,
Xbelow).
X.SH EXAMPLE
XThe following fragment of a shell program
Xshows how one might process the arguments
Xfor a command that can take the options
X.B a
Xor
X.BR b ,
Xas well as the option
X.BR o ,
Xwhich requires an option-argument:
X.PP
X.RS
X.nf
X.ss 18
X.ta +.5i +1i
X\fBwhile getopts abo: c
Xdo
X	case $c in
X	a\(bvb)	FLAGS=$FLAGS$c;;
X	o)	OARG=$OPTARG;;
X	\e?)	echo $USAGE 1>&2
X		exit 2;;
X	esac
Xdone
Xshift OPTIND\-1\fP
X.fi
X.ta
X.ss 12
X.RE
X.PP
XThis code will accept any of the following as equivalent:
X.PP
X.RS
X.nf
X.ss 18
X\fBcmd \-a \-b \-o "xxx z yy" file
Xcmd \-a \-b \-o "xxx z yy" \-\- file
Xcmd \-ab \-o "xxx z yy" file
Xcmd \-ab \-o "xxx z yy" \-\- file\fP
X.fi
X.ss 12
X.RE
X.SH SEE ALSO
Xintro(1),
Xsh(1).
X.br
Xgetopt(3C)
Xin the
X.IR "Programmer's Reference Manual" .
X.br
X.IR "UNIX System V Release 3.0 Release Notes" .
X.SH WARNING
XAlthough the following command syntax rule (see
X.IR intro (1))
Xrelaxations are permitted under the current implementation,
Xthey should not be used because they may not be supported
Xin future releases of the system.
XAs in the
X.B \s-1EXAMPLE\s0
Xsection above,
X.B a
Xand
X.B b
Xare options,
Xand the option
X.B o
Xrequires an option-argument:
X.PP
X.RS
X.nf
X.ta +1i +1.5i
X\fBcmd \-aboxxx file\fP	(Rule 5 violation: options with
X	option-arguments must not be grouped with other options)
X\fBcmd \-ab \-oxxx file\fP	(Rule 6 violation: there must be
X	white space after an option that takes an option-argument)
X.fi
X.ta
X.RE
X.PP
XChanging the value of the shell variable
X.B \s-1OPTIND\s0
Xor parsing different sets of arguments
Xmay lead to unexpected results.
X.SH DIAGNOSTICS
X.I getopts
Xprints an error message on the standard error output
Xwhen it encounters an option letter not included in
X.IR optstring .
SHAR_EOF
true || echo 'restore of src/ksh.1 failed'
fi
# ============= src/Makefile ==============
if test -f 'src/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping src/Makefile (File already exists)'
else
echo 'x - extracting src/Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/Makefile' &&
X# PD Bourne/Korn Shell
X
X# $Header: /tmp/egisin/src/RCS/Makefile,v 3.2 88/11/06 11:34:12 egisin Exp $
X
XBIN = /u/egisin/bin
XSTD = ../std
XPRINT = lpr -p -Plp26_3018
X
X# CC = cc
XCC = gcc 
X
X# Must define one of _V7, _SYSV, _BSD, _POSIX
X# may define any of JOBS (have BSD or POSIX job control),
X# EDIT (emacs-like command editing), SILLY (see edit.c)
X
XOPTIONS = -D_BSD -DJOBS -DEDIT 
X
XCFWARN = -ansi -O -W -Wcomment # -Wreturn-type
XCFLAGS = $(CFWARN) -I$(STD)/h $(OPTIONS) $(JUNK) 
XLDFLAGS = -L$(STD) $(JUNK) 
XLDLIBS = -lstdc -lposix			# compatability libraries
X
XHDRS =	sh.h table.h expand.h lex.h tree.h tty.h
XSRCS1 =	version.c main.c misc.c trap.c alloc.c io.c \
X	syn.c lex.c edit.c history.c tree.c 
XSRCS2 =	exec.c jobs.c \
X	c_sh.c c_ksh.c c_test.c getopts.c ulimit.c \
X	var.c table.c eval.c expr.c 
XSRCS =	Makefile $(HDRS) $(SRCS1) $(SRCS2) 
X
XOBJS =	version.o main.o misc.o \
X	syn.o lex.o edit.o tree.o \
X	exec.o jobs.o trap.o \
X	c_sh.o c_ksh.o c_test.o \
X	ulimit.o getopts.o expr.o history.o \
X	var.o table.o alloc.o io.o eval.o 
X
Xksh: $(OBJS) 
X	$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
X
Xinstall: ksh
X	cp ksh $(BIN)/ksh
X
Xprint: Index $(SRCS)
X	$(PRINT) Index $(HDRS)
X	$(PRINT) $(SRCS1) 
X	$(PRINT) $(SRCS2) 
X
XIndex: $(SRCS)
X	ctags -x $(SRCS) >Index
X
Xci:
X	touch version.c
X	ci -u -q $(SRCS)
X
Xfix_csh:
X	rm -f /bin/csh
X
Xtar:	ReadMe ksh.1 $(SRCS)
X	tar cf /tmp/egisin/ksh.tar ReadMe ksh.1 $(SRCS)
X
SHAR_EOF
true || echo 'restore of src/Makefile failed'
fi
# ============= src/sh.h ==============
if test -f 'src/sh.h' -a X"$1" != X"-c"; then
	echo 'x - skipping src/sh.h (File already exists)'
else
echo 'x - extracting src/sh.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/sh.h' &&
X/*
X * Public Domain Bourne/Korn shell
X */
X
X/* $Header: /tmp/egisin/src/RCS/sh.h,v 3.1 88/11/03 09:13:48 egisin Exp $ */
X
X/* allow for non-Unix linkers. main.c has a "#define Extern " */
X#ifndef Extern
X#define	Extern	extern
X#endif
X
X#ifndef SHELL
X#define	SHELL	"/bin/sh"	/* shell to exec scripts */
X#endif
X
X#if __STDC__
X#define	ARGS(args)	args	/* prototype declaration */
X#define	Void	void		/* generic pointer */
X#define	Const	const		/* constant data */
X#define	Volatile volatile	/* you know */
X#else
X#define	ARGS(args)	()	/* K&R declaration */
X#define	Void	char
X#define	Const	
X#define	Volatile 
X#endif
X
X#define	sizeofN(type, n) (sizeof(type) * (n))
X#define	BIT(i)	(1<<(i))	/* define bit in flag */
X
X#define	NUFILE	10		/* Number of user-accessible files */
X#define	FDBASE	10		/* First file usable by Shell */
X
X/* you're not going to run setuid shell scripts, are you? */
X#define	eaccess(path, mode)	access(path, mode)
X
X#define	MAGIC	(char)0x80	/* prefix for ~*?[ during expand */
X
X#define	LINE	256		/* input line size */
X#define	PATH	256		/* pathname size */
X
XExtern	int	exstat;		/* exit status */
XExtern	int	async;		/* $!, last &'d pid */
X
X/*
X * Area-based allocation built on malloc/free
X */
X
Xtypedef struct Area {
X	struct Block *free;	/* free list */
X} Area;
X
Xextern	Area	aperm;		/* permanent object space */
X#define	APERM	&aperm
X#define	ATEMP	&e.area
X
XArea   *ainit ARGS((Area *ap));		/* initialize Area */
Xvoid	afreeall ARGS((Area *ap));	/* free Area's contents */
Xvoid	ashrink ARGS((Area *ap));	/* unimplimented */
Xvoid	aerror ARGS((Area *ap, const char *msg)); /* error handler */
X
XVoid   *alloc ARGS((size_t size, Area *ap)); /* alloc object from Area */
XVoid   *aresize ARGS((Void *ptr, size_t size, Area *ap)); /* shrink object */
Xvoid	afree ARGS((Void *ptr, Area *ap)); /* free ojbect in Area */
X
X/*
X * parsing & execution environment
X */
XExtern	struct	env {
X	int	type;			/* enviroment type - see below */
X	Area	area;			/* temporary allocation area */
X	struct	block *loc;		/* local variables and functions */
X	short  *savefd;			/* original redirected fd's */
X	struct	env *oenv;		/* link to previous enviroment */
X	jmp_buf	jbuf;			/* long jump back to env creator */
X	int	interactive;		/* fd's 0,1,2 are tty */
X	struct temp *temps;		/* temp files */
X} e;
X
X#define	E_NONE	0		/* dummy enviroment */
X#define	E_PARSE	1		/* parsing command # */
X#define	E_EXEC	2		/* executing command tree */
X#define	E_LOOP	3		/* executing for/while # */
X#define	E_TCOM	5		/* executing simple command */
X#define	E_FUNC	6		/* executing function */
X#define	E_ERRH	7		/* general error handler # */
X/* # indicates env has valid jbuf */
X
X/*
X * flags
X */
X#define	FEXPORT	FLAG('a')	/* -a: allexport */
X#define	FERREXIT FLAG('e')	/* -e: errexit (quit on error) */
X#define	FBGNICE	29		/* bgnice */
X#define	FEMACS 30		/* emacs */
X#define	FIGNEOF	27		/* ignoreeof (eof does not exit) */
X#define	FHASHALL FLAG('h')	/* -h: trackall, hashall */
X#define	FTALKING FLAG('i')	/* -i: interactive (talking type wireless) */
X#define	FKEYWORD FLAG('k')	/* -k: keyword (name=value anywhere) */
X#define	FMARKDIRS 28		/* markdirs */
X#define	FMONITOR FLAG('m')	/* -m: monitor */
X#define	FNOEXEC	FLAG('n')	/* -n: noexec */
X#define	FNOGLOB	FLAG('f')	/* -f: noglob */
X#define	FPRIVILEGED FLAG('p')	/* -p: privileged */
X#define	FSTDIN	FLAG('s')	/* -s (invocation): parse stdin */
X#define	FNOUNSET FLAG('u')	/* -u: nounset (unset vars is error) */
X#define	FVERBOSE FLAG('v')	/* -v: verbose (echo input) */
X#define	FXTRACE	FLAG('x')	/* -x: (execute) xtrace */
X
X#define	FLAG(c)	(1 + c - 'a')	/* map char to flags index */
X#define	FLAGS	32
XExtern	char flag [FLAGS];
Xint	option ARGS((Const char *name));
Xchar   *getoptions ARGS((void));
Xvoid	printoptions ARGS((void));
X
Xextern	char	null [];	/* null value for variable */
X
X/*
X * other functions
X */
Xchar   *search();
Xstruct tbl *findcom();
Xchar   *strsave ARGS((char *, Area *));
Xchar   *ulton ARGS((unsigned long n, int base));
Xint	xstrcmp();
Xvoid	qsortp ARGS((void **base, size_t n, int (*compare)(void *, void *)));
Xlong	evaluate ARGS((Const char *expr));
Xvoid	resetopts();
Xvoid	histsave();
Xvoid	histlist();
X
X#if EDIT
Xvoid	x_init();
Xvoid	x_bind();
Xint	x_read();
X#endif
X
Xvoid	j_init ARGS((void));
Xvoid	j_exit ARGS((void));
Xvoid	j_notify ARGS((void));
Xvoid	j_kill ARGS((int job, int sig));
X#ifdef JOBS
Xvoid	j_change ARGS((void));
Xint	j_resume ARGS((int job, int bg));
X#endif
X
X/*
X * error handling
X */
Xvoid	leave();	/* abort shell (or fail in subshell) */
X
X/*
X * library functions
X */
Xtypedef	void (*handler_t)();	/* signal handler */
X
X/* temp/here files. the file is removed when the struct is freed */
Xstruct	temp {
X	struct	temp * next;
X	char   *name;
X};
Xstruct temp *maketemp ARGS((Area *ap));
X
X/*
X * stdio and our IO routines
X */
X
X#ifdef	BUFSIZ			/* <stdio.h> included? */
Xextern	FILE *	shf [NUFILE];	/* map shell fd to FILE */
X#endif
Xvoid	fopenshf();
Xvoid	flushshf();
X
X#undef	stdin
X#undef	stdout
X
X#define	stdin	shf[0]		/* standard input */
X#define	stdout	shf[1]		/* standard output */
X#define	shlout	shf[2]		/* shell output */
X
Xint	shellf ARGS((Const char *fmt, ...)); /* fprintf(shlout, ); */
Xint	errorf ARGS((Const char *fmt, ...)); /* fprintf(shlout, ); error(); */
X
X/*
X * IO control
X */
Xextern	int ttyfd;		/* tty fd (original fd 0) */
X
Xint	savefd ARGS((int fd));	/* save user fd */
Xvoid	restfd ARGS((int fd, int ofd));
Xvoid	openpipe ARGS((int [2]));
Xvoid	closepipe ARGS((int [2]));;
X
X/*
X * trap handlers
X */
Xtypedef struct trap {
X	int	signal;		/* signal number */
X	char   *name;		/* short name */
X	char   *mess;		/* descriptive name */
X	char   *trap;		/* trap command */
X	short	Volatile set;	/* trap pending */
X	char	ourtrap;	/* not ignored (?) */
X	char	sig_dfl;	/* originally SIG_DFL */
X} Trap;
X
X#define	SIGNALS	32
X
XExtern	int Volatile trap;	/* traps pending? */
Xextern	Trap	sigtraps[SIGNALS];
XTrap    *gettrap ARGS((char *)); /* search for struct trap by number or name */
Xvoid	trapsig ARGS((int sig)); /* trap signal handler */
X
X/*
X * fast character classes
X */
X#define	C_ALPHA	0x01		/* a-z_A-Z */
X#define	C_DIGIT	0x02		/* 0-9 */
X#define	C_LEX1	0x04		/* \0 \t\n|&;<>() */
X#define	C_VAR1	0x08		/* *@#!$-? */
X#define	C_SUBOP	0x40		/* "=-+?#%" */
X#define	C_IFS	0x80		/* $IFS */
X
Xextern	char ctypes [];
Xvoid	initctypes ARGS((void));
Xvoid	setctypes ARGS((Const char*, int type));
X
X#define	ctype(c, t)	!!(ctypes[(unsigned char)(c)]&(t))
X#define	letter(c)	ctype(c, C_ALPHA)
X#define	digit(c)	ctype(c, C_DIGIT)
X#define	letnum(c)	ctype(c, C_ALPHA|C_DIGIT)
X
SHAR_EOF
true || echo 'restore of src/sh.h failed'
fi
# ============= src/table.h ==============
if test -f 'src/table.h' -a X"$1" != X"-c"; then
	echo 'x - skipping src/table.h (File already exists)'
else
echo 'x - extracting src/table.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/table.h' &&
X/* $Header: /tmp/egisin/src/RCS/table.h,v 3.1 88/11/03 09:13:56 egisin Exp $ */
X
X/*
X * generic hashed associative table for commands and variables.
X */
X
Xstruct table {
X	Area   *areap;		/* area to allocate enties */
X	short	size, free;	/* hash size (always 2^^n), free entries */
X	struct	tbl **tbls;	/* hashed table items */
X};
X
Xstruct tbl {			/* table item */
X	short	flag;		/* flags */
X	short	type;		/* command type or base, see below */
X	union {
X		char *s;	/* string */
X		long i;		/* integer */
X		int (*f)();	/* int function */
X		struct op *t;	/* "function" tree */
X	} val;			/* value */
X	char	name[4];	/* name -- variable length */
X};
X
X/* flag bits */
X#define	ALLOC	BIT(0)		/* val.s has been allocated */
X#define	DEFINED	BIT(1)		/* is defined in block */
X#define	ISSET	BIT(2)		/* has value, vp->val.[si] */
X#define	SPECIAL	BIT(3)		/* PATH, IFS, SECONDS, etc */
X#define	INTEGER	BIT(4)		/* val.i contains integer value */
X#define	RDONLY	BIT(8)		/* read-only variable */
X#define	EXPORT	BIT(9)		/* exported variable */
X#define	LOCAL	BIT(10)		/* for local typeset() */
X#define	TRACE	BIT(11)		/* trace (-t) */
X#define	FUNCT	BIT(12)		/* function */
X
X/* command types */
X#define	CNONE	0		/* undefined */
X#define	CSHELL	1		/* built-in */
X#define	CFUNC	2		/* function */
X#define	CEXEC	4		/* executable command */
X#define	CALIAS	5		/* alias */
X#define	CKEYWD	6		/* keyword */
X
Xvoid tinit ARGS((struct table *, Area *)); /* initialize table */
Xunsigned int hash();		/* name hash function */
Xstruct tbl *tsearch();		/* table lookup primative */
Xstruct tbl *tenter();		/* table lookup/enter primative */
Xvoid tdelete();			/* mark tbl entry for deletion */
Xvoid twalk();			/* initialize walk of table */
Xstruct tbl *tnext();		/* walk table returning table time */
Xstruct tbl **tsort();		/* sort table entries by name */
X
X/*
X * activation record for function blocks
X */
Xstruct block {
X	Area	area;		/* area to allocate things */
X	int	argc;		/* current $# */
X	char **	argv;		/* current $* */
X	struct	table vars;	/* local variables */
X	struct	table funs;	/* local functions */
X#if 1
X	char *	error;		/* error handler */
X	char *	exit;		/* exit handler */
X#else
X	struct	trap error, exit;
X#endif
X	struct	block *next;	/* enclosing block */
X};
X
XExtern	struct block globals;	/* global variables and functions */
XExtern	struct table commands;	/* hashed commands */
XExtern	struct table builtins;	/* built-in commands */
XExtern	struct table lexicals;	/* keywords and aliases */
XExtern	struct table homedirs;	/* homedir() cache */
X
Xstruct builtin {
X	char   *name;
X	int  (*func)();
X};
XExtern Const struct builtin shbuiltins [], kshbuiltins [];
X
X/* var spec values */
X#define	V_NONE	0
X#define	V_PATH	1
X#define	V_IFS	2
X#define	V_SECONDS 3
X#define	V_OPTIND 4
X
XExtern	Area   *lastarea;	/* area of last variable/function looked up */
XExtern	char   *path;		/* PATH value */
XExtern	char   *prompt;		/* PS1 or PS2 */
X
Xvoid	newblock();
Xvoid	popblock();
Xstruct tbl *global(/* char *s */);
Xstruct tbl *local(/* char *s */);
Xstruct tbl *typeset(/* char *var; int set, clr */);
Xstruct tbl *setvar(/* struct tbl *vdst, *vsrc */);
Xstruct tbl *strint(/* struct tbl *vdst, *vsrc */);
Xlong	intval(/* struct tbl *vp */);
Xvoid	setint(/* struct tbl *vp; long n */);
Xchar   *strval(/* struct tbl *vp */);
Xvoid	setstr(/* struct tbl *vp; char *s */);
Xvoid	unset(/* struct tbl *vp */);
Xint	import(/* char *s */);
Xchar  **makenv();
Xint	isassign(/* char *s */);
X
SHAR_EOF
true || echo 'restore of src/table.h failed'
fi
# ============= src/expand.h ==============
if test -f 'src/expand.h' -a X"$1" != X"-c"; then
	echo 'x - skipping src/expand.h (File already exists)'
else
echo 'x - extracting src/expand.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'src/expand.h' &&
X/*
X * Expandable strings
X *
X * Usage
X *	XString xs;
X *	char *xp;
X *
X *	Xinit(xs, xp, 128);
X *	while ((c = generate()) {
X *		Xcheck(xs, xp);
X *		Xput(xs, xp, c);
X *	}
X *	return Xclose(xs, xp);
X */
X
Xtypedef struct XString {
X	char   *end, *beg;	/* end, begin of string */
X#if 1
X	char   *oth, *old;	/* togo, adjust */
X#endif
X	size_t	len;		/* length */
X} XString;
X
Xtypedef char * XStringP;
X
X/* initialize expandable string */
X#define	Xinit(xs, xp, length) { \
X			(xs).len = length; \
X			(xs).beg = alloc((xs).len + 4, ATEMP); \
X			(xs).end = (xs).beg + (xs).len; \
X			xp = (xs).beg; \
X		}
X
X/* stuff char into string */
X#define	Xput(xs, xp, c)	*xp++ = (c)
X
X/* check for overflow, expand string */
X#define	Xcheck(xs, xp) if (xp >= (xs).end) { \
X			char *old_beg = (xs).beg; \
X			(xs).len += (xs).len; \
X			(xs).beg = alloc((xs).len + 4, ATEMP); \
X			(xs).end = (xs).beg + (xs).len; \
X			memcpy((xs).beg, old_beg, (size_t)(xp - old_beg)); \
X			afree((Void*) old_beg, ATEMP); \
X			xp = (xs).beg + (xp - old_beg); \
X		}
X
X/* free string */
X#define	Xfree(xs, xp)	afree((Void*) (xs).beg, ATEMP)
X
X/* close, return string */
X#define	Xclose(xs, xp)	(char*) aresize((Void*)(xs).beg, \
X					(size_t)(xp - (xs).beg), ATEMP)
X/* begin of string */
X#define	Xstring(xs, xp)	((xs).beg)
X
X#define	Xsavepos(xs, xp) (xp - (xs).beg)
X#define	Xrestpos(xs, xp, n) ((xs).beg + (n))
X
X/*
X * expandable vector of generic pointers
X */
X
Xtypedef struct XPtrV {
X	Void  **cur;		/* next avail ptr */
X	Void  **beg, **end;	/* begin, end of vector */
X} XPtrV;
X
X#define	XPinit(x, n) { \
X			register Void **vp; \
X			vp = (Void**) alloc(sizeofN(Void*, n), ATEMP); \
X			(x).cur = (x).beg = vp; \
X			(x).end = vp + n; \
X			}
X
X#define	XPput(x, p) { \
X			if ((x).cur >= (x).end) \
X				xpexpand(&(x)); \
X			*(x).cur++ = (p); \
X			}
X
X#define	XPptrv(x)	((x).beg)
X#define	XPsize(x)	((x).cur - (x).beg)
X
X#define	XPclose(x)	(Void**) aresize((Void*)(x).beg, \
X					 sizeofN(Void*, XPsize(x)), ATEMP)
X
X#define	XPfree(x)	afree((Void*) (x).beg, ATEMP)
X
SHAR_EOF
true || echo 'restore of src/expand.h failed'
fi
true || echo 'restore of src/lex.h failed'
echo End of part 1, continue with part 2
exit 0



More information about the Alt.sources mailing list