Ver código fonte

Dpkg::IPC: Defer filehandle closures in spawn() to avoid double-close

When the caller passes the same filehandle for STDIN, STDOUT or STDERR,
the code will try to close the same filehandle more than once, producing
an error. Defer the closures to the end using the same close_in_child
array already used for other filehandles.

Closes: #839905, #840293
Guillem Jover 9 anos atrás
pai
commit
05d5a65908
2 arquivos alterados com 8 adições e 3 exclusões
  1. 2 0
      debian/changelog
  2. 6 3
      scripts/Dpkg/IPC.pm

+ 2 - 0
debian/changelog

@@ -58,6 +58,8 @@ dpkg (1.18.11) UNRELEASED; urgency=medium
     - Fix reproducible source package support in Dpkg::Source::Archive, by
       sorting the tar contents with --sort=name.
     - Prefix private Dpkg::Source::Package::* functions with _.
+    - Defer filehandle closures in Dpkg::IPC::spawn() to avoid double-close.
+      Closes: #839905, #840293
   * Packaging:
     - Add liblocale-gettext-perl to libdpkg-perl Recommends.
     - Wrap and document dependency relationships.

+ 6 - 3
scripts/Dpkg/IPC.pm

@@ -282,7 +282,8 @@ sub spawn {
 	} elsif ($opts{from_handle}) {
 	    open(STDIN, '<&', $opts{from_handle})
 		or syserr(g_('reopen stdin'));
-	    close($opts{from_handle}); # has been duped, can be closed
+	    # has been duped, can be closed
+	    push @{$opts{close_in_child}}, $opts{from_handle};
 	}
 	# Redirect STDOUT if needed
 	if ($opts{to_file}) {
@@ -291,7 +292,8 @@ sub spawn {
 	} elsif ($opts{to_handle}) {
 	    open(STDOUT, '>&', $opts{to_handle})
 		or syserr(g_('reopen stdout'));
-	    close($opts{to_handle}); # has been duped, can be closed
+	    # has been duped, can be closed
+	    push @{$opts{close_in_child}}, $opts{to_handle};
 	}
 	# Redirect STDERR if needed
 	if ($opts{error_to_file}) {
@@ -300,7 +302,8 @@ sub spawn {
 	} elsif ($opts{error_to_handle}) {
 	    open(STDERR, '>&', $opts{error_to_handle})
 	        or syserr(g_('reopen stdout'));
-	    close($opts{error_to_handle}); # has been duped, can be closed
+	    # has been duped, can be closed
+	    push @{$opts{close_in_child}}, $opts{error_to_handle};
 	}
 	# Close some inherited filehandles
 	close($_) foreach (@{$opts{close_in_child}});