# These patches influence only OS/2-related files and MANIFEST:

# To apply this patch change to perl directory, and do

mkdir os2/OS2 os2/OS2/ExtAttr os2/OS2/ExtAttr/t os2/OS2/PrfDB
mkdir os2/OS2/PrfDB/t os2/OS2/Process os2/OS2/REXX os2/OS2/REXX/t
touch os2/OS2/ExtAttr/Changes os2/OS2/ExtAttr/ExtAttr.pm
touch os2/OS2/ExtAttr/ExtAttr.xs os2/OS2/ExtAttr/Makefile.PL
touch os2/OS2/ExtAttr/MANIFEST os2/OS2/ExtAttr/myea.h
touch os2/OS2/ExtAttr/t/os2_ea.t os2/OS2/ExtAttr/typemap
touch os2/OS2/PrfDB/Changes os2/OS2/PrfDB/Makefile.PL
touch os2/OS2/PrfDB/MANIFEST os2/OS2/PrfDB/PrfDB.pm
touch os2/OS2/PrfDB/PrfDB.xs os2/OS2/PrfDB/t/os2_prfdb.t
touch os2/OS2/PrfDB/typemap os2/OS2/Process/Makefile.PL
touch os2/OS2/Process/MANIFEST os2/OS2/Process/Process.pm
touch os2/OS2/Process/Process.xs os2/OS2/REXX/Changes
touch os2/OS2/REXX/Makefile.PL os2/OS2/REXX/MANIFEST
touch os2/OS2/REXX/REXX.pm os2/OS2/REXX/REXX.xs
touch os2/OS2/REXX/t/rx_cmprt.t os2/OS2/REXX/t/rx_dllld.t
touch os2/OS2/REXX/t/rx_objcall.t os2/OS2/REXX/t/rx_sql.test
touch os2/OS2/REXX/t/rx_tiesql.test os2/OS2/REXX/t/rx_tievar.t
touch os2/OS2/REXX/t/rx_tieydb.t os2/OS2/REXX/t/rx_varset.t
touch os2/OS2/REXX/t/rx_vrexx.t os2/README
patch -p1 < this_file
exit 0

Description:
	a) Basic extensions OS2::ExtAttrib, OS2::PrfDB, OS2::Process,
OS2::REXX added;
	b) missing os2/README restored;
	c) hints set `sh' and `startsh', changed for multithread-safe
CRT, and install extensions and tests;
	d) Obsolete dl_os2.xs, os2/notes deleted from MANIFEST;
	e) os2/dlfcn.h was patched twice;
	f) Build process updated, target perl__ added (PM mode executable);
	g) Merged from ak's port: {get,set,end}*ent, do_exec moved to os2.c;
	h) sbrk code is now in malloc, moved from os2.c;
	i) DLL name mungling uses checksums;
	j) /bin/sh directory is read from ENV, as well as prefix of PERLLIB;

diff -ru perl5_003_01/hints/os2.sh perl5_003_01.try/hints/os2.sh
--- perl5_003_01/hints/os2.sh	Tue Jul 30 14:11:24 1996
+++ perl5_003_01.try/hints/os2.sh	Sat Aug 03 22:46:08 1996
@@ -16,6 +16,8 @@
 
 bin_sh=`../UU/loc sh.exe /bin c:/bin d:/bin e:/bin f:/bin g:/bin h:/bin /bin`
 echo "####### Shell found at $bin_sh #############" >&4
+sh="$bin_sh"
+startsh="#!$bin_sh"
 
 #osname="OS/2"
 sysman=`../UU/loc . /man/man1 c:/man/man1 c:/usr/man/man1 d:/man/man1 d:/usr/man/man1 e:/man/man1 e:/usr/man/man1 f:/man/man1 f:/usr/man/man1 g:/man/man1 g:/usr/man/man1 /usr/man/man1`
@@ -74,10 +76,10 @@
     ar='emxomfar'
     plibext='.lib'
     d_fork='undef'
-    lddlflags='-Zdll -Zomf -Zcrtdll'
+    lddlflags='-Zdll -Zomf -Zmt -Zcrtdll'
     # Recursive regmatch may eat 2.5M of stack alone.
-    ldflags='-Zexe -Zomf -Zcrtdll -Zstack 32000'
-    ccflags='-Zomf -DDOSISH -DOS2=2 -DEMBED -I. -DPACK_MALLOC -DDEBUGGING_MSTATS'
+    ldflags='-Zexe -Zomf -Zmt -Zcrtdll -Zstack 32000'
+    ccflags='-Zomf -Zmt -DDOSISH -DOS2=2 -DEMBED -I. -DPACK_MALLOC -DDEBUGGING_MSTATS'
     use_clib='c_import'
     usedl='define'
 fi
@@ -162,3 +164,35 @@
 
 # Commented:
 #startsh='extproc ksh\\n#! sh'
