diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
commit | fc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch) | |
tree | ce1e3bce06471410239a6f41282e328770aa404a /upstream/debian-bookworm/man1/perlos2.1 | |
parent | Initial commit. (diff) | |
download | manpages-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.1 | 2617 |
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). |