diff options
author | ivan <ivan> | 2010-05-18 18:49:59 +0000 |
---|---|---|
committer | ivan <ivan> | 2010-05-18 18:49:59 +0000 |
commit | 624b2d44625f69d71175c3348cae635d580c890b (patch) | |
tree | ed57a90db2ecbc72cea6c1d3c175c1dcd1938ab4 /rt/lib/RT/Util.pm | |
parent | 7f4aff45cd6ef2f630d538294fa9d9c4db4ac4aa (diff) | |
parent | e70abd21bab68b23488f7ef1ee2e693a3b365691 (diff) |
This commit was generated by cvs2svn to compensate for changes in r9232,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'rt/lib/RT/Util.pm')
-rw-r--r-- | rt/lib/RT/Util.pm | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/rt/lib/RT/Util.pm b/rt/lib/RT/Util.pm index dd1572127..03d27a39e 100644 --- a/rt/lib/RT/Util.pm +++ b/rt/lib/RT/Util.pm @@ -54,6 +54,42 @@ use base 'Exporter'; our @EXPORT = qw/safe_run_child/; sub safe_run_child (&) { + my $our_pid = $$; + + # situation here is wierd, running external app + # involves fork+exec. At some point after fork, + # but before exec (or during) code can die in a + # child. Local is no help here as die throws + # error out of scope and locals are reset to old + # values. Instead we set values, eval code, check pid + # on failure and reset values only in our original + # process + my $dbh = $RT::Handle->dbh; + $dbh->{'InactiveDestroy'} = 1 if $dbh; + $RT::Handle->{'DisconnectHandleOnDestroy'} = 0; + + my @res; + my $want = wantarray; + eval { + unless ( defined $want ) { + _safe_run_child( @_ ); + } elsif ( $want ) { + @res = _safe_run_child( @_ ); + } else { + @res = ( scalar _safe_run_child( @_ ) ); + } + 1; + } or do { + if ( $our_pid == $$ ) { + $dbh->{'InactiveDestroy'} = 0 if $dbh; + $RT::Handle->{'DisconnectHandleOnDestroy'} = 1; + } + die $@; + }; + return $want? (@res) : $res[0]; +} + +sub _safe_run_child { local @ENV{ 'LANG', 'LC_ALL' } = ( 'C', 'C' ); return shift->() if $ENV{'MOD_PERL'} || $CGI::SpeedyCGI::i_am_speedy; |