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