+
+# Now install the external modules. We are in the ./hints directory.
+
+cd ../os2/OS2
+
+if ! test -d ../../ext/OS2 ; then
+   mkdir ../../ext/OS2
+fi
+
+cp -rfu * ../../ext/OS2/
+
+# Install tests:
+
+for xxx in * ; do
+	if $test -d $xxx/t; then
+		cp -uf $xxx/t/*.t ../../t/lib
+	else
+		if $test -d $xxx; then
+			cd $xxx
+			for yyy in * ; do
+				if $test -d $yyy/t; then
+				    cp -uf $yyy/t/*.t ../../t/lib
+				fi
+			done
+			cd ..
+		fi
+	fi
+done
+
+
+# Now go back
+cd ../../hints
diff -ru perl5_003_01/MANIFEST perl5_003_01.try/MANIFEST
--- perl5_003_01/MANIFEST	Tue Jul 30 14:10:54 1996
+++ perl5_003_01.try/MANIFEST	Sun Aug 04 13:58:48 1996
@@ -89,7 +89,6 @@
 ext/DynaLoader/dl_hpux.xs	HP-UX implementation
 ext/DynaLoader/dl_next.xs	Next implementation
 ext/DynaLoader/dl_none.xs	Stub implementation
-ext/DynaLoader/dl_os2.xs	OS/2 (non-a.out) implementation
 ext/DynaLoader/dl_vms.xs	VMS implementation
 ext/DynaLoader/dlutils.c	Dynamic loader utilities for dl_*.xs files
 ext/Fcntl/Fcntl.pm		Fcntl extension Perl module
@@ -386,8 +385,41 @@
 os2/dlfcn.h		Addon for dl_open
 os2/Makefile.SHs	Shared library generation for OS/2
 os2/POSIX.mkfifo	POSIX.xs patch.
+os2/README		OS/2 port info
 os2/README.old		previous OS/2 port info, partially relevant.
-os2/notes		Notes for perl maintainer
+os2/OS2/ExtAttr/Changes		EA access module
+os2/OS2/ExtAttr/ExtAttr.pm	EA access module
+os2/OS2/ExtAttr/ExtAttr.xs	EA access module
+os2/OS2/ExtAttr/Makefile.PL	EA access module
+os2/OS2/ExtAttr/MANIFEST	EA access module
+os2/OS2/ExtAttr/myea.h		EA access module
+os2/OS2/ExtAttr/t/os2_ea.t	EA access module
+os2/OS2/ExtAttr/typemap		EA access module
+os2/OS2/PrfDB/Changes		System database access module
+os2/OS2/PrfDB/Makefile.PL	System database access module
+os2/OS2/PrfDB/MANIFEST		System database access module
+os2/OS2/PrfDB/PrfDB.pm		System database access module
+os2/OS2/PrfDB/PrfDB.xs		System database access module
+os2/OS2/PrfDB/t/os2_prfdb.t	System database access module
+os2/OS2/PrfDB/typemap		System database access module
+os2/OS2/Process/Makefile.PL	system() constants in a module
+os2/OS2/Process/MANIFEST	system() constants in a module
+os2/OS2/Process/Process.pm	system() constants in a module
+os2/OS2/Process/Process.xs	system() constants in a module
+os2/OS2/REXX/Changes		DLL access module
+os2/OS2/REXX/Makefile.PL	DLL access module
+os2/OS2/REXX/MANIFEST		DLL access module
+os2/OS2/REXX/REXX.pm		DLL access module
+os2/OS2/REXX/REXX.xs		DLL access module
+os2/OS2/REXX/t/rx_cmprt.t	DLL access module
+os2/OS2/REXX/t/rx_dllld.t	DLL access module
+os2/OS2/REXX/t/rx_objcall.t	DLL access module
+os2/OS2/REXX/t/rx_sql.test	DLL access module
+os2/OS2/REXX/t/rx_tiesql.test	DLL access module
+os2/OS2/REXX/t/rx_tievar.t	DLL access module
+os2/OS2/REXX/t/rx_tieydb.t	DLL access module
+os2/OS2/REXX/t/rx_varset.t	DLL access module
+os2/OS2/REXX/t/rx_vrexx.t	DLL access module
 os2/os2.c		Additional code for OS/2
 os2/os2ish.h		Header for OS/2
 os2/perl2cmd.pl		Corrects installed binaries under OS/2
diff -ru perl5_003_01/os2/dlfcn.h perl5_003_01.try/os2/dlfcn.h
--- perl5_003_01/os2/dlfcn.h	Tue Jul 30 14:11:52 1996
+++ perl5_003_01.try/os2/dlfcn.h	Thu Aug 01 02:52:44 1996
@@ -1,6 +1,3 @@
 void *dlopen(char *path, int mode);
 void *dlsym(void *handle, char *symbol);
 char *dlerror(void);
-void *dlopen(char *path, int mode);
-void *dlsym(void *handle, char *symbol);
-char *dlerror(void);
diff -ru perl5_003_01/os2/Makefile.SHs perl5_003_01.try/os2/Makefile.SHs
--- perl5_003_01/os2/Makefile.SHs	Tue Jul 30 14:11:52 1996
+++ perl5_003_01.try/os2/Makefile.SHs	Sun Aug 04 13:25:40 1996
@@ -41,6 +41,7 @@
 	echo '  "dlopen"'				>>$@
 	echo '  "dlsym"'				>>$@
 	echo '  "dlerror"'				>>$@
+	echo '  "perl_init_i18nl10n"'			>>$@
 !NO!SUBS!
 
 if [ ! -z "$myttyname" ] ; then
@@ -119,6 +120,11 @@
 perl_: $& aout_perlmain$(AOUT_OBJ_EXT) $(aout_perllib) $(AOUT_DYNALOADER) $(aout_static_ext) ext.libs
 	$(CC) $(LARGE) $(AOUT_CLDFLAGS) $(CCDLFLAGS) -o perl_ aout_perlmain$(AOUT_OBJ_EXT) $(AOUT_DYNALOADER) $(aout_static_ext) $(aout_perllib) `cat ext.libs` $(libs)
 
+perl : perl__
+
+perl__: $& perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) ext.libs
+	$(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o perl__ perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(perllib) `cat ext.libs` $(libs) -Zlinker /PM:PM
+
 aout_clean:
 	-rm *perl_.* *.o *.a lib/auto/*/*.a ext/*/Makefile.aout
 
@@ -128,13 +134,22 @@
 	./perl_ installperl
 
 aout_test: perl_
-	- cd t && (rm -f perl_$(EXE_EXT); $(LNS) ../perl_$(EXE_EXT) perl_$(EXE_EXT)) && ./perl_ TEST </dev/tty
+	- cd t && (rm -f perl_$(EXE_EXT); $(LNS) ../perl_$(EXE_EXT) perl$(EXE_EXT)) && ./perl TEST </dev/tty
+
+lib/auto/OS2/*/%.a : ext/OS2/%/Makefile.aout
+	cd ext/OS2/$(basename $(notdir $@)) ; make -f Makefile.aout config || echo "$make config failed, continuing anyway..."
+	cd ext/OS2/$(basename $(notdir $@)) ; make -f Makefile.aout LINKTYPE=static CCCDLFLAGS=
 
 lib/auto/*/%.a : ext/%/Makefile.aout
 	cd ext/$(basename $(notdir $@)) ; make -f Makefile.aout config || echo "$make config failed, continuing anyway..."
 	cd ext/$(basename $(notdir $@)) ; make -f Makefile.aout LINKTYPE=static CCCDLFLAGS=
 
+.PRECIOUS : ext/%/Makefile.aout ext/OS2/%/Makefile.aout
+
+ext/OS2/%/Makefile.aout : miniperl_
+	cd $(dir $@) ; ../../../miniperl_ -I ../../../lib Makefile.PL MAKEFILE=Makefile.aout INSTALLDIRS=perl 
+
 ext/%/Makefile.aout : miniperl_
-	cd $(dir $@) ; ../../miniperl_ Makefile.PL MAKEFILE=Makefile.aout INSTALLDIRS=perl 
+	cd $(dir $@) ; ../../miniperl_ -I ../../lib Makefile.PL MAKEFILE=Makefile.aout INSTALLDIRS=perl 
 
 !NO!SUBS!
diff -ru perl5_003_01/os2/OS2/ExtAttr/Changes perl5_003_01.try/os2/OS2/ExtAttr/Changes
--- perl5_003_01/os2/OS2/ExtAttr/Changes	Sun Aug 04 13:49:02 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/Changes	Sun Apr 21 11:07:04 1996
@@ -0,0 +1,5 @@
+Revision history for Perl extension OS2::ExtAttr.
+
+0.01  Sun Apr 21 11:07:04 1996
+	- original version; created by h2xs 1.16
+
diff -ru perl5_003_01/os2/OS2/ExtAttr/ExtAttr.pm perl5_003_01.try/os2/OS2/ExtAttr/ExtAttr.pm
--- perl5_003_01/os2/OS2/ExtAttr/ExtAttr.pm	Sun Aug 04 13:49:02 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/ExtAttr.pm	Sun Apr 21 22:59:24 1996
@@ -0,0 +1,186 @@
+package OS2::ExtAttr;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT);
+
+require Exporter;
+require DynaLoader;
+
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+@EXPORT = qw(
+	
+);
+$VERSION = '0.01';
+
+bootstrap OS2::ExtAttr $VERSION;
+
+# Preloaded methods go here.
+
+# Format of the array: 
+# 0 ead, 1 file name, 2 file handle. 3 length, 4 position, 5 need to write.
+
+sub TIEHASH {
+  my $class = shift;
+  my $ea = _create() || die "Cannot create EA: $!";
+  my $file = shift;
+  my ($name, $handle);
+  if (ref $file eq 'GLOB' or ref \$file eq 'GLOB') {
+    die "File handle is not opened" unless $handle = fileno $file;
+    _read($ea, undef, $handle, 0);
+  } else {
+    $name = $file;
+    _read($ea, $name, 0, 0);
+  }
+  bless [$ea, $name, $handle, 0, 0, 0], $class;
+}
+
+sub DESTROY {
+  my $eas = shift;
+  # 0 means: discard eas which are not in $eas->[0].
+  _write( $eas->[0], $eas->[1], $eas->[2], 0) and die "Cannot write EA: $!"
+    if $eas->[5];
+  _destroy( $eas->[0] );
+}
+
+sub FIRSTKEY {
+  my $eas = shift;
+  $eas->[3] = _count($eas->[0]);
+  $eas->[4] = 1;
+  return undef if $eas->[4] > $eas->[3];
+  return _get_name($eas->[0], $eas->[4]);
+}
+
+sub NEXTKEY {
+  my $eas = shift;
+  $eas->[4]++;
+  return undef if $eas->[4] > $eas->[3];
+  return _get_name($eas->[0], $eas->[4]);
+}
+
+sub FETCH {
+  my $eas = shift;
+  my $index = _find($eas->[0], shift);
+  return undef if $index <= 0;
+  return value($eas->[0], $index);
+}
+
+sub EXISTS {
+  my $eas = shift;
+  return _find($eas->[0], shift) > 0;
+}
+
+sub STORE {
+  my $eas = shift;
+  $eas->[5] = 1;
+  add($eas->[0], shift, shift) > 0 or die "Error setting EA: $!";
+}
+
+sub DELETE {
+  my $eas = shift;
+  my $index = _find($eas->[0], shift);
+  return undef if $index <= 0;
+  my $value = value($eas->[0], $index);
+  _delete($eas->[0], $index) and die "Error deleting EA: $!";
+  $eas->[5] = 1;
+  return $value;
+}
+
+sub CLEAR {
+  my $eas = shift;
+  _clear($eas->[0]);
+  $eas->[5] = 1;
+}
+
+# Here are additional methods:
+
+*new = \&TIEHASH;
+
+sub copy {
+  my $eas = shift;
+  my $file = shift;
+  my ($name, $handle);
+  if (ref $file eq 'GLOB' or ref \$file eq 'GLOB') {
+    die "File handle is not opened" unless $handle = fileno $file;
+    _write($eas->[0], undef, $handle, 0) or die "Cannot write EA: $!";
+  } else {
+    $name = $file;
+    _write($eas->[0], $name, 0, 0) or die "Cannot write EA: $!";
+  }
+}
+
+sub update {
+  my $eas = shift;
+  # 0 means: discard eas which are not in $eas->[0].
+  _write( $eas->[0], $eas->[1], $eas->[2], 0) and die "Cannot write EA: $!";
+}
+
+# Autoload methods go after =cut, and are processed by the autosplit program.
+
+1;
+__END__
+# Below is the stub of documentation for your module. You better edit it!
+
+=head1 NAME
+
+OS2::ExtAttr - Perl access to extended attributes.
+
+=head1 SYNOPSIS
+
+  use OS2::ExtAttr;
+  tie %ea, 'OS2::ExtAttr', 'my.file';
+  print $ea{eaname};
+  $ea{myfield} = 'value';
+  
+  untie %ea;
+
+=head1 DESCRIPTION
+
+The package provides low-level and high-level interface to Extended
+Attributes under OS/2. 
+
+=head2 High-level interface: C<tie>
+
+The only argument of tie() is a file name, or an open file handle.
+
+Note that all the changes of the tied hash happen in core, to
+propagate it to disk the tied hash should be untie()ed or should go
+out of scope. Alternatively, one may use the low-level C<update>
+method on the corresponding object. Example:
+
+  tied(%hash)->update;
+
+Note also that setting/getting EA flag is not supported by the
+high-level interface, one should use the low-level interface
+instead. To use it on a tied hash one needs undocumented way to find
+C<eas> give the tied hash.
+
+=head2 Low-level interface
+
+Two low-level methods are supported by the objects: copy() and
+update(). The copy() takes one argument: the name of a file to copy
+the attributes to, or an opened file handle. update() takes no
+arguments, and is discussed above.
+
+Three convenience functions are provided:
+
+  value($eas, $key)
+  add($eas, $key, $value [, $flag])
+  replace($eas, $key, $value [, $flag])
+
+The default value for C<flag> is 0.
+
+In addition, all the C<_ea_*> and C<_ead_*> functions defined in EMX
+library are supported, with leading C<_ea/_ead> stripped.
+
+=head1 AUTHOR
+
+Ilya Zakharevich, ilya@math.ohio-state.edu
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut
diff -ru perl5_003_01/os2/OS2/ExtAttr/ExtAttr.xs perl5_003_01.try/os2/OS2/ExtAttr/ExtAttr.xs
--- perl5_003_01/os2/OS2/ExtAttr/ExtAttr.xs	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/ExtAttr.xs	Sun Apr 21 22:57:22 1996
@@ -0,0 +1,193 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#ifdef __cplusplus
+}
+#endif
+
+#include "myea.h"
+
+SV *
+my_eadvalue(_ead ead, int index)
+{
+    SV *sv;
+    int size = _ead_value_size(ead, index);
+    void *p;
+
+    if (size == -1) {
+	die("Error getting size of EA: %s", strerror(errno));
+    }
+    p = _ead_get_value(ead, index);
+    return  newSVpv((char*)p, size);
+}
+
+#define my_eadreplace(ead, index, sv, flag)	\
+	_ead_replace((ead), (index), flag, SvPVX(sv), SvCUR(sv))
+
+#define my_eadadd(ead, name, sv, flag)	\
+	_ead_add((ead), (name), flag, SvPVX(sv), SvCUR(sv))
+
+
+MODULE = OS2::ExtAttr		PACKAGE = OS2::ExtAttr	PREFIX = my_ead
+
+SV *
+my_eadvalue(ead, index)
+	_ead	ead
+	int	index
+
+int
+my_eadreplace(ead, index, sv, flag = 0)
+	_ead	ead
+	int	index
+	SV *	sv
+	int	flag
+
+int
+my_eadadd(ead, name, sv, flag = 0)
+	_ead	ead
+	char *	name
+	SV *	sv
+	int	flag
+
+MODULE = OS2::ExtAttr		PACKAGE = OS2::ExtAttr	PREFIX = _ea
+
+
+void
+_ea_free(ptr)
+	struct _ea *	ptr
+
+int
+_ea_get(dst, path, handle, name)
+	struct _ea *	dst
+	char *	path
+	int	handle
+	char *	name
+
+int
+_ea_put(src, path, handle, name)
+	struct _ea *	src
+	char *	path
+	int	handle
+	char *	name
+
+int
+_ea_remove(path, handle, name)
+	char *	path
+	int	handle
+	char *	name
+
+MODULE = OS2::ExtAttr		PACKAGE = OS2::ExtAttr	PREFIX = _ead
+
+int
+_ead_add(ead, name, flags, value, size)
+	_ead	ead
+	char *	name
+	int	flags
+	void *	value
+	int	size
+
+void
+_ead_clear(ead)
+	_ead	ead
+
+int
+_ead_copy(dst_ead, src_ead, src_index)
+	_ead	dst_ead
+	_ead	src_ead
+	int	src_index
+
+int
+_ead_count(ead)
+	_ead	ead
+
+_ead
+_ead_create()
+
+int
+_ead_delete(ead, index)
+	_ead	ead
+	int	index
+
+void
+_ead_destroy(ead)
+	_ead	ead
+
+int
+_ead_fea2list_size(ead)
+	_ead	ead
+
+void *
+_ead_fea2list_to_fealist(src)
+	void *	src
+
+void *
+_ead_fealist_to_fea2list(src)
+	void *	src
+
+int
+_ead_find(ead, name)
+	_ead	ead
+	char *	name
+
+void *
+_ead_get_fea2list(ead)
+	_ead	ead
+
+int
+_ead_get_flags(ead, index)
+	_ead	ead
+	int	index
+
+char *
+_ead_get_name(ead, index)
+	_ead	ead
+	int	index
+
+void *
+_ead_get_value(ead, index)
+	_ead	ead
+	int	index
+
+int
+_ead_name_len(ead, index)
+	_ead	ead
+	int	index
+
+int
+_ead_read(ead, path, handle, flags)
+	_ead	ead
+	char *	path
+	int	handle
+	int	flags
+
+int
+_ead_replace(ead, index, flags, value, size)
+	_ead	ead
+	int	index
+	int	flags
+	void *	value
+	int	size
+
+void
+_ead_sort(ead)
+	_ead	ead
+
+int
+_ead_use_fea2list(ead, src)
+	_ead	ead
+	void *	src
+
+int
+_ead_value_size(ead, index)
+	_ead	ead
+	int	index
+
+int
+_ead_write(ead, path, handle, flags)
+	_ead	ead
+	char *	path
+	int	handle
+	int	flags
diff -ru perl5_003_01/os2/OS2/ExtAttr/Makefile.PL perl5_003_01.try/os2/OS2/ExtAttr/Makefile.PL
--- perl5_003_01/os2/OS2/ExtAttr/Makefile.PL	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/Makefile.PL	Sun Apr 21 11:07:04 1996
@@ -0,0 +1,10 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'	=> 'OS2::ExtAttr',
+    'VERSION_FROM' => 'ExtAttr.pm', # finds $VERSION
+    'LIBS'	=> [''],   # e.g., '-lm' 
+    'DEFINE'	=> '',     # e.g., '-DHAVE_SOMETHING' 
+    'INC'	=> '',     # e.g., '-I/usr/include/other' 
+);
diff -ru perl5_003_01/os2/OS2/ExtAttr/MANIFEST perl5_003_01.try/os2/OS2/ExtAttr/MANIFEST
--- perl5_003_01/os2/OS2/ExtAttr/MANIFEST	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/MANIFEST	Sat Aug 03 22:21:56 1996
@@ -0,0 +1,8 @@
+Changes
+ExtAttr.pm
+ExtAttr.xs
+MANIFEST
+Makefile.PL
+myea.h
+t/os2_ea.t
+typemap
diff -ru perl5_003_01/os2/OS2/ExtAttr/myea.h perl5_003_01.try/os2/OS2/ExtAttr/myea.h
--- perl5_003_01/os2/OS2/ExtAttr/myea.h	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/myea.h	Sun Apr 21 11:04:40 1996
@@ -0,0 +1,2 @@
+#include <sys/ea.h>
+#include <sys/ead.h>
diff -ru perl5_003_01/os2/OS2/ExtAttr/t/os2_ea.t perl5_003_01.try/os2/OS2/ExtAttr/t/os2_ea.t
--- perl5_003_01/os2/OS2/ExtAttr/t/os2_ea.t	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/t/os2_ea.t	Sun Aug 04 03:58:08 1996
@@ -0,0 +1,79 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl test.pl'
+
+######################### We start with some black magic to print on failure.
+
+# Change 1..1 below to 1..last_test_to_print .
+# (It may become useful if the test is moved to ./t subdirectory.)
+
+BEGIN { $| = 1; print "1..21\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use OS2::ExtAttr;
+$loaded = 1;
+print "ok 1\n";
+
+######################### End of black magic.
+
+# Insert your test code below (better if it prints "ok 13"
+# (correspondingly "not ok 13") depending on the success of chunk 13
+# of the test code):
+
+system 'cmd', '/c', 'del t.out';
+system 'cmd', '/c', 'echo OK > t.out';
+
+{
+  my %a;
+  tie %a, 'OS2::ExtAttr', 't.out';
+  print "ok 2\n";
+  
+  keys %a == 0 ? print "ok 3\n" : print "not ok 3\n";
+  $a{'++'} = '---';
+  print "ok 4\n";
+  $a{'AAA'} = 'xyz';
+  print "ok 5\n";
+}
+
+{
+  my %a;
+  tie %a, 'OS2::ExtAttr', 't.out';
+  print "ok 6\n";
+  
+  my $c = keys %a;
+  $c == 2 ? print "ok 7\n" : print "not ok 7\n# c=$c\n";
+  my @b = sort keys %a;
+  "@b" eq '++ AAA' ? print "ok 8\n" : print "not ok 8\n# keys=`@b'\n";
+  $a{'++'} eq '---' ? print "ok 9\n" : print "not ok 9\n";;
+  $a{'AAA'} eq 'xyz' ? print "ok 10\n" : print "not ok 10\n# aaa->`$a{AAA}'\n";
+  $c = delete $a{'++'};
+  $c eq '---' ? print "ok 11\n" : print "not ok 11\n# deleted->`$c'\n";;
+}
+
+print "ok 12\n";
+
+{
+  my %a;
+  tie %a, 'OS2::ExtAttr', 't.out';
+  print "ok 13\n";
+  
+  keys %a == 1 ? print "ok 14\n" : print "not ok 14\n";
+  my @b = sort keys %a;
+  "@b" eq 'AAA' ? print "ok 15\n" : print "not ok 15\n";
+  $a{'AAA'} eq 'xyz' ? print "ok 16\n" : print "not ok 16\n";;
+  ! exists $a{'+'} ? print "ok 17\n" : print "not ok 17\n";;
+  ! defined $a{'+'} ? print "ok 18\n" : print "not ok 18\n# ->`$a{'++'}'\n";;
+  ! exists $a{'++'} ? print "ok 19\n" : print "not ok 19\n";;
+  ! defined $a{'++'} ? print "ok 20\n" : print "not ok 20\n# ->`$a{'++'}'\n";;
+}
+
+print "ok 21\n";
+
diff -ru perl5_003_01/os2/OS2/ExtAttr/typemap perl5_003_01.try/os2/OS2/ExtAttr/typemap
--- perl5_003_01/os2/OS2/ExtAttr/typemap	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/ExtAttr/typemap	Sun Apr 21 11:09:34 1996
@@ -0,0 +1,2 @@
+struct _ea *		T_PTR
+_ead			T_PTR
diff -ru perl5_003_01/os2/OS2/PrfDB/Changes perl5_003_01.try/os2/OS2/PrfDB/Changes
--- perl5_003_01/os2/OS2/PrfDB/Changes	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/PrfDB/Changes	Sat Apr 13 23:17:20 1996
@@ -0,0 +1,5 @@
+Revision history for Perl extension OS2::PrfDB.
+
+0.01  Tue Mar 26 19:35:27 1996
+	- original version; created by h2xs 1.16
+0.02:  Field do-not-close added to OS2::Prf::Hini.
diff -ru perl5_003_01/os2/OS2/PrfDB/Makefile.PL perl5_003_01.try/os2/OS2/PrfDB/Makefile.PL
--- perl5_003_01/os2/OS2/PrfDB/Makefile.PL	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/PrfDB/Makefile.PL	Tue Mar 26 19:35:26 1996
@@ -0,0 +1,10 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'	=> 'OS2::PrfDB',
+    'VERSION_FROM' => 'PrfDB.pm', # finds $VERSION
+    'LIBS'	=> [''],   # e.g., '-lm' 
+    'DEFINE'	=> '',     # e.g., '-DHAVE_SOMETHING' 
+    'INC'	=> '',     # e.g., '-I/usr/include/other' 
+);
diff -ru perl5_003_01/os2/OS2/PrfDB/MANIFEST perl5_003_01.try/os2/OS2/PrfDB/MANIFEST
--- perl5_003_01/os2/OS2/PrfDB/MANIFEST	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/PrfDB/MANIFEST	Sat Aug 03 22:20:06 1996
@@ -0,0 +1,7 @@
+Changes
+MANIFEST
+Makefile.PL
+PrfDB.pm
+PrfDB.xs
+t/os2_prfdb.t
+typemap
diff -ru perl5_003_01/os2/OS2/PrfDB/PrfDB.pm perl5_003_01.try/os2/OS2/PrfDB/PrfDB.pm
--- perl5_003_01/os2/OS2/PrfDB/PrfDB.pm	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/PrfDB/PrfDB.pm	Sat Apr 13 23:21:44 1996
@@ -0,0 +1,314 @@
+package OS2::PrfDB;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT);
+
+require Exporter;
+require DynaLoader;
+
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+@EXPORT = qw(
+	     AnyIni UserIni SystemIni
+	    );
+$VERSION = '0.02';
+
+bootstrap OS2::PrfDB $VERSION;
+
+# Preloaded methods go here.
+
+sub AnyIni {
+  new_from_int OS2::PrfDB::Hini OS2::Prf::System(0), 
+  'Anyone of two "systemish" databases', 1;
+}
+
+sub UserIni {
+  new_from_int OS2::PrfDB::Hini OS2::Prf::System(1), 'User settings database', 1;
+}
+
+sub SystemIni {
+  new_from_int OS2::PrfDB::Hini OS2::Prf::System(2),'System settings database',1;
+}
+
+use vars qw{$debug @ISA};
+use Tie::Hash;
+@ISA = qw{Tie::Hash};
+
+# Internal structure 0 => HINI, 1 => array of entries, 2 => iterator.
+
+sub TIEHASH {
+  die "Usage: tie %arr, OS2::PrfDB, filename\n" unless @_ == 2;
+  my ($obj, $file) = @_;
+  my $hini = ref $file eq 'OS2::PrfDB::Hini' ? $file 
+					     : new OS2::PrfDB::Hini $file;
+  die "Error opening profile database `$file': $!" unless $hini;
+  # print "tiehash `@_', hini $hini\n" if $debug;
+  bless [$hini, undef, undef];
+}
+
+sub STORE {
+  my ($self, $key, $val) = @_;
+  die unless @_ == 3;
+  die unless ref $val eq 'HASH';
+  my %sub;
+  tie %sub, 'OS2::PrfDB::Sub', $self->[0], $key;
+  %sub = %$val;
+}
+
+sub FETCH {
+  my ($self, $key) = @_;
+  die unless @_ == 2;
+  my %sub;
+  tie %sub, 'OS2::PrfDB::Sub', $self->[0], $key;
+  \%sub;
+}
+
+sub DELETE {
+  my ($self, $key) = @_;
+  die unless @_ == 2;
+  my %sub;
+  tie %sub, 'OS2::PrfDB::Sub', $self->[0], $key;
+  %sub = ();
+}
+
+# CLEAR ???? - deletion of the whole
+
+sub EXISTS {
+  my ($self, $key) = @_;
+  die unless @_ == 2;
+  return OS2::Prf::GetLength($self->[0]->[0], $key, undef) >= 0;
+}
+
+sub FIRSTKEY {
+  my $self = shift;
+  my $keys = OS2::Prf::Get($self->[0]->[0], undef, undef);
+  return undef unless defined $keys;
+  chop($keys);
+  $self->[1] = [split /\0/, $keys];
+  # print "firstkey1 $self, `$self->[3]->[0], $self->[3]->[1]'\n" if $debug;
+  $self->[2] = 0;
+  return $self->[1]->[0];
+	  # OS2::Prf::Get($self->[0]->[0], $self->[2], $self->[3]->[0]));
+}
+
+sub NEXTKEY {
+  # print "nextkey `@_'\n" if $debug;
+  my $self = shift;
+  return undef unless $self->[2]++ < $#{$self->[1]};
+  my $key = $self->[1]->[$self->[2]];
+  return $key; #, OS2::Prf::Get($self->[0]->[0], $self->[2], $key));
+}
+
+package OS2::PrfDB::Hini;
+
+sub new {
+  die "Usage: new OS2::PrfDB::Hini filename\n" unless @_ == 2;
+  shift;
+  my $file = shift;
+  my $hini = OS2::Prf::Open($file);
+  die "Error opening profile database `$file': $!" unless $hini;
+  bless [$hini, $file];
+}
+
+# Takes HINI and file name:
+
+sub new_from_int { shift; bless [@_] }
+
+# Internal structure 0 => HINI, 1 => filename, 2 => do-not-close.
+
+sub DESTROY {
+  my $self = shift; 
+  my $hini = $self->[0];
+  unless ($self->[2]) {
+    OS2::Prf::Close($hini) or die "Error closing profile `$self->[1]': $!";
+  }
+}
+
+package OS2::PrfDB::Sub;
+use vars qw{$debug @ISA};
+use Tie::Hash;
+@ISA = qw{Tie::Hash};
+
+# Internal structure 0 => HINI, 1 => array of entries, 2 => iterator,
+# 3 => appname.
+
+sub TIEHASH {
+  die "Usage: tie %arr, OS2::PrfDB::Sub, filename, appname\n" unless @_ == 3;
+  my ($obj, $file, $app) = @_;
+  my $hini = ref $file eq 'OS2::PrfDB::Hini' ? $file 
+					     : new OS2::PrfDB::Hini $file;
+  die "Error opening profile database `$file': $!" unless $hini;
+  # print "tiehash `@_', hini $hini\n" if $debug;
+  bless [$hini, undef, undef, $app];
+}
+
+sub STORE {
+  my ($self, $key, $val) = @_;
+  die unless @_ == 3;
+  OS2::Prf::Set($self->[0]->[0], $self->[3], $key, $val);
+}
+
+sub FETCH {
+  my ($self, $key) = @_;
+  die unless @_ == 2;
+  OS2::Prf::Get($self->[0]->[0], $self->[3], $key);
+}
+
+sub DELETE {
+  my ($self, $key) = @_;
+  die unless @_ == 2;
+  OS2::Prf::Set($self->[0]->[0], $self->[3], $key, undef);
+}
+
+# CLEAR ???? - deletion of the whole
+
+sub EXISTS {
+  my ($self, $key) = @_;
+  die unless @_ == 2;
+  return OS2::Prf::GetLength($self->[0]->[0], $self->[3], $key) >= 0;
+}
+
+sub FIRSTKEY {
+  my $self = shift;
+  my $keys = OS2::Prf::Get($self->[0]->[0], $self->[3], undef);
+  return undef unless defined $keys;
+  chop($keys);
+  $self->[1] = [split /\0/, $keys];
+  # print "firstkey1 $self, `$self->[3]->[0], $self->[3]->[1]'\n" if $debug;
+  $self->[2] = 0;
+  return $self->[1]->[0];
+	  # OS2::Prf::Get($self->[0]->[0], $self->[2], $self->[3]->[0]));
+}
+
+sub NEXTKEY {
+  # print "nextkey `@_'\n" if $debug;
+  my $self = shift;
+  return undef unless $self->[2]++ < $#{$self->[1]};
+  my $key = $self->[1]->[$self->[2]];
+  return $key; #, OS2::Prf::Get($self->[0]->[0], $self->[2], $key));
+}
+
+# Autoload methods go after =cut, and are processed by the autosplit program.
+
+1;
+__END__
+# Below is the stub of documentation for your module. You better edit it!
+
+=head1 NAME
+
+OS2::PrfDB - Perl extension for access to OS/2 setting database.
+
+=head1 SYNOPSIS
+
+  use OS2::PrfDB;
+  tie %settings, OS2::PrfDB, 'my.ini';
+  tie %subsettings, OS2::PrfDB::Sub, 'my.ini', 'mykey';
+
+  print "$settings{firstkey}{subkey}\n";
+  print "$subsettings{subkey}\n";
+
+  tie %system, OS2::PrfDB, SystemIni;
+  $system{myapp}{mykey} = "myvalue";
+
+
+=head1 DESCRIPTION
+
+The extention provides both high-level and low-level access to .ini
+files. 
+
+=head2 High level access
+
+High-level access is the tie-hash access via two packages:
+C<OS2::PrfDB> and C<OS2::PrfDB::Sub>. First one supports one argument,
+the name of the file to open, the second one the name of the file to
+open and so called I<Application name>, or the primary key of the
+database.
+
+  tie %settings, OS2::PrfDB, 'my.ini';
+  tie %subsettings, OS2::PrfDB::Sub, 'my.ini', 'mykey';
+
+One may substitute a handle for already opened ini-file instead of the
+file name (obtained via low-level access functions). In particular, 3
+functions SystemIni(), UserIni(), and AnyIni() provide handles to the
+"systemish" databases. AniIni will read from both, and write into User
+database.
+
+=head2 Low-level access
+
+Low-level access functions reside in the package C<OS2::Prf>. They are
+
+=over 14
+
+=item C<Open(file)>
+
+Opens the database, returns an I<integer handle>.
+
+=item C<Close(hndl)>
+
+Closes the database given an I<integer handle>.
+
+=item C<Get(hndl, appname, key)>
+
+Retrieves data from the database given 2-part-key C<appname> C<key>.
+If C<key> is C<undef>, return the "\0" delimited list of C<key>s,
+terminated by \0. If C<appname> is C<undef>, returns the list of
+possible C<appname>s in the same form.
+
+=item C<GetLength(hndl, appname, key)>
+
+Same as above, but returns the length of the value.
+
+=item C<Set(hndl, appname, key, value [ , length ])>
+
+Sets the value. If the C<value> is not defined, removes the C<key>. If
+the C<key> is not defined, removes the C<appname>.
+
+=item C<System(val)>
+
+Return an I<integer handle> associated with the system database. If
+C<val> is 1, it is I<User> database, if 2, I<System> database, if
+0, handle for "both" of them: the handle works for read from any one,
+and for write into I<User> one.
+
+=item C<Profiles()>
+
+returns a reference to a list of two strings, giving names of the
+I<User> and I<System> databases.
+
+=item C<SetUser(file)>
+
+B<(Not tested.)> Sets the profile name of the I<User> database. The
+application should have a message queue to use this function!
+
+=back
+
+=head2 Integer handles
+
+To convert a name or an integer handle into an object acceptable as
+argument to tie() interface, one may use the following functions from
+the package C<OS2::Prf::Hini>:
+
+=over 14
+
+=item C<new(package, file)>
+
+=item C<new_from_int(package, int_hndl [ , filename ])>
+
+=back
+
+=head2 Exports
+
+SystemIni(), UserIni(), and AnyIni().
+
+=head1 AUTHOR
+
+Ilya Zakharevich, ilya@math.ohio-state.edu
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut
+
diff -ru perl5_003_01/os2/OS2/PrfDB/PrfDB.xs perl5_003_01.try/os2/OS2/PrfDB/PrfDB.xs
--- perl5_003_01/os2/OS2/PrfDB/PrfDB.xs	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/PrfDB/PrfDB.xs	Mon Apr 08 23:24:50 1996
@@ -0,0 +1,131 @@
+#define INCL_WINSHELLDATA /* Or use INCL_WIN, INCL_PM, */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include <os2.h>
+#ifdef __cplusplus
+}
+#endif
+
+#define Prf_Open(pszFileName) SaveWinError(PrfOpenProfile(Perl_hab, (pszFileName)))
+#define Prf_Close(hini) (!CheckWinError(PrfCloseProfile(hini)))
+
+SV *
+Prf_Get(HINI hini, PSZ app, PSZ key) {
+    ULONG len;
+    BOOL rc;
+    SV *sv;
+
+    if (CheckWinError(PrfQueryProfileSize(hini, app, key, &len))) return &sv_undef;
+    sv = newSVpv("", 0);
+    SvGROW(sv, len);
+    if (CheckWinError(PrfQueryProfileData(hini, app, key, SvPVX(sv), &len))
+	|| (len == 0 && (app == NULL || key == NULL))) { /* Somewhy needed. */
+	SvREFCNT_dec(sv);
+	return &sv_undef;
+    }
+    SvCUR_set(sv, len);
+    *SvEND(sv) = 0;
+    return sv;
+}
+
+U32
+Prf_GetLength(HINI hini, PSZ app, PSZ key) {
+    U32 len;
+
+    if (CheckWinError(PrfQueryProfileSize(hini, app, key, &len))) return -1;
+    return len;
+}
+
+#define Prf_Set(hini, app, key, s, l)			\
+	 (!(CheckWinError(PrfWriteProfileData(hini, app, key, s, l))))
+
+#define Prf_System(key)					\
+	( (key) ? ( (key) == 1  ? HINI_USERPROFILE	\
+				: ( (key) == 2 ? HINI_SYSTEMPROFILE \
+						: (die("Wrong profile id %i", key), 0) )) \
+	  : HINI_PROFILE)
+
+SV*
+Prf_Profiles()
+{
+    AV *av = newAV();
+    SV *rv;
+    char user[257];
+    char system[257];
+    PRFPROFILE info = { 257, user, 257, system};
+    
+    if (CheckWinError(PrfQueryProfile(Perl_hab, &info))) return &sv_undef;
+    if (info.cchUserName > 257 || info.cchSysName > 257)
+	die("Panic: Profile names too long");
+    av_push(av, newSVpv(user, info.cchUserName - 1));
+    av_push(av, newSVpv(system, info.cchSysName - 1));
+    rv = newRV((SV*)av);
+    SvREFCNT_dec(av);
+    return rv;
+}
+
+BOOL
+Prf_SetUser(SV *sv)
+{
+    char user[257];
+    char system[257];
+    PRFPROFILE info = { 257, user, 257, system};
+    
+    if (!SvPOK(sv)) die("User profile name not defined");
+    if (SvCUR(sv) > 256) die("User profile name too long");
+    if (CheckWinError(PrfQueryProfile(Perl_hab, &info))) return 0;
+    if (info.cchSysName > 257)
+	die("Panic: System profile name too long");
+    info.cchUserName = SvCUR(sv) + 1;
+    info.pszUserName = SvPVX(sv);
+    return !CheckWinError(PrfReset(Perl_hab, &info));
+}
+
+MODULE = OS2::PrfDB		PACKAGE = OS2::Prf PREFIX = Prf_
+
+HINI
+Prf_Open(pszFileName)
+ PSZ     pszFileName;
+
+BOOL
+Prf_Close(hini)
+ HINI     hini;
+
+SV *
+Prf_Get(hini, app, key)
+ HINI hini;
+ PSZ app;
+ PSZ key;
+
+int
+Prf_Set(hini, app, key, s, l = (SvPOK(ST(3)) ? SvCUR(ST(3)): -1))
+ HINI hini;
+ PSZ app;
+ PSZ key;
+ PSZ s;
+ ULONG l;
+
+U32
+Prf_GetLength(hini, app, key)
+ HINI hini;
+ PSZ app;
+ PSZ key;
+
+HINI
+Prf_System(key)
+ int key;
+
+SV*
+Prf_Profiles()
+
+BOOL
+Prf_SetUser(sv)
+ SV *sv
+
+BOOT:
+	Acquire_hab();
diff -ru perl5_003_01/os2/OS2/PrfDB/t/os2_prfdb.t perl5_003_01.try/os2/OS2/PrfDB/t/os2_prfdb.t
--- perl5_003_01/os2/OS2/PrfDB/t/os2_prfdb.t	Sun Aug 04 13:49:04 1996
+++ perl5_003_01.try/os2/OS2/PrfDB/t/os2_prfdb.t	Sun Aug 04 03:58:00 1996
@@ -0,0 +1,185 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::PrfDB\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl test.pl'
+
+######################### We start with some black magic to print on failure.
+
+# Change 1..1 below to 1..last_test_to_print .
+# (It may become useful if the test is moved to ./t subdirectory.)
+
+BEGIN { $| = 1; print "1..48\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use OS2::PrfDB;
+$loaded = 1;
+use strict;
+
+print "ok 1\n";
+
+######################### End of black magic.
+
+# Insert your test code below (better if it prints "ok 13"
+# (correspondingly "not ok 13") depending on the success of chunk 13
+# of the test code):
+
+my $inifile = "my.ini";
+
+unlink $inifile if -w $inifile;
+
+my $ini = OS2::Prf::Open($inifile);
+print( ($ini ? "": "not "), "ok 2\n# HINI=`$ini'\n");
+
+print( (OS2::Prf::GetLength($ini,'aaa', 'bbb') != -1) ? 
+    "not ok 3\n# err: `$^E'\n" : "ok 3\n");
+
+
+print( OS2::Prf::Set($ini,'aaa', 'bbb','xyz') ? "ok 4\n" :
+    "not ok 4\n# err: `$^E'\n");
+
+my $len = OS2::Prf::GetLength($ini,'aaa', 'bbb');
+print( $len == 3 ? "ok 5\n" : "not ok 5# len: `$len' err: `$^E'\n");
+
+my $val = OS2::Prf::Get($ini,'aaa', 'bbb');
+print( $val eq 'xyz' ? "ok 6\n" : "not ok 6# val: `$val' err: `$^E'\n");
+
+$val = OS2::Prf::Get($ini,'aaa', undef);
+print( $val eq "bbb\0" ? "ok 7\n" : "not ok 7# val: `$val' err: `$^E'\n");
+
+$val = OS2::Prf::Get($ini, undef, undef);
+print( $val eq "aaa\0" ? "ok 8\n" : "not ok 8# val: `$val' err: `$^E'\n");
+
+my $res = OS2::Prf::Set($ini,'aaa', 'bbb',undef);
+print( $res ? "ok 9\n" : "not ok 9# err: `$^E'\n");
+
+$val = OS2::Prf::Get($ini, undef, undef);
+print( (! defined $val) ? "ok 10\n" : "not ok 10# val: `$val' err: `$^E'\n");
+
+$val = OS2::Prf::Get($ini,'aaa', undef);
+print( (! defined $val) ? "ok 11\n" : "not ok 11# val: `$val' err: `$^E'\n");
+
+print((OS2::Prf::Close($ini) ? "" : "not ") . "ok 12\n");
+
+my $files = OS2::Prf::Profiles();
+print( (defined $files) ? "ok 13\n" : "not ok 13# err: `$^E'\n");
+print( (@$files == 2) ? "ok 14\n" : "not ok 14# `@$files' err: `$^E'\n");
+print "# `@$files'\n";
+
+$ini = OS2::Prf::Open($inifile);
+print( ($ini ? "": "not "), "ok 15\n# HINI=`$ini'\n");
+
+
+print( OS2::Prf::Set($ini,'aaa', 'ccc','xyz') ? "ok 16\n" :
+    "not ok 16\n# err: `$^E'\n");
+
+print( OS2::Prf::Set($ini,'aaa', 'ddd','123') ? "ok 17\n" :
+    "not ok 17\n# err: `$^E'\n");
+
+print( OS2::Prf::Set($ini,'bbb', 'xxx','abc') ? "ok 18\n" :
+    "not ok 18\n# err: `$^E'\n");
+
+print( OS2::Prf::Set($ini,'bbb', 'yyy','456') ? "ok 19\n" :
+    "not ok 19\n# err: `$^E'\n");
+
+my %hash1;
+
+tie %hash1, 'OS2::PrfDB::Sub', $inifile, 'aaa';
+$OS2::PrfDB::Sub::debug = 1;
+print "ok 20\n";
+
+my @a1 = keys %hash1;
+print (@a1 == 2 ? "ok 21\n" : "not ok 21\n# `@a1'\n");
+
+my @a2 = sort @a1;
+print ("@a2" eq "ccc ddd" ? "ok 22\n" : "not ok 22\n# `@a2'\n");
+
+$val = $hash1{ccc};
+print ($val eq "xyz" ? "ok 23\n" : "not ok 23\n# `$val'\n");
+
+$val = $hash1{ddd};
+print ($val eq "123" ? "ok 24\n" : "not ok 24\n# `$val'\n");
+
+print (exists $hash1{ccc} ? "ok 25\n" : "not ok 25\n# `$val'\n");
+
+print (!exists $hash1{hhh} ? "ok 26\n" : "not ok 26\n# `$val'\n");
+
+$hash1{hhh} = 12;
+print (exists $hash1{hhh} ? "ok 27\n" : "not ok 27\n# `$val'\n");
+
+$val = $hash1{hhh};
+print ($val eq "12" ? "ok 28\n" : "not ok 28\n# `$val'\n");
+
+delete $hash1{ccc};
+
+untie %hash1;
+print "ok 29\n";
+
+tie %hash1, 'OS2::PrfDB::Sub', $inifile, 'aaa';
+print "ok 30\n";
+
+@a1 = keys %hash1;
+print (@a1 == 2 ? "ok 31\n" : "not ok 31\n# `@a1'\n");
+
+@a2 = sort @a1;
+print ("@a2" eq "ddd hhh" ? "ok 32\n" : "not ok 32\n# `@a2'\n");
+
+print (exists $hash1{hhh} ? "ok 33\n" : "not ok 33\n# `$val'\n");
+
+$val = $hash1{hhh};
+print ($val eq "12" ? "ok 34\n" : "not ok 34\n# `$val'\n");
+
+%hash1 = ();
+print "ok 35\n";
+
+%hash1 = ( hhh => 12, ddd => 5);
+
+untie %hash1;
+
+my %hash;
+
+tie %hash, 'OS2::PrfDB', $inifile;
+print "ok 36\n";
+
+@a1 = keys %hash;
+print (@a1 == 2 ? "ok 37\n" : "not ok 37\n# `@a1'\n");
+
+@a2 = sort @a1;
+print ("@a2" eq "aaa bbb" ? "ok 38\n" : "not ok 38\n# `@a2'\n");
+
+print (exists $hash{aaa} ? "ok 39\n" : "not ok 39\n# `$val'\n");
+
+$val = $hash{aaa};
+print (ref $val eq "HASH" ? "ok 40\n" : "not ok 40\n# `$val'\n");
+
+%hash1 = %$val;
+print "ok 41\n";
+
+@a1 = keys %hash1;
+print (@a1 == 2 ? "ok 42\n" : "not ok 31\n# `@a1'\n");
+
+@a2 = sort @a1;
+print ("@a2" eq "ddd hhh" ? "ok 43\n" : "not ok 43\n# `@a2'\n");
+
+print (exists $hash1{hhh} ? "ok 44\n" : "not ok 44\n# `$val'\n");
+
+$val = $hash1{hhh};
+print ($val eq "12" ? "ok 45\n" : "not ok 45\n# `$val'\n");
+
+$hash{nnn}{mmm} = 67;
+print "ok 46\n";
+
+untie %hash;
+
+my %hash2;
+
+tie %hash2, 'OS2::PrfDB', $inifile;
+print "ok 47\n";
+
+print ($hash2{nnn}->{mmm} eq "67" ? "ok 48\n" : "not ok 48\n# `$val'\n");
diff -ru perl5_003_01/os2/OS2/PrfDB/typemap perl5_003_01.try/os2/OS2/PrfDB/typemap
--- perl5_003_01/os2/OS2/PrfDB/typemap	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/PrfDB/typemap	Mon Mar 25 14:03:42 1996
@@ -0,0 +1,14 @@
+BOOL			T_IV
+ULONG			T_IV
+HINI			T_IV
+HAB			T_IV
+PSZ			T_PVNULL
+
+#############################################################################
+INPUT
+T_PVNULL
+	$var = ( SvOK($arg) ? ($type)SvPV($arg,na) : NULL )
+#############################################################################
+OUTPUT
+T_PVNULL
+	sv_setpv((SV*)$arg, $var);
diff -ru perl5_003_01/os2/OS2/Process/Makefile.PL perl5_003_01.try/os2/OS2/Process/Makefile.PL
--- perl5_003_01/os2/OS2/Process/Makefile.PL	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/Process/Makefile.PL	Mon Feb 26 01:42:56 1996
@@ -0,0 +1,10 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'	=> 'OS2::Process',
+    'VERSION'	=> '0.1',
+    'LIBS'	=> [''],   # e.g., '-lm' 
+    'DEFINE'	=> '',     # e.g., '-DHAVE_SOMETHING' 
+    'INC'	=> '',     # e.g., '-I/usr/include/other' 
+);
diff -ru perl5_003_01/os2/OS2/Process/MANIFEST perl5_003_01.try/os2/OS2/Process/MANIFEST
--- perl5_003_01/os2/OS2/Process/MANIFEST	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/Process/MANIFEST	Mon Feb 26 01:42:56 1996
@@ -0,0 +1,4 @@
+MANIFEST
+Makefile.PL
+Process.pm
+Process.xs
diff -ru perl5_003_01/os2/OS2/Process/Process.pm perl5_003_01.try/os2/OS2/Process/Process.pm
--- perl5_003_01/os2/OS2/Process/Process.pm	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/Process/Process.pm	Sun Aug 04 11:49:18 1996
@@ -0,0 +1,112 @@
+package OS2::Process;
+
+require Exporter;
+require DynaLoader;
+require AutoLoader;
+
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+@EXPORT = qw(
+	P_BACKGROUND
+	P_DEBUG
+	P_DEFAULT
+	P_DETACH
+	P_FOREGROUND
+	P_FULLSCREEN
+	P_MAXIMIZE
+	P_MINIMIZE
+	P_NOCLOSE
+	P_NOSESSION
+	P_NOWAIT
+	P_OVERLAY
+	P_PM
+	P_QUOTE
+	P_SESSION
+	P_TILDE
+	P_UNRELATED
+	P_WAIT
+	P_WINDOWED
+);
+sub AUTOLOAD {
+    # This AUTOLOAD is used to 'autoload' constants from the constant()
+    # XS function.  If a constant is not found then control is passed
+    # to the AUTOLOAD in AutoLoader.
+
+    local($constname);
+    ($constname = $AUTOLOAD) =~ s/.*:://;
+    $val = constant($constname, @_ ? $_[0] : 0);
+    if ($! != 0) {
+	if ($! =~ /Invalid/) {
+	    $AutoLoader::AUTOLOAD = $AUTOLOAD;
+	    goto &AutoLoader::AUTOLOAD;
+	}
+	else {
+	    ($pack,$file,$line) = caller;
+	    die "Your vendor has not defined OS2::Process macro $constname, used at $file line $line.
+";
+	}
+    }
+    eval "sub $AUTOLOAD { $val }";
+    goto &$AUTOLOAD;
+}
+
+bootstrap OS2::Process;
+
+# Preloaded methods go here.
+
+# Autoload methods go after __END__, and are processed by the autosplit program.
+
+1;
+__END__
+
+=head1 NAME
+
+OS2::Process - exports constants for system() call on OS2.
+
+=head1 SYNOPSIS
+
+    use OS2::Process;
+    $pid = system(P_PM+P_BACKGROUND, "epm.exe");
+
+=head1 DESCRIPTION
+
+the builtin function system() under OS/2 allows an optional first
+argument which denotes the mode of the process. Note that this argument is
+recognized only if it is strictly numerical.
+
+You can use either one of the process modes:
+
+	P_WAIT (0)	= wait until child terminates (default)
+	P_NOWAIT	= do not wait until child terminates
+	P_SESSION	= new session
+	P_DETACH	= detached
+	P_PM		= PM program
+
+and optionally add PM and session option bits:
+
+	P_DEFAULT (0)	= default
+	P_MINIMIZE	= minimized
+	P_MAXIMIZE	= maximized
+	P_FULLSCREEN	= fullscreen (session only)
+	P_WINDOWED	= windowed (session only)
+
+	P_FOREGROUND	= foreground (if running in foreground)
+	P_BACKGROUND	= background
+
+	P_NOCLOSE	= don't close window on exit (session only)
+
+	P_QUOTE		= quote all arguments
+	P_TILDE		= MKS argument passing convention
+	P_UNRELATED	= do not kill child when father terminates
+
+=head1 AUTHOR
+
+Andreas Kaiser <ak@ananke.s.bawue.de>.
+
+=head1 SEE ALSO
+
+C<spawn*>() system calls.
+
+=cut
diff -ru perl5_003_01/os2/OS2/Process/Process.xs perl5_003_01.try/os2/OS2/Process/Process.xs
--- perl5_003_01/os2/OS2/Process/Process.xs	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/Process/Process.xs	Mon Feb 26 02:00:26 1996
@@ -0,0 +1,154 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <process.h>
+
+static int
+not_here(s)
+char *s;
+{
+    croak("%s not implemented on this architecture", s);
+    return -1;
+}
+
+static unsigned long
+constant(name, arg)
+char *name;
+int arg;
+{
+    errno = 0;
+    if (name[0] == 'P' && name[1] == '_') {
+	if (strEQ(name, "P_BACKGROUND"))
+#ifdef P_BACKGROUND
+	    return P_BACKGROUND;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_DEBUG"))
+#ifdef P_DEBUG
+	    return P_DEBUG;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_DEFAULT"))
+#ifdef P_DEFAULT
+	    return P_DEFAULT;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_DETACH"))
+#ifdef P_DETACH
+	    return P_DETACH;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_FOREGROUND"))
+#ifdef P_FOREGROUND
+	    return P_FOREGROUND;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_FULLSCREEN"))
+#ifdef P_FULLSCREEN
+	    return P_FULLSCREEN;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_MAXIMIZE"))
+#ifdef P_MAXIMIZE
+	    return P_MAXIMIZE;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_MINIMIZE"))
+#ifdef P_MINIMIZE
+	    return P_MINIMIZE;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_NOCLOSE"))
+#ifdef P_NOCLOSE
+	    return P_NOCLOSE;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_NOSESSION"))
+#ifdef P_NOSESSION
+	    return P_NOSESSION;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_NOWAIT"))
+#ifdef P_NOWAIT
+	    return P_NOWAIT;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_OVERLAY"))
+#ifdef P_OVERLAY
+	    return P_OVERLAY;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_PM"))
+#ifdef P_PM
+	    return P_PM;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_QUOTE"))
+#ifdef P_QUOTE
+	    return P_QUOTE;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_SESSION"))
+#ifdef P_SESSION
+	    return P_SESSION;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_TILDE"))
+#ifdef P_TILDE
+	    return P_TILDE;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_UNRELATED"))
+#ifdef P_UNRELATED
+	    return P_UNRELATED;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_WAIT"))
+#ifdef P_WAIT
+	    return P_WAIT;
+#else
+	    goto not_there;
+#endif
+	if (strEQ(name, "P_WINDOWED"))
+#ifdef P_WINDOWED
+	    return P_WINDOWED;
+#else
+	    goto not_there;
+#endif
+    }
+
+    errno = EINVAL;
+    return 0;
+
+not_there:
+    errno = ENOENT;
+    return 0;
+}
+
+
+MODULE = OS2::Process		PACKAGE = OS2::Process
+
+
+unsigned long
+constant(name,arg)
+	char *		name
+	int		arg
+
diff -ru perl5_003_01/os2/OS2/REXX/Changes perl5_003_01.try/os2/OS2/REXX/Changes
--- perl5_003_01/os2/OS2/REXX/Changes	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/REXX/Changes	Sun Aug 04 05:20:52 1996
@@ -0,0 +1,4 @@
+0.2:
+	After fixpak17 a lot of other places have mismatched lengths
+returned in the REXXPool interface.
+	Also drop does not work on stems any more.
diff -ru perl5_003_01/os2/OS2/REXX/Makefile.PL perl5_003_01.try/os2/OS2/REXX/Makefile.PL
--- perl5_003_01/os2/OS2/REXX/Makefile.PL	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/REXX/Makefile.PL	Sun Aug 04 05:22:48 1996
@@ -0,0 +1,7 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+	      NAME => 'OS2::REXX',
+	      VERSION => '0.2',
+	      XSPROTOARG => '-noprototypes',
+);
diff -ru perl5_003_01/os2/OS2/REXX/MANIFEST perl5_003_01.try/os2/OS2/REXX/MANIFEST
--- perl5_003_01/os2/OS2/REXX/MANIFEST	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/REXX/MANIFEST	Sun Aug 04 05:21:24 1996
@@ -0,0 +1,14 @@
+Changes
+MANIFEST
+Makefile.PL
+REXX.pm
+REXX.xs
+t/rx_cmprt.t
+t/rx_dllld.t
+t/rx_objcall.t
+t/rx_sql.test
+t/rx_tiesql.test
+t/rx_tievar.t
+t/rx_tieydb.t
+t/rx_varset.t
+t/rx_vrexx.t
diff -ru perl5_003_01/os2/OS2/REXX/REXX.pm perl5_003_01.try/os2/OS2/REXX/REXX.pm
--- perl5_003_01/os2/OS2/REXX/REXX.pm	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/REXX/REXX.pm	Sun Aug 04 12:24:10 1996
@@ -0,0 +1,387 @@
+package OS2::REXX;
+
+use Carp;
+require Exporter;
+require DynaLoader;
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default
+# (move infrequently used names to @EXPORT_OK below)
+@EXPORT = qw(REXX_call REXX_eval REXX_eval_with);
+# Other items we are prepared to export if requested
+@EXPORT_OK = qw(drop);
+
+sub AUTOLOAD {
+    $AUTOLOAD =~ /^OS2::REXX::.+::(.+)$/
+      or confess("Undefined subroutine &$AUTOLOAD called");
+    return undef if $1 eq "DESTROY";
+    $_[0]->find($1)
+      or confess("Can't find entry '$1' to DLL '$_[0]->{File}'");
+    goto &$AUTOLOAD;
+}
+
+@libs = split(/;/, $ENV{'PERL5REXX'} || $ENV{'PERLREXX'} || $ENV{'LIBPATH'} || $ENV{'PATH'});
+%dlls = ();
+
+bootstrap OS2::REXX;
+
+# Preloaded methods go here.  Autoload methods go after __END__, and are
+# processed by the autosplit program.
+
+# Cannot autoload, the autoloader is used for the REXX functions.
+
+sub load
+{
+	confess 'Usage: load OS2::REXX <file> [<dirs>]' unless $#_ >= 1;
+	my ($class, $file, @where) = (@_, @libs);
+	return $dlls{$file} if $dlls{$file};
+	my $handle;
+	foreach (@where) {
+		$handle = DynaLoader::dl_load_file("$_/$file.dll");
+		last if $handle;
+	}
+	return undef unless $handle;
+	eval "package OS2::REXX::$file; \@ISA = ('OS2::REXX');"
+	   . "sub AUTOLOAD {"
+	   . "  \$OS2::REXX::AUTOLOAD = \$AUTOLOAD;"
+	   . "  goto &OS2::REXX::AUTOLOAD;"
+	   . "} 1;" or die "eval package $@";
+	return $dlls{$file} = bless {Handle => $handle, File => $file, Queue => 'SESSION' }, "OS2::REXX::$file";
+}
+
+sub find
+{
+	my $self   = shift;
+	my $file   = $self->{File};
+	my $handle = $self->{Handle};
+	my $prefix = exists($self->{Prefix}) ? $self->{Prefix} : "";
+	my $queue  = $self->{Queue};
+	foreach (@_) {
+		my $name = "OS2::REXX::${file}::$_";
+		next if defined(&$name);
+		my $addr = DynaLoader::dl_find_symbol($handle, uc $prefix.$_)
+		        || DynaLoader::dl_find_symbol($handle, $prefix.$_)
+			or return 0;
+		eval "package OS2::REXX::$file; sub $_".
+		     "{ shift; OS2::REXX::_call('$_', $addr, '$queue', \@_); }".
+		     "1;"
+			or die "eval sub";
+	}
+	return 1;
+}
+
+sub prefix
+{
+	my $self = shift;
+	$self->{Prefix} = shift;
+}
+
+sub queue
+{
+	my $self = shift;
+	$self->{Queue} = shift;
+}
+
+sub drop
+{				# Supposedly should drop anything with
+                                # the given prefix. Unfortunately a
+                                # loop is needed after fixpack17.
+&OS2::REXX::_drop(@_);
+}
+
+sub dropall
+{				# Supposedly should drop anything with
+                                # the given prefix. Unfortunately a
+                                # loop is needed after fixpack17.
+  &OS2::REXX::_drop(@_);	# Try to drop them all.
+  my $name;
+  for (@_) {
+    if (/\.$/) {
+      OS2::REXX::_fetch('DUMMY'); # reset REXX's first/next iterator
+      while (($name) = OS2::REXX::_next($_)) {
+	OS2::REXX::_drop($_ . $name);
+      }
+    } 
+  }
+}
+
+sub TIESCALAR
+{
+	my ($obj, $name) = @_;
+	$name =~ s/^[\w!?]+/\U$&\E/;
+	return bless \$name, OS2::REXX::_SCALAR;
+}	
+
+sub TIEARRAY
+{
+	my ($obj, $name) = @_;
+	$name =~ s/^[\w!?]+/\U$&\E/;
+	return bless [$name, 0], OS2::REXX::_ARRAY;
+}
+
+sub TIEHASH
+{
+	my ($obj, $name) = @_;
+	$name =~ s/^[\w!?]+/\U$&\E/;
+	return bless {Stem => $name}, OS2::REXX::_HASH;
+}
+
+#############################################################################
+package OS2::REXX::_SCALAR;
+
+sub FETCH
+{
+	return OS2::REXX::_fetch(${$_[0]});
+}
+
+sub STORE
+{
+	return OS2::REXX::_set(${$_[0]}, $_[1]);
+}
+
+sub DESTROY
+{
+	return OS2::REXX::_drop(${$_[0]});
+}
+
+#############################################################################
+package OS2::REXX::_ARRAY;
+
+sub FETCH
+{
+	$_[0]->[1] = $_[1] if $_[1] > $_[0]->[1];
+	return OS2::REXX::_fetch($_[0]->[0].'.'.(0+$_[1]));
+}
+
+sub STORE
+{
+	$_[0]->[1] = $_[1] if $_[1] > $_[0]->[1];
+	return OS2::REXX::_set($_[0]->[0].'.'.(0+$_[1]), $_[2]);
+}
+
+#############################################################################
+package OS2::REXX::_HASH;
+
+require Tie::Hash;
+@ISA = ('Tie::Hash');
+
+sub FIRSTKEY
+{
+	my ($self) = @_;
+	my $stem = $self->{Stem};
+
+	delete $self->{List} if exists $self->{List};
+
+	my @list = ();
+	my ($name, $value);
+	OS2::REXX::_fetch('DUMMY'); # reset REXX's first/next iterator
+	while (($name) = OS2::REXX::_next($stem)) {
+		push @list, $name;
+	}
+	my $key = pop @list;
+
+	$self->{List} = \@list;
+	return $key;
+}
+
+sub NEXTKEY
+{
+	return pop @{$_[0]->{List}};
+}
+
+sub EXISTS
+{
+	return defined OS2::REXX::_fetch($_[0]->{Stem}.$_[1]);
+}
+
+sub FETCH
+{
+	return OS2::REXX::_fetch($_[0]->{Stem}.$_[1]);
+}
+
+sub STORE
+{
+	return OS2::REXX::_set($_[0]->{Stem}.$_[1], $_[2]);
+}
+
+sub DELETE
+{
+	OS2::REXX::_drop($_[0]->{Stem}.$_[1]);
+}
+
+#############################################################################
+package OS2::REXX;
+
+1;
+__END__
+
+=head1 NAME
+
+OS2::REXX - access to DLLs with REXX calling convention and REXX runtime.
+
+=head2 NOTE
+
+By default, the REXX variable pool is not available, neither
+to Perl, nor to external REXX functions. To enable it, you need to put
+your code inside C<REXX_call> function.  REXX functions which do not use
+variables may be usable even without C<REXX_call> though.
+
+=head1 SYNOPSIS
+
+	use OS2::REXX;
+	$ydb = load OS2::REXX "ydbautil" or die "Cannot load: $!";
+	@pid = $ydb->RxProcId();
+	REXX_call {
+	  tie $s, OS2::REXX, "TEST";
+	  $s = 1;
+	};
+
+=head1 DESCRIPTION
+
+=head2 Load REXX DLL
+
+	$dll = load OS2::REXX NAME [, WHERE];
+
+NAME is DLL name, without path and extension.
+
+Directories are searched WHERE first (list of dirs), then environment
+paths PERL5REXX, PERLREXX or, as last resort, PATH.
+
+The DLL is not unloaded when the variable dies.
+
+Returns DLL object reference, or undef on failure.
+
+=head2 Define function prefix:
+
+	$dll->prefix(NAME);
+
+Define the prefix of external functions, prepended to the function
+names used within your program, when looking for the entries in the
+DLL.
+
+=head2 Example
+
+		$dll = load OS2::REXX "RexxBase";
+		$dll->prefix("RexxBase_");
+		$dll->Init();
+
+is the same as
+
+		$dll = load OS2::REXX "RexxBase";
+		$dll->RexxBase_Init();
+
+=head2 Define queue:
+
+	$dll->queue(NAME);
+
+Define the name of the REXX queue passed to all external
+functions of this module. Defaults to "SESSION".
+
+Check for functions (optional):
+
+	BOOL = $dll->find(NAME [, NAME [, ...]]);
+
+Returns true if all functions are available.
+
+=head2 Call external REXX function:
+
+	$dll->function(arguments);
+
+Returns the return string if the return code is 0, else undef.
+Dies with error message if the function is not available.
+
+=head1 Accessing REXX-runtime
+
+While calling functions with REXX signature does not require the presence
+of the system REXX DLL, there are some actions which require REXX-runtime 
+present. Among them is the access to REXX variables by name.
+
+One enables REXX runtime by bracketing your code by
+
+	REXX_call BLOCK;
+
+(trailing semicolon required!) or
+
+	REXX_call \&subroutine_name;
+
+Inside such a call one has access to REXX variables (see below), and to
+
+	REXX_eval EXPR;
+	REXX_eval_with EXPR, 
+		subroutine_name_in_REXX => \&Perl_subroutine
+
+=head2 Bind scalar variable to REXX variable:
+
+	tie $var, OS2::REXX, "NAME";
+
+=head2 Bind array variable to REXX stem variable:
+
+	tie @var, OS2::REXX, "NAME.";
+
+Only scalar operations work so far. No array assignments, no array
+operations, ... FORGET IT.
+
+=head2 Bind hash array variable to REXX stem variable:
+
+	tie %var, OS2::REXX, "NAME.";
+
+To access all visible REXX variables via hash array, bind to "";
+
+No array assignments. No array operations, other than hash array
+operations. Just like the *dbm based implementations.
+
+For the usual REXX stem variables, append a "." to the name,
+as shown above. If the hash key is part of the stem name, for
+example if you bind to "", you cannot use lower case in the stem
+part of the key and it is subject to character set restrictions.
+
+=head2 Erase individual REXX variables (bound or not):
+
+	OS2::REXX::drop("NAME" [, "NAME" [, ...]]);
+
+=head2 Erase REXX variables with given stem (bound or not):
+
+	OS2::REXX::dropall("STEM" [, "STEM" [, ...]]);
+
+=head1 NOTES
+
+Note that while function and variable names are case insensitive in the
+REXX language, function names exported by a DLL and the REXX variables
+(as seen by Perl through the chosen API) are all case sensitive!
+
+Most REXX DLLs export function names all upper case, but there are a
+few which export mixed case names (such as RxExtras). When trying to
+find the entry point, both exact case and all upper case are searched.
+If the DLL exports "RxNap", you have to specify the exact case, if it
+exports "RXOPEN", you can use any case.
+
+To avoid interfering with subroutine names defined by Perl (DESTROY)
+or used within the REXX module (prefix, find), it is best to use mixed
+case and to avoid lowercase only or uppercase only names when calling
+REXX functions. Be consistent. The same function written in different
+ways results in different Perl stubs.
+
+There is no REXX interpolation on variable names, so the REXX variable
+name TEST.ONE is not affected by some other REXX variable ONE. And it
+is not the same variable as TEST.one!
+
+You cannot call REXX functions which are not exported by the DLL.
+While most DLLs export all their functions, some, like RxFTP, export
+only "...LoadFuncs", which registers the functions within REXX only.
+
+You cannot call 16-bit DLLs. The few interesting ones I found
+(FTP,NETB,APPC) do not export their functions.
+
+I do not know whether the REXX API is reentrant with respect to
+exceptions (signals) when the REXX top-level exception handler is
+overridden. So unless you know better than I do, do not access REXX
+variables (probably tied to Perl variables) or call REXX functions
+which access REXX queues or REXX variables in signal handlers.
+
+See C<t/rx*.t> for examples.
+
+=head1 AUTHOR
+
+Andreas Kaiser ak@ananke.s.bawue.de, with additions by Ilya Zakharevich
+ilya@math.ohio-state.edu.
+
+=cut
diff -ru perl5_003_01/os2/OS2/REXX/REXX.xs perl5_003_01.try/os2/OS2/REXX/REXX.xs
--- perl5_003_01/os2/OS2/REXX/REXX.xs	Sun Aug 04 13:49:06 1996
+++ perl5_003_01.try/os2/OS2/REXX/REXX.xs	Sun Aug 04 04:37:44 1996
@@ -0,0 +1,484 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#define INCL_BASE
+#define INCL_REXXSAA
+#include <os2emx.h>
+
+#if 0
+#define INCL_REXXSAA
+#pragma pack(1)
+#define _Packed
+#include <rexxsaa.h>
+#pragma pack()
+#endif
+
+extern ULONG _emx_exception (	EXCEPTIONREPORTRECORD *,
+				EXCEPTIONREGISTRATIONRECORD *,
+                                CONTEXTRECORD *,
+                                void *);
+
+static RXSTRING * strs;
+static int	  nstrs;
+static SHVBLOCK * vars;
+static int	  nvars;
+static char *	  trace;
+
+static RXSTRING   rxcommand    = {  9, "RXCOMMAND" };
+static RXSTRING   rxsubroutine = { 12, "RXSUBROUTINE" };
+static RXSTRING   rxfunction   = { 11, "RXFUNCTION" };
+
+static ULONG PERLCALL(PSZ name, ULONG argc, PRXSTRING argv, PSZ queue, PRXSTRING ret);
+
+#if 1
+ #define Set	RXSHV_SET
+ #define Fetch	RXSHV_FETCH
+ #define Drop	RXSHV_DROPV
+#else
+ #define Set	RXSHV_SYSET
+ #define Fetch	RXSHV_SYFET
+ #define Drop	RXSHV_SYDRO
+#endif
+
+static long incompartment;
+
+static SV*
+exec_in_REXX(char *cmd, char * handlerName, RexxFunctionHandler *handler)
+{
+    HMODULE hRexx, hRexxAPI;
+    BYTE    buf[200];
+    LONG    APIENTRY (*pRexxStart) (LONG, PRXSTRING, PSZ, PRXSTRING, 
+				    PSZ, LONG, PRXSYSEXIT, PSHORT, PRXSTRING);
+    APIRET  APIENTRY (*pRexxRegisterFunctionExe) (PSZ,
+						  RexxFunctionHandler *);
+    APIRET  APIENTRY (*pRexxDeregisterFunction) (PSZ);
+    RXSTRING args[1];
+    RXSTRING inst[2];
+    RXSTRING result;
+    USHORT   retcode;
+    LONG rc;
+    SV *res;
+
+    if (incompartment) die ("Attempt to reenter into REXX compartment");
+    incompartment = 1;
+
+    if (DosLoadModule(buf, sizeof buf, "REXX", &hRexx)
+	|| DosLoadModule(buf, sizeof buf, "REXXAPI", &hRexxAPI)
+	|| DosQueryProcAddr(hRexx, 0, "RexxStart", (PFN *)&pRexxStart)
+	|| DosQueryProcAddr(hRexxAPI, 0, "RexxRegisterFunctionExe", 
+			    (PFN *)&pRexxRegisterFunctionExe)
+	|| DosQueryProcAddr(hRexxAPI, 0, "RexxDeregisterFunction",
+			    (PFN *)&pRexxDeregisterFunction)) {
+	die("REXX not available\n");
+    }
+
+    if (handlerName)
+	pRexxRegisterFunctionExe(handlerName, handler);
+
+    MAKERXSTRING(args[0], NULL, 0);
+    MAKERXSTRING(inst[0], cmd,  strlen(cmd));
+    MAKERXSTRING(inst[1], NULL, 0);
+    MAKERXSTRING(result,  NULL, 0);
+    rc = pRexxStart(0, args, "StartPerl", inst, "Perl", RXSUBROUTINE, NULL,
+		    &retcode, &result);
+
+    incompartment = 0;
+    pRexxDeregisterFunction("StartPerl");
+    DosFreeModule(hRexxAPI);
+    DosFreeModule(hRexx);
+    if (!RXNULLSTRING(result)) {
+	res = newSVpv(RXSTRPTR(result), RXSTRLEN(result));
+	DosFreeMem(RXSTRPTR(result));
+    } else {
+	res = NEWSV(729,0);
+    }
+    if (rc || SvTRUE(GvSV(errgv))) {
+	if (SvTRUE(GvSV(errgv))) {
+	    die ("Error inside perl function called from REXX compartment.\n%s", SvPV(GvSV(errgv), na)) ;
+	}
+	die ("REXX compartment returned non-zero status %li", rc);
+    }
+
+    return res;
+}
+
+static SV* exec_cv;
+
+static ULONG
+PERLSTART(PSZ name, ULONG argc, PRXSTRING argv, PSZ queue, PRXSTRING ret)
+{
+    return PERLCALL(NULL, argc, argv, queue, ret);
+}
+
+#define in_rexx_compartment() exec_in_REXX("return StartPerl()\r\n", \
+					   "StartPerl", PERLSTART)
+#define REXX_call(cv) ( exec_cv = (cv), in_rexx_compartment())
+#define REXX_eval_with(cmd,name,cv) ( exec_cv = (cv),		\
+				      exec_in_REXX(cmd,name,PERLSTART))
+#define REXX_eval(cmd) REXX_eval_with(cmd,NULL,NULL)
+
+static ULONG
+PERLCALL(PSZ name, ULONG argc, PRXSTRING argv, PSZ queue, PRXSTRING ret)
+{
+    EXCEPTIONREGISTRATIONRECORD xreg = { NULL, _emx_exception };
+    int i, rc;
+    unsigned long len;
+    char *str;
+    char **arr;
+    dSP;
+
+    DosSetExceptionHandler(&xreg);
+
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(sp);
+
+#if 0
+    if (!my_perl) {
+	DosUnsetExceptionHandler(&xreg);
+	return 1;
+    }
+#endif 
+
+    if (name) {
+	int ac = 0;
+	char **arr = alloca((argc + 1) * sizeof(char *));
+
+	for (i = 0; i < argc; ++i)
+	    arr[ac++] = argv[i].strptr;
+	arr[ac] = NULL;
+
+	rc = perl_call_argv(name, G_SCALAR | G_EVAL, arr);
+    } else if (exec_cv) {
+	SV *cv = exec_cv;
+
+	exec_cv = NULL;
+	rc = perl_call_sv(cv, G_SCALAR | G_EVAL);
+    } else rc = -1;
+
+    SPAGAIN;
+
+    if (rc == 1 && SvOK(TOPs)) { 
+	str = SvPVx(POPs, len);
+	if (len > 256)
+	    if (DosAllocMem((PPVOID)&ret->strptr, len, PAG_READ|PAG_WRITE|PAG_COMMIT)) {
+		DosUnsetExceptionHandler(&xreg);
+		return 1;
+	    }
+	memcpy(ret->strptr, str, len);
+	ret->strlength = len;
+    }
+
+    PUTBACK ;
+    FREETMPS ;
+    LEAVE ;
+
+    if (rc != 1) {
+	DosUnsetExceptionHandler(&xreg);
+	return 1;
+    }
+
+
+    DosUnsetExceptionHandler(&xreg);
+    return 0;
+}
+
+static void
+needstrs(int n)
+{
+    if (n > nstrs) {
+	if (strs)
+	    free(strs);
+	nstrs = 2 * n;
+	strs = malloc(nstrs * sizeof(RXSTRING));
+    }
+}
+
+static void
+needvars(int n)
+{
+    if (n > nvars) {
+	if (vars)
+	    free(vars);
+	nvars = 2 * n;
+	vars = malloc(nvars * sizeof(SHVBLOCK));
+    }
+}
+
+static void
+initialize(void)
+{
+    needstrs(8);
+    needvars(8);
+    trace = getenv("PERL_REXX_DEBUG");
+}
+
+static int
+not_here(s)
+char *s;
+{
+    croak("%s not implemented on this architecture", s);
+    return -1;
+}
+
+static int
+constant(name, arg)
+char *name;
+int arg;
+{
+    errno = EINVAL;
+    return 0;
+}
+
+
+MODULE = OS2::REXX		PACKAGE = OS2::REXX
+
+BOOT:
+	initialize();
+
+int
+constant(name,arg)
+	char *		name
+	int		arg
+
+SV *
+_call(name, address, queue="SESSION", ...)
+	char *		name
+	void *		address
+	char *		queue
+ CODE:
+   {
+       ULONG	rc;
+       int	argc, i;
+       RXSTRING	result;
+       UCHAR	resbuf[256];
+       RexxFunctionHandler *fcn = address;
+       argc = items-3;
+       needstrs(argc);
+       if (trace)
+	   fprintf(stderr, "REXXCALL::_call name: '%s' args:", name);
+       for (i = 0; i < argc; ++i) {
+	   STRLEN len;
+	   char *ptr = SvPV(ST(3+i), len);
+	   MAKERXSTRING(strs[i], ptr, len);
+	   if (trace)
+	       fprintf(stderr, " '%.*s'", len, ptr);
+       }
+       if (!*queue)
+	   queue = "SESSION";
+       if (trace)
+	   fprintf(stderr, "\n");
+       MAKERXSTRING(result, resbuf, sizeof resbuf);
+       rc = fcn(name, argc, strs, queue, &result);
+       if (trace)
+	   fprintf(stderr, "  rc=%X, result='%.*s'\n", rc,
+		   result.strlength, result.strptr);
+       ST(0) = sv_newmortal();
+       if (rc == 0) {
+	   if (result.strptr)
+	       sv_setpvn(ST(0), result.strptr, result.strlength);
+	   else
+	       sv_setpvn(ST(0), "", 0);
+       }
+       if (result.strptr && result.strptr != resbuf)
+	   DosFreeMem(result.strptr);
+   }
+
+int
+_set(name,value,...)
+	char *		name
+	char *		value
+ CODE:
+   {
+       int   i;
+       int   n = (items + 1) / 2;
+       ULONG rc;
+       needvars(n);
+       if (trace)
+	   fprintf(stderr, "REXXCALL::_set");
+       for (i = 0; i < n; ++i) {
+	   SHVBLOCK * var = &vars[i];
+	   STRLEN     namelen;
+	   STRLEN     valuelen;
+	   name = SvPV(ST(2*i+0),namelen);
+	   if (2*i+1 < items) {
+	       value = SvPV(ST(2*i+1),valuelen);
+	   }
+	   else {
+	       value = "";
+	       valuelen = 0;
+	   }
+	   var->shvcode = RXSHV_SET;
+	   var->shvnext = &vars[i+1];
+	   var->shvnamelen = namelen;
+	   var->shvvaluelen = valuelen;
+	   MAKERXSTRING(var->shvname, name, namelen);
+	   MAKERXSTRING(var->shvvalue, value, valuelen);
+	   if (trace)
+	       fprintf(stderr, " %.*s='%.*s'",
+		       var->shvname.strlength, var->shvname.strptr,
+		       var->shvvalue.strlength, var->shvvalue.strptr);
+       }
+       if (trace)
+	   fprintf(stderr, "\n");
+       vars[n-1].shvnext = NULL;
+       rc = RexxVariablePool(vars);
+       if (trace)
+	   fprintf(stderr, "  rc=%X\n", rc);
+       RETVAL = (rc & ~RXSHV_NEWV) ? FALSE : TRUE;
+   }
+ OUTPUT:
+    RETVAL
+
+void
+_fetch(name, ...)
+	char *		name
+ PPCODE:
+   {
+       int   i;
+       ULONG rc;
+       EXTEND(sp, items);
+       needvars(items);
+       if (trace)
+	   fprintf(stderr, "REXXCALL::_fetch");
+       for (i = 0; i < items; ++i) {
+	   SHVBLOCK * var = &vars[i];
+	   STRLEN     namelen;
+	   name = SvPV(ST(i),namelen);
+	   var->shvcode = RXSHV_FETCH;
+	   var->shvnext = &vars[i+1];
+	   var->shvnamelen = namelen;
+	   var->shvvaluelen = 0;
+	   MAKERXSTRING(var->shvname, name, namelen);
+	   MAKERXSTRING(var->shvvalue, NULL, 0);
+	   if (trace)
+	       fprintf(stderr, " '%s'", name);
+       }
+       if (trace)
+	   fprintf(stderr, "\n");
+       vars[items-1].shvnext = NULL;
+       rc = RexxVariablePool(vars);
+       if (!(rc & ~RXSHV_NEWV)) {
+	   for (i = 0; i < items; ++i) {
+	       int namelen;
+	       SHVBLOCK * var = &vars[i];
+	       /* returned lengths appear to be swapped */
+	       /* but beware of "future bug fixes" */
+	       namelen = var->shvvalue.strlength; /* should be */
+	       if (var->shvvaluelen < var->shvvalue.strlength)
+		   namelen = var->shvvaluelen; /* is */
+	       if (trace)
+		   fprintf(stderr, "  %.*s='%.*s'\n",
+			   var->shvname.strlength, var->shvname.strptr,
+			   namelen, var->shvvalue.strptr);
+	       if (var->shvret & RXSHV_NEWV || !var->shvvalue.strptr)
+		   PUSHs(&sv_undef);
+	       else
+		   PUSHs(sv_2mortal(newSVpv(var->shvvalue.strptr,
+					    namelen)));
+	   }
+       } else {
+	   if (trace)
+	       fprintf(stderr, "  rc=%X\n", rc);
+       }
+   }
+
+void
+_next(stem)
+	char *	stem
+ PPCODE:
+   {
+       SHVBLOCK sv;
+       BYTE     name[4096];
+       ULONG    rc;
+       int      len = strlen(stem), namelen, valuelen;
+       if (trace)
+	   fprintf(stderr, "REXXCALL::_next stem='%s'\n", stem);
+       sv.shvcode = RXSHV_NEXTV;
+       sv.shvnext = NULL;
+       MAKERXSTRING(sv.shvvalue, NULL, 0);
+       do {
+	   sv.shvnamelen = sizeof name;
+	   sv.shvvaluelen = 0;
+	   MAKERXSTRING(sv.shvname, name, sizeof name);
+	   if (sv.shvvalue.strptr) {
+	       DosFreeMem(sv.shvvalue.strptr);
+	       MAKERXSTRING(sv.shvvalue, NULL, 0);
+	   }
+	   rc = RexxVariablePool(&sv);
+       } while (!rc && memcmp(stem, sv.shvname.strptr, len) != 0);
+       if (!rc) {
+	   EXTEND(sp, 2);
+	   /* returned lengths appear to be swapped */
+	   /* but beware of "future bug fixes" */
+	   namelen = sv.shvname.strlength; /* should be */
+	   if (sv.shvnamelen < sv.shvname.strlength)
+	       namelen = sv.shvnamelen; /* is */
+	   valuelen = sv.shvvalue.strlength; /* should be */
+	   if (sv.shvvaluelen < sv.shvvalue.strlength)
+	       valuelen = sv.shvvaluelen; /* is */
+	   if (trace)
+	       fprintf(stderr, "  %.*s='%.*s'\n",
+		       namelen, sv.shvname.strptr,
+		       valuelen, sv.shvvalue.strptr);
+	   PUSHs(sv_2mortal(newSVpv(sv.shvname.strptr+len, namelen-len)));
+	   if (sv.shvvalue.strptr) {
+	       PUSHs(sv_2mortal(newSVpv(sv.shvvalue.strptr, valuelen)));
+				DosFreeMem(sv.shvvalue.strptr);
+	   } else	
+	       PUSHs(&sv_undef);
+       } else if (rc != RXSHV_LVAR) {
+	   die("Error %i when in _next", rc);
+       } else {
+	   if (trace)
+	       fprintf(stderr, "  rc=%X\n", rc);
+       }
+   }
+
+int
+_drop(name,...)
+	char *		name
+ CODE:
+   {
+       int i;
+       needvars(items);
+       for (i = 0; i < items; ++i) {
+	   SHVBLOCK * var = &vars[i];
+	   STRLEN     namelen;
+	   name = SvPV(ST(i),namelen);
+	   var->shvcode = RXSHV_DROPV;
+	   var->shvnext = &vars[i+1];
+	   var->shvnamelen = namelen;
+	   var->shvvaluelen = 0;
+	   MAKERXSTRING(var->shvname, name, var->shvnamelen);
+	   MAKERXSTRING(var->shvvalue, NULL, 0);
+       }
+       vars[items-1].shvnext = NULL;
+       RETVAL = (RexxVariablePool(vars) & ~RXSHV_NEWV) ? FALSE : TRUE;
+   }
+ OUTPUT:
+    RETVAL
+
+int
+_register(name)
+	char *	name
+ CODE:
+    RETVAL = RexxRegisterFunctionExe(name, PERLCALL);
+ OUTPUT:
+    RETVAL
+
+SV*
+REXX_call(cv)
+	SV *cv
+  PROTOTYPE: &
+
+SV*
+REXX_eval(cmd)
+	char *cmd
+
+SV*
+REXX_eval_with(cmd,name,cv)
+	char *cmd
+	char *name
+	SV *cv
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_cmprt.t perl5_003_01.try/os2/OS2/REXX/t/rx_cmprt.t
--- perl5_003_01/os2/OS2/REXX/t/rx_cmprt.t	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_cmprt.t	Sun Aug 04 03:07:26 1996
@@ -0,0 +1,40 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+
+$| = 1;				# Otherwise data from REXX may come first
+
+print "1..13\n";
+
+$n = 1;
+sub do_me {
+  print "ok $n\n";
+  "OK";
+}
+
+@res = REXX_call(\&do_me);
+print "ok 2\n";
+@res == 1 ? print "ok 3\n" : print "not ok 3\n";
+$res[0] eq "OK" ? print "ok 4\n" : print "not ok 4\n# `$res[0]'\n";
+
+# Try again
+$n = 5;
+@res = REXX_call(\&do_me);
+print "ok 6\n";
+@res == 1 ? print "ok 7\n" : print "not ok 7\n";
+$res[0] eq "OK" ? print "ok 8\n" : print "not ok 8\n# `$res[0]'\n";
+
+REXX_call { print "ok 9\n" };
+REXX_eval 'say "ok 10"';
+# Try again
+REXX_eval 'say "ok 11"';
+print "ok 12\n" if REXX_eval("return 2 + 3") eq 5;
+REXX_eval_with 'say myfunc()', myfunc => sub {"ok 13"};
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_dllld.t perl5_003_01.try/os2/OS2/REXX/t/rx_dllld.t
--- perl5_003_01/os2/OS2/REXX/t/rx_dllld.t	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_dllld.t	Sun Aug 04 03:07:34 1996
@@ -0,0 +1,36 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+
+$path = $ENV{LIBPATH} || $ENV{PATH} or die;
+foreach $dir (split(';', $path)) {
+  next unless -f "$dir/YDBAUTIL.DLL";
+  $found = "$dir/YDBAUTIL.DLL";
+  last;
+}
+$found or die "1..0\n#Cannot find YDBAUTIL.DLL\n";
+
+print "1..5\n";
+
+$module = DynaLoader::dl_load_file($found) or die "not ok 1\n# load\n";
+print "ok 1\n";
+
+$address = DynaLoader::dl_find_symbol($module, "RXPROCID") 
+  or die "not ok 2\n# find\n";
+print "ok 2\n";
+
+$result = OS2::REXX::_call("RxProcId", $address) or die "not ok 3\n# REXX";
+print "ok 3\n";
+
+($pid, $ppid, $ssid) = split(/\s+/, $result);
+$pid == $$ ? print "ok 4\n" : print "not ok 4\n# pid\n";
+$ssid == 1 ? print "ok 5\n" : print "not ok 5\n# pid\n";
+print "# pid=$pid, ppid=$ppid, ssid=$ssid\n";
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_objcall.t perl5_003_01.try/os2/OS2/REXX/t/rx_objcall.t
--- perl5_003_01/os2/OS2/REXX/t/rx_objcall.t	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_objcall.t	Sun Aug 04 03:07:42 1996
@@ -0,0 +1,33 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+
+#
+# DLL
+#
+$ydba = load OS2::REXX "ydbautil" or die "1..0\n# load\n";
+print "1..5\n", "ok 1\n";
+
+#
+# function
+#
+@pid = $ydba->RxProcId();
+@pid == 1 ? print "ok 2\n" : print "not ok 2\n";
+@res = split " ", $pid[0];
+print "ok 3\n" if $res[0] == $$;
+@pid = $ydba->RxProcId();
+@res = split " ", $pid[0];
+print "ok 4\n" if $res[0] == $$;
+print "# @pid\n";
+
+eval { $ydba->nixda(); };
+print "ok 5\n" if $@ =~ /^Can't find entry 'nixda\'/;
+
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_sql.test perl5_003_01.try/os2/OS2/REXX/t/rx_sql.test
--- perl5_003_01/os2/OS2/REXX/t/rx_sql.test	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_sql.test	Sun Aug 04 02:58:02 1996
@@ -0,0 +1,97 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib';
+    require Config; import Config;
+    if ($Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+
+sub stmt
+{
+	my ($s) = @_;
+	$s =~ s/\s*\n\s*/ /g;
+	$s =~ s/^\s+//;
+	$s =~ s/\s+$//;
+	return $s;
+}
+
+sub sqlcode
+{
+	OS2::REXX::_fetch("SQLCA.SQLCODE");
+}
+
+sub sqlstate
+{
+	OS2::REXX::_fetch("SQLCA.SQLSTATE");
+}
+
+sub sql
+{
+	my ($stmt) = stmt(@_);
+	return 0 if OS2::REXX::_call("sqlexec", $sqlexec, "", $stmt);
+	return sqlcode() >= 0;
+}
+
+sub dbs
+{
+	my ($stmt) = stmt(@_);
+	return 0 if OS2::REXX::_call("sqldbs", $sqldbs, "", $stmt);
+	return sqlcode() >= 0;
+}
+
+sub error
+{
+	my ($where) = @_;
+	print "ERROR in $where: sqlcode=", sqlcode(), " sqlstate=", sqlstate(), "\n";
+	dbs("GET MESSAGE INTO :MSG LINEWIDTH 75");
+	my $msg = OS2::REXX::_fetch("MSG");
+	print "\n", $msg;
+	exit 1;
+}
+
+REXX_call {
+
+  $sqlar   = DynaLoader::dl_load_file("h:/sqllib/dll/sqlar.dll") or die "load";
+  $sqldbs  = DynaLoader::dl_find_symbol($sqlar, "SQLDBS")  or die "find sqldbs"; 
+  $sqlexec = DynaLoader::dl_find_symbol($sqlar, "SQLEXEC") or die "find sqlexec";
+
+  sql(<<) or error("connect");
+     CONNECT TO sample IN SHARE MODE
+
+  OS2::REXX::_set("STMT" => stmt(<<));
+     SELECT name FROM sysibm.systables
+
+  sql(<<) or error("prepare");
+     PREPARE s1 FROM :stmt
+
+  sql(<<) or error("declare");
+     DECLARE c1 CURSOR FOR s1
+
+  sql(<<) or error("open");
+     OPEN c1
+
+  while (1) {
+     sql(<<) or error("fetch");
+          FETCH c1 INTO :name
+
+     last if sqlcode() == 100;
+
+     print "Table name is ", OS2::REXX::_fetch("NAME"), "\n";
+  }
+	
+  sql(<<) or error("close");
+     CLOSE c1
+
+  sql(<<) or error("rollback");
+     ROLLBACK
+
+  sql(<<) or error("disconnect");
+     CONNECT RESET
+
+};
+
+exit 0;
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_tiesql.test perl5_003_01.try/os2/OS2/REXX/t/rx_tiesql.test
--- perl5_003_01/os2/OS2/REXX/t/rx_tiesql.test	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_tiesql.test	Sun Aug 04 02:58:06 1996
@@ -0,0 +1,86 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib';
+    require Config; import Config;
+    if ($Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+#extproc perl5 -Rx
+#! perl
+
+use REXX;
+
+$db2 = load REXX "sqlar" or die "load";
+tie $sqlcode, REXX, "SQLCA.SQLCODE";
+tie $sqlstate, REXX, "SQLCA.SQLSTATE";
+tie %rexx, REXX, "";
+
+sub stmt
+{
+	my ($s) = @_;
+	$s =~ s/\s*\n\s*/ /g;
+	$s =~ s/^\s+//;
+	$s =~ s/\s+$//;
+	return $s;
+}
+
+sub sql
+{
+	my ($stmt) = stmt(@_);
+	return 0 if $db2->SqlExec($stmt);
+	return $sqlcode >= 0;
+}
+
+sub dbs
+{
+	my ($stmt) = stmt(@_);
+	return 0 if $db2->SqlDBS($stmt);
+	return $sqlcode >= 0;
+}
+
+sub error
+{
+	my ($where) = @_;
+	print "ERROR in $where: sqlcode=$sqlcode, sqlstate=$sqlstate\n";
+	dbs("GET MESSAGE INTO :msg LINEWIDTH 75");
+	print "\n", $rexx{'MSG'};
+	exit 1;
+}
+
+sql(<<) or error("connect");
+     CONNECT TO sample IN SHARE MODE
+
+$rexx{'STMT'} = stmt(<<);
+     SELECT name FROM sysibm.systables
+
+sql(<<) or error("prepare");
+     PREPARE s1 FROM :stmt
+
+sql(<<) or error("declare");
+     DECLARE c1 CURSOR FOR s1
+
+sql(<<) or error("open");
+     OPEN c1
+
+while (1) {
+     sql(<<) or error("fetch");
+          FETCH c1 INTO :name
+
+     last if $sqlcode == 100;
+
+     print "Table name is $rexx{'NAME'}\n";
+}
+	
+sql(<<) or error("close");
+     CLOSE c1
+
+sql(<<) or error("rollback");
+     ROLLBACK
+
+sql(<<) or error("disconnect");
+     CONNECT RESET
+
+exit 0;
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_tievar.t perl5_003_01.try/os2/OS2/REXX/t/rx_tievar.t
--- perl5_003_01/os2/OS2/REXX/t/rx_tievar.t	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_tievar.t	Sun Aug 04 05:18:18 1996
@@ -0,0 +1,88 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+
+#
+# DLL
+#
+load OS2::REXX "ydbautil" or die "1..0\n# load\n";
+
+print "1..19\n";
+
+REXX_call {
+  print "ok 1\n";
+
+  #
+  # scalar
+  #
+  tie $s, OS2::REXX, "TEST";
+  print "ok 2\n";
+  $s = 1;
+  print "ok 3\n" if $s eq 1;
+  print "not ok 3\n# `$s'\n" unless $s eq 1;
+  untie $s;
+
+  #
+  # hash
+  #
+
+  tie %all, OS2::REXX, "";	# all REXX vars
+  print "ok 4\n";
+
+  sub show {
+	# show all REXX vars
+	print "--@_--\n";
+	foreach (keys %all) {
+		$v = $all{$_};
+		print "$_ => $v\n";
+	}
+  }
+
+  sub check {
+	# check all REXX vars
+	my ($test, @arr) = @_;
+	my @rx;
+	foreach $key (sort keys %all) { push @rx, $key, $all{$key} }
+	if ("@rx" eq "@arr") {print "ok $test\n"}
+	else { print "not ok $test\n# expect `@arr', got `@rx'\n" }
+  }
+
+
+  tie %h, OS2::REXX, "TEST.";
+  print "ok 5\n";
+  check(6);
+
+  $h{"one"} = 1;
+  check(7, "TEST.one", 1);
+
+  $h{"two"} = 2;
+  check(8, "TEST.one", 1, "TEST.two", 2);
+
+  $h{"one"} = "";
+  check(9, "TEST.one", "", "TEST.two", 2);
+  print "ok 10\n" if exists $h{"one"};
+  print "ok 11\n" if exists $h{"two"};
+
+  delete $h{"one"};
+  check(12, "TEST.two", 2);
+  print "ok 13\n" if not exists $h{"one"};
+  print "ok 14\n" if exists $h{"two"};
+
+  OS2::REXX::dropall("TEST.");
+  print "ok 15\n";
+  check(16);
+  print "ok 17\n" if not exists $h{"one"};
+  print "ok 18\n" if not exists $h{"two"};
+
+  untie %h;
+  print "ok 19";
+
+};
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_tieydb.t perl5_003_01.try/os2/OS2/REXX/t/rx_tieydb.t
--- perl5_003_01/os2/OS2/REXX/t/rx_tieydb.t	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_tieydb.t	Sun Aug 04 03:07:56 1996
@@ -0,0 +1,31 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+$rx = load OS2::REXX "ydbautil" or die "1..0\n# load\n";    # from RXU17.ZIP
+print "1..7\n", "ok 1\n";
+
+$rx->prefix("Rx");                         # implicit function prefix
+print "ok 2\n";
+
+REXX_call {
+  tie @pib, OS2::REXX, "IB.P";       # bind array to REXX stem variable
+  print "ok 3\n";
+  tie %tib, OS2::REXX, "IB.T.";      # bind associative array to REXX stem var
+  print "ok 4\n";
+
+  $rx->GetInfoBlocks("IB.");    # call REXX function
+  print "ok 5\n";
+  defined $pib[6] ? print "ok 6\n" : print "not ok 6\n# pib\n";
+  defined $tib{7} && $tib{7} =~ /^\d+$/ ? print "ok 7\n"
+    : print "not ok 7\n# tib\n";
+  print "# Process status is ", unpack("I", $pib[6]),
+        ", thread ordinal is $tib{7}\n";
+};
\ No newline at end of file
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_varset.t perl5_003_01.try/os2/OS2/REXX/t/rx_varset.t
--- perl5_003_01/os2/OS2/REXX/t/rx_varset.t	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_varset.t	Sun Aug 04 04:41:06 1996
@@ -0,0 +1,39 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+
+print "1..9\n";
+
+REXX_call {
+  OS2::REXX::_set("X" => sqrt(2)) and print "ok 1\n";
+  $x = OS2::REXX::_fetch("X") and print "ok 2\n";
+  if (abs($x - sqrt(2)) < 5e-15) {
+    print "ok 3\n";
+  } else {  print "not ok 3\n# sqrt(2) = @{[sqrt(2)]} != `$x'\n" }
+  OS2::REXX::_set("Y" => sqrt(3)) and print "ok 4\n";
+  $i = 0;
+  $n = 4;
+  while (($name, $value) = OS2::REXX::_next("")) {
+	$i++; $n++;
+	if ($i <= 2 and $name eq "Y" ) {
+	  if ($value eq sqrt(3)) {
+	    print "ok $n\n";
+	  } else {
+	    print "not ok $n\n# `$name' => `$value'\n" ;
+	  }
+	} elsif ($i <= 2 and $name eq "X") {
+	  print "ok $n\n" if $value eq sqrt(2);
+	} else { print "not ok 7\n# name `$name', value `$value'\n" }
+  }
+  print "ok 7\n" if $i == 2;
+  OS2::REXX::_drop("X") and print "ok 8\n";
+  $x = OS2::REXX::_fetch("X") or print "ok 9\n";
+};
diff -ru perl5_003_01/os2/OS2/REXX/t/rx_vrexx.t perl5_003_01.try/os2/OS2/REXX/t/rx_vrexx.t
--- perl5_003_01/os2/OS2/REXX/t/rx_vrexx.t	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/OS2/REXX/t/rx_vrexx.t	Sun Aug 04 03:08:08 1996
@@ -0,0 +1,59 @@
+BEGIN {
+    chdir 't' if -d 't/lib';
+    @INC = '../lib' if -d 'lib';
+    require Config; import Config;
+    if (-d 'lib' and $Config{'extensions'} !~ /\bOS2::REXX\b/) {
+	print "1..0\n";
+	exit 0;
+    }
+}
+
+use OS2::REXX;
+
+$name = "VREXX";
+$path = $ENV{LIBPATH} || $ENV{PATH} or die;
+foreach $dir (split(';', $path)) {
+  next unless -f "$dir/$name.DLL";
+  $found = "$dir/$name.DLL";
+  print "# found at `$found'\n";
+  last;
+}
+$found or die "1..0\n#Cannot find $name.DLL\n";
+
+print "1..10\n";
+
+REXX_call {
+  $vrexx = DynaLoader::dl_load_file($found) or die "not ok 1\n# load\n";
+  print "ok 1\n";
+  $vinit   = DynaLoader::dl_find_symbol($vrexx, "VINIT")   or die "find vinit";
+  print "ok 2\n";
+  $vexit   = DynaLoader::dl_find_symbol($vrexx, "VEXIT")   or die "find vexit";
+  print "ok 3\n";
+  $vmsgbox = DynaLoader::dl_find_symbol($vrexx, "VMSGBOX") or die "find vmsgbox";
+  print "ok 4\n";
+  $vversion= DynaLoader::dl_find_symbol($vrexx, "VGETVERSION") or die "find vgetversion";
+  print "ok 5\n";
+  
+  $result = OS2::REXX::_call("VInit", $vinit) or die "VInit";
+  print "ok 6\n";
+  print "# VInit: $result\n";
+  
+  OS2::REXX::_set("MBOX.0" => 4,
+  	        "MBOX.1" => "Perl VREXX Access Test",
+  	        "MBOX.2" => "",
+  	        "MBOX.3" => "(C) Andreas Kaiser",
+  	        "MBOX.4" => "December 1994")
+  	or die "set var";
+  print "ok 7\n";
+  
+  $result = OS2::REXX::_call("VGetVersion", $vversion) or die "VMsgBox";
+  print "ok 8\n";
+  print "# VGetVersion: $result\n";
+  
+  $result = OS2::REXX::_call("VMsgBox", $vmsgbox, "", "Perl", "MBOX", 1) or die "VMsgBox";
+  print "ok 9\n";
+  print "# VMsgBox: $result\n";
+  
+  OS2::REXX::_call("VExit", $vexit);
+  print "ok 10\n";
+};
diff -ru perl5_003_01/os2/os2.c perl5_003_01.try/os2/os2.c
--- perl5_003_01/os2/os2.c	Tue Jul 30 14:11:52 1996
+++ perl5_003_01.try/os2/os2.c	Sat Aug 03 20:47:28 1996
@@ -1,10 +1,8 @@
 #define INCL_DOS
 #define INCL_NOPM
 #define INCL_DOSFILEMGR
-#ifndef NO_SYS_ALLOC 
-#  define INCL_DOSMEMMGR
-#  define INCL_DOSERRORS
-#endif /* ! defined NO_SYS_ALLOC */
+#define INCL_DOSMEMMGR
+#define INCL_DOSERRORS
 #include <os2.h>
 
 /*
@@ -137,10 +135,15 @@
 	int r, status;
 	Signal_t (*ihand)();     /* place to save signal during system() */
 	Signal_t (*qhand)();     /* place to save signal during system() */
+#ifndef __EMX__
+	RESULTCODES res;
+	int rpid;
+#endif
 
-	if (pid < 0 || flag != 0) 
+	if (pid < 0 || flag != 0)
 		return pid;
 
+#ifdef __EMX__
 	ihand = signal(SIGINT, SIG_IGN);
 	qhand = signal(SIGQUIT, SIG_IGN);
 	do {
@@ -153,6 +156,15 @@
 	if (r < 0)
 		return -1;
 	return status & 0xFFFF;
+#else
+	ihand = signal(SIGINT, SIG_IGN);
+	r = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, &res, &rpid, pid);
+	signal(SIGINT, ihand);
+	statusvalue = res.codeResult << 8 | res.codeTerminate;
+	if (r)
+		return -1;
+	return statusvalue;
+#endif
 }
 
 int
@@ -170,7 +182,7 @@
 	New(401,Argv, sp - mark + 1, char*);
 	a = Argv;
 
-	if (mark < sp && SvIOKp(*(mark+1))) {
+	if (mark < sp && SvNIOKp(*(mark+1)) && !SvPOKp(*(mark+1))) {
 		++mark;
 		flag = SvIVx(*mark);
 	}
@@ -187,8 +199,12 @@
 	if (flag == P_WAIT)
 		flag = P_NOWAIT;
 
-	if (*Argv[0] != '/' && *Argv[0] != '\\') /* will swawnvp use PATH? */
+	if (*Argv[0] != '/' && *Argv[0] != '\\'
+	    && !(*Argv[0] && *Argv[1] == ':' 
+		 && (*Argv[2] == '/' || *Argv[2] != '\\'))
+	    ) /* will swawnvp use PATH? */
 	    TAINT_ENV();	/* testing IFS here is overkill, probably */
+	/* We should check PERL_SH* and PERLLIB_* as well? */
 	if (really && *(tmps = SvPV(really, na)))
 	    rc = result(trueflag, spawnvp(flag,tmps,Argv));
 	else
@@ -203,9 +219,14 @@
     return rc;
 }
 
+#define EXECF_SPAWN 0
+#define EXECF_EXEC 1
+#define EXECF_TRUEEXEC 2
+
 int
-do_spawn(cmd)
+do_spawn2(cmd, execf)
 char *cmd;
+int execf;
 {
     register char **a;
     register char *s;
@@ -254,10 +275,17 @@
 		break;
 	    }
 	  doshell:
+	    if (execf == EXECF_TRUEEXEC)
+                return execl(shell,shell,copt,cmd,(char*)0);
+	    else if (execf == EXECF_EXEC)
+                return spawnl(P_OVERLAY,shell,shell,copt,cmd,(char*)0);
+	    /* In the ak code internal P_NOWAIT is P_WAIT ??? */
 	    rc = result(P_WAIT,
-			  spawnl(P_NOWAIT,shell,shell,copt,cmd,(char*)0));
+			spawnl(P_NOWAIT,shell,shell,copt,cmd,(char*)0));
 	    if (rc < 0 && dowarn)
