Просмотр исходного кода

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
Родитель
Сommit
e5235b174b
3 измененных файлов с 15 добавлено и 3 удалено
  1. 3 0
      debian/changelog
  2. 9 1
      scripts/Dpkg/Source/CompressedFile.pm
  3. 3 2
      scripts/Dpkg/Source/Compressor.pm

+ 3 - 0
debian/changelog

@@ -50,6 +50,9 @@ dpkg (1.15.1) UNRELEASED; urgency=low
     Thanks to Nils Rennebarth for the patch.
   * Fix a mistake in the french translation of dpkg's manual page.
     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 ]
   * 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::Gettext;
 use Dpkg::ErrorHandling;
+use POSIX;
 
 # Object methods
 sub new {
@@ -35,6 +36,7 @@ sub new {
     $self->{"compressor"} = Dpkg::Source::Compressor->new();
     $self->{"add_comp_ext"} = $args{"add_compression_extension"} ||
 	    $args{"add_comp_ext"} || 0;
+    $self->{"allow_sigpipe"} = 0;
     if (exists $args{"filename"}) {
 	$self->set_filename($args{"filename"});
     }
@@ -126,6 +128,7 @@ sub open_for_read {
     if ($self->use_compression()) {
 	$self->{'compressor'}->uncompress(to_pipe => \$handle,
 		from_file => $self->get_filename());
+        $self->{'allow_sigpipe'} = 1;
     } else {
 	open($handle, '<', $self->get_filename()) ||
 		syserr(_g("cannot read %s"), $self->get_filename());
@@ -135,7 +138,12 @@ sub open_for_read {
 
 sub cleanup_after_open {
     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;

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

@@ -122,8 +122,9 @@ sub uncompress {
 }
 
 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->{"cmdline"};
 }