CGI-Compile
view release on metacpan or search on metacpan
lib/CGI/Compile.pm view on Meta::CPAN
}
},
'};';
my $sub = do {
no warnings 'uninitialized'; # for 5.8
# NOTE: this is a workaround to fix a problem in Perl 5.10
local @SIG{keys %SIG} = @{[]} = values %SIG;
local $USE_REAL_EXIT = 0;
my $code = $self->_eval($eval);
my $exception = $@;
die "Could not compile $script: $exception" if $exception;
subname "${package}::$subname", sub {
my @args = @_;
# this is necessary for MSWin32
my $orig_warn = $SIG{__WARN__} || sub { warn(@_) };
local $SIG{__WARN__} = sub { $orig_warn->(@_) unless $_[0] =~ /^No such signal/ };
$code->($self, $data, $path, $dir, \@args)
};
};
return $sub;
}
sub _read_source {
my($self, $file) = @_;
open my $fh, "<", $file or die "$file: $!";
return do { local $/; <$fh> };
}
sub _build_subname {
my($self, $path) = @_;
my ($volume, $dirs, $file) = File::Spec::Functions::splitpath($path);
my @dirs = File::Spec::Functions::splitdir($dirs);
my $name = $file;
my $package = join '_', grep { defined && length } $volume, @dirs, $name;
# Escape everything into valid perl identifiers
s/([^A-Za-z0-9_])/sprintf("_%2x", unpack("C", $1))/eg for $package, $name;
# make sure the identifiers don't start with a digit
s/^(\d)/_$1/ for $package, $name;
$package = $self->{namespace_root} . ($package ? "::$package" : '');
return ($package, $name);
}
# define tmp_dir value later on first usage, otherwise all children
# share the same directory when forked
my $tmp_dir;
sub _eval {
my $code = \$_[1];
# we use a tmpdir chmodded to 0700 so that the tempfiles are secure
$tmp_dir ||= File::Spec->catfile(File::Spec->tmpdir, "cgi_compile_$$");
if (! -d $tmp_dir) {
mkdir $tmp_dir or die "Could not mkdir $tmp_dir: $!";
chmod 0700, $tmp_dir or die "Could not chmod 0700 $tmp_dir: $!";
}
my ($fh, $fname) = File::Temp::tempfile('cgi_compile_XXXXX',
UNLINK => 1, SUFFIX => '.pm', DIR => $tmp_dir);
print $fh $$code;
close $fh;
my $sub = do $fname;
unlink $fname or die "Could not delete $fname: $!";
return $sub;
}
END {
if ($tmp_dir and -d $tmp_dir) {
File::Path::remove_tree($tmp_dir);
}
}
1;
__END__
=encoding utf-8
=for stopwords
=head1 NAME
CGI::Compile - Compile .cgi scripts to a code reference like ModPerl::Registry
=head1 SYNOPSIS
use CGI::Compile;
my $sub = CGI::Compile->compile("/path/to/script.cgi");
=head1 DESCRIPTION
CGI::Compile is a utility to compile CGI scripts into a code
reference that can run many times on its own namespace, as long as the
script is ready to run on a persistent environment.
B<NOTE:> for best results, load L<CGI::Compile> before any modules used by your
CGIs.
=head1 RUN ON PSGI
Combined with L<CGI::Emulate::PSGI>, your CGI script can be turned
into a persistent PSGI application like:
use CGI::Emulate::PSGI;
use CGI::Compile;
my $cgi_script = "/path/to/foo.cgi";
my $sub = CGI::Compile->compile($cgi_script);
my $app = CGI::Emulate::PSGI->handler($sub);
# $app is a PSGI application
( run in 0.346 second using v1.01-cache-2.11-cpan-483215c6ad5 )