File: | Dpkg/Compression/Process.pm |
Coverage: | 88.5% |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | # Copyright © 2008-2010 Raphaël Hertzog <hertzog@debian.org> | ||||||
2 | # | ||||||
3 | # This program is free software; you can redistribute it and/or modify | ||||||
4 | # it under the terms of the GNU General Public License as published by | ||||||
5 | # the Free Software Foundation; either version 2 of the License, or | ||||||
6 | # (at your option) any later version. | ||||||
7 | # | ||||||
8 | # This program is distributed in the hope that it will be useful, | ||||||
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
11 | # GNU General Public License for more details. | ||||||
12 | # | ||||||
13 | # You should have received a copy of the GNU General Public License | ||||||
14 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||||
15 | |||||||
16 | package Dpkg::Compression::Process; | ||||||
17 | |||||||
18 | 24 24 24 | 50 21 272 | use strict; | ||||
19 | 24 24 24 | 33 13 509 | use warnings; | ||||
20 | |||||||
21 | our $VERSION = '1.00'; | ||||||
22 | |||||||
23 | 24 24 24 | 42 17 458 | use Carp; | ||||
24 | |||||||
25 | 24 24 24 | 43 66 608 | use Dpkg::Compression; | ||||
26 | 24 24 24 | 42 20 644 | use Dpkg::ErrorHandling; | ||||
27 | 24 24 24 | 38 19 428 | use Dpkg::Gettext; | ||||
28 | 24 24 24 | 2571 21 7591 | use Dpkg::IPC; | ||||
29 | |||||||
30 | =encoding utf8 | ||||||
31 | |||||||
32 - 50 | =head1 NAME Dpkg::Compression::Process - run compression/decompression processes =head1 DESCRIPTION This module provides an object oriented interface to run and manage compression/decompression processes. =head1 METHODS =over 4 =item $proc = Dpkg::Compression::Process->new(%opts) Create a new instance of the object. Supported options are "compression" and "compression_level" (see corresponding set_* functions). =cut | ||||||
51 | |||||||
52 | sub new { | ||||||
53 | 168 | 1 | 206 | my ($this, %args) = @_; | |||
54 | 168 | 484 | my $class = ref($this) || $this; | ||||
55 | 168 | 127 | my $self = {}; | ||||
56 | 168 | 182 | bless $self, $class; | ||||
57 | 168 | 404 | $self->set_compression($args{compression} || compression_get_default()); | ||||
58 | $self->set_compression_level($args{compression_level} || | ||||||
59 | 168 | 372 | compression_get_default_level()); | ||||
60 | 168 | 284 | return $self; | ||||
61 | } | ||||||
62 | |||||||
63 - 69 | =item $proc->set_compression($comp) Select the compression method to use. It errors out if the method is not supported according to C<compression_is_supported> (of B<Dpkg::Compression>). =cut | ||||||
70 | |||||||
71 | sub set_compression { | ||||||
72 | 182 | 1 | 171 | my ($self, $method) = @_; | |||
73 | 182 | 242 | error(g_('%s is not a supported compression method'), $method) | ||||
74 | unless compression_is_supported($method); | ||||||
75 | 182 | 238 | $self->{compression} = $method; | ||||
76 | } | ||||||
77 | |||||||
78 - 84 | =item $proc->set_compression_level($level) Select the compression level to use. It errors out if the level is not valid according to C<compression_is_valid_level> (of B<Dpkg::Compression>). =cut | ||||||
85 | |||||||
86 | sub set_compression_level { | ||||||
87 | 168 | 1 | 158 | my ($self, $level) = @_; | |||
88 | 168 | 209 | error(g_('%s is not a compression level'), $level) | ||||
89 | unless compression_is_valid_level($level); | ||||||
90 | 168 | 205 | $self->{compression_level} = $level; | ||||
91 | } | ||||||
92 | |||||||
93 - 104 | =item @exec = $proc->get_compress_cmdline() =item @exec = $proc->get_uncompress_cmdline() Returns a list ready to be passed to C<exec>, its first element is the program name (either for compression or decompression) and the following elements are parameters for the program. When executed the program acts as a filter between its standard input and its standard output. =cut | ||||||
105 | |||||||
106 | sub get_compress_cmdline { | ||||||
107 | 9 | 1 | 9 | my $self = shift; | |||
108 | 9 9 | 9 9 | my @prog = (@{compression_get_property($self->{compression}, 'comp_prog')}); | ||||
109 | 9 | 9 | my $level = '-' . $self->{compression_level}; | ||||
110 | $level = '--' . $self->{compression_level} | ||||||
111 | 9 | 22 | if $self->{compression_level} !~ m/^[1-9]$/; | ||||
112 | 9 | 9 | push @prog, $level; | ||||
113 | 9 | 9 | return @prog; | ||||
114 | } | ||||||
115 | |||||||
116 | sub get_uncompress_cmdline { | ||||||
117 | 5 | 1 | 0 | my $self = shift; | |||
118 | 5 5 | 5 5 | return (@{compression_get_property($self->{compression}, 'decomp_prog')}); | ||||
119 | } | ||||||
120 | |||||||
121 | sub _check_opts { | ||||||
122 | 14 | 23 | my ($self, %opts) = @_; | ||||
123 | # Check for proper cleaning before new start | ||||||
124 | error(g_('Dpkg::Compression::Process can only start one subprocess at a time')) | ||||||
125 | 14 | 14 | if $self->{pid}; | ||||
126 | # Check options | ||||||
127 | 14 | 14 | my $to = my $from = 0; | ||||
128 | 14 | 23 | foreach my $thing (qw(file handle string pipe)) { | ||||
129 | 56 | 61 | $to++ if $opts{"to_$thing"}; | ||||
130 | 56 | 48 | $from++ if $opts{"from_$thing"}; | ||||
131 | } | ||||||
132 | 14 | 14 | croak 'exactly one to_* parameter is needed' if $to != 1; | ||||
133 | 14 | 14 | croak 'exactly one from_* parameter is needed' if $from != 1; | ||||
134 | 14 | 14 | return %opts; | ||||
135 | } | ||||||
136 | |||||||
137 - 147 | =item $proc->compress(%opts) Starts a compressor program. You must indicate where it will read its uncompressed data from and where it will write its compressed data to. This is accomplished by passing one parameter C<to_*> and one parameter C<from_*> as accepted by B<Dpkg::IPC::spawn>. You must call C<wait_end_process> after having called this method to properly close the sub-process (and verify that it exited without error). =cut | ||||||
148 | |||||||
149 | sub compress { | ||||||
150 | 9 | 1 | 25 | my ($self, %opts) = @_; | |||
151 | |||||||
152 | 9 | 22 | $self->_check_opts(%opts); | ||||
153 | 9 | 9 | my @prog = $self->get_compress_cmdline(); | ||||
154 | 9 | 17 | $opts{exec} = \@prog; | ||||
155 | 9 | 22 | $self->{cmdline} = "@prog"; | ||||
156 | 9 | 26 | $self->{pid} = spawn(%opts); | ||||
157 | 7 | 165 | delete $self->{pid} if $opts{to_string}; # wait_child already done | ||||
158 | } | ||||||
159 | |||||||
160 - 170 | =item $proc->uncompress(%opts) Starts a decompressor program. You must indicate where it will read its compressed data from and where it will write its uncompressed data to. This is accomplished by passing one parameter C<to_*> and one parameter C<from_*> as accepted by B<Dpkg::IPC::spawn>. You must call C<wait_end_process> after having called this method to properly close the sub-process (and verify that it exited without error). =cut | ||||||
171 | |||||||
172 | sub uncompress { | ||||||
173 | 5 | 1 | 13 | my ($self, %opts) = @_; | |||
174 | |||||||
175 | 5 | 13 | $self->_check_opts(%opts); | ||||
176 | 5 | 8 | my @prog = $self->get_uncompress_cmdline(); | ||||
177 | 5 | 16 | $opts{exec} = \@prog; | ||||
178 | 5 | 5 | $self->{cmdline} = "@prog"; | ||||
179 | 5 | 18 | $self->{pid} = spawn(%opts); | ||||
180 | 3 | 69 | delete $self->{pid} if $opts{to_string}; # wait_child already done | ||||
181 | } | ||||||
182 | |||||||
183 - 191 | =item $proc->wait_end_process(%opts) Call B<Dpkg::IPC::wait_child> to wait until the sub-process has exited and verify its return code. Any given option will be forwarded to the C<wait_child> function. Most notably you can use the "nocheck" option to verify the return code yourself instead of letting C<wait_child> do it for you. =cut | ||||||
192 | |||||||
193 | sub wait_end_process { | ||||||
194 | 142 | 1 | 198 | my ($self, %opts) = @_; | |||
195 | 142 | 464 | $opts{cmdline} //= $self->{cmdline}; | ||||
196 | 142 | 233 | wait_child($self->{pid}, %opts) if $self->{pid}; | ||||
197 | 142 | 108 | delete $self->{pid}; | ||||
198 | 142 | 158 | delete $self->{cmdline}; | ||||
199 | } | ||||||
200 | |||||||
201 | =back | ||||||
202 | |||||||
203 - 209 | =head1 CHANGES =head2 Version 1.00 (dpkg 1.15.6) Mark the module as public. =cut | ||||||
210 | |||||||
211 | 1; |