	OS/2 port of pdksh version 5
	May 8, 1995

This document is intended to define the specific features and
differences in the os/2 port of pdksh.  For general features and
descriptions of pdksh itself please refer to the standard pdksh readme
or the man page.  In general the port has tried to maintain as many of
the standard ksh features as possible.

A default build of pdksh, called ksh.exe, is included in the os2
run time package.  This version was built using the emx facility and
therefore requires that an emx run time package 0.9a or later be
installed on the system.  This is not normally a problem since you
probably already installed it for 'ls' and other unix commands.

If you would rather build your own, obtain the sources from
ftp.cs.mun.ca in the directory pub/pdksh.  You will need a copy of gtar
and gunzip to unload the archive and install on an hpfs partition. Now cd
to the source directory and run the script os2\configure.cmd. (If you
prefer you can copy configure.cmd to the source directory.)  This will
prepare the build environment so that your version of make can be used
to build the executable.  Note that configure.cmd is still under
construction and you may need to make changes to the Makefile and to
config.h to match your specific needs.  Copies of all of these files
will be placed into the source directory. In addition you may want to
make changes to options.h to define your particular preferences.
Configure.cmd for os2 does support two options. Use /v for verbose output 
and /d to build a debug version with symbols (for gcc).

KSH 5 versus KSH 4.9

The KSH version 5 effort is being spearheaded by Michael Rendell, who
took over the effort by Simon J. Gerraty who maintained the version 4
code.  While the version 4 code was a good implementation of ksh
version 5 strives to continue the conformance to the actual posix
definitions and to AT&T ksh.

For this version 5 port to os/2, I originally started with the 4.9 os/2
changes and applied them to the new version.  Subsequently many changes
have been made so that there is little resemblance to that version.
One of my goals for this version is to make ksh not only and interactive 
shell but one that can run some limited Unix(tm) shell scripts as well.

Generally the two shells behave the same.  Version 5 has no logout script
(This can be set up using a trap in your profile.ksh file if desired.)
and the option 'hashall' has been replaced with 'trackall'.
(To see all of the options use the command 'set -o'.)  In addition the
prompt has been changed to conform with the at&t ksh shell instead of
the csh like implemetation of version 4.  The '!' sign is used for the
history number and $ substitutions can be used in the prompt.  The
commands behave more consistently.  For example bind now goes to
standard out so it can be redirected or piped.  Arrays are now
implemented as are almost all AT&T ksh features plus a few more.  The
os/2 port provides file name completion that is not case sensitive.
The startup file kshrc.ksh is still supported but the way it works
is slightly different.

OS2 implementation vs. Unix

The original OS/2 port was done by Kai Uwe Rommel.  I have re-implemented
his ideas in this os/2 version.  The os/2 version of ksh has been
modified to accept the standard os/2 conventions.  Drive designations
a:, etc., are accepted and path separators in variables have been
changed to ';'.  In addition either '/' or '\' can be used as a
directory separator.  The bind command in emacs mode has been enhanced
to accept function key and alt key bindings.  (To see what the alt key
binding should be, use ^Q followed by the key you are interested in.
Replace the ^ alpha you see with ^0 in the bind command.)  The
cursor keys have been implemented for command history for both emacs
mode and vi insert mode.  Standard default stty settings are implemented
for both modes as well.  (This causes some strange behavior when an
edit mode is not set so I recommend that you always set either emacs
or vi mode.)

The remapping of keys can lead to some confusion for Unix and OS/2
users.  The '\' key has a different meaning in Unix where it is used
to escape a special meaning for the character following it or in the
case of the echo (typeset) command it provides special meanings to
certain characters. At the end of a line the '\' is used to escape the
line feed permitting a command to extend to multiple lines. In OS/2
this key is generally the directory name separator.  To provide for
both functions in the OS/2 pdksh the '\' is defined to be a directory
separator in any pathname specification and will keep its escape
meaning when it is followed by any non-alphanumeric character.  The
echo command retains its special interpretation of '\' and will, for
example, interpret \t as a tab when printing.  This can be
disconcerting when you echo the variable that you just set to c:\tmp.
If you want to use echo on a variable with pathnames in it you should
either use uppercase names or a '/' as a separator. If you have loaded
the printenv command it can be used to look at variables.

Unix uses '/' as a directory separator and the OS/2 implementation
permits and in some cases prefers this use as well.  Generally you
can freely mix '/' and '\' characters in a pathname.  However, 'cd \'
will not complete since '\' will escape the new line command and you
will get the secondary prompt.  Just enter a / and the command will
complete.  For many os/2 commands the '/' is used to indicate an
option.  This will still work with pdksh as long as it is not
attached directly to the command name.

