summaryrefslogtreecommitdiffstats
path: root/upstream/debian-bookworm/man1/perlos2.1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
commitfc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch)
treece1e3bce06471410239a6f41282e328770aa404a /upstream/debian-bookworm/man1/perlos2.1
parentInitial commit. (diff)
downloadmanpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz
manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/debian-bookworm/man1/perlos2.1')
-rw-r--r--upstream/debian-bookworm/man1/perlos2.12617
1 files changed, 2617 insertions, 0 deletions
diff --git a/upstream/debian-bookworm/man1/perlos2.1 b/upstream/debian-bookworm/man1/perlos2.1
new file mode 100644
index 00000000..e04bd23b
--- /dev/null
+++ b/upstream/debian-bookworm/man1/perlos2.1
@@ -0,0 +1,2617 @@
+.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "PERLOS2 1"
+.TH PERLOS2 1 "2023-11-25" "perl v5.36.0" "Perl Programmers Reference Guide"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+perlos2 \- Perl under OS/2, DOS, Win0.3*, Win0.95 and WinNT.
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+One can read this document in the following formats:
+.PP
+.Vb 4
+\& man perlos2
+\& view perl perlos2
+\& explorer perlos2.html
+\& info perlos2
+.Ve
+.PP
+to list some (not all may be available simultaneously), or it may
+be read \fIas is\fR: either as \fI\s-1README\s0.os2\fR, or \fIpod/perlos2.pod\fR.
+.PP
+To read the \fI.INF\fR version of documentation (\fBvery\fR recommended)
+outside of \s-1OS/2,\s0 one needs an \s-1IBM\s0's reader (may be available on \s-1IBM\s0
+ftp sites (?) (\s-1URL\s0 anyone?)) or shipped with \s-1PC DOS 7.0\s0 and \s-1IBM\s0's
+Visual Age \*(C+ 3.5.
+.PP
+A copy of a Win* viewer is contained in the \*(L"Just add \s-1OS/2\s0 Warp\*(R" package
+.PP
+.Vb 1
+\& ftp://ftp.software.ibm.com/ps/products/os2/tools/jaow/jaow.zip
+.Ve
+.PP
+in \fI?:\eJUST_ADD\eview.exe\fR. This gives one an access to \s-1EMX\s0's
+\&\fI.INF\fR docs as well (text form is available in \fI/emx/doc\fR in
+\&\s-1EMX\s0's distribution). There is also a different viewer named xview.
+.PP
+Note that if you have \fIlynx.exe\fR or \fInetscape.exe\fR installed, you can follow \s-1WWW\s0 links
+from this document in \fI.INF\fR format. If you have \s-1EMX\s0 docs installed
+correctly, you can follow library links (you need to have \f(CW\*(C`view emxbook\*(C'\fR
+working by setting \f(CW\*(C`EMXBOOK\*(C'\fR environment variable as it is described
+in \s-1EMX\s0 docs).
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+.SS "Target"
+.IX Subsection "Target"
+The target is to make \s-1OS/2\s0 one of the best supported platform for
+using/building/developing Perl and \fIPerl applications\fR, as well as
+make Perl the best language to use under \s-1OS/2.\s0 The secondary target is
+to try to make this work under \s-1DOS\s0 and Win* as well (but not \fBtoo\fR hard).
+.PP
+The current state is quite close to this target. Known limitations:
+.IP "\(bu" 5
+Some *nix programs use \fBfork()\fR a lot; with the mostly useful flavors of
+perl for \s-1OS/2\s0 (there are several built simultaneously) this is
+supported; but some flavors do not support this (e.g., when Perl is
+called from inside \s-1REXX\s0). Using \fBfork()\fR after
+\&\fIuse\fRing dynamically loading extensions would not work with \fIvery\fR old
+versions of \s-1EMX.\s0
+.IP "\(bu" 5
+You need a separate perl executable \fIperl_\|_.exe\fR (see \*(L"perl_\|_.exe\*(R")
+if you want to use \s-1PM\s0 code in your application (as Perl/Tk or OpenGL
+Perl modules do) without having a text-mode window present.
+.Sp
+While using the standard \fIperl.exe\fR from a text-mode window is possible
+too, I have seen cases when this causes degradation of the system stability.
+Using \fIperl_\|_.exe\fR avoids such a degradation.
+.IP "\(bu" 5
+There is no simple way to access \s-1WPS\s0 objects. The only way I know
+is via \f(CW\*(C`OS2::REXX\*(C'\fR and \f(CW\*(C`SOM\*(C'\fR extensions (see \s-1OS2::REXX\s0, \s-1SOM\s0).
+However, we do not have access to
+convenience methods of Object-REXX. (Is it possible at all? I know
+of no Object-REXX \s-1API.\s0) The \f(CW\*(C`SOM\*(C'\fR extension (currently in alpha-text)
+may eventually remove this shortcoming; however, due to the fact that
+\&\s-1DII\s0 is not supported by the \f(CW\*(C`SOM\*(C'\fR module, using \f(CW\*(C`SOM\*(C'\fR is not as
+convenient as one would like it.
+.PP
+Please keep this list up-to-date by informing me about other items.
+.SS "Other OSes"
+.IX Subsection "Other OSes"
+Since \s-1OS/2\s0 port of perl uses a remarkable \s-1EMX\s0 environment, it can
+run (and build extensions, and \- possibly \- be built itself) under any
+environment which can run \s-1EMX.\s0 The current list is \s-1DOS,\s0
+DOS\-inside\-OS/2, Win0.3*, Win0.95 and WinNT. Out of many perl flavors,
+only one works, see "\fIperl_.exe\fR".
+.PP
+Note that not all features of Perl are available under these
+environments. This depends on the features the \fIextender\fR \- most
+probably \s-1RSX\s0 \- decided to implement.
+.PP
+Cf. \*(L"Prerequisites\*(R".
+.SS "Prerequisites"
+.IX Subsection "Prerequisites"
+.IP "\s-1EMX\s0" 6
+.IX Item "EMX"
+\&\s-1EMX\s0 runtime is required (may be substituted by \s-1RSX\s0). Note that
+it is possible to make \fIperl_.exe\fR to run under \s-1DOS\s0 without any
+external support by binding \fIemx.exe\fR/\fIrsx.exe\fR to it, see \fBemxbind\fR\|(1).
+Note that under \s-1DOS\s0 for best results one should use \s-1RSX\s0 runtime, which
+has much more functions working (like \f(CW\*(C`fork\*(C'\fR, \f(CW\*(C`popen\*(C'\fR and so on). In
+fact \s-1RSX\s0 is required if there is no \s-1VCPI\s0 present. Note the
+\&\s-1RSX\s0 requires \s-1DPMI.\s0 Many implementations of \s-1DPMI\s0 are known to be very
+buggy, beware!
+.Sp
+Only the latest runtime is supported, currently \f(CW\*(C`0.9d fix 03\*(C'\fR. Perl may run
+under earlier versions of \s-1EMX,\s0 but this is not tested.
+.Sp
+One can get different parts of \s-1EMX\s0 from, say
+.Sp
+.Vb 2
+\& ftp://crydee.sai.msu.ru/pub/comp/os/os2/leo/gnu/emx+gcc/
+\& http://hobbes.nmsu.edu/h\-browse.php?dir=/pub/os2/dev/emx/v0.9d/
+.Ve
+.Sp
+The runtime component should have the name \fIemxrt.zip\fR.
+.Sp
+\&\fB\s-1NOTE\s0\fR. When using \fIemx.exe\fR/\fIrsx.exe\fR, it is enough to have them on your path. One
+does not need to specify them explicitly (though this
+.Sp
+.Vb 1
+\& emx perl_.exe \-de 0
+.Ve
+.Sp
+will work as well.)
+.IP "\s-1RSX\s0" 6
+.IX Item "RSX"
+To run Perl on \s-1DPMI\s0 platforms one needs \s-1RSX\s0 runtime. This is
+needed under DOS\-inside\-OS/2, Win0.3*, Win0.95 and WinNT (see
+\&\*(L"Other OSes\*(R"). \s-1RSX\s0 would not work with \s-1VCPI\s0
+only, as \s-1EMX\s0 would, it requires \s-1DMPI.\s0
+.Sp
+Having \s-1RSX\s0 and the latest \fIsh.exe\fR one gets a fully functional
+\&\fB*nix\fR\-ish environment under \s-1DOS,\s0 say, \f(CW\*(C`fork\*(C'\fR, \f(CW\*(C`\`\`\*(C'\fR and
+pipe\-\f(CW\*(C`open\*(C'\fR work. In fact, MakeMaker works (for static build), so one
+can have Perl development environment under \s-1DOS.\s0
+.Sp
+One can get \s-1RSX\s0 from, say
+.Sp
+.Vb 2
+\& http://cd.textfiles.com/hobbesos29804/disk1/EMX09C/
+\& ftp://crydee.sai.msu.ru/pub/comp/os/os2/leo/gnu/emx+gcc/contrib/
+.Ve
+.Sp
+Contact the author on \f(CW\*(C`rainer@mathematik.uni\-bielefeld.de\*(C'\fR.
+.Sp
+The latest \fIsh.exe\fR with \s-1DOS\s0 hooks is available in
+.Sp
+.Vb 1
+\& http://www.ilyaz.org/software/os2/
+.Ve
+.Sp
+as \fIsh_dos.zip\fR or under similar names starting with \f(CW\*(C`sh\*(C'\fR, \f(CW\*(C`pdksh\*(C'\fR etc.
+.IP "\s-1HPFS\s0" 6
+.IX Item "HPFS"
+Perl does not care about file systems, but the perl library contains
+many files with long names, so to install it intact one needs a file
+system which supports long file names.
+.Sp
+Note that if you do not plan to build the perl itself, it may be
+possible to fool \s-1EMX\s0 to truncate file names. This is not supported,
+read \s-1EMX\s0 docs to see how to do it.
+.IP "pdksh" 6
+.IX Item "pdksh"
+To start external programs with complicated command lines (like with
+pipes in between, and/or quoting of arguments), Perl uses an external
+shell. With \s-1EMX\s0 port such shell should be named \fIsh.exe\fR, and located
+either in the wired-in-during-compile locations (usually \fIF:/bin\fR),
+or in configurable location (see "\f(CW\*(C`PERL_SH_DIR\*(C'\fR").
+.Sp
+For best results use \s-1EMX\s0 pdksh. The standard binary (5.2.14 or later) runs
+under \s-1DOS\s0 (with \*(L"\s-1RSX\*(R"\s0) as well, see
+.Sp
+.Vb 1
+\& http://www.ilyaz.org/software/os2/
+.Ve
+.SS "Starting Perl programs under \s-1OS/2\s0 (and \s-1DOS\s0 and...)"
+.IX Subsection "Starting Perl programs under OS/2 (and DOS and...)"
+Start your Perl program \fIfoo.pl\fR with arguments \f(CW\*(C`arg1 arg2 arg3\*(C'\fR the
+same way as on any other platform, by
+.PP
+.Vb 1
+\& perl foo.pl arg1 arg2 arg3
+.Ve
+.PP
+If you want to specify perl options \f(CW\*(C`\-my_opts\*(C'\fR to the perl itself (as
+opposed to your program), use
+.PP
+.Vb 1
+\& perl \-my_opts foo.pl arg1 arg2 arg3
+.Ve
+.PP
+Alternately, if you use OS/2\-ish shell, like \s-1CMD\s0 or 4os2, put
+the following at the start of your perl script:
+.PP
+.Vb 1
+\& extproc perl \-S \-my_opts
+.Ve
+.PP
+rename your program to \fIfoo.cmd\fR, and start it by typing
+.PP
+.Vb 1
+\& foo arg1 arg2 arg3
+.Ve
+.PP
+Note that because of stupid \s-1OS/2\s0 limitations the full path of the perl
+script is not available when you use \f(CW\*(C`extproc\*(C'\fR, thus you are forced to
+use \f(CW\*(C`\-S\*(C'\fR perl switch, and your script should be on the \f(CW\*(C`PATH\*(C'\fR. As a plus
+side, if you know a full path to your script, you may still start it
+with
+.PP
+.Vb 1
+\& perl ../../blah/foo.cmd arg1 arg2 arg3
+.Ve
+.PP
+(note that the argument \f(CW\*(C`\-my_opts\*(C'\fR is taken care of by the \f(CW\*(C`extproc\*(C'\fR line
+in your script, see \f(CW"extproc"\fR on the first line).
+.PP
+To understand what the above \fImagic\fR does, read perl docs about \f(CW\*(C`\-S\*(C'\fR
+switch \- see perlrun, and cmdref about \f(CW\*(C`extproc\*(C'\fR:
+.PP
+.Vb 4
+\& view perl perlrun
+\& man perlrun
+\& view cmdref extproc
+\& help extproc
+.Ve
+.PP
+or whatever method you prefer.
+.PP
+There are also endless possibilities to use \fIexecutable extensions\fR of
+4os2, \fIassociations\fR of \s-1WPS\s0 and so on... However, if you use
+*nixish shell (like \fIsh.exe\fR supplied in the binary distribution),
+you need to follow the syntax specified in \*(L"Command Switches\*(R" in perlrun.
+.PP
+Note that \fB\-S\fR switch supports scripts with additional extensions
+\&\fI.cmd\fR, \fI.btm\fR, \fI.bat\fR, \fI.pl\fR as well.
+.SS "Starting \s-1OS/2\s0 (and \s-1DOS\s0) programs under Perl"
+.IX Subsection "Starting OS/2 (and DOS) programs under Perl"
+This is what \fBsystem()\fR (see \*(L"system\*(R" in perlfunc), \f(CW\*(C`\`\`\*(C'\fR (see
+\&\*(L"I/O Operators\*(R" in perlop), and \fIopen pipe\fR (see \*(L"open\*(R" in perlfunc)
+are for. (Avoid \fBexec()\fR (see \*(L"exec\*(R" in perlfunc) unless you know what you
+do).
+.PP
+Note however that to use some of these operators you need to have a
+sh-syntax shell installed (see \*(L"Pdksh\*(R",
+\&\*(L"Frequently asked questions\*(R"), and perl should be able to find it
+(see "\f(CW\*(C`PERL_SH_DIR\*(C'\fR").
+.PP
+The cases when the shell is used are:
+.IP "1." 4
+One-argument \fBsystem()\fR (see \*(L"system\*(R" in perlfunc), \fBexec()\fR (see \*(L"exec\*(R" in perlfunc)
+with redirection or shell meta-characters;
+.IP "2." 4
+Pipe-open (see \*(L"open\*(R" in perlfunc) with the command which contains redirection
+or shell meta-characters;
+.IP "3." 4
+Backticks \f(CW\*(C`\`\`\*(C'\fR (see \*(L"I/O Operators\*(R" in perlop) with the command which contains
+redirection or shell meta-characters;
+.IP "4." 4
+If the executable called by \fBsystem()\fR/\fBexec()\fR/pipe\-\fBopen()\fR/\f(CW\*(C`\`\`\*(C'\fR is a script
+with the \*(L"magic\*(R" \f(CW\*(C`#!\*(C'\fR line or \f(CW\*(C`extproc\*(C'\fR line which specifies shell;
+.IP "5." 4
+If the executable called by \fBsystem()\fR/\fBexec()\fR/pipe\-\fBopen()\fR/\f(CW\*(C`\`\`\*(C'\fR is a script
+without \*(L"magic\*(R" line, and \f(CW$ENV{EXECSHELL}\fR is set to shell;
+.IP "6." 4
+If the executable called by \fBsystem()\fR/\fBexec()\fR/pipe\-\fBopen()\fR/\f(CW\*(C`\`\`\*(C'\fR is not
+found (is not this remark obsolete?);
+.IP "7." 4
+For globbing (see \*(L"glob\*(R" in perlfunc, \*(L"I/O Operators\*(R" in perlop)
+(obsolete? Perl uses builtin globbing nowadays...).
+.PP
+For the sake of speed for a common case, in the above algorithms
+backslashes in the command name are not considered as shell metacharacters.
+.PP
+Perl starts scripts which begin with cookies
+\&\f(CW\*(C`extproc\*(C'\fR or \f(CW\*(C`#!\*(C'\fR directly, without an intervention of shell. Perl uses the
+same algorithm to find the executable as \fIpdksh\fR: if the path
+on \f(CW\*(C`#!\*(C'\fR line does not work, and contains \f(CW\*(C`/\*(C'\fR, then the directory
+part of the executable is ignored, and the executable
+is searched in \fI.\fR and on \f(CW\*(C`PATH\*(C'\fR. To find arguments for these scripts
+Perl uses a different algorithm than \fIpdksh\fR: up to 3 arguments are
+recognized, and trailing whitespace is stripped.
+.PP
+If a script
+does not contain such a cooky, then to avoid calling \fIsh.exe\fR, Perl uses
+the same algorithm as \fIpdksh\fR: if \f(CW$ENV{EXECSHELL}\fR is set, the
+script is given as the first argument to this command, if not set, then
+\&\f(CW\*(C`$ENV{COMSPEC} /c\*(C'\fR is used (or a hardwired guess if \f(CW$ENV{COMSPEC}\fR is
+not set).
+.PP
+When starting scripts directly, Perl uses exactly the same algorithm as for
+the search of script given by \fB\-S\fR command-line option: it will look in
+the current directory, then on components of \f(CW$ENV{PATH}\fR using the
+following order of appended extensions: no extension, \fI.cmd\fR, \fI.btm\fR,
+\&\fI.bat\fR, \fI.pl\fR.
+.PP
+Note that Perl will start to look for scripts only if \s-1OS/2\s0 cannot start the
+specified application, thus \f(CW\*(C`system \*(Aqblah\*(Aq\*(C'\fR will not look for a script if
+there is an executable file \fIblah.exe\fR \fIanywhere\fR on \f(CW\*(C`PATH\*(C'\fR. In
+other words, \f(CW\*(C`PATH\*(C'\fR is essentially searched twice: once by the \s-1OS\s0 for
+an executable, then by Perl for scripts.
+.PP
+Note also that executable files on \s-1OS/2\s0 can have an arbitrary extension, but
+\&\fI.exe\fR will be automatically appended if no dot is present in the name. The
+workaround is as simple as that: since \fIblah.\fR and \fIblah\fR denote the same
+file (at list on \s-1FAT\s0 and \s-1HPFS\s0 file systems), to start an executable residing in
+file \fIn:/bin/blah\fR (no extension) give an argument \f(CW\*(C`n:/bin/blah.\*(C'\fR (dot
+appended) to \fBsystem()\fR.
+.PP
+Perl will start \s-1PM\s0 programs from \s-1VIO\s0 (=text\-mode) Perl process in a
+separate \s-1PM\s0 session;
+the opposite is not true: when you start a non-PM program from a \s-1PM\s0
+Perl process, Perl would not run it in a separate session. If a separate
+session is desired, either ensure
+that shell will be used, as in \f(CW\*(C`system \*(Aqcmd /c myprog\*(Aq\*(C'\fR, or start it using
+optional arguments to \fBsystem()\fR documented in \f(CW\*(C`OS2::Process\*(C'\fR module. This
+is considered to be a feature.
+.SH "Frequently asked questions"
+.IX Header "Frequently asked questions"
+.ie n .SS """It does not work"""
+.el .SS "``It does not work''"
+.IX Subsection "It does not work"
+Perl binary distributions come with a \fItestperl.cmd\fR script which tries
+to detect common problems with misconfigured installations. There is a
+pretty large chance it will discover which step of the installation you
+managed to goof. \f(CW\*(C`;\-)\*(C'\fR
+.SS "I cannot run external programs"
+.IX Subsection "I cannot run external programs"
+.IP "\(bu" 4
+Did you run your programs with \f(CW\*(C`\-w\*(C'\fR switch? See
+\&\*(L"Starting \s-1OS/2\s0 (and \s-1DOS\s0) programs under Perl\*(R".
+.IP "\(bu" 4
+Do you try to run \fIinternal\fR shell commands, like \f(CW\*(C`\`copy a b\`\*(C'\fR
+(internal for \fIcmd.exe\fR), or \f(CW\*(C`\`glob a*b\`\*(C'\fR (internal for ksh)? You
+need to specify your shell explicitly, like \f(CW\*(C`\`cmd /c copy a b\`\*(C'\fR,
+since Perl cannot deduce which commands are internal to your shell.
+.SS "I cannot embed perl into my program, or use \fIperl.dll\fP from my program."
+.IX Subsection "I cannot embed perl into my program, or use perl.dll from my program."
+.ie n .IP "Is your program EMX-compiled with ""\-Zmt \-Zcrtdll""?" 4
+.el .IP "Is your program EMX-compiled with \f(CW\-Zmt \-Zcrtdll\fR?" 4
+.IX Item "Is your program EMX-compiled with -Zmt -Zcrtdll?"
+Well, nowadays Perl \s-1DLL\s0 should be usable from a differently compiled
+program too... If you can run Perl code from \s-1REXX\s0 scripts (see
+\&\s-1OS2::REXX\s0), then there are some other aspect of interaction which
+are overlooked by the current hackish code to support
+differently-compiled principal programs.
+.Sp
+If everything else fails, you need to build a stand-alone \s-1DLL\s0 for
+perl. Contact me, I did it once. Sockets would not work, as a lot of
+other stuff.
+.IP "Did you use ExtUtils::Embed?" 4
+.IX Item "Did you use ExtUtils::Embed?"
+Some time ago I had reports it does not work. Nowadays it is checked
+in the Perl test suite, so grep \fI./t\fR subdirectory of the build tree
+(as well as \fI*.t\fR files in the \fI./lib\fR subdirectory) to find how it
+should be done \*(L"correctly\*(R".
+.ie n .SS """\`\`"" and pipe\-""open"" do not work under \s-1DOS.\s0"
+.el .SS "\f(CW\`\`\fP and pipe\-\f(CWopen\fP do not work under \s-1DOS.\s0"
+.IX Subsection " and pipe-open do not work under DOS."
+This may a variant of just \*(L"I cannot run external programs\*(R", or a
+deeper problem. Basically: you \fIneed\fR \s-1RSX\s0 (see \*(L"Prerequisites\*(R")
+for these commands to work, and you may need a port of \fIsh.exe\fR which
+understands command arguments. One of such ports is listed in
+\&\*(L"Prerequisites\*(R" under \s-1RSX.\s0 Do not forget to set variable
+"\f(CW\*(C`PERL_SH_DIR\*(C'\fR" as well.
+.PP
+\&\s-1DPMI\s0 is required for \s-1RSX.\s0
+.ie n .SS "Cannot start ""find.exe ""pattern"" file"""
+.el .SS "Cannot start \f(CWfind.exe ``pattern'' file\fP"
+.IX Subsection "Cannot start find.exe ""pattern"" file"
+The whole idea of the \*(L"standard C \s-1API\s0 to start applications\*(R" is that
+the forms \f(CW\*(C`foo\*(C'\fR and \f(CW"foo"\fR of program arguments are completely
+interchangeable. \fIfind\fR breaks this paradigm;
+.PP
+.Vb 2
+\& find "pattern" file
+\& find pattern file
+.Ve
+.PP
+are not equivalent; \fIfind\fR cannot be started directly using the above
+\&\s-1API.\s0 One needs a way to surround the doublequotes in some other
+quoting construction, necessarily having an extra non-Unixish shell in
+between.
+.PP
+Use one of
+.PP
+.Vb 2
+\& system \*(Aqcmd\*(Aq, \*(Aq/c\*(Aq, \*(Aqfind "pattern" file\*(Aq;
+\& \`cmd /c \*(Aqfind "pattern" file\*(Aq\`
+.Ve
+.PP
+This would start \fIfind.exe\fR via \fIcmd.exe\fR via \f(CW\*(C`sh.exe\*(C'\fR via
+\&\f(CW\*(C`perl.exe\*(C'\fR, but this is a price to pay if you want to use
+non-conforming program.
+.SH "INSTALLATION"
+.IX Header "INSTALLATION"
+.SS "Automatic binary installation"
+.IX Subsection "Automatic binary installation"
+The most convenient way of installing a binary distribution of perl is via perl installer
+\&\fIinstall.exe\fR. Just follow the instructions, and 99% of the
+installation blues would go away.
+.PP
+Note however, that you need to have \fIunzip.exe\fR on your path, and
+\&\s-1EMX\s0 environment \fIrunning\fR. The latter means that if you just
+installed \s-1EMX,\s0 and made all the needed changes to \fIConfig.sys\fR,
+you may need to reboot in between. Check \s-1EMX\s0 runtime by running
+.PP
+.Vb 1
+\& emxrev
+.Ve
+.PP
+Binary installer also creates a folder on your desktop with some useful
+objects. If you need to change some aspects of the work of the binary
+installer, feel free to edit the file \fIPerl.pkg\fR. This may be useful
+e.g., if you need to run the installer many times and do not want to
+make many interactive changes in the \s-1GUI.\s0
+.PP
+\&\fBThings not taken care of by automatic binary installation:\fR
+.ie n .IP """PERL_BADLANG""" 15
+.el .IP "\f(CWPERL_BADLANG\fR" 15
+.IX Item "PERL_BADLANG"
+may be needed if you change your codepage \fIafter\fR perl installation,
+and the new value is not supported by \s-1EMX.\s0 See "\f(CW\*(C`PERL_BADLANG\*(C'\fR".
+.ie n .IP """PERL_BADFREE""" 15
+.el .IP "\f(CWPERL_BADFREE\fR" 15
+.IX Item "PERL_BADFREE"
+see "\f(CW\*(C`PERL_BADFREE\*(C'\fR".
+.IP "\fIConfig.pm\fR" 15
+.IX Item "Config.pm"
+This file resides somewhere deep in the location you installed your
+perl library, find it out by
+.Sp
+.Vb 1
+\& perl \-MConfig \-le "print $INC{\*(AqConfig.pm\*(Aq}"
+.Ve
+.Sp
+While most important values in this file \fIare\fR updated by the binary
+installer, some of them may need to be hand-edited. I know no such
+data, please keep me informed if you find one. Moreover, manual
+changes to the installed version may need to be accompanied by an edit
+of this file.
+.PP
+\&\fB\s-1NOTE\s0\fR. Because of a typo the binary installer of 5.00305
+would install a variable \f(CW\*(C`PERL_SHPATH\*(C'\fR into \fIConfig.sys\fR. Please
+remove this variable and put \f(CW"PERL_SH_DIR"\fR instead.
+.SS "Manual binary installation"
+.IX Subsection "Manual binary installation"
+As of version 5.00305, \s-1OS/2\s0 perl binary distribution comes split
+into 11 components. Unfortunately, to enable configurable binary
+installation, the file paths in the zip files are not absolute, but
+relative to some directory.
+.PP
+Note that the extraction with the stored paths is still necessary
+(default with unzip, specify \f(CW\*(C`\-d\*(C'\fR to pkunzip). However, you
+need to know where to extract the files. You need also to manually
+change entries in \fIConfig.sys\fR to reflect where did you put the
+files. Note that if you have some primitive unzipper (like
+\&\f(CW\*(C`pkunzip\*(C'\fR), you may get a lot of warnings/errors during
+unzipping. Upgrade to \f(CW\*(C`(w)unzip\*(C'\fR.
+.PP
+Below is the sample of what to do to reproduce the configuration on my
+machine. In \fI\s-1VIEW.EXE\s0\fR you can press \f(CW\*(C`Ctrl\-Insert\*(C'\fR now, and
+cut-and-paste from the resulting file \- created in the directory you
+started \fI\s-1VIEW.EXE\s0\fR from.
+.PP
+For each component, we mention environment variables related to each
+installation directory. Either choose directories to match your
+values of the variables, or create/append\-to variables to take into
+account the directories.
+.IP "Perl \s-1VIO\s0 and \s-1PM\s0 executables (dynamically linked)" 3
+.IX Item "Perl VIO and PM executables (dynamically linked)"
+.Vb 2
+\& unzip perl_exc.zip *.exe *.ico \-d f:/emx.add/bin
+\& unzip perl_exc.zip *.dll \-d f:/emx.add/dll
+.Ve
+.Sp
+(have the directories with \f(CW\*(C`*.exe\*(C'\fR on \s-1PATH,\s0 and \f(CW\*(C`*.dll\*(C'\fR on
+\&\s-1LIBPATH\s0);
+.IP "Perl_ \s-1VIO\s0 executable (statically linked)" 3
+.IX Item "Perl_ VIO executable (statically linked)"
+.Vb 1
+\& unzip perl_aou.zip \-d f:/emx.add/bin
+.Ve
+.Sp
+(have the directory on \s-1PATH\s0);
+.IP "Executables for Perl utilities" 3
+.IX Item "Executables for Perl utilities"
+.Vb 1
+\& unzip perl_utl.zip \-d f:/emx.add/bin
+.Ve
+.Sp
+(have the directory on \s-1PATH\s0);
+.IP "Main Perl library" 3
+.IX Item "Main Perl library"
+.Vb 1
+\& unzip perl_mlb.zip \-d f:/perllib/lib
+.Ve
+.Sp
+If this directory is exactly the same as the prefix which was compiled
+into \fIperl.exe\fR, you do not need to change
+anything. However, for perl to find the library if you use a different
+path, you need to
+\&\f(CW\*(C`set PERLLIB_PREFIX\*(C'\fR in \fIConfig.sys\fR, see "\f(CW\*(C`PERLLIB_PREFIX\*(C'\fR".
+.IP "Additional Perl modules" 3
+.IX Item "Additional Perl modules"
+.Vb 1
+\& unzip perl_ste.zip \-d f:/perllib/lib/site_perl/5.36.0/
+.Ve
+.Sp
+Same remark as above applies. Additionally, if this directory is not
+one of directories on \f(CW@INC\fR (and \f(CW@INC\fR is influenced by \f(CW\*(C`PERLLIB_PREFIX\*(C'\fR), you
+need to put this
+directory and subdirectory \fI./os2\fR in \f(CW\*(C`PERLLIB\*(C'\fR or \f(CW\*(C`PERL5LIB\*(C'\fR
+variable. Do not use \f(CW\*(C`PERL5LIB\*(C'\fR unless you have it set already. See
+\&\*(L"\s-1ENVIRONMENT\*(R"\s0 in perl.
+.Sp
+\&\fB[Check whether this extraction directory is still applicable with
+the new directory structure layout!]\fR
+.IP "Tools to compile Perl modules" 3
+.IX Item "Tools to compile Perl modules"
+.Vb 1
+\& unzip perl_blb.zip \-d f:/perllib/lib
+.Ve
+.Sp
+Same remark as for \fIperl_ste.zip\fR.
+.IP "Manpages for Perl and utilities" 3
+.IX Item "Manpages for Perl and utilities"
+.Vb 1
+\& unzip perl_man.zip \-d f:/perllib/man
+.Ve
+.Sp
+This directory should better be on \f(CW\*(C`MANPATH\*(C'\fR. You need to have a
+working \fIman\fR to access these files.
+.IP "Manpages for Perl modules" 3
+.IX Item "Manpages for Perl modules"
+.Vb 1
+\& unzip perl_mam.zip \-d f:/perllib/man
+.Ve
+.Sp
+This directory should better be on \f(CW\*(C`MANPATH\*(C'\fR. You need to have a
+working man to access these files.
+.IP "Source for Perl documentation" 3
+.IX Item "Source for Perl documentation"
+.Vb 1
+\& unzip perl_pod.zip \-d f:/perllib/lib
+.Ve
+.Sp
+This is used by the \f(CW\*(C`perldoc\*(C'\fR program (see perldoc), and may be used to
+generate \s-1HTML\s0 documentation usable by \s-1WWW\s0 browsers, and
+documentation in zillions of other formats: \f(CW\*(C`info\*(C'\fR, \f(CW\*(C`LaTeX\*(C'\fR,
+\&\f(CW\*(C`Acrobat\*(C'\fR, \f(CW\*(C`FrameMaker\*(C'\fR and so on. [Use programs such as
+\&\fIpod2latex\fR etc.]
+.IP "Perl manual in \fI.INF\fR format" 3
+.IX Item "Perl manual in .INF format"
+.Vb 1
+\& unzip perl_inf.zip \-d d:/os2/book
+.Ve
+.Sp
+This directory should better be on \f(CW\*(C`BOOKSHELF\*(C'\fR.
+.IP "Pdksh" 3
+.IX Item "Pdksh"
+.Vb 1
+\& unzip perl_sh.zip \-d f:/bin
+.Ve
+.Sp
+This is used by perl to run external commands which explicitly
+require shell, like the commands using \fIredirection\fR and \fIshell
+metacharacters\fR. It is also used instead of explicit \fI/bin/sh\fR.
+.Sp
+Set \f(CW\*(C`PERL_SH_DIR\*(C'\fR (see "\f(CW\*(C`PERL_SH_DIR\*(C'\fR") if you move \fIsh.exe\fR from
+the above location.
+.Sp
+\&\fBNote.\fR It may be possible to use some other sh-compatible shell (untested).
+.PP
+After you installed the components you needed and updated the
+\&\fIConfig.sys\fR correspondingly, you need to hand-edit
+\&\fIConfig.pm\fR. This file resides somewhere deep in the location you
+installed your perl library, find it out by
+.PP
+.Vb 1
+\& perl \-MConfig \-le "print $INC{\*(AqConfig.pm\*(Aq}"
+.Ve
+.PP
+You need to correct all the entries which look like file paths (they
+currently start with \f(CW\*(C`f:/\*(C'\fR).
+.SS "\fBWarning\fP"
+.IX Subsection "Warning"
+The automatic and manual perl installation leave precompiled paths
+inside perl executables. While these paths are overwritable (see
+"\f(CW\*(C`PERLLIB_PREFIX\*(C'\fR", "\f(CW\*(C`PERL_SH_DIR\*(C'\fR"), some people may prefer
+binary editing of paths inside the executables/DLLs.
+.SH "Accessing documentation"
+.IX Header "Accessing documentation"
+Depending on how you built/installed perl you may have (otherwise
+identical) Perl documentation in the following formats:
+.SS "\s-1OS/2\s0 \fI.INF\fP file"
+.IX Subsection "OS/2 .INF file"
+Most probably the most convenient form. Under \s-1OS/2\s0 view it as
+.PP
+.Vb 4
+\& view perl
+\& view perl perlfunc
+\& view perl less
+\& view perl ExtUtils::MakeMaker
+.Ve
+.PP
+(currently the last two may hit a wrong location, but this may improve
+soon). Under Win* see \*(L"\s-1SYNOPSIS\*(R"\s0.
+.PP
+If you want to build the docs yourself, and have \fI\s-1OS/2\s0 toolkit\fR, run
+.PP
+.Vb 1
+\& pod2ipf > perl.ipf
+.Ve
+.PP
+in \fI/perllib/lib/pod\fR directory, then
+.PP
+.Vb 1
+\& ipfc /inf perl.ipf
+.Ve
+.PP
+(Expect a lot of errors during the both steps.) Now move it on your
+\&\s-1BOOKSHELF\s0 path.
+.SS "Plain text"
+.IX Subsection "Plain text"
+If you have perl documentation in the source form, perl utilities
+installed, and \s-1GNU\s0 groff installed, you may use
+.PP
+.Vb 3
+\& perldoc perlfunc
+\& perldoc less
+\& perldoc ExtUtils::MakeMaker
+.Ve
+.PP
+to access the perl documentation in the text form (note that you may get
+better results using perl manpages).
+.PP
+Alternately, try running pod2text on \fI.pod\fR files.
+.SS "Manpages"
+.IX Subsection "Manpages"
+If you have \fIman\fR installed on your system, and you installed perl
+manpages, use something like this:
+.PP
+.Vb 3
+\& man perlfunc
+\& man 3 less
+\& man ExtUtils.MakeMaker
+.Ve
+.PP
+to access documentation for different components of Perl. Start with
+.PP
+.Vb 1
+\& man perl
+.Ve
+.PP
+Note that dot (\fI.\fR) is used as a package separator for documentation
+for packages, and as usual, sometimes you need to give the section \- \f(CW3\fR
+above \- to avoid shadowing by the \fI\f(BIless\fI\|(1) manpage\fR.
+.PP
+Make sure that the directory \fBabove\fR the directory with manpages is
+on our \f(CW\*(C`MANPATH\*(C'\fR, like this
+.PP
+.Vb 1
+\& set MANPATH=c:/man;f:/perllib/man
+.Ve
+.PP
+for Perl manpages in \f(CW\*(C`f:/perllib/man/man1/\*(C'\fR etc.
+.SS "\s-1HTML\s0"
+.IX Subsection "HTML"
+If you have some \s-1WWW\s0 browser available, installed the Perl
+documentation in the source form, and Perl utilities, you can build
+\&\s-1HTML\s0 docs. Cd to directory with \fI.pod\fR files, and do like this
+.PP
+.Vb 2
+\& cd f:/perllib/lib/pod
+\& pod2html
+.Ve
+.PP
+After this you can direct your browser the file \fIperl.html\fR in this
+directory, and go ahead with reading docs, like this:
+.PP
+.Vb 1
+\& explore file:///f:/perllib/lib/pod/perl.html
+.Ve
+.PP
+Alternatively you may be able to get these docs prebuilt from \s-1CPAN.\s0
+.ie n .SS "\s-1GNU\s0 ""info"" files"
+.el .SS "\s-1GNU\s0 \f(CWinfo\fP files"
+.IX Subsection "GNU info files"
+Users of Emacs would appreciate it very much, especially with
+\&\f(CW\*(C`CPerl\*(C'\fR mode loaded. You need to get latest \f(CW\*(C`pod2texi\*(C'\fR from \f(CW\*(C`CPAN\*(C'\fR,
+or, alternately, the prebuilt info pages.
+.SS "\fI\s-1PDF\s0\fP files"
+.IX Subsection "PDF files"
+for \f(CW\*(C`Acrobat\*(C'\fR are available on \s-1CPAN\s0 (may be for slightly older version of
+perl).
+.ie n .SS """LaTeX"" docs"
+.el .SS "\f(CWLaTeX\fP docs"
+.IX Subsection "LaTeX docs"
+can be constructed using \f(CW\*(C`pod2latex\*(C'\fR.
+.SH "BUILD"
+.IX Header "BUILD"
+Here we discuss how to build Perl under \s-1OS/2.\s0
+.SS "The short story"
+.IX Subsection "The short story"
+Assume that you are a seasoned porter, so are sure that all the necessary
+tools are already present on your system, and you know how to get the Perl
+source distribution. Untar it, change to the extract directory, and
+.PP
+.Vb 7
+\& gnupatch \-p0 < os2\ediff.configure
+\& sh Configure \-des \-D prefix=f:/perllib
+\& make
+\& make test
+\& make install
+\& make aout_test
+\& make aout_install
+.Ve
+.PP
+This puts the executables in f:/perllib/bin. Manually move them to the
+\&\f(CW\*(C`PATH\*(C'\fR, manually move the built \fIperl*.dll\fR to \f(CW\*(C`LIBPATH\*(C'\fR (here for
+Perl \s-1DLL\s0 \fI*\fR is a not-very-meaningful hex checksum), and run
+.PP
+.Vb 1
+\& make installcmd INSTALLCMDDIR=d:/ir/on/path
+.Ve
+.PP
+Assuming that the \f(CW\*(C`man\*(C'\fR\-files were put on an appropriate location,
+this completes the installation of minimal Perl system. (The binary
+distribution contains also a lot of additional modules, and the
+documentation in \s-1INF\s0 format.)
+.PP
+What follows is a detailed guide through these steps.
+.SS "Prerequisites"
+.IX Subsection "Prerequisites"
+You need to have the latest \s-1EMX\s0 development environment, the full
+\&\s-1GNU\s0 tool suite (gawk renamed to awk, and \s-1GNU\s0 \fIfind.exe\fR
+earlier on path than the \s-1OS/2\s0 \fIfind.exe\fR, same with \fIsort.exe\fR, to
+check use
+.PP
+.Vb 2
+\& find \-\-version
+\& sort \-\-version
+.Ve
+.PP
+). You need the latest version of \fIpdksh\fR installed as \fIsh.exe\fR.
+.PP
+Check that you have \fB\s-1BSD\s0\fR libraries and headers installed, and \-
+optionally \- Berkeley \s-1DB\s0 headers and libraries, and crypt.
+.PP
+Possible locations to get the files:
+.PP
+.Vb 4
+\& ftp://ftp.uni\-heidelberg.de/pub/os2/unix/
+\& http://hobbes.nmsu.edu/h\-browse.php?dir=/pub/os2
+\& http://cd.textfiles.com/hobbesos29804/disk1/DEV32/
+\& http://cd.textfiles.com/hobbesos29804/disk1/EMX09C/
+.Ve
+.PP
+It is reported that the following archives contain enough utils to
+build perl: \fIgnufutil.zip\fR, \fIgnusutil.zip\fR, \fIgnututil.zip\fR, \fIgnused.zip\fR,
+\&\fIgnupatch.zip\fR, \fIgnuawk.zip\fR, \fIgnumake.zip\fR, \fIgnugrep.zip\fR, \fIbsddev.zip\fR and
+\&\fIksh527rt.zip\fR (or a later version). Note that all these utilities are
+known to be available from \s-1LEO:\s0
+.PP
+.Vb 1
+\& ftp://crydee.sai.msu.ru/pub/comp/os/os2/leo/gnu/
+.Ve
+.PP
+Note also that the \fIdb.lib\fR and \fIdb.a\fR from the \s-1EMX\s0 distribution
+are not suitable for multi-threaded compile (even single-threaded
+flavor of Perl uses multi-threaded C \s-1RTL,\s0 for
+compatibility with XFree86\-OS/2). Get a corrected one from
+.PP
+.Vb 1
+\& http://www.ilyaz.org/software/os2/db_mt.zip
+.Ve
+.PP
+If you have \fIexactly the same version of Perl\fR installed already,
+make sure that no copies or perl are currently running. Later steps
+of the build may fail since an older version of \fIperl.dll\fR loaded into
+memory may be found. Running \f(CW\*(C`make test\*(C'\fR becomes meaningless, since
+the test are checking a previous build of perl (this situation is detected
+and reported by \fIos2/os2_base.t\fR test). Do not forget to unset
+\&\f(CW\*(C`PERL_EMXLOAD_SEC\*(C'\fR in environment.
+.PP
+Also make sure that you have \fI/tmp\fR directory on the current drive,
+and \fI.\fR directory in your \f(CW\*(C`LIBPATH\*(C'\fR. One may try to correct the
+latter condition by
+.PP
+.Vb 1
+\& set BEGINLIBPATH .\e.
+.Ve
+.PP
+if you use something like \fI\s-1CMD.EXE\s0\fR or latest versions of
+\&\fI4os2.exe\fR. (Setting \s-1BEGINLIBPATH\s0 to just \f(CW\*(C`.\*(C'\fR is ignored by the
+\&\s-1OS/2\s0 kernel.)
+.PP
+Make sure your gcc is good for \f(CW\*(C`\-Zomf\*(C'\fR linking: run \f(CW\*(C`omflibs\*(C'\fR
+script in \fI/emx/lib\fR directory.
+.PP
+Check that you have link386 installed. It comes standard with \s-1OS/2,\s0
+but may be not installed due to customization. If typing
+.PP
+.Vb 1
+\& link386
+.Ve
+.PP
+shows you do not have it, do \fISelective install\fR, and choose \f(CW\*(C`Link
+object modules\*(C'\fR in \fIOptional system utilities/More\fR. If you get into
+link386 prompts, press \f(CW\*(C`Ctrl\-C\*(C'\fR to exit.
+.SS "Getting perl source"
+.IX Subsection "Getting perl source"
+You need to fetch the latest perl source (including developers
+releases). With some probability it is located in
+.PP
+.Vb 2
+\& http://www.cpan.org/src/
+\& http://www.cpan.org/src/unsupported
+.Ve
+.PP
+If not, you may need to dig in the indices to find it in the directory
+of the current maintainer.
+.PP
+Quick cycle of developers release may break the \s-1OS/2\s0 build time to
+time, looking into
+.PP
+.Vb 1
+\& http://www.cpan.org/ports/os2/
+.Ve
+.PP
+may indicate the latest release which was publicly released by the
+maintainer. Note that the release may include some additional patches
+to apply to the current source of perl.
+.PP
+Extract it like this
+.PP
+.Vb 1
+\& tar vzxf perl5.00409.tar.gz
+.Ve
+.PP
+You may see a message about errors while extracting \fIConfigure\fR. This is
+because there is a conflict with a similarly-named file \fIconfigure\fR.
+.PP
+Change to the directory of extraction.
+.SS "Application of the patches"
+.IX Subsection "Application of the patches"
+You need to apply the patches in \fI./os2/diff.*\fR like this:
+.PP
+.Vb 1
+\& gnupatch \-p0 < os2\ediff.configure
+.Ve
+.PP
+You may also need to apply the patches supplied with the binary
+distribution of perl. It also makes sense to look on the
+perl5\-porters mailing list for the latest OS/2\-related patches (see
+<http://www.xray.mpe.mpg.de/mailing\-lists/perl5\-porters/>). Such
+patches usually contain strings \f(CW\*(C`/os2/\*(C'\fR and \f(CW\*(C`patch\*(C'\fR, so it makes
+sense looking for these strings.
+.SS "Hand-editing"
+.IX Subsection "Hand-editing"
+You may look into the file \fI./hints/os2.sh\fR and correct anything
+wrong you find there. I do not expect it is needed anywhere.
+.SS "Making"
+.IX Subsection "Making"
+.Vb 1
+\& sh Configure \-des \-D prefix=f:/perllib
+.Ve
+.PP
+\&\f(CW\*(C`prefix\*(C'\fR means: where to install the resulting perl library. Giving
+correct prefix you may avoid the need to specify \f(CW\*(C`PERLLIB_PREFIX\*(C'\fR,
+see "\f(CW\*(C`PERLLIB_PREFIX\*(C'\fR".
+.PP
+\&\fIIgnore the message about missing \f(CI\*(C`ln\*(C'\fI, and about \f(CI\*(C`\-c\*(C'\fI option to
+tr\fR. The latter is most probably already fixed, if you see it and can trace
+where the latter spurious warning comes from, please inform me.
+.PP
+Now
+.PP
+.Vb 1
+\& make
+.Ve
+.PP
+At some moment the built may die, reporting a \fIversion mismatch\fR or
+\&\fIunable to run \fIperl\fI\fR. This means that you do not have \fI.\fR in
+your \s-1LIBPATH,\s0 so \fIperl.exe\fR cannot find the needed \fIperl67B2.dll\fR (treat
+these hex digits as line noise). After this is fixed the build
+should finish without a lot of fuss.
+.SS "Testing"
+.IX Subsection "Testing"
+Now run
+.PP
+.Vb 1
+\& make test
+.Ve
+.PP
+All tests should succeed (with some of them skipped). If you have the
+same version of Perl installed, it is crucial that you have \f(CW\*(C`.\*(C'\fR early
+in your \s-1LIBPATH\s0 (or in \s-1BEGINLIBPATH\s0), otherwise your tests will most
+probably test the wrong version of Perl.
+.PP
+Some tests may generate extra messages similar to
+.ie n .IP "A lot of ""bad free""" 4
+.el .IP "A lot of \f(CWbad free\fR" 4
+.IX Item "A lot of bad free"
+in database tests related to Berkeley \s-1DB.\s0 \fIThis should be fixed already.\fR
+If it persists, you may disable this warnings, see "\f(CW\*(C`PERL_BADFREE\*(C'\fR".
+.IP "Process terminated by \s-1SIGTERM/SIGINT\s0" 4
+.IX Item "Process terminated by SIGTERM/SIGINT"
+This is a standard message issued by \s-1OS/2\s0 applications. *nix
+applications die in silence. It is considered to be a feature. One can
+easily disable this by appropriate sighandlers.
+.Sp
+However the test engine bleeds these message to screen in unexpected
+moments. Two messages of this kind \fIshould\fR be present during
+testing.
+.PP
+To get finer test reports, call
+.PP
+.Vb 1
+\& perl t/harness
+.Ve
+.PP
+The report with \fIio/pipe.t\fR failing may look like this:
+.PP
+.Vb 6
+\& Failed Test Status Wstat Total Fail Failed List of failed
+\& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+\& io/pipe.t 12 1 8.33% 9
+\& 7 tests skipped, plus 56 subtests skipped.
+\& Failed 1/195 test scripts, 99.49% okay. 1/6542 subtests failed,
+\& 99.98% okay.
+.Ve
+.PP
+The reasons for most important skipped tests are:
+.IP "\fIop/fs.t\fR" 8
+.IX Item "op/fs.t"
+.RS 8
+.PD 0
+.IP "18" 4
+.IX Item "18"
+.PD
+Checks \f(CW\*(C`atime\*(C'\fR and \f(CW\*(C`mtime\*(C'\fR of \f(CW\*(C`stat()\*(C'\fR \- unfortunately, \s-1HPFS\s0
+provides only 2sec time granularity (for compatibility with \s-1FAT\s0?).
+.IP "25" 4
+.IX Item "25"
+Checks \f(CW\*(C`truncate()\*(C'\fR on a filehandle just opened for write \- I do not
+know why this should or should not work.
+.RE
+.RS 8
+.RE
+.IP "\fIop/stat.t\fR" 8
+.IX Item "op/stat.t"
+Checks \f(CW\*(C`stat()\*(C'\fR. Tests:
+.RS 8
+.IP "4" 4
+.IX Item "4"
+Checks \f(CW\*(C`atime\*(C'\fR and \f(CW\*(C`mtime\*(C'\fR of \f(CW\*(C`stat()\*(C'\fR \- unfortunately, \s-1HPFS\s0
+provides only 2sec time granularity (for compatibility with \s-1FAT\s0?).
+.RE
+.RS 8
+.RE
+.SS "Installing the built perl"
+.IX Subsection "Installing the built perl"
+If you haven't yet moved \f(CW\*(C`perl*.dll\*(C'\fR onto \s-1LIBPATH,\s0 do it now.
+.PP
+Run
+.PP
+.Vb 1
+\& make install
+.Ve
+.PP
+It would put the generated files into needed locations. Manually put
+\&\fIperl.exe\fR, \fIperl_\|_.exe\fR and \fIperl_\|_\|_.exe\fR to a location on your
+\&\s-1PATH,\s0 \fIperl.dll\fR to a location on your \s-1LIBPATH.\s0
+.PP
+Run
+.PP
+.Vb 1
+\& make installcmd INSTALLCMDDIR=d:/ir/on/path
+.Ve
+.PP
+to convert perl utilities to \fI.cmd\fR files and put them on
+\&\s-1PATH.\s0 You need to put \fI.EXE\fR\-utilities on path manually. They are
+installed in \f(CW\*(C`$prefix/bin\*(C'\fR, here \f(CW$prefix\fR is what you gave to
+\&\fIConfigure\fR, see \*(L"Making\*(R".
+.PP
+If you use \f(CW\*(C`man\*(C'\fR, either move the installed \fI*/man/\fR directories to
+your \f(CW\*(C`MANPATH\*(C'\fR, or modify \f(CW\*(C`MANPATH\*(C'\fR to match the location. (One
+could have avoided this by providing a correct \f(CW\*(C`manpath\*(C'\fR option to
+\&\fI./Configure\fR, or editing \fI./config.sh\fR between configuring and
+making steps.)
+.ie n .SS """a.out""\-style build"
+.el .SS "\f(CWa.out\fP\-style build"
+.IX Subsection "a.out-style build"
+Proceed as above, but make \fIperl_.exe\fR (see "\fIperl_.exe\fR") by
+.PP
+.Vb 1
+\& make perl_
+.Ve
+.PP
+test and install by
+.PP
+.Vb 2
+\& make aout_test
+\& make aout_install
+.Ve
+.PP
+Manually put \fIperl_.exe\fR to a location on your \s-1PATH.\s0
+.PP
+\&\fBNote.\fR The build process for \f(CW\*(C`perl_\*(C'\fR \fIdoes not know\fR about all the
+dependencies, so you should make sure that anything is up-to-date,
+say, by doing
+.PP
+.Vb 1
+\& make perl_dll
+.Ve
+.PP
+first.
+.SH "Building a binary distribution"
+.IX Header "Building a binary distribution"
+[This section provides a short overview only...]
+.PP
+Building should proceed differently depending on whether the version of perl
+you install is already present and used on your system, or is a new version
+not yet used. The description below assumes that the version is new, so
+installing its DLLs and \fI.pm\fR files will not disrupt the operation of your
+system even if some intermediate steps are not yet fully working.
+.PP
+The other cases require a little bit more convoluted procedures. Below I
+suppose that the current version of Perl is \f(CW5.8.2\fR, so the executables are
+named accordingly.
+.IP "1." 4
+Fully build and test the Perl distribution. Make sure that no tests are
+failing with \f(CW\*(C`test\*(C'\fR and \f(CW\*(C`aout_test\*(C'\fR targets; fix the bugs in Perl and
+the Perl test suite detected by these tests. Make sure that \f(CW\*(C`all_test\*(C'\fR
+make target runs as clean as possible. Check that \fIos2/perlrexx.cmd\fR
+runs fine.
+.IP "2." 4
+Fully install Perl, including \f(CW\*(C`installcmd\*(C'\fR target. Copy the generated DLLs
+to \f(CW\*(C`LIBPATH\*(C'\fR; copy the numbered Perl executables (as in \fIperl5.8.2.exe\fR)
+to \f(CW\*(C`PATH\*(C'\fR; copy \f(CW\*(C`perl_.exe\*(C'\fR to \f(CW\*(C`PATH\*(C'\fR as \f(CW\*(C`perl_5.8.2.exe\*(C'\fR. Think whether
+you need backward-compatibility DLLs. In most cases you do not need to install
+them yet; but sometime this may simplify the following steps.
+.IP "3." 4
+Make sure that \f(CW\*(C`CPAN.pm\*(C'\fR can download files from \s-1CPAN.\s0 If not, you may need
+to manually install \f(CW\*(C`Net::FTP\*(C'\fR.
+.IP "4." 4
+Install the bundle \f(CW\*(C`Bundle::OS2_default\*(C'\fR
+.Sp
+.Vb 1
+\& perl5.8.2 \-MCPAN \-e "install Bundle::OS2_default" < nul |& tee 00cpan_i_1
+.Ve
+.Sp
+This may take a couple of hours on 1GHz processor (when run the first time).
+And this should not be necessarily a smooth procedure. Some modules may not
+specify required dependencies, so one may need to repeat this procedure several
+times until the results stabilize.
+.Sp
+.Vb 2
+\& perl5.8.2 \-MCPAN \-e "install Bundle::OS2_default" < nul |& tee 00cpan_i_2
+\& perl5.8.2 \-MCPAN \-e "install Bundle::OS2_default" < nul |& tee 00cpan_i_3
+.Ve
+.Sp
+Even after they stabilize, some tests may fail.
+.Sp
+Fix as many discovered bugs as possible. Document all the bugs which are not
+fixed, and all the failures with unknown reasons. Inspect the produced logs
+\&\fI00cpan_i_1\fR to find suspiciously skipped tests, and other fishy events.
+.Sp
+Keep in mind that \fIinstallation\fR of some modules may fail too: for example,
+the DLLs to update may be already loaded by \fI\s-1CPAN\s0.pm\fR. Inspect the \f(CW\*(C`install\*(C'\fR
+logs (in the example above \fI00cpan_i_1\fR etc) for errors, and install things
+manually, as in
+.Sp
+.Vb 2
+\& cd $CPANHOME/.cpan/build/Digest\-MD5\-2.31
+\& make install
+.Ve
+.Sp
+Some distributions may fail some tests, but you may want to install them
+anyway (as above, or via \f(CW\*(C`force install\*(C'\fR command of \f(CW\*(C`CPAN.pm\*(C'\fR shell-mode).
+.Sp
+Since this procedure may take quite a long time to complete, it makes sense
+to \*(L"freeze\*(R" your \s-1CPAN\s0 configuration by disabling periodic updates of the
+local copy of \s-1CPAN\s0 index: set \f(CW\*(C`index_expire\*(C'\fR to some big value (I use 365),
+then save the settings
+.Sp
+.Vb 2
+\& CPAN> o conf index_expire 365
+\& CPAN> o conf commit
+.Ve
+.Sp
+Reset back to the default value \f(CW1\fR when you are finished.
+.IP "5." 4
+When satisfied with the results, rerun the \f(CW\*(C`installcmd\*(C'\fR target. Now you
+can copy \f(CW\*(C`perl5.8.2.exe\*(C'\fR to \f(CW\*(C`perl.exe\*(C'\fR, and install the other OMF-build
+executables: \f(CW\*(C`perl_\|_.exe\*(C'\fR etc. They are ready to be used.
+.IP "6." 4
+Change to the \f(CW\*(C`./pod\*(C'\fR directory of the build tree, download the Perl logo
+\&\fICamelGrayBig.BMP\fR, and run
+.Sp
+.Vb 2
+\& ( perl2ipf > perl.ipf ) |& tee 00ipf
+\& ipfc /INF perl.ipf |& tee 00inf
+.Ve
+.Sp
+This produces the Perl docs online book \f(CW\*(C`perl.INF\*(C'\fR. Install in on
+\&\f(CW\*(C`BOOKSHELF\*(C'\fR path.
+.IP "7." 4
+Now is the time to build statically linked executable \fIperl_.exe\fR which
+includes newly-installed via \f(CW\*(C`Bundle::OS2_default\*(C'\fR modules. Doing testing
+via \f(CW\*(C`CPAN.pm\*(C'\fR is going to be painfully slow, since it statically links
+a new executable per \s-1XS\s0 extension.
+.Sp
+Here is a possible workaround: create a toplevel \fIMakefile.PL\fR in
+\&\fI\f(CI$CPANHOME\fI/.cpan/build/\fR with contents being (compare with \*(L"Making
+executables with a custom collection of statically loaded extensions\*(R")
+.Sp
+.Vb 2
+\& use ExtUtils::MakeMaker;
+\& WriteMakefile NAME => \*(Aqdummy\*(Aq;
+.Ve
+.Sp
+execute this as
+.Sp
+.Vb 2
+\& perl_5.8.2.exe Makefile.PL <nul |& tee 00aout_c1
+\& make \-k all test <nul |& 00aout_t1
+.Ve
+.Sp
+Again, this procedure should not be absolutely smooth. Some \f(CW\*(C`Makefile.PL\*(C'\fR's
+in subdirectories may be buggy, and would not run as \*(L"child\*(R" scripts. The
+interdependency of modules can strike you; however, since non-XS modules
+are already installed, the prerequisites of most modules have a very good
+chance to be present.
+.Sp
+If you discover some glitches, move directories of problematic modules to a
+different location; if these modules are non-XS modules, you may just ignore
+them \- they are already installed; the remaining, \s-1XS,\s0 modules you need to
+install manually one by one.
+.Sp
+After each such removal you need to rerun the \f(CW\*(C`Makefile.PL\*(C'\fR/\f(CW\*(C`make\*(C'\fR process;
+usually this procedure converges soon. (But be sure to convert all the
+necessary external C libraries from \fI.lib\fR format to \fI.a\fR format: run one of
+.Sp
+.Vb 2
+\& emxaout foo.lib
+\& emximp \-o foo.a foo.lib
+.Ve
+.Sp
+whichever is appropriate.) Also, make sure that the DLLs for external
+libraries are usable with executables compiled without \f(CW\*(C`\-Zmtd\*(C'\fR options.
+.Sp
+When you are sure that only a few subdirectories
+lead to failures, you may want to add \f(CW\*(C`\-j4\*(C'\fR option to \f(CW\*(C`make\*(C'\fR to speed up
+skipping subdirectories with already finished build.
+.Sp
+When you are satisfied with the results of tests, install the build C libraries
+for extensions:
+.Sp
+.Vb 1
+\& make install |& tee 00aout_i
+.Ve
+.Sp
+Now you can rename the file \fI./perl.exe\fR generated during the last phase
+to \fIperl_5.8.2.exe\fR; place it on \f(CW\*(C`PATH\*(C'\fR; if there is an inter-dependency
+between some \s-1XS\s0 modules, you may need to repeat the \f(CW\*(C`test\*(C'\fR/\f(CW\*(C`install\*(C'\fR loop
+with this new executable and some excluded modules \- until the procedure
+converges.
+.Sp
+Now you have all the necessary \fI.a\fR libraries for these Perl modules in the
+places where Perl builder can find it. Use the perl builder: change to an
+empty directory, create a \*(L"dummy\*(R" \fIMakefile.PL\fR again, and run
+.Sp
+.Vb 2
+\& perl_5.8.2.exe Makefile.PL |& tee 00c
+\& make perl |& tee 00p
+.Ve
+.Sp
+This should create an executable \fI./perl.exe\fR with all the statically loaded
+extensions built in. Compare the generated \fIperlmain.c\fR files to make sure
+that during the iterations the number of loaded extensions only increases.
+Rename \fI./perl.exe\fR to \fIperl_5.8.2.exe\fR on \f(CW\*(C`PATH\*(C'\fR.
+.Sp
+When it converges, you got a functional variant of \fIperl_5.8.2.exe\fR; copy it
+to \f(CW\*(C`perl_.exe\*(C'\fR. You are done with generation of the local Perl installation.
+.IP "8." 4
+Make sure that the installed modules are actually installed in the location
+of the new Perl, and are not inherited from entries of \f(CW@INC\fR given for
+inheritance from the older versions of Perl: set \f(CW\*(C`PERLLIB_582_PREFIX\*(C'\fR to
+redirect the new version of Perl to a new location, and copy the installed
+files to this new location. Redo the tests to make sure that the versions of
+modules inherited from older versions of Perl are not needed.
+.Sp
+Actually, the log output of \fBpod2ipf\fR\|(1) during the step 6 gives a very detailed
+info about which modules are loaded from which place; so you may use it as
+an additional verification tool.
+.Sp
+Check that some temporary files did not make into the perl install tree.
+Run something like this
+.Sp
+.Vb 1
+\& pfind . \-f "!(/\e.(pm|pl|ix|al|h|a|lib|txt|pod|imp|bs|dll|ld|bs|inc|xbm|yml|cgi|uu|e2x|skip|packlist|eg|cfg|html|pub|enc|all|ini|po|pot)$/i or /^\ew+$/") | less
+.Ve
+.Sp
+in the install tree (both top one and \fIsitelib\fR one).
+.Sp
+Compress all the DLLs with \fIlxlite\fR. The tiny \fI.exe\fR can be compressed with
+\&\f(CW\*(C`/c:max\*(C'\fR (the bug only appears when there is a fixup in the last 6 bytes of a
+page (?); since the tiny executables are much smaller than a page, the bug
+will not hit). Do not compress \f(CW\*(C`perl_.exe\*(C'\fR \- it would not work under \s-1DOS.\s0
+.IP "9." 4
+Now you can generate the binary distribution. This is done by running the
+test of the \s-1CPAN\s0 distribution \f(CW\*(C`OS2::SoftInstaller\*(C'\fR. Tune up the file
+\&\fItest.pl\fR to suit the layout of current version of Perl first. Do not
+forget to pack the necessary external DLLs accordingly. Include the
+description of the bugs and test suite failures you could not fix. Include
+the small-stack versions of Perl executables from Perl build directory.
+.Sp
+Include \fIperl5.def\fR so that people can relink the perl \s-1DLL\s0 preserving
+the binary compatibility, or can create compatibility DLLs. Include the diff
+files (\f(CW\*(C`diff \-pu old new\*(C'\fR) of fixes you did so that people can rebuild your
+version. Include \fIperl5.map\fR so that one can use remote debugging.
+.IP "10." 4
+Share what you did with the other people. Relax. Enjoy fruits of your work.
+.IP "11." 4
+Brace yourself for thanks, bug reports, hate mail and spam coming as result
+of the previous step. No good deed should remain unpunished!
+.SH "Building custom \fI.EXE\fP files"
+.IX Header "Building custom .EXE files"
+The Perl executables can be easily rebuilt at any moment. Moreover, one can
+use the \fIembedding\fR interface (see perlembed) to make very customized
+executables.
+.SS "Making executables with a custom collection of statically loaded extensions"
+.IX Subsection "Making executables with a custom collection of statically loaded extensions"
+It is a little bit easier to do so while \fIdecreasing\fR the list of statically
+loaded extensions. We discuss this case only here.
+.IP "1." 4
+Change to an empty directory, and create a placeholder <Makefile.PL>:
+.Sp
+.Vb 2
+\& use ExtUtils::MakeMaker;
+\& WriteMakefile NAME => \*(Aqdummy\*(Aq;
+.Ve
+.IP "2." 4
+Run it with the flavor of Perl (\fIperl.exe\fR or \fIperl_.exe\fR) you want to
+rebuild.
+.Sp
+.Vb 1
+\& perl_ Makefile.PL
+.Ve
+.IP "3." 4
+Ask it to create new Perl executable:
+.Sp
+.Vb 1
+\& make perl
+.Ve
+.Sp
+(you may need to manually add \f(CW\*(C`PERLTYPE=\-DPERL_CORE\*(C'\fR to this commandline on
+some versions of Perl; the symptom is that the command-line globbing does not
+work from \s-1OS/2\s0 shells with the newly-compiled executable; check with
+.Sp
+.Vb 1
+\& .\eperl.exe \-wle "print for @ARGV" *
+.Ve
+.Sp
+).
+.IP "4." 4
+The previous step created \fIperlmain.c\fR which contains a list of \fBnewXS()\fR calls
+near the end. Removing unnecessary calls, and rerunning
+.Sp
+.Vb 1
+\& make perl
+.Ve
+.Sp
+will produce a customized executable.
+.SS "Making executables with a custom search-paths"
+.IX Subsection "Making executables with a custom search-paths"
+The default perl executable is flexible enough to support most usages.
+However, one may want something yet more flexible; for example, one may want
+to find Perl \s-1DLL\s0 relatively to the location of the \s-1EXE\s0 file; or one may want
+to ignore the environment when setting the Perl-library search patch, etc.
+.PP
+If you fill comfortable with \fIembedding\fR interface (see perlembed), such
+things are easy to do repeating the steps outlined in \*(L"Making
+executables with a custom collection of statically loaded extensions\*(R", and
+doing more comprehensive edits to \fBmain()\fR of \fIperlmain.c\fR. The people with
+little desire to understand Perl can just rename \fBmain()\fR, and do necessary
+modification in a custom \fBmain()\fR which calls the renamed function in appropriate
+time.
+.PP
+However, there is a third way: perl \s-1DLL\s0 exports the \fBmain()\fR function and several
+callbacks to customize the search path. Below is a complete example of a
+\&\*(L"Perl loader\*(R" which
+.IP "1." 4
+Looks for Perl \s-1DLL\s0 in the directory \f(CW\*(C`$exedir/../dll\*(C'\fR;
+.IP "2." 4
+Prepends the above directory to \f(CW\*(C`BEGINLIBPATH\*(C'\fR;
+.IP "3." 4
+Fails if the Perl \s-1DLL\s0 found via \f(CW\*(C`BEGINLIBPATH\*(C'\fR is different from what was
+loaded on step 1; e.g., another process could have loaded it from \f(CW\*(C`LIBPATH\*(C'\fR
+or from a different value of \f(CW\*(C`BEGINLIBPATH\*(C'\fR. In these cases one needs to
+modify the setting of the system so that this other process either does not
+run, or loads the \s-1DLL\s0 from \f(CW\*(C`BEGINLIBPATH\*(C'\fR with \f(CW\*(C`LIBPATHSTRICT=T\*(C'\fR (available
+with kernels after September 2000).
+.IP "4." 4
+Loads Perl library from \f(CW\*(C`$exedir/../dll/lib/\*(C'\fR.
+.IP "5." 4
+Uses Bourne shell from \f(CW\*(C`$exedir/../dll/sh/ksh.exe\*(C'\fR.
+.PP
+For best results compile the C file below with the same options as the Perl
+\&\s-1DLL.\s0 However, a lot of functionality will work even if the executable is not
+an \s-1EMX\s0 applications, e.g., if compiled with
+.PP
+.Vb 2
+\& gcc \-Wall \-DDOSISH \-DOS2=1 \-O2 \-s \-Zomf \-Zsys perl\-starter.c \e
+\& \-DPERL_DLL_BASENAME=\e"perl312F\e" \-Zstack 8192 \-Zlinker /PM:VIO
+.Ve
+.PP
+Here is the sample C file:
+.PP
+.Vb 6
+\& #define INCL_DOS
+\& #define INCL_NOPM
+\& /* These are needed for compile if os2.h includes os2tk.h, not
+\& * os2emx.h */
+\& #define INCL_DOSPROCESS
+\& #include <os2.h>
+\&
+\& #include "EXTERN.h"
+\& #define PERL_IN_MINIPERLMAIN_C
+\& #include "perl.h"
+\&
+\& static char *me;
+\& HMODULE handle;
+\&
+\& static void
+\& die_with(char *msg1, char *msg2, char *msg3, char *msg4)
+\& {
+\& ULONG c;
+\& char *s = " error: ";
+\&
+\& DosWrite(2, me, strlen(me), &c);
+\& DosWrite(2, s, strlen(s), &c);
+\& DosWrite(2, msg1, strlen(msg1), &c);
+\& DosWrite(2, msg2, strlen(msg2), &c);
+\& DosWrite(2, msg3, strlen(msg3), &c);
+\& DosWrite(2, msg4, strlen(msg4), &c);
+\& DosWrite(2, "\er\en", 2, &c);
+\& exit(255);
+\& }
+\&
+\& typedef ULONG (*fill_extLibpath_t)(int type,
+\& char *pre,
+\& char *post,
+\& int replace,
+\& char *msg);
+\& typedef int (*main_t)(int type, char *argv[], char *env[]);
+\& typedef int (*handler_t)(void* data, int which);
+\&
+\& #ifndef PERL_DLL_BASENAME
+\& # define PERL_DLL_BASENAME "perl"
+\& #endif
+\&
+\& static HMODULE
+\& load_perl_dll(char *basename)
+\& {
+\& char buf[300], fail[260];
+\& STRLEN l, dirl;
+\& fill_extLibpath_t f;
+\& ULONG rc_fullname;
+\& HMODULE handle, handle1;
+\&
+\& if (_execname(buf, sizeof(buf) \- 13) != 0)
+\& die_with("Can\*(Aqt find full path: ", strerror(errno), "", "");
+\& /* XXXX Fill \*(Aqme\*(Aq with new value */
+\& l = strlen(buf);
+\& while (l && buf[l\-1] != \*(Aq/\*(Aq && buf[l\-1] != \*(Aq\e\e\*(Aq)
+\& l\-\-;
+\& dirl = l \- 1;
+\& strcpy(buf + l, basename);
+\& l += strlen(basename);
+\& strcpy(buf + l, ".dll");
+\& if ( (rc_fullname = DosLoadModule(fail, sizeof fail, buf, &handle))
+\& != 0
+\& && DosLoadModule(fail, sizeof fail, basename, &handle) != 0 )
+\& die_with("Can\*(Aqt load DLL ", buf, "", "");
+\& if (rc_fullname)
+\& return handle; /* was loaded with short name; all is fine */
+\& if (DosQueryProcAddr(handle, 0, "fill_extLibpath", (PFN*)&f))
+\& die_with(buf,
+\& ": DLL exports no symbol ",
+\& "fill_extLibpath",
+\& "");
+\& buf[dirl] = 0;
+\& if (f(0 /*BEGINLIBPATH*/, buf /* prepend */, NULL /* append */,
+\& 0 /* keep old value */, me))
+\& die_with(me, ": prepending BEGINLIBPATH", "", "");
+\& if (DosLoadModule(fail, sizeof fail, basename, &handle1) != 0)
+\& die_with(me,
+\& ": finding perl DLL again via BEGINLIBPATH",
+\& "",
+\& "");
+\& buf[dirl] = \*(Aq\e\e\*(Aq;
+\& if (handle1 != handle) {
+\& if (DosQueryModuleName(handle1, sizeof(fail), fail))
+\& strcpy(fail, "???");
+\& die_with(buf,
+\& ":\en\etperl DLL via BEGINLIBPATH is different: \en\et",
+\& fail,
+\& "\en\etYou may need to manipulate global BEGINLIBPATH"
+\& " and LIBPATHSTRICT"
+\& "\en\etso that the other copy is loaded via"
+\& BEGINLIBPATH.");
+\& }
+\& return handle;
+\& }
+\&
+\& int
+\& main(int argc, char **argv, char **env)
+\& {
+\& main_t f;
+\& handler_t h;
+\&
+\& me = argv[0];
+\& /**/
+\& handle = load_perl_dll(PERL_DLL_BASENAME);
+\&
+\& if (DosQueryProcAddr(handle,
+\& 0,
+\& "Perl_OS2_handler_install",
+\& (PFN*)&h))
+\& die_with(PERL_DLL_BASENAME,
+\& ": DLL exports no symbol ",
+\& "Perl_OS2_handler_install",
+\& "");
+\& if ( !h((void *)"~installprefix", Perlos2_handler_perllib_from)
+\& || !h((void *)"~dll", Perlos2_handler_perllib_to)
+\& || !h((void *)"~dll/sh/ksh.exe", Perlos2_handler_perl_sh) )
+\& die_with(PERL_DLL_BASENAME,
+\& ": Can\*(Aqt install @INC manglers",
+\& "",
+\& "");
+\& if (DosQueryProcAddr(handle, 0, "dll_perlmain", (PFN*)&f))
+\& die_with(PERL_DLL_BASENAME,
+\& ": DLL exports no symbol ",
+\& "dll_perlmain",
+\& "");
+\& return f(argc, argv, env);
+\& }
+.Ve
+.SH "Build FAQ"
+.IX Header "Build FAQ"
+.ie n .SS "Some ""/"" became ""\e"" in pdksh."
+.el .SS "Some \f(CW/\fP became \f(CW\e\fP in pdksh."
+.IX Subsection "Some / became in pdksh."
+You have a very old pdksh. See \*(L"Prerequisites\*(R".
+.ie n .SS "\*(Aqerrno\*(Aq \- unresolved external"
+.el .SS "\f(CW\*(Aqerrno\*(Aq\fP \- unresolved external"
+.IX Subsection "errno - unresolved external"
+You do not have MT-safe \fIdb.lib\fR. See \*(L"Prerequisites\*(R".
+.SS "Problems with tr or sed"
+.IX Subsection "Problems with tr or sed"
+reported with very old version of tr and sed.
+.SS "Some problem (forget which ;\-)"
+.IX Subsection "Some problem (forget which ;-)"
+You have an older version of \fIperl.dll\fR on your \s-1LIBPATH,\s0 which
+broke the build of extensions.
+.SS "Library ... not found"
+.IX Subsection "Library ... not found"
+You did not run \f(CW\*(C`omflibs\*(C'\fR. See \*(L"Prerequisites\*(R".
+.SS "Segfault in make"
+.IX Subsection "Segfault in make"
+You use an old version of \s-1GNU\s0 make. See \*(L"Prerequisites\*(R".
+.SS "op/sprintf test failure"
+.IX Subsection "op/sprintf test failure"
+This can result from a bug in emx sprintf which was fixed in 0.9d fix 03.
+.SH "Specific (mis)features of OS/2 port"
+.IX Header "Specific (mis)features of OS/2 port"
+.ie n .SS """setpriority"", ""getpriority"""
+.el .SS "\f(CWsetpriority\fP, \f(CWgetpriority\fP"
+.IX Subsection "setpriority, getpriority"
+Note that these functions are compatible with *nix, not with the older
+ports of '94 \- 95. The priorities are absolute, go from 32 to \-95,
+lower is quicker. 0 is the default priority.
+.PP
+\&\fB\s-1WARNING\s0\fR. Calling \f(CW\*(C`getpriority\*(C'\fR on a non-existing process could lock
+the system before Warp3 fixpak22. Starting with Warp3, Perl will use
+a workaround: it aborts \fBgetpriority()\fR if the process is not present.
+This is not possible on older versions \f(CW\*(C`2.*\*(C'\fR, and has a race
+condition anyway.
+.ie n .SS """system()"""
+.el .SS "\f(CWsystem()\fP"
+.IX Subsection "system()"
+Multi-argument form of \f(CW\*(C`system()\*(C'\fR allows an additional numeric
+argument. The meaning of this argument is described in
+OS2::Process.
+.PP
+When finding a program to run, Perl first asks the \s-1OS\s0 to look for executables
+on \f(CW\*(C`PATH\*(C'\fR (\s-1OS/2\s0 adds extension \fI.exe\fR if no extension is present).
+If not found, it looks for a script with possible extensions
+added in this order: no extension, \fI.cmd\fR, \fI.btm\fR,
+\&\fI.bat\fR, \fI.pl\fR. If found, Perl checks the start of the file for magic
+strings \f(CW"#!"\fR and \f(CW"extproc "\fR. If found, Perl uses the rest of the
+first line as the beginning of the command line to run this script. The
+only mangling done to the first line is extraction of arguments (currently
+up to 3), and ignoring of the path-part of the \*(L"interpreter\*(R" name if it can't
+be found using the full path.
+.PP
+E.g., \f(CW\*(C`system \*(Aqfoo\*(Aq, \*(Aqbar\*(Aq, \*(Aqbaz\*(Aq\*(C'\fR may lead Perl to finding
+\&\fIC:/emx/bin/foo.cmd\fR with the first line being
+.PP
+.Vb 1
+\& extproc /bin/bash \-x \-c
+.Ve
+.PP
+If \fI/bin/bash.exe\fR is not found, then Perl looks for an executable \fIbash.exe\fR on
+\&\f(CW\*(C`PATH\*(C'\fR. If found in \fIC:/emx.add/bin/bash.exe\fR, then the above \fBsystem()\fR is
+translated to
+.PP
+.Vb 1
+\& system qw(C:/emx.add/bin/bash.exe \-x \-c C:/emx/bin/foo.cmd bar baz)
+.Ve
+.PP
+One additional translation is performed: instead of \fI/bin/sh\fR Perl uses
+the hardwired-or-customized shell (see "\f(CW\*(C`PERL_SH_DIR\*(C'\fR").
+.PP
+The above search for \*(L"interpreter\*(R" is recursive: if \fIbash\fR executable is not
+found, but \fIbash.btm\fR is found, Perl will investigate its first line etc.
+The only hardwired limit on the recursion depth is implicit: there is a limit
+4 on the number of additional arguments inserted before the actual arguments
+given to \fBsystem()\fR. In particular, if no additional arguments are specified
+on the \*(L"magic\*(R" first lines, then the limit on the depth is 4.
+.PP
+If Perl finds that the found executable is of \s-1PM\s0 type when the
+current session is not, it will start the new process in a separate session of
+necessary type. Call via \f(CW\*(C`OS2::Process\*(C'\fR to disable this magic.
+.PP
+\&\fB\s-1WARNING\s0\fR. Due to the described logic, you need to explicitly
+specify \fI.com\fR extension if needed. Moreover, if the executable
+\&\fIperl5.6.1\fR is requested, Perl will not look for \fIperl5.6.1.exe\fR.
+[This may change in the future.]
+.ie n .SS """extproc"" on the first line"
+.el .SS "\f(CWextproc\fP on the first line"
+.IX Subsection "extproc on the first line"
+If the first chars of a Perl script are \f(CW"extproc "\fR, this line is treated
+as \f(CW\*(C`#!\*(C'\fR\-line, thus all the switches on this line are processed (twice
+if script was started via cmd.exe). See \*(L"\s-1DESCRIPTION\*(R"\s0 in perlrun.
+.SS "Additional modules:"
+.IX Subsection "Additional modules:"
+OS2::Process, \s-1OS2::DLL\s0, \s-1OS2::REXX\s0, OS2::PrfDB, OS2::ExtAttr. These
+modules provide access to additional numeric argument for \f(CW\*(C`system\*(C'\fR
+and to the information about the running process,
+to DLLs having functions with \s-1REXX\s0 signature and to the \s-1REXX\s0 runtime, to
+\&\s-1OS/2\s0 databases in the \fI.INI\fR format, and to Extended Attributes.
+.PP
+Two additional extensions by Andreas Kaiser, \f(CW\*(C`OS2::UPM\*(C'\fR, and
+\&\f(CW\*(C`OS2::FTP\*(C'\fR, are included into \f(CW\*(C`ILYAZ\*(C'\fR directory, mirrored on \s-1CPAN.\s0
+Other OS/2\-related extensions are available too.
+.SS "Prebuilt methods:"
+.IX Subsection "Prebuilt methods:"
+.ie n .IP """File::Copy::syscopy""" 4
+.el .IP "\f(CWFile::Copy::syscopy\fR" 4
+.IX Item "File::Copy::syscopy"
+used by \f(CW\*(C`File::Copy::copy\*(C'\fR, see File::Copy.
+.ie n .IP """DynaLoader::mod2fname""" 4
+.el .IP "\f(CWDynaLoader::mod2fname\fR" 4
+.IX Item "DynaLoader::mod2fname"
+used by \f(CW\*(C`DynaLoader\*(C'\fR for \s-1DLL\s0 name mangling.
+.ie n .IP """Cwd::current_drive()""" 4
+.el .IP "\f(CWCwd::current_drive()\fR" 4
+.IX Item "Cwd::current_drive()"
+Self explanatory.
+.ie n .IP """Cwd::sys_chdir(name)""" 4
+.el .IP "\f(CWCwd::sys_chdir(name)\fR" 4
+.IX Item "Cwd::sys_chdir(name)"
+leaves drive as it is.
+.ie n .IP """Cwd::change_drive(name)""" 4
+.el .IP "\f(CWCwd::change_drive(name)\fR" 4
+.IX Item "Cwd::change_drive(name)"
+changes the \*(L"current\*(R" drive.
+.ie n .IP """Cwd::sys_is_absolute(name)""" 4
+.el .IP "\f(CWCwd::sys_is_absolute(name)\fR" 4
+.IX Item "Cwd::sys_is_absolute(name)"
+means has drive letter and is_rooted.
+.ie n .IP """Cwd::sys_is_rooted(name)""" 4
+.el .IP "\f(CWCwd::sys_is_rooted(name)\fR" 4
+.IX Item "Cwd::sys_is_rooted(name)"
+means has leading \f(CW\*(C`[/\e\e]\*(C'\fR (maybe after a drive-letter:).
+.ie n .IP """Cwd::sys_is_relative(name)""" 4
+.el .IP "\f(CWCwd::sys_is_relative(name)\fR" 4
+.IX Item "Cwd::sys_is_relative(name)"
+means changes with current dir.
+.ie n .IP """Cwd::sys_cwd(name)""" 4
+.el .IP "\f(CWCwd::sys_cwd(name)\fR" 4
+.IX Item "Cwd::sys_cwd(name)"
+Interface to cwd from \s-1EMX.\s0 Used by \f(CW\*(C`Cwd::cwd\*(C'\fR.
+.ie n .IP """Cwd::sys_abspath(name, dir)""" 4
+.el .IP "\f(CWCwd::sys_abspath(name, dir)\fR" 4
+.IX Item "Cwd::sys_abspath(name, dir)"
+Really really odious function to implement. Returns absolute name of
+file which would have \f(CW\*(C`name\*(C'\fR if \s-1CWD\s0 were \f(CW\*(C`dir\*(C'\fR. \f(CW\*(C`Dir\*(C'\fR defaults to the
+current dir.
+.ie n .IP """Cwd::extLibpath([type])""" 4
+.el .IP "\f(CWCwd::extLibpath([type])\fR" 4
+.IX Item "Cwd::extLibpath([type])"
+Get current value of extended library search path. If \f(CW\*(C`type\*(C'\fR is
+present and positive, works with \f(CW\*(C`END_LIBPATH\*(C'\fR, if negative, works
+with \f(CW\*(C`LIBPATHSTRICT\*(C'\fR, otherwise with \f(CW\*(C`BEGIN_LIBPATH\*(C'\fR.
+.ie n .IP """Cwd::extLibpath_set( path [, type ] )""" 4
+.el .IP "\f(CWCwd::extLibpath_set( path [, type ] )\fR" 4
+.IX Item "Cwd::extLibpath_set( path [, type ] )"
+Set current value of extended library search path. If \f(CW\*(C`type\*(C'\fR is
+present and positive, works with <\s-1END_LIBPATH\s0>, if negative, works
+with \f(CW\*(C`LIBPATHSTRICT\*(C'\fR, otherwise with \f(CW\*(C`BEGIN_LIBPATH\*(C'\fR.
+.ie n .IP """OS2::Error(do_harderror,do_exception)""" 4
+.el .IP "\f(CWOS2::Error(do_harderror,do_exception)\fR" 4
+.IX Item "OS2::Error(do_harderror,do_exception)"
+Returns \f(CW\*(C`undef\*(C'\fR if it was not called yet, otherwise bit 1 is
+set if on the previous call do_harderror was enabled, bit
+2 is set if on previous call do_exception was enabled.
+.Sp
+This function enables/disables error popups associated with
+hardware errors (Disk not ready etc.) and software exceptions.
+.Sp
+I know of no way to find out the state of popups \fIbefore\fR the first call
+to this function.
+.ie n .IP """OS2::Errors2Drive(drive)""" 4
+.el .IP "\f(CWOS2::Errors2Drive(drive)\fR" 4
+.IX Item "OS2::Errors2Drive(drive)"
+Returns \f(CW\*(C`undef\*(C'\fR if it was not called yet, otherwise return false if errors
+were not requested to be written to a hard drive, or the drive letter if
+this was requested.
+.Sp
+This function may redirect error popups associated with hardware errors
+(Disk not ready etc.) and software exceptions to the file \s-1POPUPLOG.OS2\s0 at
+the root directory of the specified drive. Overrides \fBOS2::Error()\fR specified
+by individual programs. Given argument undef will disable redirection.
+.Sp
+Has global effect, persists after the application exits.
+.Sp
+I know of no way to find out the state of redirection of popups to the disk
+\&\fIbefore\fR the first call to this function.
+.IP "\fBOS2::SysInfo()\fR" 4
+.IX Item "OS2::SysInfo()"
+Returns a hash with system information. The keys of the hash are
+.Sp
+.Vb 8
+\& MAX_PATH_LENGTH, MAX_TEXT_SESSIONS, MAX_PM_SESSIONS,
+\& MAX_VDM_SESSIONS, BOOT_DRIVE, DYN_PRI_VARIATION,
+\& MAX_WAIT, MIN_SLICE, MAX_SLICE, PAGE_SIZE,
+\& VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION,
+\& MS_COUNT, TIME_LOW, TIME_HIGH, TOTPHYSMEM, TOTRESMEM,
+\& TOTAVAILMEM, MAXPRMEM, MAXSHMEM, TIMER_INTERVAL,
+\& MAX_COMP_LENGTH, FOREGROUND_FS_SESSION,
+\& FOREGROUND_PROCESS
+.Ve
+.IP "\fBOS2::BootDrive()\fR" 4
+.IX Item "OS2::BootDrive()"
+Returns a letter without colon.
+.ie n .IP """OS2::MorphPM(serve)"", ""OS2::UnMorphPM(serve)""" 4
+.el .IP "\f(CWOS2::MorphPM(serve)\fR, \f(CWOS2::UnMorphPM(serve)\fR" 4
+.IX Item "OS2::MorphPM(serve), OS2::UnMorphPM(serve)"
+Transforms the current application into a \s-1PM\s0 application and back.
+The argument true means that a real message loop is going to be served.
+\&\fBOS2::MorphPM()\fR returns the \s-1PM\s0 message queue handle as an integer.
+.Sp
+See \*(L"Centralized management of resources\*(R" for additional details.
+.ie n .IP """OS2::Serve_Messages(force)""" 4
+.el .IP "\f(CWOS2::Serve_Messages(force)\fR" 4
+.IX Item "OS2::Serve_Messages(force)"
+Fake on-demand retrieval of outstanding \s-1PM\s0 messages. If \f(CW\*(C`force\*(C'\fR is false,
+will not dispatch messages if a real message loop is known to
+be present. Returns number of messages retrieved.
+.Sp
+Dies with \*(L"QUITing...\*(R" if \s-1WM_QUIT\s0 message is obtained.
+.ie n .IP """OS2::Process_Messages(force [, cnt])""" 4
+.el .IP "\f(CWOS2::Process_Messages(force [, cnt])\fR" 4
+.IX Item "OS2::Process_Messages(force [, cnt])"
+Retrieval of \s-1PM\s0 messages until window creation/destruction.
+If \f(CW\*(C`force\*(C'\fR is false, will not dispatch messages if a real message loop
+is known to be present.
+.Sp
+Returns change in number of windows. If \f(CW\*(C`cnt\*(C'\fR is given,
+it is incremented by the number of messages retrieved.
+.Sp
+Dies with \*(L"QUITing...\*(R" if \s-1WM_QUIT\s0 message is obtained.
+.ie n .IP """OS2::_control87(new,mask)""" 4
+.el .IP "\f(CWOS2::_control87(new,mask)\fR" 4
+.IX Item "OS2::_control87(new,mask)"
+the same as \fB_control87\fR\|(3) of \s-1EMX.\s0 Takes integers as arguments, returns
+the previous coprocessor control word as an integer. Only bits in \f(CW\*(C`new\*(C'\fR which
+are present in \f(CW\*(C`mask\*(C'\fR are changed in the control word.
+.IP "\fBOS2::get_control87()\fR" 4
+.IX Item "OS2::get_control87()"
+gets the coprocessor control word as an integer.
+.ie n .IP """OS2::set_control87_em(new=MCW_EM,mask=MCW_EM)""" 4
+.el .IP "\f(CWOS2::set_control87_em(new=MCW_EM,mask=MCW_EM)\fR" 4
+.IX Item "OS2::set_control87_em(new=MCW_EM,mask=MCW_EM)"
+The variant of \fBOS2::_control87()\fR with default values good for
+handling exception mask: if no \f(CW\*(C`mask\*(C'\fR, uses exception mask part of \f(CW\*(C`new\*(C'\fR
+only. If no \f(CW\*(C`new\*(C'\fR, disables all the floating point exceptions.
+.Sp
+See \*(L"Misfeatures\*(R" for details.
+.ie n .IP """OS2::DLLname([how [, \e&xsub]])""" 4
+.el .IP "\f(CWOS2::DLLname([how [, \e&xsub]])\fR" 4
+.IX Item "OS2::DLLname([how [, &xsub]])"
+Gives the information about the Perl \s-1DLL\s0 or the \s-1DLL\s0 containing the C
+function bound to by \f(CW&xsub\fR. The meaning of \f(CW\*(C`how\*(C'\fR is: default (2):
+full name; 0: handle; 1: module name.
+.PP
+(Note that some of these may be moved to different libraries \-
+eventually).
+.SS "Prebuilt variables:"
+.IX Subsection "Prebuilt variables:"
+.ie n .IP "$OS2::emx_rev" 4
+.el .IP "\f(CW$OS2::emx_rev\fR" 4
+.IX Item "$OS2::emx_rev"
+numeric value is the same as _emx_rev of \s-1EMX,\s0 a string value the same
+as _emx_vprt (similar to \f(CW\*(C`0.9c\*(C'\fR).
+.ie n .IP "$OS2::emx_env" 4
+.el .IP "\f(CW$OS2::emx_env\fR" 4
+.IX Item "$OS2::emx_env"
+same as _emx_env of \s-1EMX,\s0 a number similar to 0x8001.
+.ie n .IP "$OS2::os_ver" 4
+.el .IP "\f(CW$OS2::os_ver\fR" 4
+.IX Item "$OS2::os_ver"
+a number \f(CW\*(C`OS_MAJOR + 0.001 * OS_MINOR\*(C'\fR.
+.ie n .IP "$OS2::is_aout" 4
+.el .IP "\f(CW$OS2::is_aout\fR" 4
+.IX Item "$OS2::is_aout"
+true if the Perl library was compiled in \s-1AOUT\s0 format.
+.ie n .IP "$OS2::can_fork" 4
+.el .IP "\f(CW$OS2::can_fork\fR" 4
+.IX Item "$OS2::can_fork"
+true if the current executable is an \s-1AOUT EMX\s0 executable, so Perl can
+fork. Do not use this, use the portable check for
+\&\f(CW$Config::Config\fR{dfork}.
+.ie n .IP "$OS2::nsyserror" 4
+.el .IP "\f(CW$OS2::nsyserror\fR" 4
+.IX Item "$OS2::nsyserror"
+This variable (default is 1) controls whether to enforce the contents
+of $^E to start with \f(CW\*(C`SYS0003\*(C'\fR\-like id. If set to 0, then the string
+value of $^E is what is available from the \s-1OS/2\s0 message file. (Some
+messages in this file have an \f(CW\*(C`SYS0003\*(C'\fR\-like id prepended, some not.)
+.SS "Misfeatures"
+.IX Subsection "Misfeatures"
+.IP "\(bu" 4
+Since \fBflock\fR\|(3) is present in \s-1EMX,\s0 but is not functional, it is
+emulated by perl. To disable the emulations, set environment variable
+\&\f(CW\*(C`USE_PERL_FLOCK=0\*(C'\fR.
+.IP "\(bu" 4
+Here is the list of things which may be \*(L"broken\*(R" on
+\&\s-1EMX\s0 (from \s-1EMX\s0 docs):
+.RS 4
+.IP "\(bu" 4
+The functions \fBrecvmsg\fR\|(3), \fBsendmsg\fR\|(3), and \fBsocketpair\fR\|(3) are not
+implemented.
+.IP "\(bu" 4
+\&\fBsock_init\fR\|(3) is not required and not implemented.
+.IP "\(bu" 4
+\&\fBflock\fR\|(3) is not yet implemented (dummy function). (Perl has a workaround.)
+.IP "\(bu" 4
+\&\fBkill\fR\|(3): Special treatment of PID=0, PID=1 and PID=\-1 is not implemented.
+.IP "\(bu" 4
+\&\fBwaitpid\fR\|(3):
+.Sp
+.Vb 3
+\& WUNTRACED
+\& Not implemented.
+\& waitpid() is not implemented for negative values of PID.
+.Ve
+.RE
+.RS 4
+.Sp
+Note that \f(CW\*(C`kill \-9\*(C'\fR does not work with the current version of \s-1EMX.\s0
+.RE
+.IP "\(bu" 4
+See \*(L"Text-mode filehandles\*(R".
+.IP "\(bu" 4
+Unix-domain sockets on \s-1OS/2\s0 live in a pseudo-file-system \f(CW\*(C`/sockets/...\*(C'\fR.
+To avoid a failure to create a socket with a name of a different form,
+\&\f(CW"/socket/"\fR is prepended to the socket name (unless it starts with this
+already).
+.Sp
+This may lead to problems later in case the socket is accessed via the
+\&\*(L"usual\*(R" file-system calls using the \*(L"initial\*(R" name.
+.IP "\(bu" 4
+Apparently, \s-1IBM\s0 used a compiler (for some period of time around '95?) which
+changes \s-1FP\s0 mask right and left. This is not \fIthat\fR bad for \s-1IBM\s0's
+programs, but the same compiler was used for DLLs which are used with
+general-purpose applications. When these DLLs are used, the state of
+floating-point flags in the application is not predictable.
+.Sp
+What is much worse, some DLLs change the floating point flags when in
+\&\fB_DLLInitTerm()\fR (e.g., \fI\s-1TCP32IP\s0\fR). This means that even if you do not \fIcall\fR
+any function in the \s-1DLL,\s0 just the act of loading this \s-1DLL\s0 will reset your
+flags. What is worse, the same compiler was used to compile some \s-1HOOK\s0 DLLs.
+Given that \s-1HOOK\s0 dlls are executed in the context of \fIall\fR the applications
+in the system, this means a complete unpredictability of floating point
+flags on systems using such \s-1HOOK\s0 DLLs. E.g., \fI\s-1GAMESRVR.DLL\s0\fR of \fB\s-1DIVE\s0\fR
+origin changes the floating point flags on each write to the \s-1TTY\s0 of a \s-1VIO\s0
+(windowed text-mode) applications.
+.Sp
+Some other (not completely debugged) situations when \s-1FP\s0 flags change include
+some video drivers (?), and some operations related to creation of the windows.
+People who code \fBOpenGL\fR may have more experience on this.
+.Sp
+Perl is generally used in the situation when all the floating-point
+exceptions are ignored, as is the default under \s-1EMX.\s0 If they are not ignored,
+some benign Perl programs would get a \f(CW\*(C`SIGFPE\*(C'\fR and would die a horrible death.
+.Sp
+To circumvent this, Perl uses two hacks. They help against \fIone\fR type of
+damage only: \s-1FP\s0 flags changed when loading a \s-1DLL.\s0
+.Sp
+One of the hacks is to disable floating point exceptions on Perl startup (as
+is the default with \s-1EMX\s0). This helps only with compile-time-linked DLLs
+changing the flags before \fBmain()\fR had a chance to be called.
+.Sp
+The other hack is to restore \s-1FP\s0 flags after a call to \fBdlopen()\fR. This helps
+against similar damage done by DLLs \fB_DLLInitTerm()\fR at runtime. Currently
+no way to switch these hacks off is provided.
+.SS "Modifications"
+.IX Subsection "Modifications"
+Perl modifies some standard C library calls in the following ways:
+.ie n .IP """popen""" 9
+.el .IP "\f(CWpopen\fR" 9
+.IX Item "popen"
+\&\f(CW\*(C`my_popen\*(C'\fR uses \fIsh.exe\fR if shell is required, cf. "\f(CW\*(C`PERL_SH_DIR\*(C'\fR".
+.ie n .IP """tmpnam""" 9
+.el .IP "\f(CWtmpnam\fR" 9
+.IX Item "tmpnam"
+is created using \f(CW\*(C`TMP\*(C'\fR or \f(CW\*(C`TEMP\*(C'\fR environment variable, via
+\&\f(CW\*(C`tempnam\*(C'\fR.
+.ie n .IP """tmpfile""" 9
+.el .IP "\f(CWtmpfile\fR" 9
+.IX Item "tmpfile"
+If the current directory is not writable, file is created using modified
+\&\f(CW\*(C`tmpnam\*(C'\fR, so there may be a race condition.
+.ie n .IP """ctermid""" 9
+.el .IP "\f(CWctermid\fR" 9
+.IX Item "ctermid"
+a dummy implementation.
+.ie n .IP """stat""" 9
+.el .IP "\f(CWstat\fR" 9
+.IX Item "stat"
+\&\f(CW\*(C`os2_stat\*(C'\fR special-cases \fI/dev/tty\fR and \fI/dev/con\fR.
+.ie n .IP """mkdir"", ""rmdir""" 9
+.el .IP "\f(CWmkdir\fR, \f(CWrmdir\fR" 9
+.IX Item "mkdir, rmdir"
+these \s-1EMX\s0 functions do not work if the path contains a trailing \f(CW\*(C`/\*(C'\fR.
+Perl contains a workaround for this.
+.ie n .IP """flock""" 9
+.el .IP "\f(CWflock\fR" 9
+.IX Item "flock"
+Since \fBflock\fR\|(3) is present in \s-1EMX,\s0 but is not functional, it is
+emulated by perl. To disable the emulations, set environment variable
+\&\f(CW\*(C`USE_PERL_FLOCK=0\*(C'\fR.
+.SS "Identifying DLLs"
+.IX Subsection "Identifying DLLs"
+All the DLLs built with the current versions of Perl have \s-1ID\s0 strings
+identifying the name of the extension, its version, and the version
+of Perl required for this \s-1DLL.\s0 Run \f(CW\*(C`bldlevel DLL\-name\*(C'\fR to find this
+info.
+.SS "Centralized management of resources"
+.IX Subsection "Centralized management of resources"
+Since to call certain \s-1OS/2 API\s0 one needs to have a correctly initialized
+\&\f(CW\*(C`Win\*(C'\fR subsystem, OS/2\-specific extensions may require getting \f(CW\*(C`HAB\*(C'\fRs and
+\&\f(CW\*(C`HMQ\*(C'\fRs. If an extension would do it on its own, another extension could
+fail to initialize.
+.PP
+Perl provides a centralized management of these resources:
+.ie n .IP """HAB""" 4
+.el .IP "\f(CWHAB\fR" 4
+.IX Item "HAB"
+To get the \s-1HAB,\s0 the extension should call \f(CW\*(C`hab = perl_hab_GET()\*(C'\fR in C. After
+this call is performed, \f(CW\*(C`hab\*(C'\fR may be accessed as \f(CW\*(C`Perl_hab\*(C'\fR. There is
+no need to release the \s-1HAB\s0 after it is used.
+.Sp
+If by some reasons \fIperl.h\fR cannot be included, use
+.Sp
+.Vb 1
+\& extern int Perl_hab_GET(void);
+.Ve
+.Sp
+instead.
+.ie n .IP """HMQ""" 4
+.el .IP "\f(CWHMQ\fR" 4
+.IX Item "HMQ"
+There are two cases:
+.RS 4
+.IP "\(bu" 4
+the extension needs an \f(CW\*(C`HMQ\*(C'\fR only because some \s-1API\s0 will not work otherwise.
+Use \f(CW\*(C`serve = 0\*(C'\fR below.
+.IP "\(bu" 4
+the extension needs an \f(CW\*(C`HMQ\*(C'\fR since it wants to engage in a \s-1PM\s0 event loop.
+Use \f(CW\*(C`serve = 1\*(C'\fR below.
+.RE
+.RS 4
+.Sp
+To get an \f(CW\*(C`HMQ\*(C'\fR, the extension should call \f(CW\*(C`hmq = perl_hmq_GET(serve)\*(C'\fR in C.
+After this call is performed, \f(CW\*(C`hmq\*(C'\fR may be accessed as \f(CW\*(C`Perl_hmq\*(C'\fR.
+.Sp
+To signal to Perl that \s-1HMQ\s0 is not needed any more, call
+\&\f(CW\*(C`perl_hmq_UNSET(serve)\*(C'\fR. Perl process will automatically morph/unmorph itself
+into/from a \s-1PM\s0 process if \s-1HMQ\s0 is needed/not\-needed. Perl will automatically
+enable/disable \f(CW\*(C`WM_QUIT\*(C'\fR message during shutdown if the message queue is
+served/not\-served.
+.Sp
+\&\fB\s-1NOTE\s0\fR. If during a shutdown there is a message queue which did not disable
+\&\s-1WM_QUIT,\s0 and which did not process the received \s-1WM_QUIT\s0 message, the
+shutdown will be automatically cancelled. Do not call \f(CWperl_hmq_GET(1)\fR
+unless you are going to process messages on an orderly basis.
+.RE
+.IP "Treating errors reported by \s-1OS/2 API\s0" 4
+.IX Item "Treating errors reported by OS/2 API"
+There are two principal conventions (it is useful to call them \f(CW\*(C`Dos*\*(C'\fR
+and \f(CW\*(C`Win*\*(C'\fR \- though this part of the function signature is not always
+determined by the name of the \s-1API\s0) of reporting the error conditions
+of \s-1OS/2 API.\s0 Most of \f(CW\*(C`Dos*\*(C'\fR APIs report the error code as the result
+of the call (so 0 means success, and there are many types of errors).
+Most of \f(CW\*(C`Win*\*(C'\fR \s-1API\s0 report success/fail via the result being
+\&\f(CW\*(C`TRUE\*(C'\fR/\f(CW\*(C`FALSE\*(C'\fR; to find the reason for the failure one should call
+\&\fBWinGetLastError()\fR \s-1API.\s0
+.Sp
+Some \f(CW\*(C`Win*\*(C'\fR entry points also overload a \*(L"meaningful\*(R" return value
+with the error indicator; having a 0 return value indicates an error.
+Yet some other \f(CW\*(C`Win*\*(C'\fR entry points overload things even more, and 0
+return value may mean a successful call returning a valid value 0, as
+well as an error condition; in the case of a 0 return value one should
+call \fBWinGetLastError()\fR \s-1API\s0 to distinguish a successful call from a
+failing one.
+.Sp
+By convention, all the calls to \s-1OS/2 API\s0 should indicate their
+failures by resetting $^E. All the Perl-accessible functions which
+call \s-1OS/2 API\s0 may be broken into two classes: some \fBdie()\fRs when an \s-1API\s0
+error is encountered, the other report the error via a false return
+value (of course, this does not concern Perl-accessible functions
+which \fIexpect\fR a failure of the \s-1OS/2 API\s0 call, having some workarounds
+coded).
+.Sp
+Obviously, in the situation of the last type of the signature of an \s-1OS/2
+API,\s0 it is must more convenient for the users if the failure is
+indicated by \fBdie()\fRing: one does not need to check $^E to know that
+something went wrong. If, however, this solution is not desirable by
+some reason, the code in question should reset $^E to 0 before making
+this \s-1OS/2 API\s0 call, so that the caller of this Perl-accessible
+function has a chance to distinguish a success\-but\-0\-return value from
+a failure. (One may return undef as an alternative way of reporting
+an error.)
+.Sp
+The macros to simplify this type of error propagation are
+.RS 4
+.ie n .IP """CheckOSError(expr)""" 4
+.el .IP "\f(CWCheckOSError(expr)\fR" 4
+.IX Item "CheckOSError(expr)"
+Returns true on error, sets $^E. Expects \fBexpr()\fR be a call of
+\&\f(CW\*(C`Dos*\*(C'\fR\-style \s-1API.\s0
+.ie n .IP """CheckWinError(expr)""" 4
+.el .IP "\f(CWCheckWinError(expr)\fR" 4
+.IX Item "CheckWinError(expr)"
+Returns true on error, sets $^E. Expects \fBexpr()\fR be a call of
+\&\f(CW\*(C`Win*\*(C'\fR\-style \s-1API.\s0
+.ie n .IP """SaveWinError(expr)""" 4
+.el .IP "\f(CWSaveWinError(expr)\fR" 4
+.IX Item "SaveWinError(expr)"
+Returns \f(CW\*(C`expr\*(C'\fR, sets $^E from \fBWinGetLastError()\fR if \f(CW\*(C`expr\*(C'\fR is false.
+.ie n .IP """SaveCroakWinError(expr,die,name1,name2)""" 4
+.el .IP "\f(CWSaveCroakWinError(expr,die,name1,name2)\fR" 4
+.IX Item "SaveCroakWinError(expr,die,name1,name2)"
+Returns \f(CW\*(C`expr\*(C'\fR, sets $^E from \fBWinGetLastError()\fR if \f(CW\*(C`expr\*(C'\fR is false,
+and \fBdie()\fRs if \f(CW\*(C`die\*(C'\fR and $^E are true. The message to die is the
+concatenated strings \f(CW\*(C`name1\*(C'\fR and \f(CW\*(C`name2\*(C'\fR, separated by \f(CW": "\fR from
+the contents of $^E.
+.ie n .IP """WinError_2_Perl_rc""" 4
+.el .IP "\f(CWWinError_2_Perl_rc\fR" 4
+.IX Item "WinError_2_Perl_rc"
+Sets \f(CW\*(C`Perl_rc\*(C'\fR to the return value of \fBWinGetLastError()\fR.
+.ie n .IP """FillWinError""" 4
+.el .IP "\f(CWFillWinError\fR" 4
+.IX Item "FillWinError"
+Sets \f(CW\*(C`Perl_rc\*(C'\fR to the return value of \fBWinGetLastError()\fR, and sets $^E
+to the corresponding value.
+.ie n .IP """FillOSError(rc)""" 4
+.el .IP "\f(CWFillOSError(rc)\fR" 4
+.IX Item "FillOSError(rc)"
+Sets \f(CW\*(C`Perl_rc\*(C'\fR to \f(CW\*(C`rc\*(C'\fR, and sets $^E to the corresponding value.
+.RE
+.RS 4
+.RE
+.IP "Loading DLLs and ordinals in DLLs" 4
+.IX Item "Loading DLLs and ordinals in DLLs"
+Some DLLs are only present in some versions of \s-1OS/2,\s0 or in some
+configurations of \s-1OS/2.\s0 Some exported entry points are present only
+in DLLs shipped with some versions of \s-1OS/2.\s0 If these DLLs and entry
+points were linked directly for a Perl executable/DLL or from a Perl
+extensions, this binary would work only with the specified
+versions/setups. Even if these entry points were not needed, the
+\&\fIload\fR of the executable (or \s-1DLL\s0) would fail.
+.Sp
+For example, many newer useful APIs are not present in \s-1OS/2\s0 v2; many
+PM-related APIs require DLLs not available on floppy-boot setup.
+.Sp
+To make these calls fail \fIonly when the calls are executed\fR, one
+should call these \s-1API\s0 via a dynamic linking \s-1API.\s0 There is a subsystem
+in Perl to simplify such type of calls. A large number of entry
+points available for such linking is provided (see \f(CW\*(C`entries_ordinals\*(C'\fR
+\&\- and also \f(CW\*(C`PMWIN_entries\*(C'\fR \- in \fIos2ish.h\fR). These ordinals can be
+accessed via the APIs:
+.Sp
+.Vb 6
+\& CallORD(), DeclFuncByORD(), DeclVoidFuncByORD(),
+\& DeclOSFuncByORD(), DeclWinFuncByORD(), AssignFuncPByORD(),
+\& DeclWinFuncByORD_CACHE(), DeclWinFuncByORD_CACHE_survive(),
+\& DeclWinFuncByORD_CACHE_resetError_survive(),
+\& DeclWinFunc_CACHE(), DeclWinFunc_CACHE_resetError(),
+\& DeclWinFunc_CACHE_survive(), DeclWinFunc_CACHE_resetError_survive()
+.Ve
+.Sp
+See the header files and the C code in the supplied OS/2\-related
+modules for the details on usage of these functions.
+.Sp
+Some of these functions also combine dynaloading semantic with the
+error-propagation semantic discussed above.
+.SH "Perl flavors"
+.IX Header "Perl flavors"
+Because of idiosyncrasies of \s-1OS/2\s0 one cannot have all the eggs in the
+same basket (though \s-1EMX\s0 environment tries hard to overcome this
+limitations, so the situation may somehow improve). There are 4
+executables for Perl provided by the distribution:
+.SS "\fIperl.exe\fP"
+.IX Subsection "perl.exe"
+The main workhorse. This is a chimera executable: it is compiled as an
+\&\f(CW\*(C`a.out\*(C'\fR\-style executable, but is linked with \f(CW\*(C`omf\*(C'\fR\-style dynamic
+library \fIperl.dll\fR, and with dynamic \s-1CRT DLL.\s0 This executable is a
+\&\s-1VIO\s0 application.
+.PP
+It can load perl dynamic extensions, and it can \fBfork()\fR.
+.PP
+\&\fBNote.\fR Keep in mind that \fBfork()\fR is needed to open a pipe to yourself.
+.SS "\fIperl_.exe\fP"
+.IX Subsection "perl_.exe"
+This is a statically linked \f(CW\*(C`a.out\*(C'\fR\-style executable. It cannot
+load dynamic Perl extensions. The executable supplied in binary
+distributions has a lot of extensions prebuilt, thus the above restriction is
+important only if you use custom-built extensions. This executable is a \s-1VIO\s0
+application.
+.PP
+\&\fIThis is the only executable with does not require \s-1OS/2.\s0\fR The
+friends locked into \f(CW\*(C`M$\*(C'\fR world would appreciate the fact that this
+executable runs under \s-1DOS,\s0 Win0.3*, Win0.95 and WinNT with an
+appropriate extender. See \*(L"Other OSes\*(R".
+.SS "\fIperl_\|_.exe\fP"
+.IX Subsection "perl__.exe"
+This is the same executable as \fIperl_\|_\|_.exe\fR, but it is a \s-1PM\s0
+application.
+.PP
+\&\fBNote.\fR Usually (unless explicitly redirected during the startup)
+\&\s-1STDIN, STDERR,\s0 and \s-1STDOUT\s0 of a \s-1PM\s0
+application are redirected to \fInul\fR. However, it is possible to \fIsee\fR
+them if you start \f(CW\*(C`perl_\|_.exe\*(C'\fR from a \s-1PM\s0 program which emulates a
+console window, like \fIShell mode\fR of Emacs or \s-1EPM.\s0 Thus it \fIis
+possible\fR to use Perl debugger (see perldebug) to debug your \s-1PM\s0
+application (but beware of the message loop lockups \- this will not
+work if you have a message queue to serve, unless you hook the serving
+into the \fBgetc()\fR function of the debugger).
+.PP
+Another way to see the output of a \s-1PM\s0 program is to run it as
+.PP
+.Vb 1
+\& pm_prog args 2>&1 | cat \-
+.Ve
+.PP
+with a shell \fIdifferent\fR from \fIcmd.exe\fR, so that it does not create
+a link between a \s-1VIO\s0 session and the session of \f(CW\*(C`pm_porg\*(C'\fR. (Such a link
+closes the \s-1VIO\s0 window.) E.g., this works with \fIsh.exe\fR \- or with Perl!
+.PP
+.Vb 2
+\& open P, \*(Aqpm_prog args 2>&1 |\*(Aq or die;
+\& print while <P>;
+.Ve
+.PP
+The flavor \fIperl_\|_.exe\fR is required if you want to start your program without
+a \s-1VIO\s0 window present, but not \f(CW\*(C`detach\*(C'\fRed (run \f(CW\*(C`help detach\*(C'\fR for more info).
+Very useful for extensions which use \s-1PM,\s0 like \f(CW\*(C`Perl/Tk\*(C'\fR or \f(CW\*(C`OpenGL\*(C'\fR.
+.PP
+Note also that the differences between \s-1PM\s0 and \s-1VIO\s0 executables are only
+in the \fIdefault\fR behaviour. One can start \fIany\fR executable in
+\&\fIany\fR kind of session by using the arguments \f(CW\*(C`/fs\*(C'\fR, \f(CW\*(C`/pm\*(C'\fR or
+\&\f(CW\*(C`/win\*(C'\fR switches of the command \f(CW\*(C`start\*(C'\fR (of \fI\s-1CMD.EXE\s0\fR or a similar
+shell). Alternatively, one can use the numeric first argument of the
+\&\f(CW\*(C`system\*(C'\fR Perl function (see OS2::Process).
+.SS "\fIperl_\|_\|_.exe\fP"
+.IX Subsection "perl___.exe"
+This is an \f(CW\*(C`omf\*(C'\fR\-style executable which is dynamically linked to
+\&\fIperl.dll\fR and \s-1CRT DLL. I\s0 know no advantages of this executable
+over \f(CW\*(C`perl.exe\*(C'\fR, but it cannot \fBfork()\fR at all. Well, one advantage is
+that the build process is not so convoluted as with \f(CW\*(C`perl.exe\*(C'\fR.
+.PP
+It is a \s-1VIO\s0 application.
+.SS "Why strange names?"
+.IX Subsection "Why strange names?"
+Since Perl processes the \f(CW\*(C`#!\*(C'\fR\-line (cf.
+\&\*(L"\s-1DESCRIPTION\*(R"\s0 in perlrun, \*(L"Command Switches\*(R" in perlrun,
+\&\*(L"No Perl script found in input\*(R" in perldiag), it should know when a
+program \fIis a Perl\fR. There is some naming convention which allows
+Perl to distinguish correct lines from wrong ones. The above names are
+almost the only names allowed by this convention which do not contain
+digits (which have absolutely different semantics).
+.SS "Why dynamic linking?"
+.IX Subsection "Why dynamic linking?"
+Well, having several executables dynamically linked to the same huge
+library has its advantages, but this would not substantiate the
+additional work to make it compile. The reason is the complicated-to-developers
+but very quick and convenient-to-users \*(L"hard\*(R" dynamic linking used by \s-1OS/2.\s0
+.PP
+There are two distinctive features of the dyna-linking model of \s-1OS/2:\s0
+first, all the references to external functions are resolved at the compile time;
+second, there is no runtime fixup of the DLLs after they are loaded into memory.
+The first feature is an enormous advantage over other models: it avoids
+conflicts when several DLLs used by an application export entries with
+the same name. In such cases \*(L"other\*(R" models of dyna-linking just choose
+between these two entry points using some random criterion \- with predictable
+disasters as results. But it is the second feature which requires the build
+of \fIperl.dll\fR.
+.PP
+The address tables of DLLs are patched only once, when they are
+loaded. The addresses of the entry points into DLLs are guaranteed to be
+the same for all the programs which use the same \s-1DLL.\s0 This removes the
+runtime fixup \- once \s-1DLL\s0 is loaded, its code is read-only.
+.PP
+While this allows some (significant?) performance advantages, this makes life
+much harder for developers, since the above scheme makes it impossible
+for a \s-1DLL\s0 to be \*(L"linked\*(R" to a symbol in the \fI.EXE\fR file. Indeed, this
+would need a \s-1DLL\s0 to have different relocations tables for the
+(different) executables which use this \s-1DLL.\s0
+.PP
+However, a dynamically loaded Perl extension is forced to use some symbols
+from the perl
+executable, e.g., to know how to find the arguments to the functions:
+the arguments live on the perl
+internal evaluation stack. The solution is to put the main code of
+the interpreter into a \s-1DLL,\s0 and make the \fI.EXE\fR file which just loads
+this \s-1DLL\s0 into memory and supplies command-arguments. The extension \s-1DLL\s0
+cannot link to symbols in \fI.EXE\fR, but it has no problem linking
+to symbols in the \fI.DLL\fR.
+.PP
+This \fIgreatly\fR increases the load time for the application (as well as
+complexity of the compilation). Since interpreter is in a \s-1DLL,\s0
+the C \s-1RTL\s0 is basically forced to reside in a \s-1DLL\s0 as well (otherwise
+extensions would not be able to use \s-1CRT\s0). There are some advantages if
+you use different flavors of perl, such as running \fIperl.exe\fR and
+\&\fIperl_\|_.exe\fR simultaneously: they share the memory of \fIperl.dll\fR.
+.PP
+\&\fB\s-1NOTE\s0\fR. There is one additional effect which makes DLLs more wasteful:
+DLLs are loaded in the shared memory region, which is a scarse resource
+given the 512M barrier of the \*(L"standard\*(R" \s-1OS/2\s0 virtual memory. The code of
+\&\fI.EXE\fR files is also shared by all the processes which use the particular
+\&\fI.EXE\fR, but they are \*(L"shared in the private address space of the process\*(R";
+this is possible because the address at which different sections
+of the \fI.EXE\fR file are loaded is decided at compile-time, thus all the
+processes have these sections loaded at same addresses, and no fixup
+of internal links inside the \fI.EXE\fR is needed.
+.PP
+Since DLLs may be loaded at run time, to have the same mechanism for DLLs
+one needs to have the address range of \fIany of the loaded\fR DLLs in the
+system to be available \fIin all the processes\fR which did not load a particular
+\&\s-1DLL\s0 yet. This is why the DLLs are mapped to the shared memory region.
+.SS "Why chimera build?"
+.IX Subsection "Why chimera build?"
+Current \s-1EMX\s0 environment does not allow DLLs compiled using Unixish
+\&\f(CW\*(C`a.out\*(C'\fR format to export symbols for data (or at least some types of
+data). This forces \f(CW\*(C`omf\*(C'\fR\-style compile of \fIperl.dll\fR.
+.PP
+Current \s-1EMX\s0 environment does not allow \fI.EXE\fR files compiled in
+\&\f(CW\*(C`omf\*(C'\fR format to \fBfork()\fR. \fBfork()\fR is needed for exactly three Perl
+operations:
+.IP "\(bu" 4
+explicit \fBfork()\fR in the script,
+.IP "\(bu" 4
+\&\f(CW\*(C`open FH, "|\-"\*(C'\fR
+.IP "\(bu" 4
+\&\f(CW\*(C`open FH, "\-|"\*(C'\fR, in other words, opening pipes to itself.
+.PP
+While these operations are not questions of life and death, they are
+needed for a lot of
+useful scripts. This forces \f(CW\*(C`a.out\*(C'\fR\-style compile of
+\&\fIperl.exe\fR.
+.SH "ENVIRONMENT"
+.IX Header "ENVIRONMENT"
+Here we list environment variables with are either \s-1OS/2\-\s0 and \s-1DOS\-\s0 and
+Win*\-specific, or are more important under \s-1OS/2\s0 than under other OSes.
+.ie n .SS """PERLLIB_PREFIX"""
+.el .SS "\f(CWPERLLIB_PREFIX\fP"
+.IX Subsection "PERLLIB_PREFIX"
+Specific for \s-1EMX\s0 port. Should have the form
+.PP
+.Vb 1
+\& path1;path2
+.Ve
+.PP
+or
+.PP
+.Vb 1
+\& path1 path2
+.Ve
+.PP
+If the beginning of some prebuilt path matches \fIpath1\fR, it is
+substituted with \fIpath2\fR.
+.PP
+Should be used if the perl library is moved from the default
+location in preference to \f(CW\*(C`PERL(5)LIB\*(C'\fR, since this would not leave wrong
+entries in \f(CW@INC\fR. For example, if the compiled version of perl looks for \f(CW@INC\fR
+in \fIf:/perllib/lib\fR, and you want to install the library in
+\&\fIh:/opt/gnu\fR, do
+.PP
+.Vb 1
+\& set PERLLIB_PREFIX=f:/perllib/lib;h:/opt/gnu
+.Ve
+.PP
+This will cause Perl with the prebuilt \f(CW@INC\fR of
+.PP
+.Vb 5
+\& f:/perllib/lib/5.00553/os2
+\& f:/perllib/lib/5.00553
+\& f:/perllib/lib/site_perl/5.00553/os2
+\& f:/perllib/lib/site_perl/5.00553
+\& .
+.Ve
+.PP
+to use the following \f(CW@INC:\fR
+.PP
+.Vb 5
+\& h:/opt/gnu/5.00553/os2
+\& h:/opt/gnu/5.00553
+\& h:/opt/gnu/site_perl/5.00553/os2
+\& h:/opt/gnu/site_perl/5.00553
+\& .
+.Ve
+.ie n .SS """PERL_BADLANG"""
+.el .SS "\f(CWPERL_BADLANG\fP"
+.IX Subsection "PERL_BADLANG"
+If 0, perl ignores \fBsetlocale()\fR failing. May be useful with some
+strange \fIlocale\fRs.
+.ie n .SS """PERL_BADFREE"""
+.el .SS "\f(CWPERL_BADFREE\fP"
+.IX Subsection "PERL_BADFREE"
+If 0, perl would not warn of in case of unwarranted \fBfree()\fR. With older
+perls this might be
+useful in conjunction with the module DB_File, which was buggy when
+dynamically linked and OMF-built.
+.PP
+Should not be set with newer Perls, since this may hide some \fIreal\fR problems.
+.ie n .SS """PERL_SH_DIR"""
+.el .SS "\f(CWPERL_SH_DIR\fP"
+.IX Subsection "PERL_SH_DIR"
+Specific for \s-1EMX\s0 port. Gives the directory part of the location for
+\&\fIsh.exe\fR.
+.ie n .SS """USE_PERL_FLOCK"""
+.el .SS "\f(CWUSE_PERL_FLOCK\fP"
+.IX Subsection "USE_PERL_FLOCK"
+Specific for \s-1EMX\s0 port. Since \fBflock\fR\|(3) is present in \s-1EMX,\s0 but is not
+functional, it is emulated by perl. To disable the emulations, set
+environment variable \f(CW\*(C`USE_PERL_FLOCK=0\*(C'\fR.
+.ie n .SS """TMP"" or ""TEMP"""
+.el .SS "\f(CWTMP\fP or \f(CWTEMP\fP"
+.IX Subsection "TMP or TEMP"
+Specific for \s-1EMX\s0 port. Used as storage place for temporary files.
+.SH "Evolution"
+.IX Header "Evolution"
+Here we list major changes which could make you by surprise.
+.SS "Text-mode filehandles"
+.IX Subsection "Text-mode filehandles"
+Starting from version 5.8, Perl uses a builtin translation layer for
+text-mode files. This replaces the efficient well-tested \s-1EMX\s0 layer by
+some code which should be best characterized as a \*(L"quick hack\*(R".
+.PP
+In addition to possible bugs and an inability to follow changes to the
+translation policy with off/on switches of \s-1TERMIO\s0 translation, this
+introduces a serious incompatible change: before \fBsysread()\fR on
+text-mode filehandles would go through the translation layer, now it
+would not.
+.SS "Priorities"
+.IX Subsection "Priorities"
+\&\f(CW\*(C`setpriority\*(C'\fR and \f(CW\*(C`getpriority\*(C'\fR are not compatible with earlier
+ports by Andreas Kaiser. See \*(L"setpriority, getpriority\*(R".
+.SS "\s-1DLL\s0 name mangling: pre 5.6.2"
+.IX Subsection "DLL name mangling: pre 5.6.2"
+With the release 5.003_01 the dynamically loadable libraries
+should be rebuilt when a different version of Perl is compiled. In particular,
+DLLs (including \fIperl.dll\fR) are now created with the names
+which contain a checksum, thus allowing workaround for \s-1OS/2\s0 scheme of
+caching DLLs.
+.PP
+It may be possible to code a simple workaround which would
+.IP "\(bu" 4
+find the old DLLs looking through the old \f(CW@INC\fR;
+.IP "\(bu" 4
+mangle the names according to the scheme of new perl and copy the DLLs to
+these names;
+.IP "\(bu" 4
+edit the internal \f(CW\*(C`LX\*(C'\fR tables of \s-1DLL\s0 to reflect the change of the name
+(probably not needed for Perl extension DLLs, since the internally coded names
+are not used for \*(L"specific\*(R" DLLs, they used only for \*(L"global\*(R" DLLs).
+.IP "\(bu" 4
+edit the internal \f(CW\*(C`IMPORT\*(C'\fR tables and change the name of the \*(L"old\*(R"
+\&\fIperl????.dll\fR to the \*(L"new\*(R" \fIperl????.dll\fR.
+.SS "\s-1DLL\s0 name mangling: 5.6.2 and beyond"
+.IX Subsection "DLL name mangling: 5.6.2 and beyond"
+In fact mangling of \fIextension\fR DLLs was done due to misunderstanding
+of the \s-1OS/2\s0 dynaloading model. \s-1OS/2\s0 (effectively) maintains two
+different tables of loaded \s-1DLL:\s0
+.IP "Global DLLs" 4
+.IX Item "Global DLLs"
+those loaded by the base name from \f(CW\*(C`LIBPATH\*(C'\fR; including those
+associated at link time;
+.IP "specific DLLs" 4
+.IX Item "specific DLLs"
+loaded by the full name.
+.PP
+When resolving a request for a global \s-1DLL,\s0 the table of already-loaded
+specific DLLs is (effectively) ignored; moreover, specific DLLs are
+\&\fIalways\fR loaded from the prescribed path.
+.PP
+There is/was a minor twist which makes this scheme fragile: what to do
+with DLLs loaded from
+.ie n .IP """BEGINLIBPATH"" and ""ENDLIBPATH""" 4
+.el .IP "\f(CWBEGINLIBPATH\fR and \f(CWENDLIBPATH\fR" 4
+.IX Item "BEGINLIBPATH and ENDLIBPATH"
+(which depend on the process)
+.ie n .IP "\fI.\fR from ""LIBPATH""" 4
+.el .IP "\fI.\fR from \f(CWLIBPATH\fR" 4
+.IX Item ". from LIBPATH"
+which \fIeffectively\fR depends on the process (although \f(CW\*(C`LIBPATH\*(C'\fR is the
+same for all the processes).
+.PP
+Unless \f(CW\*(C`LIBPATHSTRICT\*(C'\fR is set to \f(CW\*(C`T\*(C'\fR (and the kernel is after
+2000/09/01), such DLLs are considered to be global. When loading a
+global \s-1DLL\s0 it is first looked in the table of already-loaded global
+DLLs. Because of this the fact that one executable loaded a \s-1DLL\s0 from
+\&\f(CW\*(C`BEGINLIBPATH\*(C'\fR and \f(CW\*(C`ENDLIBPATH\*(C'\fR, or \fI.\fR from \f(CW\*(C`LIBPATH\*(C'\fR may affect
+\&\fIwhich\fR \s-1DLL\s0 is loaded when \fIanother\fR executable requests a \s-1DLL\s0 with
+the same name. \fIThis\fR is the reason for version-specific mangling of
+the \s-1DLL\s0 name for perl \s-1DLL.\s0
+.PP
+Since the Perl extension DLLs are always loaded with the full path,
+there is no need to mangle their names in a version-specific ways:
+their directory already reflects the corresponding version of perl,
+and \f(CW@INC\fR takes into account binary compatibility with older version.
+Starting from \f(CW5.6.2\fR the name mangling scheme is fixed to be the
+same as for Perl 5.005_53 (same as in a popular binary release). Thus
+new Perls will be able to \fIresolve the names\fR of old extension DLLs
+if \f(CW@INC\fR allows finding their directories.
+.PP
+However, this still does not guarantee that these \s-1DLL\s0 may be loaded.
+The reason is the mangling of the name of the \fIPerl \s-1DLL\s0\fR. And since
+the extension DLLs link with the Perl \s-1DLL,\s0 extension DLLs for older
+versions would load an older Perl \s-1DLL,\s0 and would most probably
+segfault (since the data in this \s-1DLL\s0 is not properly initialized).
+.PP
+There is a partial workaround (which can be made complete with newer
+\&\s-1OS/2\s0 kernels): create a forwarder \s-1DLL\s0 with the same name as the \s-1DLL\s0 of
+the older version of Perl, which forwards the entry points to the
+newer Perl's \s-1DLL.\s0 Make this \s-1DLL\s0 accessible on (say) the \f(CW\*(C`BEGINLIBPATH\*(C'\fR of
+the new Perl executable. When the new executable accesses old Perl's
+extension DLLs, they would request the old Perl's \s-1DLL\s0 by name, get the
+forwarder instead, so effectively will link with the currently running
+(new) Perl \s-1DLL.\s0
+.PP
+This may break in two ways:
+.IP "\(bu" 4
+Old perl executable is started when a new executable is running has
+loaded an extension compiled for the old executable (ouph!). In this
+case the old executable will get a forwarder \s-1DLL\s0 instead of the old
+perl \s-1DLL,\s0 so would link with the new perl \s-1DLL.\s0 While not directly
+fatal, it will behave the same as new executable. This beats the whole
+purpose of explicitly starting an old executable.
+.IP "\(bu" 4
+A new executable loads an extension compiled for the old executable
+when an old perl executable is running. In this case the extension
+will not pick up the forwarder \- with fatal results.
+.PP
+With support for \f(CW\*(C`LIBPATHSTRICT\*(C'\fR this may be circumvented \- unless
+one of DLLs is started from \fI.\fR from \f(CW\*(C`LIBPATH\*(C'\fR (I do not know
+whether \f(CW\*(C`LIBPATHSTRICT\*(C'\fR affects this case).
+.PP
+\&\fB\s-1REMARK\s0\fR. Unless newer kernels allow \fI.\fR in \f(CW\*(C`BEGINLIBPATH\*(C'\fR (older
+do not), this mess cannot be completely cleaned. (It turns out that
+as of the beginning of 2002, \fI.\fR is not allowed, but \fI.\e.\fR is \- and
+it has the same effect.)
+.PP
+\&\fB\s-1REMARK\s0\fR. \f(CW\*(C`LIBPATHSTRICT\*(C'\fR, \f(CW\*(C`BEGINLIBPATH\*(C'\fR and \f(CW\*(C`ENDLIBPATH\*(C'\fR are
+not environment variables, although \fIcmd.exe\fR emulates them on \f(CW\*(C`SET
+\&...\*(C'\fR lines. From Perl they may be accessed by
+Cwd::extLibpath and
+Cwd::extLibpath_set.
+.SS "\s-1DLL\s0 forwarder generation"
+.IX Subsection "DLL forwarder generation"
+Assume that the old \s-1DLL\s0 is named \fIperlE0AC.dll\fR (as is one for
+5.005_53), and the new version is 5.6.1. Create a file
+\&\fIperl5shim.def\-leader\fR with
+.PP
+.Vb 5
+\& LIBRARY \*(AqperlE0AC\*(Aq INITINSTANCE TERMINSTANCE
+\& DESCRIPTION \*(Aq@#perl5\-porters@perl.org:5.006001#@ Perl module for 5.00553 \-> Perl 5.6.1 forwarder\*(Aq
+\& CODE LOADONCALL
+\& DATA LOADONCALL NONSHARED MULTIPLE
+\& EXPORTS
+.Ve
+.PP
+modifying the versions/names as needed. Run
+.PP
+.Vb 2
+\& perl \-wnle "next if 0../EXPORTS/; print qq( \e"$1\e")
+\& if /\e"(\ew+)\e"/" perl5.def >lst
+.Ve
+.PP
+in the Perl build directory (to make the \s-1DLL\s0 smaller replace perl5.def
+with the definition file for the older version of Perl if present).
+.PP
+.Vb 2
+\& cat perl5shim.def\-leader lst >perl5shim.def
+\& gcc \-Zomf \-Zdll \-o perlE0AC.dll perl5shim.def \-s \-llibperl
+.Ve
+.PP
+(ignore multiple \f(CW\*(C`warning L4085\*(C'\fR).
+.SS "Threading"
+.IX Subsection "Threading"
+As of release 5.003_01 perl is linked to multithreaded C \s-1RTL
+DLL.\s0 If perl itself is not compiled multithread-enabled, so will not be perl's
+\&\fBmalloc()\fR. However, extensions may use multiple thread on their own
+risk.
+.PP
+This was needed to compile \f(CW\*(C`Perl/Tk\*(C'\fR for XFree86\-OS/2 out-of-the-box, and
+link with DLLs for other useful libraries, which typically are compiled
+with \f(CW\*(C`\-Zmt \-Zcrtdll\*(C'\fR.
+.SS "Calls to external programs"
+.IX Subsection "Calls to external programs"
+Due to a popular demand the perl external program calling has been
+changed wrt Andreas Kaiser's port. \fIIf\fR perl needs to call an
+external program \fIvia shell\fR, the \fIf:/bin/sh.exe\fR will be called, or
+whatever is the override, see "\f(CW\*(C`PERL_SH_DIR\*(C'\fR".
+.PP
+Thus means that you need to get some copy of a \fIsh.exe\fR as well (I
+use one from pdksh). The path \fIF:/bin\fR above is set up automatically during
+the build to a correct value on the builder machine, but is
+overridable at runtime,
+.PP
+\&\fBReasons:\fR a consensus on \f(CW\*(C`perl5\-porters\*(C'\fR was that perl should use
+one non-overridable shell per platform. The obvious choices for \s-1OS/2\s0
+are \fIcmd.exe\fR and \fIsh.exe\fR. Having perl build itself would be impossible
+with \fIcmd.exe\fR as a shell, thus I picked up \f(CW\*(C`sh.exe\*(C'\fR. This assures almost
+100% compatibility with the scripts coming from *nix. As an added benefit
+this works as well under \s-1DOS\s0 if you use DOS-enabled port of pdksh
+(see \*(L"Prerequisites\*(R").
+.PP
+\&\fBDisadvantages:\fR currently \fIsh.exe\fR of pdksh calls external programs
+via \fBfork()\fR/\fBexec()\fR, and there is \fIno\fR functioning \fBexec()\fR on
+\&\s-1OS/2.\s0 \fBexec()\fR is emulated by \s-1EMX\s0 by an asynchronous call while the caller
+waits for child completion (to pretend that the \f(CW\*(C`pid\*(C'\fR did not change). This
+means that 1 \fIextra\fR copy of \fIsh.exe\fR is made active via \fBfork()\fR/\fBexec()\fR,
+which may lead to some resources taken from the system (even if we do
+not count extra work needed for \fBfork()\fRing).
+.PP
+Note that this a lesser issue now when we do not spawn \fIsh.exe\fR
+unless needed (metachars found).
+.PP
+One can always start \fIcmd.exe\fR explicitly via
+.PP
+.Vb 1
+\& system \*(Aqcmd\*(Aq, \*(Aq/c\*(Aq, \*(Aqmycmd\*(Aq, \*(Aqarg1\*(Aq, \*(Aqarg2\*(Aq, ...
+.Ve
+.PP
+If you need to use \fIcmd.exe\fR, and do not want to hand-edit thousands of your
+scripts, the long-term solution proposed on p5\-p is to have a directive
+.PP
+.Vb 1
+\& use OS2::Cmd;
+.Ve
+.PP
+which will override \fBsystem()\fR, \fBexec()\fR, \f(CW\*(C`\`\`\*(C'\fR, and
+\&\f(CW\*(C`open(,\*(Aq...|\*(Aq)\*(C'\fR. With current perl you may override only \fBsystem()\fR,
+\&\fBreadpipe()\fR \- the explicit version of \f(CW\*(C`\`\`\*(C'\fR, and maybe \fBexec()\fR. The code
+will substitute the one-argument call to \fBsystem()\fR by
+\&\f(CW\*(C`CORE::system(\*(Aqcmd.exe\*(Aq, \*(Aq/c\*(Aq, shift)\*(C'\fR.
+.PP
+If you have some working code for \f(CW\*(C`OS2::Cmd\*(C'\fR, please send it to me,
+I will include it into distribution. I have no need for such a module, so
+cannot test it.
+.PP
+For the details of the current situation with calling external programs,
+see \*(L"Starting \s-1OS/2\s0 (and \s-1DOS\s0) programs under Perl\*(R". Set us
+mention a couple of features:
+.IP "\(bu" 4
+External scripts may be called by their basename. Perl will try the same
+extensions as when processing \fB\-S\fR command-line switch.
+.IP "\(bu" 4
+External scripts starting with \f(CW\*(C`#!\*(C'\fR or \f(CW\*(C`extproc \*(C'\fR will be executed directly,
+without calling the shell, by calling the program specified on the rest of
+the first line.
+.SS "Memory allocation"
+.IX Subsection "Memory allocation"
+Perl uses its own \fBmalloc()\fR under \s-1OS/2\s0 \- interpreters are usually malloc-bound
+for speed, but perl is not, since its malloc is lightning-fast.
+Perl-memory-usage-tuned benchmarks show that Perl's malloc is 5 times quicker
+than \s-1EMX\s0 one. I do not have convincing data about memory footprint, but
+a (pretty random) benchmark showed that Perl's one is 5% better.
+.PP
+Combination of perl's \fBmalloc()\fR and rigid \s-1DLL\s0 name resolution creates
+a special problem with library functions which expect their return value to
+be \fBfree()\fRd by system's \fBfree()\fR. To facilitate extensions which need to call
+such functions, system memory-allocation functions are still available with
+the prefix \f(CW\*(C`emx_\*(C'\fR added. (Currently only \s-1DLL\s0 perl has this, it should
+propagate to \fIperl_.exe\fR shortly.)
+.SS "Threads"
+.IX Subsection "Threads"
+One can build perl with thread support enabled by providing \f(CW\*(C`\-D usethreads\*(C'\fR
+option to \fIConfigure\fR. Currently \s-1OS/2\s0 support of threads is very
+preliminary.
+.PP
+Most notable problems:
+.ie n .IP """COND_WAIT""" 4
+.el .IP "\f(CWCOND_WAIT\fR" 4
+.IX Item "COND_WAIT"
+may have a race condition (but probably does not due to edge-triggered
+nature of \s-1OS/2\s0 Event semaphores). (Needs a reimplementation (in terms of chaining
+waiting threads, with the linked list stored in per-thread structure?)?)
+.IP "\fIos2.c\fR" 4
+.IX Item "os2.c"
+has a couple of static variables used in OS/2\-specific functions. (Need to be
+moved to per-thread structure, or serialized?)
+.PP
+Note that these problems should not discourage experimenting, since they
+have a low probability of affecting small programs.
+.SH "BUGS"
+.IX Header "BUGS"
+This description is not updated often (since 5.6.1?), see \fI./os2/Changes\fR
+for more info.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Ilya Zakharevich, cpan@ilyaz.org
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fBperl\fR\|(1).