NAME
Filter::gunzip - gunzip Perl source code for execution
SYNOPSIS
perl -MFilter::gunzip foo.pl.gz
use Filter::gunzip;
... # inline gzipped source code bytes
DESCRIPTION
This filter uncompresses gzipped Perl code at run-time. It's slightly a proof of concept, but works well as far as it goes. It can be used from the command line to run a .pl.gz file,
perl -MFilter::gunzip foo.pl.gz
Or in a self-uncompressing executable beginning with a use
and gzip bytes immediately following that line,
#!/usr/bin/perl
use Filter::gunzip;
... raw gzip bytes
The filter is implemented one of two ways. For the usual case that Filter::gunzip
is the first filter and PerlIO is available then push a PerlIO::gzip
layer. Otherwise add a block-oriented source filter per perlfilter. In both cases the uncompressed code can apply further source filters in the usual way.
DATA Handle
The __DATA__
token ("Special Literals" in perldata) and DATA
handle can be used in the compressed source, but only some of the time.
For the PerlIO case the DATA
handle is simply the input, including the :gzip
uncompressing layer, positioned just after the __DATA__
token. This works well for data compressed along with the code, though PerlIO::gzip
as of version 0.18 cannot dup or seek which means for instance SelfLoader
doesn't work. (Duping and seeking are probably both feasible, though seeking backward might be slow.)
For the filter case DATA
doesn't really work properly. Perl stops reading from the source filters at the __DATA__
token, because that's where the source ends. But a block oriented filter like Filter::gunzip
may read ahead in the input file, so the position the DATA
handle is left is unpredictable, especially if there's a couple of block-oriented filters stacked up.
Further Details
Perl source is normally read without CRLF translation (in Perl 5.6.1 and up at least). If Filter::gunzip
sees a :crlf
layer on the input it pushes the :gzip
underneath that, since the CRLF is almost certainly meant to apply to the text, not to the raw gzip bytes. This should let it work with the forced PERLIO=crlf
suggested by README.cygwin (see "PERLIO" in perlrun).
The gzip format has a CRC checksum at the end of the data. This might catch subtle corruption in the compressed bytes, except as of Perl 5.10 the parser usually doesn't report a read error and in any case the code is compiled and BEGIN
blocks are executed as uncompressing proceeds, so corruption will likely provoke a syntax error before the CRC is reached.
Only the gzip format (RFC 1952) is supported. Zlib format (RFC 1950) differs only in the header, but PerlIO::gzip
(version 0.18) doesn't allow it. The actual gunzip
program can handle some other formats, like Unix .Z compress
, but they're probably best left to other modules.
The bzip2 format could be handled by a very similar filter, if .pl.bz2 files were used. Its decompressor uses at least 2.5 Mbytes of memory though, so if choosing that format there'd have to be a big disk saving before it was worth that much memory at runtime.
OTHER WAYS TO DO IT
Filter::exec
and the zcat
program can the same thing, either from the command line or self-expanding,
perl -MFilter::exec=zcat foo.pl.gz
Because Filter::exec
is a block-oriented filter (as of version 1.37) a compressed __DATA__
section within the script doesn't work.
PerlIO::gzip
can be applied to a script with the open
pragma and a require
. For example something like the following from the command line. Since the open
pragma is lexical it doesn't affect other later loads or opens.
perl -e '{use open IN=>":gzip";require shift}' \
foo.pl.gz arg1 arg2
It doesn't work to set a PERLIO
environment variable for a global :gzip
layer, eg. PERLIO=':gzip(autopop)'
, because the default layers are restricted to Perl builtins (see "PERLIO" in perlrun).
SEE ALSO
PerlIO::gzip, PerlIO, Filter::Util::Call, Filter::exec, gzip(1), zcat(1), open
HOME PAGE
http://user42.tuxfamily.org/filter-gunzip/index.html
LICENSE
Filter-gunzip is Copyright 2010 Kevin Ryde
Filter-gunzip is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
Filter-gunzip is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Filter-gunzip. If not, see <http://www.gnu.org/licenses/>.