Another conflict is the use of ':' and ';'.  Unix uses ':' to separate
entries in variable assignment and ';' to indicate multiple commands
on the same line.  OS/2 uses the ';' to separate entries in a variable.
This could lead to problems when making an assignment to a variable in
pdksh.  You will need to escape the ';' in OS/2 to prevent the shell
from interpreting it as the end of the command.  Either place the
assignment command in quotes or use '\;'.  Note that since a ';' is
not a valid filename or pathname character the '\' will be correctly
interpreted as an escape character.  Note also that something like
ls \tmp\*.exe won't do what you expect.  In this case the '\' will
be interpreted as an escape for the '*' character.  You may need quotes
or several back slashes to get what you want.

In OS/2 the ':' is used to separate the drive letter from the rest of
the pathname.  This usage had been preserved in pdksh.  You can imbed
the drive letter as needed in pathnames.  In addition pdksh preserves
the notion of separate contexts for each drive.  To change drives you
would use the cd command.  "cd A:/" would change to the root on drive
A while "cd C:." would change to whatever was current context on drive
C.

OS/2 and pdksh have similar notions about wildcard characters '*' and
'?' except that pdksh handles the expansion of these wildcard within
the shell and then passes the answer as a list to the application.  If
the application needs to see the wildcard character then you must
escape it from the shell.  Note that pdksh knows about other wildcard
techniques as well.  Please see the man page.