-		warn("Can't spawn \"%s\": %s", shell, Strerror(errno));
+		warn("Can't %s \"%s\": %s", 
+		     (execf == EXECF_SPAWN ? "spawn" : "exec"),
+		     shell, Strerror(errno));
 	    if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
 	    return rc;
 	}
@@ -276,9 +304,16 @@
     }
     *a = Nullch;
     if (Argv[0]) {
-	rc = result(P_WAIT, spawnvp(P_NOWAIT,Argv[0],Argv));
+	if (execf == EXECF_TRUEEXEC)
+	    rc = execvp(Argv[0],Argv);
+	else if (execf == EXECF_EXEC)
+	    rc = spawnvp(P_OVERLAY,Argv[0],Argv);
+        else
+	    rc = result(P_WAIT, spawnvp(P_NOWAIT,Argv[0],Argv));
 	if (rc < 0 && dowarn)
-	    warn("Can't spawn \"%s\": %s", Argv[0], Strerror(errno));
+	    warn("Can't %s \"%s\": %s", 
+		 (execf == EXECF_SPAWN ? "spawn" : "exec"),
+		 Argv[0], Strerror(errno));
 	if (rc < 0) rc = 255 << 8; /* Emulate the fork(). */
     } else
     	rc = -1;
@@ -286,12 +321,36 @@
     return rc;
 }
 
