	OS/2 port of pdksh version 5
	Dec 12, 1994

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 .08h 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.  Unload the archive and 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 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 first version 5 port to os/2, I started with the 4.9 os/2
changes and applied them to the new version as best I could.  Many
bugs and limitations from that port may still be there (and there are
probably some new ones).  A few things did get fixed, most notably
arguments to scripts are now passed in correctly.  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 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.

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 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 should 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.

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.

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.

It is more difficult to get an OS/2 shell to read login files although
this shell will honor a loginfile called profile.ksh if located in
$INIT/etc, c:/usr/etc, or your home.  The trick is to fool it into 
thinking that you logged in.  Renaming the shell to something beginning 
with a '-' will do the trick.  Real Unix systems modify argument 0 
during the login process to accomplish this.  Now if you start this 
shell it will think that you just logged in.  Too bad OS/2 doesn't 
support symbolic links.  A future release will add a special start up 
option (was -0 in 4.9) to support simulated logging in.

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.

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 Korne 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.  (Yes it can run dos commands and OS/2 command
files as well.)  The .ksh extension tells the shell that this is an
executable shell script.  It need not necessarily be a ksh shell
script however.  the standard Unix #! line at the top of the file
determines the actual comand that will be used to run the
script. (Perhaps in the future Michael or I will design an alias
capability that permits you to define your own extensions.)

The sample kshrc.ksh file that came 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.
However, to get the most from the shell you will probably want the 
set of Unix commands ported by the Gnu team.

Unix file systems are case sensitive and ksh expects this also.  This
means that command completion is done on a case sensitive nature and
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. 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.  (I
have provided an automatic map for shell references to /dev/null.)
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.

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, but gnu make has problems.  The config.h
file was hand built to get something to work but other options and
configurations could be tried.  Ksh job control emulation isn't done
nor is ksh background processing (you can use the OS/2 start command).
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.  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

