Przeglądaj źródła

dpkg-source: don't die on SIGPIPE of uncompressors

Modify Dpkg::Source::CompressedFile to not die when uncompressors
processes (gunzip, bunzip, etc.) are killed by SIGPIPE. Recent tar
versions close the pipe before having read everything sent by the
uncompressor process when they encounter the end of the tar file.
This was of course problematic for Dpkg::Source::Archive.
This is a regression compared to etch's dpkg-source which dealt with
SIGPIPE properly.

The Dpkg::Source::Compressor::wait_end_process() function had to be
extended to be able to forward options to Dpkg::IPC::wait_child().
Raphael Hertzog 17 lat temu
rodzic
commit
e5235b174b

+ 3 - 0
debian/changelog

@@ -50,6 +50,9 @@ dpkg (1.15.1) UNRELEASED; urgency=low
     Thanks to Nils Rennebarth for the patch.
     Thanks to Nils Rennebarth for the patch.
   * Fix a mistake in the french translation of dpkg's manual page.
   * Fix a mistake in the french translation of dpkg's manual page.
     Thanks to Jonathan Gibert. Closes: #522032
     Thanks to Jonathan Gibert. Closes: #522032
+  * Fix dpkg-source to not die when uncompressor processes are killed by
+    SIGPIPE due to tar closing the pipe without exhausting all the data
+    available. Closes: #523329
 
 
   [ Guillem Jover ]
   [ Guillem Jover ]
   * Fix typo in dpkg output (‘unexecpted’ → ‘unexpected’). Closes: #519082
   * Fix typo in dpkg output (‘unexecpted’ → ‘unexpected’). Closes: #519082

+ 9 - 1
scripts/Dpkg/Source/CompressedFile.pm

@@ -23,6 +23,7 @@ use Dpkg::Compression;
 use Dpkg::Source::Compressor;
 use Dpkg::Source::Compressor;
 use Dpkg::Gettext;
 use Dpkg::Gettext;
 use Dpkg::ErrorHandling;
 use Dpkg::ErrorHandling;
+use POSIX;
 
 
 # Object methods
 # Object methods
 sub new {
 sub new {
@@ -35,6 +36,7 @@ sub new {
     $self->{"compressor"} = Dpkg::Source::Compressor->new();
     $self->{"compressor"} = Dpkg::Source::Compressor->new();
     $self->{"add_comp_ext"} = $args{"add_compression_extension"} ||
     $self->{"add_comp_ext"} = $args{"add_compression_extension"} ||
 	    $args{"add_comp_ext"} || 0;
 	    $args{"add_comp_ext"} || 0;
+    $self->{"allow_sigpipe"} = 0;
     if (exists $args{"filename"}) {
     if (exists $args{"filename"}) {
 	$self->set_filename($args{"filename"});
 	$self->set_filename($args{"filename"});
     }
     }
@@ -126,6 +128,7 @@ sub open_for_read {
     if ($self->use_compression()) {
     if ($self->use_compression()) {
 	$self->{'compressor'}->uncompress(to_pipe => \$handle,
 	$self->{'compressor'}->uncompress(to_pipe => \$handle,
 		from_file => $self->get_filename());
 		from_file => $self->get_filename());
+        $self->{'allow_sigpipe'} = 1;
     } else {
     } else {
 	open($handle, '<', $self->get_filename()) ||
 	open($handle, '<', $self->get_filename()) ||
 		syserr(_g("cannot read %s"), $self->get_filename());
 		syserr(_g("cannot read %s"), $self->get_filename());
@@ -135,7 +138,12 @@ sub open_for_read {
 
 
 sub cleanup_after_open {
 sub cleanup_after_open {
     my ($self) = @_;
     my ($self) = @_;
-    $self->{"compressor"}->wait_end_process();
+    $self->{"compressor"}->wait_end_process(nocheck => $self->{'allow_sigpipe'});
+    if ($self->{'allow_sigpipe'}) {
+        unless (($? == 0) || (WIFSIGNALED($?) && (WTERMSIG($?) == SIGPIPE))) {
+            subprocerr($self->{"compressor"}{"cmdline"});
+        }
+    }
 }
 }
 
 
 1;
 1;

+ 3 - 2
scripts/Dpkg/Source/Compressor.pm

@@ -122,8 +122,9 @@ sub uncompress {
 }
 }
 
 
 sub wait_end_process {
 sub wait_end_process {
-    my ($self) = @_;
-    wait_child($self->{"pid"}, cmdline => $self->{"cmdline"}) if $self->{'pid'};
+    my ($self, %opts) = @_;
+    $opts{"cmdline"} ||= $self->{"cmdline"};
+    wait_child($self->{"pid"}, %opts) if $self->{'pid'};
     delete $self->{"pid"};
     delete $self->{"pid"};
     delete $self->{"cmdline"};
     delete $self->{"cmdline"};
 }
 }