+int
+do_spawn(cmd)
+char *cmd;
+{
+    return do_spawn2(cmd, EXECF_SPAWN);
+}
+
+bool
+do_exec(cmd)
+char *cmd;
+{
+    return do_spawn2(cmd, EXECF_EXEC);
+}
+
+bool
+os2exec(cmd)
+char *cmd;
+{
+    return do_spawn2(cmd, EXECF_TRUEEXEC);
+}
+
 #ifndef HAS_FORK
 FILE *
 my_popen(cmd,mode)
 char	*cmd;
 char	*mode;
 {
+#ifdef TRYSHELL
+    return popen(cmd, mode);
+#else
     char *shell = getenv("EMXSHELL");
     FILE *res;
     
@@ -299,6 +358,7 @@
     res = popen(cmd, mode);
     my_setenv("EMXSHELL", shell);
     return res;
+#endif 
 }
 #endif
 
@@ -323,18 +383,54 @@
 void *	ttyname(x)	{ return 0; }
 #endif
 
-void *	gethostent()	{ return 0; }
-void *	getnetent()	{ return 0; }
-void *	getprotoent()	{ return 0; }
-void *	getservent()	{ return 0; }
-void	sethostent(x)	{}
-void	setnetent(x)	{}
-void	setprotoent(x)	{}
-void	setservent(x)	{}
-void	endhostent(x)	{}
-void	endnetent(x)	{}
-void	endprotoent(x)	{}
-void	endservent(x)	{}
+/*****************************************************************************/
+/* my socket forwarders - EMX lib only provides static forwarders */
+
+static HMODULE htcp = 0;
+
+static void *
+tcp0(char *name)
+{
+    static BYTE buf[20];
+    PFN fcn;
+    if (!htcp)
+	DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
+    if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
+	return (void *) ((void * (*)(void)) fcn) ();
+    return 0;
+}
+
+static void
+tcp1(char *name, int arg)
+{
+    static BYTE buf[20];
+    PFN fcn;
+    if (!htcp)
+	DosLoadModule(buf, sizeof buf, "tcp32dll", &htcp);
+    if (htcp && DosQueryProcAddr(htcp, 0, name, &fcn) == 0)
+	((void (*)(int)) fcn) (arg);
+}
+
+void *	gethostent()	{ return tcp0("GETHOSTENT");  }
+void *	getnetent()	{ return tcp0("GETNETENT");   }
+void *	getprotoent()	{ return tcp0("GETPROTOENT"); }
+void *	getservent()	{ return tcp0("GETSERVENT");  }
+void	sethostent(x)	{ tcp1("SETHOSTENT",  x); }
+void	setnetent(x)	{ tcp1("SETNETENT",   x); }
+void	setprotoent(x)	{ tcp1("SETPROTOENT", x); }
+void	setservent(x)	{ tcp1("SETSERVENT",  x); }
+void	endhostent()	{ tcp0("ENDHOSTENT");  }
+void	endnetent()	{ tcp0("ENDNETENT");   }
+void	endprotoent()	{ tcp0("ENDPROTOENT"); }
+void	endservent()	{ tcp0("ENDSERVENT");  }
+
+/*****************************************************************************/
+/* not implemented in C Set++ */
+
+#ifndef __EMX__
+int	setuid(x)	{ errno = EINVAL; return -1; }
+int	setgid(x)	{ errno = EINVAL; return -1; }
+#endif
 
 /*****************************************************************************/
 /* stat() hack for char/block device */
