/usr/share/perl5/Apache/ASP/StatINC.pm is in libapache-asp-perl 2.62-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | package Apache::ASP;
# quickly decomped out of Apache::ASP just to optionally load
# it at runtime for CGI programs ( which shouldn't need it anyway )
# will still precompile this for mod_perl
use strict;
use vars qw( $StatINCReady $StatINCInit %Stat $StatStartTime );
$StatStartTime = time();
# Apache::StatINC didn't quite work right, so writing own
sub StatINCRun {
my $self = shift;
my $stats = 0;
# include necessary libs, without nice error message...
# we only do this once if successful, to speed up code a bit,
# and load success bool into global. otherwise keep trying
# to generate consistent error messages
unless($StatINCReady) {
my $ready = 1;
for('Devel::Symdump') {
eval "use $_";
if($@) {
$ready = 0;
$self->Error("You need $_ to use StatINC: $@ ... ".
"Please download it from your nearest CPAN");
}
}
$StatINCReady = $ready;
}
return unless $StatINCReady;
# make sure that we have pre-registered all the modules before
# this only happens on the first request of a new process
unless($StatINCInit) {
$StatINCInit = 1;
$self->Debug("statinc init");
$self->StatRegisterAll();
}
while(my($key,$file) = each %INC) {
if($self->{stat_inc_match} && defined $Stat{$file}) {
# we skip only if we have already registered this file
# we need to register the codes so we don't undef imported symbols
next unless ($key =~ /$self->{stat_inc_match}/);
}
next unless (-e $file); # sometimes there is a bad file in the %INC
my $mtime = (stat($file))[9];
# its ok if this block is CPU intensive, since it should only happen
# when modules get changed, and that should be infrequent on a production site
if(! defined $Stat{$file}) {
$self->{dbg} && $self->Debug("loading symbols first time", { $key => $file});
$self->StatRegister($key, $file, $mtime);
} elsif($mtime > $Stat{$file}) {
$self->{dbg} && $self->Debug("reloading", {$key => $file});
$stats++; # count files we have reloaded
$self->StatRegisterAll();
# we need to explicitly re-register a namespace that
# we are about to undef, in case any imports happened there
# since last we checked, so we don't delete duplicate symbols
$self->StatRegister($key, $file, $mtime);
my $class = &File2Class($key);
my $sym = Devel::Symdump->new($class);
my $function;
my $is_global_package = $class eq $self->{GlobalASA}{'package'} ? 1 : 0;
my @global_events_list = $self->{GlobalASA}->EventsList;
for $function ($sym->functions()) {
my $code = \&{$function};
if($function =~ /::O_[^:]+$/) {
$self->Debug("skipping undef of troublesome $function");
next;
}
if($Apache::ASP::Codes{$code}{count} > 1) {
$self->Debug("skipping undef of multiply defined $function: $code");
next;
}
if($is_global_package) {
# skip undef if id is an include or script
if($function =~ /::__ASP_/) {
$self->Debug("skipping undef compiled ASP sub $function");
next;
}
if(grep($function eq $class."::".$_, @global_events_list)) {
$self->Debug("skipping undef global event $function");
next;
}
if($Apache::ASP::ScriptSubs{$function}) {
$self->Debug("skipping undef script subroutine $function");
next;
}
}
$self->{dbg} && $self->Debug("undef code $function: $code");
undef(&$code); # method for perl 5.6.1
delete $Apache::ASP::Codes{$code};
undef($code); # older perls
}
# extract the lib, just incase our @INC went away
(my $lib = $file) =~ s/$key$//g;
push(@INC, $lib);
# don't use "use", since we don't want symbols imported into ASP
delete $INC{$key};
$self->Debug("loading $key with require");
eval { require($key); };
if($@) {
$INC{$key} = $file; # make sure we keep trying to reload it
$self->Error("can't require/reload $key: $@");
next;
}
# if this was the same module as the global.asa package,
# then we need to reload the global.asa, since we just
# undef'd the subs
if($is_global_package) {
# we just undef'd the global.asa routines, so these too
# must be recompiled
$self->Debug("reloading global.asa file after clearing package namespace");
delete $Apache::ASP::Compiled{$self->{GlobalASA}{'id'}};
&Apache::ASP::GlobalASA::new($self);
}
$self->StatRegister($key, $file, $mtime);
# we want to register INC now in case any new libs were
# added when this module was reloaded
$self->StatRegisterAll();
}
}
$stats;
}
sub StatRegister {
my($self, $key, $file, $mtime) = @_;
# keep track of times
$Stat{$file} = $mtime;
# keep track of codes, don't undef on codes
# with multiple refs, since these are exported
my $class = &File2Class($key);
# we skip Apache stuff as on some platforms (RedHat 6.0)
# Apache::OK seems to error when getting its code ref
# these shouldn't be reloaded anyway, as they are internal to
# modperl and should require a full server restart
if($class eq 'Apache' or $class eq 'Apache::Constants') {
$self->Debug("skipping StatINC register of $class");
return;
}
$self->{dbg} && $self->Debug("stat register of $key $file $class");
if($class eq 'CGI') {
# must compensate for its autoloading behavior, and
# precompile all the routines, so we can register them
# and not delete them later
CGI->compile(':all');
}
my $sym = Devel::Symdump->new($class);
my $function;
for $function ($sym->functions()) {
my $code = \&{$function};
unless($code =~ /CODE/) {
$self->Debug("no code ref for function $function");
next;
}
# don't update if we already have this code defined for this func.
next if $Apache::ASP::Codes{$code}{funcs}{$function};
# $self->Debug("code $code for $function");
$Apache::ASP::Codes{$code}{count}++;
$Apache::ASP::Codes{$code}{libs}{$key}++;
$Apache::ASP::Codes{$code}{funcs}{$function}++;
}
1;
}
sub StatRegisterAll {
my $self = shift;
# we make sure that all modules that are loaded are registered
# so we don't undef exported subroutines, when we reload
my($key, $file);
while(($key,$file) = each %INC) {
next if defined $Stat{$file};
next unless -e $file;
# we use the module load time to init, in case it was
# pulled in with PerlModule, and has changed since,
# so it won't break with a graceful restart
$self->StatRegister($key, $file, $StatStartTime - 1);
}
1;
}
sub File2Class {
my $file = shift;
return $file unless $file =~ s,\.pm$,,;
$file =~ s,/,::,g;
$file;
}
1;
|