diff options
author | Guillem Jover <guillem@debian.org> | 2016-10-14 23:58:59 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2016-10-30 05:02:34 +0100 |
commit | 05d5a6590879078c9992b9e8a8a07371413858e1 (patch) | |
tree | ee12b65fd4a45dc7c6634ac111f5072566cc9b0c /scripts/Dpkg/IPC.pm | |
parent | ea506ec3f20f6c81ce3dcff5cd99ab8146685a35 (diff) | |
download | dpkg-05d5a6590879078c9992b9e8a8a07371413858e1.tar.gz |
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
Diffstat (limited to 'scripts/Dpkg/IPC.pm')
-rw-r--r-- | scripts/Dpkg/IPC.pm | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/scripts/Dpkg/IPC.pm b/scripts/Dpkg/IPC.pm index 51725406b..3dfbde94a 100644 --- a/scripts/Dpkg/IPC.pm +++ b/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}}); |