@@ -362,55 +458,22 @@
 
 #endif
 
-#ifndef NO_SYS_ALLOC
-
-static char *oldchunk;
-static long oldsize;
-
-#define _32_K (1<<15)
-#define _64_K (1<<16)
+#ifdef USE_PERL_SBRK
 
-/* The real problem is that DosAllocMem will grant memory on 64K-chunks
- * boundaries only. Note that addressable space for application memory
- * is around 240M, thus we will run out of addressable space if we
- * allocate around 14M worth of 4K segments.
- * Thus we allocate memory in 64K chunks, and abandon the rest of the old
- * chunk if the new is bigger than that rest. Also, we just allocate
- * whatever is requested if the size is bigger that 32K. With this strategy
- * we cannot lose more than 1/2 of addressable space. */
+/* SBRK() emulation, mostly moved to malloc.c. */
 
 void *
-sbrk(int size)
-{
-    char *got;
-    APIRET rc;
-    int small, reqsize;
-
-    if (!size) return 0;
-    else if (size <= oldsize) {
-	got = oldchunk;
-	oldchunk += size;
-	oldsize -= size;
-	return (void *)got;
-    } else if (size >= _32_K) {
-	small = 0;
-    } else {
-	reqsize = size;
-	size = _64_K;
-	small = 1;
-    }
-    rc = DosAllocMem((void **)&got, size, PAG_COMMIT | PAG_WRITE);
+sys_alloc(int size) {
+    void *got;
+    APIRET rc = DosAllocMem(&got, size, PAG_COMMIT | PAG_WRITE);
+
     if (rc == ERROR_NOT_ENOUGH_MEMORY) {
 	return (void *) -1;
     } else if ( rc ) die("Got an error from DosAllocMem: %li", (long)rc);
-    if (small) {
-	/* Chunk is small, register the rest for future allocs. */
-	oldchunk = got + reqsize;
-	oldsize = size - reqsize;
-    }
-    return (void *)got;
+    return got;
 }
-#endif /* ! defined NO_SYS_ALLOC */
+
+#endif /* USE_PERL_SBRK */
 
 /* tmp path */
 
@@ -463,8 +526,8 @@
      SV   *sv;
 {
     static char fname[9];
-    int pos = 7;
-    int len;
+    int pos = 6, len, avlen;
+    unsigned int sum = 0;
     AV  *av;
     SV  *svp;
     char *s;
@@ -473,13 +536,30 @@
     sv = SvRV(sv);
     if (SvTYPE(sv) != SVt_PVAV) 
       croak("Not array reference given to mod2fname");
-    if (av_len((AV*)sv) < 0) 
+
+    avlen = av_len((AV*)sv);
+    if (avlen < 0) 
       croak("Empty array reference given to mod2fname");
-    s = SvPV(*av_fetch((AV*)sv, av_len((AV*)sv), FALSE), na);
+
+    s = SvPV(*av_fetch((AV*)sv, avlen, FALSE), na);
     strncpy(fname, s, 8);
-    if ((len=strlen(s)) < 7) pos = len;
-    fname[pos] = '_';
-    fname[pos + 1] = '\0';
+    len = strlen(s);
+    if (len < 6) pos = len;
+    while (*s) {
+	sum = 33 * sum + *(s++);	/* Checksumming first chars to
+					 * get the capitalization into c.s. */
+    }
+    avlen --;
+    while (avlen >= 0) {
+	s = SvPV(*av_fetch((AV*)sv, avlen, FALSE), na);
+	while (*s) {
+	    sum = 33 * sum + *(s++);	/* 7 is primitive mod 13. */
+	}
+	avlen --;
+    }
+    fname[pos] = 'A' + (sum % 26);
+    fname[pos + 1] = 'A' + (sum / 26 % 26);
+    fname[pos + 2] = '\0';
     return (char *)fname;
 }
 
@@ -525,9 +605,9 @@
 	
         newXS("File::Copy::syscopy", XS_File__Copy_syscopy, file);
         newXS("DynaLoader::mod2fname", XS_DynaLoader_mod2fname, file);
-#ifdef PERL_IS_AOUT
 	gv = gv_fetchpv("OS2::is_aout", TRUE, SVt_PV);
 	GvMULTI_on(gv);
+#ifdef PERL_IS_AOUT
 	sv_setiv(GvSV(gv), 1);
 #endif 
     }
