diff options
author | Raphael Hertzog <hertzog@debian.org> | 2008-04-01 17:33:08 +0200 |
---|---|---|
committer | Raphael Hertzog <hertzog@debian.org> | 2008-04-01 19:23:16 +0200 |
commit | 10b5f63549fce397982db587b00ebb24e05a9322 (patch) | |
tree | 67314c2289d67884ae297c4ae21de4e17d692841 /scripts/Dpkg/IPC.pm | |
parent | dfce3fac910526aa41d6a22ce826c2a725c1b431 (diff) | |
download | dpkg-10b5f63549fce397982db587b00ebb24e05a9322.tar.gz |
Dpkg::IPC: Support redirection of STDERR in fork_and_exec()
* scripts/Dpkg/IPC.pm (fork_and_exec): Handle redirection
of STDERR with new options error_to_{file,pipe,string,handle}.
Diffstat (limited to 'scripts/Dpkg/IPC.pm')
-rw-r--r-- | scripts/Dpkg/IPC.pm | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/scripts/Dpkg/IPC.pm b/scripts/Dpkg/IPC.pm index 6184c14da..e75ba989c 100644 --- a/scripts/Dpkg/IPC.pm +++ b/scripts/Dpkg/IPC.pm @@ -68,32 +68,33 @@ globbing. Mandatory Option. -=item from_file, to_file +=item from_file, to_file, error_to_file -Filename as scalar. Standard input and/or standard output of the +Filename as scalar. Standard input/output/error of the child process will be redirected to the file specifed. -=item from_handle, to_handle +=item from_handle, to_handle, error_to_handle -Filehandle. Standard input and/or standard output of the -child process will be dup'ed from the handle. +Filehandle. Standard input/output/error of the child process will be +dup'ed from the handle. -=item from_pipe, to_pipe +=item from_pipe, to_pipe, error_to_pipe Scalar reference. A pipe will be opened for each of the two options -and either the reading (C<to_pipe>) or the writing end (C<from_pipe>) -will be returned in the referenced scalar. Standard input and/or standard -output of the child process will be dup'ed to the other ends of the -pipes. +and either the reading (C<to_pipe> and C<error_to_pipe>) or the writing +end (C<from_pipe>) will be returned in the referenced scalar. Standard +input/output/error of the child process will be dup'ed to the other ends +of the pipes. -=item from_string, to_string +=item from_string, to_string, error_to_string -Scalar reference. Standard input and/or standard output of the child +Scalar reference. Standard input/output/error of the child process will be redirected to the string given as reference. Note that it wouldn't be strictly necessary to use a scalar reference for C<from_string>, as the string is not modified in any way. This was -chosen only for reasons of symmetry with C<to_string>. C<to_string> -implies the C<wait_child> option. +chosen only for reasons of symmetry with C<to_string> and +C<error_to_string>. C<to_string> and C<error_to_string> imply the +C<wait_child> option. =item wait_child @@ -126,17 +127,22 @@ sub _sanity_check_opts { error("exec parameter is mandatory in fork_and_exec()") unless $opts{"exec"}; - my $to = my $from = 0; + my $to = my $error_to = my $from = 0; foreach (qw(file handle string pipe)) { $to++ if $opts{"to_$_"}; + $error_to++ if $opts{"error_to_$_"}; $from++ if $opts{"from_$_"}; } error("not more than one of to_* parameters is allowed") if $to > 1; + error("not more than one of error_to_* parameters is allowed") + if $error_to > 1; error("not more than one of from_* parameters is allowed") if $from > 1; - foreach (qw(to_string from_string to_pipe from_pipe)) { + foreach (qw(to_string error_to_string from_string + to_pipe error_to_pipe from_pipe)) + { if (exists $opts{$_} and (!ref($opts{$_}) or ref($opts{$_}) ne 'SCALAR')) { error("parameter $_ must be a scalar reference"); @@ -165,16 +171,20 @@ sub fork_and_exec { } else { error(_g("invalid exec parameter in fork_and_exec()")); } - my ($from_string_pipe, $to_string_pipe); + my ($from_string_pipe, $to_string_pipe, $error_to_string_pipe); if ($opts{"to_string"}) { $opts{"to_pipe"} = \$to_string_pipe; $opts{"wait_child"} = 1; } + if ($opts{"error_to_string"}) { + $opts{"error_to_pipe"} = \$error_to_string_pipe; + $opts{"wait_child"} = 1; + } if ($opts{"from_string"}) { $opts{"from_pipe"} = \$from_string_pipe; } # Create pipes if needed - my ($input_pipe, $output_pipe); + my ($input_pipe, $output_pipe, $error_pipe); if ($opts{"from_pipe"}) { pipe($opts{"from_handle"}, $input_pipe) || syserr(_g("pipe for %s"), "@prog"); @@ -187,6 +197,12 @@ sub fork_and_exec { ${$opts{"to_pipe"}} = $output_pipe; push @{$opts{"close_in_child"}}, $output_pipe; } + if ($opts{"error_to_pipe"}) { + pipe($error_pipe, $opts{"error_to_handle"}) || + syserr(_g("pipe for %s"), "@prog"); + ${$opts{"error_to_pipe"}} = $error_pipe; + push @{$opts{"close_in_child"}}, $error_pipe; + } # Fork and exec my $pid = fork(); syserr(_g("fork for %s"), "@prog") unless defined $pid; @@ -220,6 +236,14 @@ sub fork_and_exec { open(STDOUT, ">&", $opts{"to_handle"}) || syserr(_g("reopen stdout")); close($opts{"to_handle"}); # has been duped, can be closed } + # Redirect STDERR if needed + if ($opts{"error_to_file"}) { + open(STDERR, ">", $opts{"error_to_file"}) || + syserr(_g("cannot write %s"), $opts{"error_to_file"}); + } elsif ($opts{"error_to_handle"}) { + open(STDERR, ">&", $opts{"error_to_handle"}) || syserr(_g("reopen stdout")); + close($opts{"error_to_handle"}); # has been duped, can be closed + } # Close some inherited filehandles close($_) foreach (@{$opts{"close_in_child"}}); # Execute the program @@ -228,6 +252,7 @@ sub fork_and_exec { # Close handle that we can't use any more close($opts{"from_handle"}) if exists $opts{"from_handle"}; close($opts{"to_handle"}) if exists $opts{"to_handle"}; + close($opts{"error_to_handle"}) if exists $opts{"error_to_handle"}; if ($opts{"from_string"}) { print $from_string_pipe ${$opts{"from_string"}}; @@ -237,6 +262,10 @@ sub fork_and_exec { local $/ = undef; ${$opts{"to_string"}} = readline($to_string_pipe); } + if ($opts{"error_to_string"}) { + local $/ = undef; + ${$opts{"error_to_string"}} = readline($error_to_string_pipe); + } if ($opts{"wait_child"}) { wait_child($pid, cmdline => "@prog"); return 1; |