Do to some limitations in the os2 fork process and other differences
between os2 and unix it is not possible to support back-grounding from
pdksh of commands that begin a new window.  For this reason I have
automatically backgrounded all such tasks when they are started.  This
will permit the os2 ksh to serve as a command line launch mechanism for
dos, full screen, and pm applications. (Note that currently ksh can only
launch an application of the same type (windowed, or fullscreen) that
ksh itself is.

PDSKH, OS/2 and the ENVIRONMENT.

The environment in OS/2 and Unix are quite different.  For one thing
you don't actually login to your machine in OS/2 and your initial
environment is established by your CONFIG.SYS file. The Shell will use
the variables that were set in CONFIG.SYS and you should really
consider assigning TMPDIR and HOME for use by pdksh. It will also use
ENV as a variable that names a startup file that will run each time
the shell is started, even if a script is started.  This start up file
is located in your home directory.  For compatability with 4.9 this
shell will also automatically use a startup shell kshrc.ksh if it
finds one in your home directory and is started interactively (and $ENV
is not set).  The variable OS2_SHELL should point to cmd.exe or a fully
compatible version.  This is used to run native os2 scripts.

A new feature with this release is the support of the -l, login option.
This shell will honor a loginfile called profile.ksh if located in
$INIT/etc, c:/usr/etc, or your home. If you are using this shell
as your primary shell you may wish to change the settings in your
os2 command shell notebook to call ksh.exe -l.  I would not recommend
changing the default shell in config.sys.

Should you mess up your PATH variable try 'unset PATH'.  A default
path may get you going again.  In addition pdksh for OS/2 always uses
commands from current context first in the search path even if it is
not explicitly set.  By default c: drive is used when no variables
are set.  Specifically c:/usr/bin and c:/usr/etc can be used as defaults
variouse places in ksh.

The shell itself can be called any name you wish.  Good names include
pdksh.exe, ksh.exe, sh.exe.  You can build two completely different
shells using the options file.  A full blown Korn shell can be built
or a complete subset that behaves very much like a Bourne shell.  The
smaller version is excellent for script support.  In the run time
release I have provided the full shell under the name ksh.exe and a
smaller version under the name sh.exe.  Be careful with names like
rksh.exe or you could end up with a restricted shell that can't do
everything.  In Unix an executable can be tagged with an attribute to
make it known to the system as an executable.  In OS/2 this is done
with an extension.  This shell knows all of the standard OS/2
extensions plus .ksh and .sh.  (Yes it can run dos commands and OS/2 command
files as well.)  The .ksh or .sh extension tells the shell that this is an
executable shell script.  The current version will also treat a file
without an extension as an executable in the style of unix.  Hopefully
this won't cause problems since it really aids scripts.  If it does we 
may have to take it out. Scripts need not necessarily be a ksh shell
scripts however.  the standard Unix #! line at the top of the file
determines the actual comand that will be used to run the
script. A new feature in this release is that any unix absolute
pathnames will be stripped from the #! line since they are unlikely
to match os2 usage.  Your standard PATH search path will be used.

The sample kshrc.ksh file that comes with the distribution can be used
as an example that shows you how to create aliases that will simulate
the standard OS/2 commands.  This means you can still use copy, dir,
and del if you want to.  Keyboard bindings supplied will still provide
the command stack and suddenly you also have command line completion.
To get the most from the shell you will probably want the set of Unix 
commands ported by the Gnu team.  You will most certainly need them if
you want to run any Unix scripts.  A few functions are also provided to
demonstrate the power of this feature.

Unix file systems are case sensitive and ksh generally expects this also.  
This means that internal commands as well as aliases are case sensitive.  
You can use this to your advantage.  For example you want to run a dos 
shell only to find out that 'command' is captured as an internal command 
by ksh.  Try 'COMMAND' or even 'Command' and you will get what you wanted.  
The file name completion and wild card expansion has been modified to 
permit it to ignore case.

SHELL SCRIPT PROGRAMMING

One of my goals in porting this shell was to be able to do shell
level script programming and to run unix shell scripts with minimal
modification.  The first goal is easy and fully functional in this
release.  You can write shell scripts for this or other shells. The
name of the shell you want to run the script is entered in the first
line of the script itself after a '#!' sequence.  If you only enter
the name of the command then pdksh will use your search path to find
the shell.  This is the recommended approach, however absolute paths
of the form /bin/ etc. will be stripped automatically to permit running
unix scripts unmodified. To write portable scripts use the 'uname' 
command from Gnu to set a variable that can be checked for specialized 
approaches.

It is even possible to use ksh as a scripting language when your main
shell is a standard OS/2 shell.  To do this you would write your ksh
script as usual except that the first line in the script should read
'extproc ksh'.  The script should be named with a '.cmd' extension so
that the OS/2 shell can find it.  When the cmd.exe finds this line in
the file it will call ksh to process the script for you.  A script
that is written this way can also be called directly from ksh.  As a
matter of fact you could use this technique entirely for script
creation and name all your scripts with the .cmd extension.  Pdksh
will honor 'extproc' exactly like the standard Unix '#!' processing.

The second goal is much more difficult to achieve. Unix makes many
assumptions about how the system is set up which makes fully portable
scripts difficult to accomplish without the knowledge of the script
internals.  Many script assume the presense of /dev/null and /tmp.  (The
emx layer provides an automatic map for shell references to /dev/null
and /dev/tty as of the 0.9a version.) Some assume /bin and certain 
commands within /bin (usually cp and sh). Until I can figure out how to 
make this more transparent you can simply make these directories on the 
drive that you intend to run the script on.  (Of course, you could also 
modify the script.)  Another standard "trick" in Bourne shell script 
programming is to modify IFS to include a colon and then use the set 
command to parse a variable setting $1, $2, etc.  In OS/2 this needs 
to be a ';'.  For now you will have to hand modify the script.

Of course Unix scripts expect the presence of Unix commands.  You will
need to install a set of Unix utilities, Unix text processing
commands, and probably sed and a version of awk.  I have created a
c:/usr directory on my system for Unix stuff.  I have /usr/bin,
/usr/man, /usr/etc, /usr/home, and /usr/local.  You could establish
even more, or perhaps less, Unix conformance.  You will also need a ps
command.  I use procs.exe which I renamed to ps.exe.  Kill is a ksh
builtin.

RUNNING UNIX GNU CONFIGURE SCRIPTS.

A lot of people would like to use pdksh to permit them to run the
gnu automatic configure scripts.  I am pleased to report that this
is possible using pdksh.  However, I can't guarantee that the results
will match the true configuration for os2 since this is dependant on
the way the individual configure script is written.

To set up to run configure scripts you will need to have a copy of pdksh
called sh.exe somewhere in your path.  One of the very early things done
by most configure scripts is to figure out the compiler.  This will fail
since it depends on setting the IFS (see the above discussion).  To
workaround this problem simply set CC to the compiler you want to use
prior to running the script.  For example to use gcc: export CC=gcc.
Most configure scripts couldn't figure out the names of os2 compilers
anyway.  Now you should be able to simply type 'configure' and watch it
work.  At some point the configure script will build a config.status
script to perform the final step.  If this is not run using 'sh -c
config.status' or some such it will fail since .status is not an os2
legal executable suffix.  You can run it manually however by typing 
'ksh config.status'.  If you have problems you should inspect the
config.status script and fix it as required.

Many configure scripts actually build and execute programs to test
for certain features.  In OS2 using emx, the final link step must have
the .exe extension tied to the executable name or the linker will not
link correctly.  You will need to modify the configure script to
insure the correct executable name.  Once this is built it can be
renamed to a name without an extension if ksh is being used to run it.
A line similar to the following may work for you if you are using 2.0:

ac_link='${CC-cc} -o conftest.exe $CFLAGS $CPPFLAGS $LDFLAGS \
conftest.$ac_ext $LIBS && mv conftest.exe conftest'

This trick takes advantage of ksh's ability to run a command without an
extension.  Even with these changes you may still find
that configure does not correctly identify some os2 features.  I would
recommend that the config.cache file be edited as requred.  The config.cache
file used to build ksh for os2 is located in the os2 subdirectory and
can be used as a reference.

WORK IN PROGRESS

There is still much to do to complete this project.  The confiure.cmd
file needs work as does the Makefile.  The standard defaults work in
the Makefile but many other things have not been checked.  It is known
to work with nmake and dmake, gnu make requires at least version 3.7.3.
And of course there are bugs to fix and enhancements to be made.

Please let me know if you like this port, have found a porting bug,
have fixed a bug, or have coded a spiffy enhancement.  Michael Rendell
should be consulted for general pdksh items and is now actually
maintaining and enhancing all of the code.  Please check the standard
README for more information and also the file os2bugs for current known
problems and limitations.  I can be reached at daled@cadence.com.
Note that this is a home brew project and is in no way related to my
employment.

	Dale DePriest
