From: Thomas Lamprecht Date: Tue, 12 Sep 2017 11:25:30 +0000 (+0200) Subject: run_fork_with_timeout: allow returning complex structures X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=commitdiff_plain;h=f2c72fc3ba35b0ff951914bef6ca2c54dd7b52de;ds=inline run_fork_with_timeout: allow returning complex structures Encode the result or the error in JSON. This way complex objects or exceptions may be passed to the parent in a generic way. This allows to remove the second pipe 'pipe_err'. Allow also to return undef without any warnings to our caller. This avoids a "use of uninitialized variable ..." warning Signed-off-by: Thomas Lamprecht --- diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index 81662b1..3080b3e 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -20,6 +20,7 @@ use base 'Exporter'; use URI::Escape; use Encode; use Digest::SHA; +use JSON; use Text::ParseWords; use String::ShellQuote; use Time::HiRes qw(usleep gettimeofday tv_interval alarm); @@ -905,7 +906,6 @@ sub run_fork_with_timeout { my $res; my $error; my $pipe_out = IO::Pipe->new(); - my $pipe_err = IO::Pipe->new(); # disable pending alarms, save their remaining time my $prev_alarm = alarm 0; @@ -922,35 +922,33 @@ sub run_fork_with_timeout { if (!$child) { $pipe_out->writer(); - $pipe_err->writer(); eval { $res = $sub->(); - print {$pipe_out} "$res"; + print {$pipe_out} encode_json({ result => $res }); $pipe_out->flush(); }; if (my $err = $@) { - print {$pipe_err} "$err"; - $pipe_err->flush(); + print {$pipe_out} encode_json({ error => $err }); + $pipe_out->flush(); POSIX::_exit(1); } POSIX::_exit(0); } $pipe_out->reader(); - $pipe_err->reader(); my $readvalues = sub { local $/ = undef; - $res = <$pipe_out>; - $error = <$pipe_err>; + my $child_res = decode_json(scalar<$pipe_out>); + $res = $child_res->{result}; + $error = $child_res->{error}; }; eval { run_with_timeout($timeout, $readvalues); }; warn $@ if $@; $pipe_out->close(); - $pipe_err->close(); kill('KILL', $child); waitpid($child, 0);