[prev in list] [next in list] [prev in thread] [next in thread] 

List:       apache-modperl
Subject:    Robust way to check for version number [FEATURE REQUEST / HOW-TO]
From:       Dominique Quatravaux <dom () idealx ! com>
Date:       2005-06-29 14:36:46
Message-ID: 42C2B1FE.2070100 () idealx ! com
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dear members of the mod_perl list,

I did not find an elegant, robust way of checking for the mod_perl
version number. I propose an unelegant, robust way below for those
interested.

$ENV{MOD_PERL} is obviously not OK because the UNIX environment has
the wrong semantics: it can be altered in too many places for
starters, and not just from Perl (e.g. it's customary for
security-minded code to reset all of %ENV to sane values, which makes
parts of the app "forget" that they are running mod_perl). And it's
inherited in child processes, so say when Apache forks/execs a helper
written in Perl things tend to go from bad to worse.

$mod_perl2::VERSION skips these drawbacks (it can only be altered from
Perl and is not inherited) but it is currently not trustworthy either:

 $ perl -Mmod_perl2 -e 'print $mod_perl2::VERSION'
 2.000001

BTW this problem triggers a bug in e.g. Apache::DB when several
installations of mod_perl (1.26 and 2.000001 in my case) cohabit on
the same system (I'm sending a separate bug report to Frank Wiles).

The only reliable way of checking for mod_perl is by probing for an
"unusual" feature of the Perl runtime, say an XS sub that the core of
mod_perl provides directly. Here is the crock I'm currently using to
that effect:

sub mod_perl_version {
    my @discriminating_symbols =
        (2 => "Apache2::XSLoader::BOOTSTRAP",
         1.99 => "Apache::XSLoader::BOOTSTRAP",
         1 => "Apache::exit");

    use B;
    while(my ($version, $discrimsymbol) =
          splice(@discriminating_symbols, 0, 2)) {
        no strict "refs";
        next if (! exists &{$discrimsymbol});
        my $bref = B::svref_2object(\&{$discrimsymbol});
        next if ( (! defined $bref) || (! $bref->XSUB()) );
        return $version;
    }
    return undef;
}


Not exactly pretty, but robust it is: "PerlSetupEnv Off" won't derail
it, it works at every stage of the mod_perl state automaton including
early initialization, and so on.

FEATURE REQUEST: I'd love to get rid of the "use B;" crockery above, e.g.

  return mod_perl::version_running() if exists
&mod_perl::version_running();

Best regards and thanks for all the great work!

- --
Dominique QUATRAVAUX                           Ingénieur senior
01 44 42 00 08                                 IDEALX

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCwrH9MJAKAU3mjcsRAr1mAJ41sytkT6zJJRpynMJQeVokeLii+gCfdcy9
EFOfI0IrtRo7m2VpHddDB2U=
=YGaG
-----END PGP SIGNATURE-----


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic