The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

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 for execution. 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 by pushing a PerlIO::gzip layer for the usual case that Filter::gunzip is the first filter and PerlIO is available. Otherwise a block-oriented source filter is used per perlfilter. In both cases the compressed code can include 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 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 SelfLoader doesn't work. (Both probably feasible, though seeking 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 a 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, though 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 executed as uncompressing proceeds, so corruption is likely to provoke an 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 a couple of other formats, like Unix .Z compress, but they're likely 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 a format there'd have to be a big disk saving before it was worth that much 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 it's a block-oriented filter (as of version 1.37) a compressed __DATA__ section within the script doesn't work.

PerlIO::gzip can be pushed on the command line using the open pragma with a require. Since that 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 global PERLIO=':gzip(autopop)' though, since the default layers can only be Perl builtins (see "PERLIO" in perlrun).

SEE ALSO

PerlIO::gzip, PerlIO, Filter::Util::Call, Filter::exec, gzip(1), zcat(1)

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/>.