Open duelafn opened 9 years ago
capturex will, if execution fails, call END{} blocks one too many times. Suggest adding this fix from http://stackoverflow.com/questions/4307482/how-do-i-disable-end-blocks-in-child-processes
Can you provide a code example that demonstrates the problem which your p.r. is intended to address?
Thank you very much. Jim Keenan (co-maintainer)
I think that my original problem was an END{}
block used by a GUI library being called prematurely. However, this example shows what can happen:
use strict;
use warnings;
use IPC::System::Simple qw/ capturex /;
use File::Path qw/ remove_tree /;
my $dir = "/tmp/t6LupMzfsF";
mkdir $dir;
END {
print STDERR "FINISHED!\n";
remove_tree $dir;
# Log out of a website (invalidate LWP cookie)
# Delete temporary directory
# Use a GUI module that does cleanup in an END block
}
open my $F1, ">", "$dir/test.1" or die "Error writing $dir/test.1: $!";
print $F1 "Hello\n";
close $F1;
eval {
capturex "/usr/bin/NO-SUCH-PROGRAM";
};
open my $F2, ">", "$dir/test.2" or die "Error writing $dir/test.2: $!";
print $F2 "Hello\n";
close $F2;
The END block is called in the forked child of capturex when in an eval. In this case, that child END block removes a temporary directory that the original process is still using. The result is that the open $F2
call fails since the directory is now gone.
Script output:
FINISHED!
Error writing /tmp/t6LupMzfsF/test.2: No such file or directory at /tmp/test.pl line 25.
FINISHED!
Also, eval { capturex }
with a failure is the only situation that causes an extra evaluation of END blocks. Other functions (capture, system, systemx) and successful capturex all behave correctly and do not evaluate END blocks multiple times. Therefore, there should be little concern of breaking existing code. It is unlikely that anyone is relying on calling END in the capturex child.
capturex will, if execution fails, call END{} blocks one too many times. Suggest adding this fix from http://stackoverflow.com/questions/4307482/how-do-i-disable-end-blocks-in-child-processes