@@ -542,10 +622,62 @@
     OS2_Perl_data.xs_init = &Xs_OS2_init;
     if ( (shell = getenv("PERL_SH_DRIVE")) ) {
 	sh_path[0] = shell[0];
+    } else if ( (shell = getenv("PERL_SH_DIR")) ) {
+	int l = strlen(shell);
+	if (shell[l-1] == '/' || shell[l-1] == '\\') {
+	    l--;
+	}
+	if (l > STATIC_FILE_LENGTH - 7) {
+	    die("PERL_SH_DIR too long");
+	}
+	strncpy(sh_path, shell, l);
+	strcpy(sh_path + l, "/sh.exe");
     }
 }
 
-char sh_path[33] = BIN_SH;
+char sh_path[STATIC_FILE_LENGTH+1] = BIN_SH;
+
+char *
+perllib_mangle(char *s, unsigned int l)
+{
+    static char *newp, *oldp;
+    static int newl, oldl, notfound;
+    static char ret[STATIC_FILE_LENGTH+1];
+    
+    if (!newp && !notfound) {
+	newp = getenv("PERLLIB_PREFIX");
+	if (newp) {
+	    oldp = newp;
+	    while (*newp && !isSPACE(*newp)) {
+		newp++; oldl++;		/* Skip digits. */
+	    }
+	    while (*newp && (isSPACE(*newp) || *newp == ';')) {
+		newp++;			/* Skip whitespace. */
+	    }
+	    newl = strlen(newp);
+	    if (newl == 0 || oldl == 0) {
+		die("Malformed PERLLIB_PREFIX");
+	    }
+	} else {
+	    notfound = 1;
+	}
+    }
+    if (!newp) {
+	return s;
+    }
+    if (l == 0) {
+	l = strlen(s);
+    }
+    if (l <= oldl || strnicmp(oldp, s, oldl) != 0) {
+	return s;
+    }
+    if (l + newl - oldl > STATIC_FILE_LENGTH || newl > STATIC_FILE_LENGTH) {
+	die("Malformed PERLLIB_PREFIX");
+    }
+    strncpy(ret, newp, newl);
+    strncpy(ret + newl, s + oldl, l - oldl);
+    return ret;
+}
 
 extern void dlopen();
 void *fakedl = &dlopen;		/* Pull in dynaloading part. */
