perl
view release on metacpan or search on metacpan
closes the VIO window.) E.g., this works with F<sh.exe> - or with Perl!
open P, 'pm_prog args 2>&1 |' or die;
print while <P>;
The flavor F<perl__.exe> is required if you want to start your program without
a VIO window present, but not C<detach>ed (run C<help detach> for more info).
Very useful for extensions which use PM, like C<Perl/Tk> or C<OpenGL>.
Note also that the differences between PM and VIO executables are only
in the I<default> behaviour. One can start I<any> executable in
I<any> kind of session by using the arguments C</fs>, C</pm> or
C</win> switches of the command C<start> (of F<CMD.EXE> or a similar
shell). Alternatively, one can use the numeric first argument of the
C<system> Perl function (see L<OS2::Process>).
=head2 F<perl___.exe>
This is an C<omf>-style executable which is dynamically linked to
F<perl.dll> and CRT DLL. I know no advantages of this executable
over C<perl.exe>, but it cannot fork() at all. Well, one advantage is
that the build process is not so convoluted as with C<perl.exe>.
It is a VIO application.
=head2 Why strange names?
Since Perl processes the C<#!>-line (cf.
L<perlrun/DESCRIPTION>, L<perlrun/Command Switches>,
L<perldiag/"No Perl script found in input">), it should know when a
program I<is a Perl>. 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).
=head2 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 "hard" dynamic linking used by OS/2.
There are two distinctive features of the dyna-linking model of OS/2:
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 "other" 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 F<perl.dll>.
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 DLL. This removes the
runtime fixup - once DLL is loaded, its code is read-only.
While this allows some (significant?) performance advantages, this makes life
much harder for developers, since the above scheme makes it impossible
for a DLL to be "linked" to a symbol in the F<.EXE> file. Indeed, this
would need a DLL to have different relocations tables for the
(different) executables which use this DLL.
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 DLL, and make the F<.EXE> file which just loads
this DLL into memory and supplies command-arguments. The extension DLL
cannot link to symbols in F<.EXE>, but it has no problem linking
to symbols in the F<.DLL>.
This I<greatly> increases the load time for the application (as well as
complexity of the compilation). Since interpreter is in a DLL,
the C RTL is basically forced to reside in a DLL as well (otherwise
extensions would not be able to use CRT). There are some advantages if
you use different flavors of perl, such as running F<perl.exe> and
F<perl__.exe> simultaneously: they share the memory of F<perl.dll>.
B<NOTE>. 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 "standard" OS/2 virtual memory. The code of
F<.EXE> files is also shared by all the processes which use the particular
F<.EXE>, but they are "shared in the private address space of the process";
this is possible because the address at which different sections
of the F<.EXE> 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 F<.EXE> is needed.
Since DLLs may be loaded at run time, to have the same mechanism for DLLs
one needs to have the address range of I<any of the loaded> DLLs in the
system to be available I<in all the processes> which did not load a particular
DLL yet. This is why the DLLs are mapped to the shared memory region.
=head2 Why chimera build?
Current EMX environment does not allow DLLs compiled using Unixish
C<a.out> format to export symbols for data (or at least some types of
data). This forces C<omf>-style compile of F<perl.dll>.
Current EMX environment does not allow F<.EXE> files compiled in
C<omf> format to fork(). fork() is needed for exactly three Perl
operations:
=over 4
=item *
explicit fork() in the script,
=item *
C<open FH, "|-">
=item *
C<open FH, "-|">, in other words, opening pipes to itself.
=back
( run in 0.657 second using v1.01-cache-2.11-cpan-5511b514fd6 )