diff -ru perl5_003_01/os2/os2ish.h perl5_003_01.try/os2/os2ish.h
--- perl5_003_01/os2/os2ish.h	Tue Jul 30 14:11:52 1996
+++ perl5_003_01.try/os2/os2ish.h	Thu Aug 01 19:17:46 1996
@@ -45,7 +45,7 @@
 #endif
 #define ABORT() kill(getpid(),SIGABRT);
 
-#define BIT_BUCKET "/dev/null"  /* Will this work? */
+#define BIT_BUCKET "/dev/nul"  /* Will this work? */
 
 void Perl_OS2_init();
 
@@ -62,8 +62,18 @@
 #define dXSUB_SYS int fake = OS2_XS_init()
 
 #ifdef PERL_IS_AOUT
-#define NO_SYS_ALLOC
-#endif 
+#  define HAS_FORK
+/* #  define HIDEMYMALLOC */
+/* #  define PERL_SBRK_VIA_MALLOC */ /* gets off-page sbrk... */
+#else /* !PERL_IS_AOUT */
+#  ifndef PERL_FOR_X2P
+#    define USE_PERL_SBRK
+#  endif 
+#  define SYSTEM_ALLOC(a) sys_alloc(a)
+
+void *sys_alloc(int size);
+
+#endif /* !PERL_IS_AOUT */
 
 #define TMPPATH tmppath
 #define TMPPATH1 "plXXXXXX"
@@ -160,8 +170,11 @@
 	   set_Perl_HAB_f;						\
 	}
 
-extern char sh_path[33];
+#define STATIC_FILE_LENGTH 127
+extern char sh_path[STATIC_FILE_LENGTH+1];
 #define SH_PATH sh_path
+#define PERLLIB_MANGLE(s, n) perllib_mangle((s), (n))
+char *perllib_mangle(char *, unsigned int);
 
 char *os2error(int rc);
 
diff -ru perl5_003_01/os2/perl2cmd.pl perl5_003_01.try/os2/perl2cmd.pl
--- perl5_003_01/os2/perl2cmd.pl	Sun Mar 24 22:05:00 1996
+++ perl5_003_01.try/os2/perl2cmd.pl	Fri Aug 02 01:27:12 1996
@@ -16,7 +16,8 @@
 $idir = $Config{installbin};
 $indir =~ s|\\|/|g ;
 
-foreach $file (<$idir/*.>) {
+foreach $file (<$idir/*>) {
+  next if $file =~ /\.exe/i;
   $base = $file;
   $base =~ s/\.$//;		# just in case...
   $base =~ s|.*/||;
diff -ru perl5_003_01/os2/README perl5_003_01.try/os2/README
--- perl5_003_01/os2/README	Sun Aug 04 13:49:08 1996
+++ perl5_003_01.try/os2/README	Sun Aug 04 13:19:00 1996
@@ -0,0 +1,812 @@
+Contents:
+	Notes on the patch
+	IMPORTANT NOTE
+	Target
+	Binary Install
+	Reading the docs
+	Notes on build on OS/2
+	Compile summary
+	Tests which fail
+	Calls to external programs
+	OS/2 extensions
+	Report from the battlefield on 5.002_01
+
+Notes on the patch:
+~~~~~~~~~~~~~~~~~~~
+patches should be applied as
+	patch -p0 <.....
+All the diff.* files and POSIX.mkfifo should be applied.
+
+Additional files are available on
+	ftp://ftp.math.ohio-state.edu/pub/users/ilya/os2
+including patched pdksh and gnumake, needed for build.
+
+		   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+IMPORTANT NOTE     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+                   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+Note with the release 5.003_01 the dynamically loadable libraries
+should be rebuilt. In particular, DLLs are now created with the names
+which contain a checksum, thus allowing workaround for OS/2 scheme of
+caching DLLs.
+
+In particular, it is VERY IMPORTANT to have a correct perl.dll on
+LIBPATH during build, otherwise DLLs with wrong names will be
+created. Or have a perl.dll with the same naming convention for DLLs
+(hopefully, it should not change any time soon), or remove it from
+LIBPATH, add . to LIBPATH, wait until the build of DynaLoader fails,
+and then move the built DLL into LIBPATH.
+
+I also used this possibility to change perl linking type to -Zmt. It
+means that Perl now uses multithreaded CRTDLL, so your extensions can
+be multithreaded (note that the perl core is not thread-safe so far,
+so make sure you access Perl from one thread only). In particular, it
+is no longer needed to statically link X11_s.lib if you compile
+Perl/Tk/XFree.
+
+This newer port includes 
+	. numeric first argument to system(), see OS2::Process docs;
+	. modules OS2::Process, OS2::REXX, OS2::PrfDB, OS2::ExtAttrib.
+	. {get,set,end}*ent may work now (not checked)
+(most of this merged from ak's port).
+
+Note that static build of OS2::ExtAttrib fails some tests!
+
+Target:
+~~~~~~~
+
+This is not supposed to make a perfect Perl on OS/2. This patch is
+concerned only with perfect _build_ of Perl on OS/2. Some good
+features from Andreas Kaiser port missed this port. However, most of
+the features are available (possibly in different form). 
+
+!!! Note that [gs]etpriority functions in this port are compatible
+!!! with *nix, not with ak's port!!! 
+
+The priorities are absolute, go from 32 to -95, lower is quickier. 0
+is default,
+
+Binary Install:
+~~~~~~~~~~~~~~
+This version of perl allows binary installation on another site. There
+are two possibilities:
+	a) sh.exe is in the directory with the same name as on machine
+where perl was compiled (f:/bin here), and perl library is installed
+into the same directory as the built target (f:/perllib);
+	b) One of the above conditions is not true. Perl may be
+informed about location of sh.exe via PERL_SH_DRIVE or PERL_SH_DIR
+(see below). To relocate the perl library, one can
+	b1) either use the usual PERLLIB environment variable - but
+you should deduce yourself which components should be put there, say,
+by doing 
+		perl -de 0
+		x \@INC
+		q
+in the directory of the perl library. Another problem with this is
+that a module is missing, then perl will try to scan the builtin
+directories nevertheless. If perl was intended to be installed on
+f:/perllib, but your f: is a CDROM, then you may have some trouble.
+	b2) Best: binary edit perl.dll and perl_.exe (using perl
+itself as a binary editor) to fix the paths. Note that the new paths
+should be better no longer than the old.
+	b3) More convinient: set PERLLIB_PREFIX environment
+variable. It should contain two components, separated by whitespace
+and/or semicolon `;'. The first component is translated to the second
+one if it is 
+	     a prefix of 
+			 a component of
+				        Perl library lookup path.
+Say, if you install perllibrary into c:/lib/perl/ instead of
+f:/perllib/, set it to
+	set PERLLIB_PREFIX=f:/perllib/;c:/lib/perl/
+
+Reading the docs:
+~~~~~~~~~~~~~~~~
+If your `man' is correctly installed, you should just add
+x:/perllib/man directory to the end of MANPATH like this:
+	set MANPATH=c:/man;f:/perllib/man
+After this you can access the docs like this:
+	man perlfunc
+	man 3 less
+	man ExtUtils.MakeMaker
+Note that dot is used as package separator for package documentation,
+and as usual, sometimes you need to give the section - 3 above - to
+avoid shadowing by the less(1) manpage.
+
+Alternatively, you can build HTML docs by running
+	pod2html
+in x:/perllib/lib/pod directory.
+
+Alternatively, you can build IPF source by running
+	pod2ipf > perl.ipf
+in x:/perllib/lib/pod directory, and build (excellent! - best of perl
+docs available!) .INF documentation by running
+	ipfc /inf perl.ipf
+Move it on your BOOKSHELF path, and now you may inspect docs by
+	view perl
+or
+	view perl keyword_to_see
+
+Alternatively you may pick up precompiled HTML and .INF docs from the
+net, as usual, .INF is available on CPAN/.../os2/ilyaz.
+
+There are also _very_ good docs in TexInfo and Adobe PDF format.
+
+Notes on build on OS/2:
+~~~~~~~~~~~~~~~~~~~~~~~
+a) Make sure your sort is not the broken OS/2 one, and that you have /tmp
+on the build partition. Make sure that your pdksh.exe, make.exe and
+db.lib are OK (look elsewhere in this file).
+
+b) when extracting perl5.*.tar.gz you need to extract perl5.*/Configure
+separately, since by default perl5.001m/configure may overwrite it;
+	like this:
+		tar vzxf perl5.004.tar.gz --case-sensitive perl5.004/Configure
+or
+		tar --case-sensitive -vzxf perl5.004.tar.gz perl5.004/Configure
+
+c) Necessary manual intervention when compiling on OS/2:
+
+	Need to put perl.dll on LIBPATH after it is created.
+
+d) Compile summary:
+   ~~~~~~~~~~~~~~~
+!!! At the end of this README is independent description of the build
+!!! process by Rocco Caputo.
+
+# Look for hints/os2.sh and correct what is different on your system
+# I have rather spartan configuration.
+
+	# Prefix means where to install:
+sh Configure -des -D prefix=f:/perl5.005
+	# Note that you need to have /tmp/ ready.
+	#
+	# Ignore the message about missing `ln', and about `c' option
+	# to tr.
+make
+	# Will probably die after build of miniperl (unless you have DLL
+	# from previous compile). Need to move DLL where it belongs
+	#
+	# Somehow with 5.002b3 I needed to type another make after pod2man
+make
+	# some warnings in POSIX.c
+make test
+	# some tests fail, 9 or 10 on my system (see the list at end).
+	#
+	# before this you should create subdirs bin and lib in the 
+	# prefix directory (f:/perl5.005 above):
+	#
+	# To run finer tests, cd t && perl harness
+make install
+
+e) At the end of July 1996 GNU make was too buggy for compile.
+The maintainer has the patch (for a year now) that make it possible to
+compile perl. The binaries are included in
+	ftp://ftp.math.ohio-state.edu/pub/users/ilya/os2
+patches are available too.
+
+Note that the pdksh5.2.7 or later is required.
+
+!!!!!!!!!!!!!!!!!
+If you see that some '/' became '\' in pdksh, you use an old pdksh!
+Same with segfaults in Make 3.76 (?) - use my patched verions.
+!!!!!!!!!!!!!!!!!
+
+f) As distributed the DB library db.a-db.lib is not suitable for
+linking with -Zmt. A recompiled version must be available from my FTP
+site in os2/db_mt.zip.
+
+!!!!!!!!!!!!!!!!
+If you see: 
+	'errno' - unresolved external
+it means you use a wrong db.lib.
+!!!!!!!!!!!!!!!!
+
+Problems reported: 
+
+a) one of the latest tr is broken, get an old one :-(
+	1.11 works. (On compuserver?)
+b) You need a perlglob.exe and link386.
+c) Get rid of invalid perl.dll on your LIBPATH.
+
+
+Send comments to ilya@math.ohio-state.edu.
+
+======================================================
+Requires 0.9b (well, provision are made to make it build under 0.9a6,
+but they are not tested, please inform me on success).
+(earlier than 0.9b ttyname was not present, it is hard to maintain this
+difference automatically, though I try).
+======================================================
+
+Building with a.out style is supported by the `perl_' target of make.
+Dynamic extensions are not possible with perl_.exe, since boot code
+should return the retvalue on the Perl stack, the address of which is
+not known to the extension. Moreover: The build process for `perl_'
+DOES NOT KNOW about dependencies, so you should make sure that
+anything is up-to-date, say, by doing
+	make perl.dll
+first.
+
+The reason why compiling with a.out style executables leads to problems
+with dynamic extensions is:
+	a) OS/2 does not export symbols from executables;
+	b) Thus if extension needs to import symbols from an application
+		the symbols for the application should reside in a .dll.
+	c) You cannot export data from a .dll compiled with a.out style.
+On the other hand, aout-style compiled extension enjoys all the 
+(dis)advantages of fork().
+
+======================================================
+
+If you need to run PM code from perl, you may use PM mode executable
+perl__.exe. It is subject to restrictions specific to PM programs: it
+will close the VIO window the moment any PM call is performed.
+
+It is needed to run Perl/Tk (currently 7/96 - pre-alpha).
+
+======================================================
+
+The reason why the executables are named perl_.exe and perl__.exe is
+the following: Perl may parse #! lines in perl scripts to find out the
+additional switches to enable. Thus there is a convention `What is a
+perl executable - judging by name', and the above names conform to
+this convention.
+
+======================================================
+Tests which fail 
+~~~~~~~~~~~~~~~~
+with OMF compile (fork works - and all the related
+test - with A.OUT compile):
+
+io/fs.t: 2-5, 7-11, 18  as they should.
+io/pipe: all, since open("|-") is not working (works with perl_.exe).
+lib/"all the dbm".t: 1 test should fail (file permission).
+lib/io_pipe io_sock, as they should: use fork.
+op/fork all fail, as they should (except with perl_.exe)
+op/stat 3 20 35 as they should, 39 (-t on /dev/null) ???? Sometimes 4
+- timing problem ????
+
+Sometimes I have seen segfault in socket ????, only if run with Testing tools.
+
+A lot of `bad free'... in databases, bug in DB confirmed on other
+platforms. - Disappeared here.
+
+Here is my result with OMF:
+
+Test         Status Wstat Total Fail Success  List of failed
+------------------------------------------------------------------------------
+io/fs.t                      22   10  45.45%  2-5, 7-11, 18
+io/pipe.t         1   256     8   ??       %  ??
+lib/anydbm.t                 12    1   8.33%  2
+lib/db-btree.t               86    1   1.16%  20
+lib/db-hash.t                43    1   2.33%  16
+lib/db-recno.t               35    1   2.86%  18
+lib/io_pipe.t     2   512     6   ??       %  ??
+lib/io_sock.t   255 65280     5   ??       %  ??
+lib/sdbm.t                   12    1   8.33%  2
+op/exec.t                     8    1  12.50%  5
+op/fork.t       255 65280     2   ??       %  ??
+op/stat.t                    56    4   7.14%  3, 20, 35, 39
+Failed 12/104 test scripts, 88.46% okay. 41/2224 subtests failed, 98.16% okay.
+
+and with A.OUT:
+
+Test         Status Wstat Total Fail  Failed  List of failed
+------------------------------------------------------------------------------
+io/fs.t                      22   10  45.45%  2-5, 7-11, 18
+lib/anydbm.t                 12    1   8.33%  2
+lib/db-btree.t               86    1   1.16%  20
+lib/db-hash.t                43    1   2.33%  16
+lib/db-recno.t               35    1   2.86%  18
+lib/sdbm.t                   12    1   8.33%  2
+op/exec.t                     8    1  12.50%  5
+op/stat.t                    56    4   7.14%  3, 20, 35, 39
+Failed 8/104 test scripts, 92.31% okay. 20/2224 subtests failed, 99.10% okay.
+
+Note that op/exec.5 fail because I do not have /bin/sh on this drive.
+
+With newer configs I could not reproduce most the crashes. However,
+after fixpak17 REXX variables acquire a trailing '\0' at end when go
+through the variable pool (even if they had one), thus making some
+REXX tests fail.
+
+=======================================================
+
+Calls to external programs:
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+Due to a popular demand the perl external program calling has been
+changed.  _If_ perl needs to call an external program _via shell_, the
+X:/bin/sh.exe will be called. The name of the shell is 
+overridable, as described below.
+
+Thus means that you need to pickup some copy of a sh.exe as well (I use one
+from pdksh). The drive X: above is set up automatically during the
+build, is settable in runtime from $ENV{PERL_SH_DRIVE}. Another way to
+change it is to set $ENV{PERL_SH_DIR} to be the directory in which
+sh.exe resides.
+
+Reasons: a consensus on perl5-porters was that perl should use one 
+non-overridable shell per platform. The obvious choices for OS/2 are cmd.exe
+and sh.exe. Having perl build itself would be impossible with cmd.exe as
+a shell, thus I picked up sh.exe. Thus assures almost 100% compatibility
+with the scripts coming from *nix.
+
+Disadvantages: sh.exe calls external programs via fork/exec, and there is
+_no_ functioning exec on OS/2. exec is emulated by EMX by asyncroneous call
+while the caller waits for child completion (to pretend that pid did
+not change). This means that 1 _extra_ copy of sh.exe is made active via
+fork/exec, which may lead to some resources taken from the system.
+
+The long-term solution proposed on p5-p is to have a directive
+	use OS2::Cmd;
+which will override system(), exec(), ``, and open(,'   |'). With current
+perl you may override only system(), readpipe() - the explicit version
+of ``, and maybe exec(). The code will substitute a one-argument system
+by CORE::system('cmd.exe', '/c', shift).
+
+If you have some working code for OS2::Cmd.pm, please send it to me,
+I will include it into distribution. I have no need for such a module, so
+cannot test it.
+
+===================================================
+
+OS/2 extensions
+~~~~~~~~~~~~~~~
+Since binaries cannot go into perl distribution, no extensions are
+included. They are available in .../os2/ilyaz directory of CPAN, as
+well as in my directory
+	ftp://ftp.math.ohio-state.edu/pub/users/ilya/os2
+
+I include 3 extensions by Andread Kaiser, OS2::REXX, OS2::UPM, and OS2::FTP, 
+into my ftp directory, mirrored on CPAN. I made
+some minor changes needed to compile them by standard tools. I cannot 
+test UPM and FTP, so I will appreciate your feedback. Other extensions
+there are OS2::ExtAttribs, OS2::PrfDB for tied access to EAs and .INI
+files - and maybe some other extensions at the time you read it.
+
+Note that OS2 perl defines 2 pseudo-extension functions
+OS2::Copy::copy and DynaLoader::mod2fname.
+
+The -R switch of older perl is deprecated. If you need to call a REXX code
+which needs access to variables, include the call into a REXX compartment
+created by 
+	REXX_call {...block...};
+
+Two new functions are supported by REXX code, 
+	REXX_eval 'string';
+	REXX_eval_with 'string', REXX_function_name => \&perl_sub_reference;
+
+If you have some other extensions you want to share, send the code to
+me.  At least two are available: tied access to EA's, and tied access
+to system databases.
+
+==================================================================
+==								==
+==		User report [my comments in brackets, IZ]	==
+==								==
+==	A web page: http://www.shadow.net/~troc/os2perl.html	==
+==								==
+==================================================================
+
+Starting in x:/usr/src, using 4OS2/32 2.5 as the command interpreter on
+OS/2 2.30 with FixPak-17.  DAX is installed, but this shouldn't be a
+factor.  Drive X is a TVFS virtual drive pointing to several physical
+HPFS drives.
+
+>>> Make sure that no copies or perl are currently running.  Miniperl
+    may fail during the build because it will find an older version
+    of perl.dll loaded in memory.
+
+        Close any running perl scripts.
+        Shut down anything that might run perl scripts, like cron.
+        `emxload -l` to check for loaded versions of perl.
+        `emxload -u perl.exe` to unload them.
+
+>>> Pre-load some common utilities:
+
+        emxload -e sh.exe make.exe ls.exe tr.exe id.exe sed.exe
+        SET GCCLOAD=30   (number of minutes to hold the compiler)
+[grep egrep fgrep cat rm uniq basename uniq sort - are not bad too.]
+    The theory is that it's faster to demand-load the development tools
+    from virtual memory than it is to re-load and re-link them all the
+    time.  This is definitely true with my system because swapfile.dat
+    is on a faster drive than my development environment.
+
+    ls, tr, and id represent the GNU file, text, and shell utilities.
+    These may not be needed, but it makes sure that their respective
+    DLLs are in memory.
+
+>>> Unpack the perl 5_002_01 archive onto an HPFS partition.
+
+        tar vxzf perl5_002_01.tar-gz
+        cd perl5.002_01
+
+[Do not forget to extract Configure as described above.]
+
+>>> Read the README, keeping a copy open in another session for reference.
+
+        start /c /fg less os2/README
+
+>>> Apply the OS/2 patches included with 5.002_01, as per the README.
+
+        for %m in (os2\diff.*) patch -p0 < %m
+        patch -p0 < os2\POSIX.mkfifo
+
+[The patch below is already applied.]
+
+>>> You may need to apply this patch if you plan to run a non-standard
+    Configure (that is, if you defy the README).  This patch will ensure
+    that Makefile inherits the libraries specified during Configure.
+    People running standard perl builds can probably ignore this patch.
+
+*** os2\Makefile.SHs	Mon Mar 25 02:05:00 1996
+--- os2\Makefile.SHs.new	Fri May 24 10:37:10 1996
+***************
+*** 9,15 ****
+  	emximp -o perl.imp perl5.def
+  
+  perl.dll: $(obj) perl5.def perl$(OBJ_EXT)
+! 	$(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) -lsocket perl5.def
+  
+  perl5.def: perl.linkexp
+  	echo "LIBRARY 'Perl' INITINSTANCE TERMINSTANCE"	> $@
+--- 9,15 ----
+  	emximp -o perl.imp perl5.def
+  
+  perl.dll: $(obj) perl5.def perl$(OBJ_EXT)
+! 	$(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) $(libs) perl5.def
+  
+  perl5.def: perl.linkexp
+  	echo "LIBRARY 'Perl' INITINSTANCE TERMINSTANCE"	> $@
+***************
+*** 49,55 ****
+  	cat perl.exports perl.map | sort | uniq -d | sed -e 's/\w\+/  "\0"/' > perl.linkexp
+  
+  perl.map: $(obj) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT)
+! 	$(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o dummy.exe miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) $(obj) -lsocket -lm -Zmap -Zlinker /map
+  	awk '{if ($$3 == "") print $$2}' <dummy.map | sort | uniq > perl.map
+  	rm dummy.exe dummy.map
+  
+--- 49,55 ----
+  	cat perl.exports perl.map | sort | uniq -d | sed -e 's/\w\+/  "\0"/' > perl.linkexp
+  
+  perl.map: $(obj) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT)
+! 	$(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o dummy.exe miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) $(obj) $(libs) -Zmap -Zlinker /map
+  	awk '{if ($$3 == "") print $$2}' <dummy.map | sort | uniq > perl.map
+  	rm dummy.exe dummy.map
+
+>>> Apply the patches from Ilya's perl5.002_01 binary distribution:
+
+        touch os2/dlfcn.h os2/dl_os2.c
+        patch -p1 < f:\perllib\README.fix1
+
+>>> Run Configure.  Most people can run it by following the README:
+
+        sh Configure -des -D prefix=f:/usr/local
+
+    Advanced perl users (experienced C programmers, recommended) can run
+    the interactive Configure and answer the questions.  When in doubt
+    about an answer, check the EMX headers and documentation.  Pick the
+    default answer if that doesn't help:
+
+        sh Configure
+
+[Yet more advanced users just specify the answers on the command line
+of Configure, like I did with prefix.]
+
+    Note:  You may need to wrap an answer in quotes if it contains
+    spaces.  For example, "-lsocket -lm".
+
+    Note:  If you want to add some options to a long default, you can
+    use $* to include the default in your answer:  "$* -DDEBUGGING".
+
+    Configure warnings and errors, and possible work-arounds:
+
+        I don't know where 'ln' is....
+            (ignored; OS/2 doesn't have a ln command)
+
+        nm didn't seem to work right. Trying emxomfar instead...
+            (nothing to worry about)
+
+        The recommended value for $d_shrplib on this machine was "define"!
+            (kept the recommended value: y)
+
+        Directory f:/usr/lib/perl5/os2/5.00201/CORE doesn't exist.
+            (created the directory from another window with
+            \usr\bin\mkdir -p f:/usr/lib/perl5/os2/5.00201/CORE
+            and then answered: y.  Your directory may look different.)
+
+[Ignore this as well, install script will create it for you.]
+
+        The recommended value for $i_dlfcn on this machine was "define"!
+            (kept the recommended value: y)
+
+        The recommended value for $d_fork on this machine was "undef"!
+            (kept the recommended value: y)
+
+        Figuring out the flag used by open() for non-blocking I/O...
+        Seems like we can use O_NONBLOCK.
+            This seems to be used for informative purposes only.
+            The errors that follow this (including a SIGPIPE) don't seem
+            to affect perl at all.  These were safely ignored.
+
+        What pager is used on your system? [/usr/ucb/more]
+            Had to answer "/usr/bin/less.exe" because Configure wants a
+            leading / (unix full path).  Need to edit config.sh later with
+            the real full path to the pager, including the drive letter.
+
+[Apparently this setting is never used, so it is safe to ignore it.]
+
+        Hmm... F:/USR/BIN/sed: Unterminated `s' command
+            Perl built fine even with this error, so it seems safe to
+            ignore.
+
+    Things I did different from the defaults.  Most (if not all) of these
+    are optional changes.  They're listed here to show how good Configure
+    is at detecting the system setup.
+
+[I add the options to put it on command line of Configure, see below.]
+
+        Selected 'none' for the man1 location.
+            (I prefer the pod2html version.)
+[-D man1dir=none]
+        Selected 'none' for the man3 location.
+            (I prefer the pod2html version.)
+[-D man3dir=none]
+        Changed the hostname and domain.
+            (I wanted to override a dynamic PPP address.  This only
+            matters if other people will be using your perl build.)
+[-D myhostname=my_host_name -D mydomain=.foo.org]
+        Fixed the e-mail address.
+            (Put in a known working e-mail address.  This only matters
+            if other people will be using your perl build.)
+[-D cf_email=root@myhostname.uucp]
+        Added some directories to the library search path.
+[-D "libpth=f:/emx/lib/st f:/emx/lib"]
+        Added -g to the optimizer/debugger flags.
+[-D optimize=-g]
+        Added "-lgdbm -ldb -lcrypt -lbsd" to the additional libraries.
+[  -D "libs=-lsocket -lcrypt -lgdbm"
+  the rest of libraries will not be used]
+
+>>> Advanced users may want to edit config.sh when prompted by Configure.
+    Most (all?) of these changes aren't really necessary:
+
+        d_getprior='define'
+        d_setprior='define'
+            (getpriority and setpriority are included in os2.c, but
+            Configure doesn't know to look there.)
+[fixed already]
+        pager='f:/usr/bin/less.exe'
+            (Correcting Configure's insistence on a leading slash.)
+        bin_sh='f:/usr/bin/sh.exe'
+            (If Configure detects sh.exe somewhere else first.  Example:
+            it saw sh.exe at /bin/sh.exe on my TVFS drive, but I want
+            perl to look for it on the physical F drive.)
+        aout_ccflags='... existing flags... -DDEBUGGING'
+        aout_cppflags='... existing flags... -DDEBUGGING'
+            (If you want to include DEBUGGING for the aout version.)
+[Do not do it, -D optimize=-g will automatically add these flags.]
+
+>>> Allow Configure to make the build scripts.
+
+>>> Allow Configure to run `make depend`.  Ignore the following warning:
+
+        perl.h:861: warning: `DEBUGGING_MSTATS' redefined
+[corrected now]
+
+>>> Rename any existing perl.dll, preventing anything from loading it and
+    saving a known working copy in case something goes wrong:
+
+        mv /usr/lib/perl.dll /usr/lib/ilya-perl.dll
+
+>>> Run `make`, and ignore the following warnings:
+
+        perl.h:861: warning: `DEBUGGING_MSTATS' redefined
+[corrected now]
+        invalid preprocessing directive name
+        emxomf warning: Cycle detected by make_type
+        LINK386 :  warning L4071: application type not specified; assuming WINDOWCOMPAT
+        Warning (will try anyway): No library found for -lposix
+        Warning (will try anyway): No library found for -lcposix
+        POSIX.c:203: warning: `mkfifo' redefined
+        POSIX.c:4603: warning: assignment makes pointer from integer without a cast
+
+>>> If `make` dies while "Making DynaLoader (static)", you'll need to
+    put miniperl in the OS/2 paths.  This step is only necessary if `make`
+    can't find miniperl:
+[I would be interested if somebody confirmes this.]
+
+        cp perl.dll /usr/lib        (where /usr/lib is in your LIBPATH)
+        cp miniperl.exe /usr/bin    (where /usr/bin is in your PATH)
+        make                        (ignore the errors in the previous step)
+
+        This should run to completion.
+
+>>> Test the build:
+
+        make test
+
+    These tests fail:
+
+        io/fs..........FAILED on test 2
+
+            "OS/2 is not unix".  Test 2 checks the link() command, which
+            is not supported by OS/2.
+
+        io/pipe........f:/usr/bin/sh.exe: -c requires an argument
+        f:/usr/bin/sh.exe: -c requires an argument
+        The Unsupported function fork function is unimplemented at
+            io/pipe.t line 26.
+        FAILED on test 1
+
+            More "OS/2 is not unix" errors.  Read ahead to find out
+            why fork() fails.
+
+        op/exec........FAILED on test 4
+
+                if (system "true") {print "not ok 4\n";} else \
+                {print "ok 4\n";}
+
+            This fails for me, but changing it to read like this works:
+
+                if (system '\usr\bin\true.cmd') {print "not ok 4\n";} \
+                else {print "ok 4\n";}
+
+            So you can count this as another "OS/2 is not unix".
+
+        op/fork........The Unsupported function fork function is \
+            unimplemented at op/fork.t line 8.
+        FAILED on test 1
+
+            The dynamically-loaded version of perl currently doesn't
+            support fork().  This is a known behavior of EMX.
+
+        op/magic.......
+        Process terminated by SIGINT
+        ok
+
+            The test passed even with the SIGINT message.  I don't
+            know why, but I won't argue.
+
+        op/stat........ls: /dev: No such file or directory
+        f:/usr/bin/sh.exe: ln: not found
+        ls: perl: No such file or directory
+        FAILED on test 3
+
+            "OS/2 is not unix".  We don't have the ln command.
+
+        lib/anydbm.....Bad free() ignored at lib/anydbm.t line 51.
+        Bad free() ignored at lib/anydbm.t line 51.
+        Bad free() ignored at lib/anydbm.t line 51.
+        Bad free() ignored during global destruction.
+        Bad free() ignored during global destruction.
+        Bad free() ignored during global destruction.
+        FAILED on test 2
+
+            Test 2 looks at the file permissions for a database.  "OS/2
+            is not unix" so the permissions aren't exactly what this test
+            expects.
+
+        lib/db-btree...Bad free() ignored at lib/db-btree.t line 109.
+        Bad free() ignored at lib/db-btree.t line 221.
+        Bad free() ignored at lib/db-btree.t line 337.
+        Bad free() ignored at lib/db-btree.t line 349.
+        Bad free() ignored at lib/db-btree.t line 349.
+        Bad free() ignored at lib/db-btree.t line 399.
+        Bad free() ignored at lib/db-btree.t line 400.
+        Bad free() ignored at lib/db-btree.t line 401.
+        FAILED on test 20
+
+            Another file permissions test fails.
+
+        lib/db-hash....Bad free() ignored at lib/db-hash.t line 101.
+        Bad free() ignored at lib/db-hash.t line 101.
+        Bad free() ignored at lib/db-hash.t line 101.
+        Bad free() ignored at lib/db-hash.t line 239.
+        Bad free() ignored at lib/db-hash.t line 239.
+        Bad free() ignored at lib/db-hash.t line 239.
+        Bad free() ignored at lib/db-hash.t line 253.
+        Bad free() ignored at lib/db-hash.t line 253.
+        Bad free() ignored at lib/db-hash.t line 253.
+        FAILED on test 16
+
+            Another file permissions test fails.
+
+        lib/db-recno...Bad free() ignored at lib/db-recno.t line 138.
+        Bad free() ignored at lib/db-recno.t line 138.
+        FAILED on test 18
+
+            Another file permissions test fails.
+
+        lib/gdbm.......FAILED on test 2
+
+            Another file permissions test fails.
+
+        lib/sdbm.......FAILED on test 2
+
+            Another file permissions test fails.
+
+        Failed 11/94 tests, 88.30% okay.
+
+            All of which are known differences with unix or documented
+            behaviors in EMX.  I re-run the test with Ilya's version,
+            and the same tests fail.  This new build is a success.
+[Note that bad free() mentioned above are bugs in the Berkeley
+DB. They just are more visible under OS/2 with perl free(), because of
+"rigid" function name resolution.
+	To get finer tests, cd to ./t and run 
+		perl harness
+]
+
+    (Actually, Ilya's perl release fails an extra test because I don't
+    have sed in f:\emx.add.  This shows how important it is to configure
+    and build perl yourself instead of grabbing pre-built binaries.)
+[Hmm, should not happen... There is no mentions of full_sed under ./t
+directory...]
+
+>>> Cross your fingers and install it:
+
+        make install
+
+    Warnings encountered and workarounds presented.:
+
+        WARNING: You've never run 'make test'!!!  (Installing anyway.)
+            (Lies!  All lies!  At least it still installs.)
+
+        WARNING: Can't find libperl*.dll* to install into \
+        f:/usr/lib/perl5/os2/5.00201/CORE.  (Installing other things anyway.)
+            (Safe to ignore.  The important one, libperl.lib, gets copied.)
+
+        Couldn't copy f:/usr/bin/perl5.00201.exe to f:/usr/bin/perl.exe: \
+        No such file or directory
+            cp /usr/bin/perl5.00201.exe /usr/bin/perl.exe
+
+        Couldn't copy f:/usr/bin/perl.exe to /usr/bin/perl.exe: No such \
+        file or directory
+            (I think this one is safe to ignore since the two directories
+            point to the same place.)
+
+>>> Laugh maniacally because you just built and installed your own copy
+    of perl, with all the paths set "just so" and with whatever little
+    psychotic modifications you've always wanted but were afraid to add.
+
+-----------------------------------------------------------------------------
+
+Development tools and versions:
+
+        EMX 0.9b with emxfix04 applied.
+
+        `ls --version` reports: 'GNU file utilities 3.12'
+        `tr --version` reports: 'tr - GNU textutils 1.14'
+        `id --version` reports: 'id - GNU sh-utils 1.12'
+
+        `sed --version` reports: 'GNU sed version 2.05'
+        `awk --version` reports: 'Gnu Awk (gawk) 2.15, patchlevel 6'
+        `grep --version` reports an illegal option and: 'GNU grep version 2.0'
+                (this includes egrep)
+
+        `sort --version` reports: 'sort - GNU textutils 1.14'
+        `uniq --version` reports: 'uniq - GNU textutils 1.14'
+        `find --version` reports: 'GNU find version 4.1'
+
+        KSH_VERSION='@(#)PD KSH v5.2.4 96/01/17'
+                (Ilya's patched version.)
+
+        `make --version` reports: 'GNU Make version 3.74'
+                (Ilya's patched version.)
+
+        `emxrev` reports:
+                EMX : revision = 42
+                EMXIO : revision = 40
+                EMXLIBC : revision = 40
+                EMXLIBCM : revision = 43
+                EMXLIBCS : revision = 43
+                EMXWRAP : revision = 40
+
+-----------------------------------------------------------------------------
+
+Rocco
+<troc@shadow.net>
+
