rtg has asked for the wisdom of the Perl Monks concerning the following question:
Dear Monks of the Monastery of the greatest language, we are in deep need for your help.
Here is the code that looks like nothing bad is happening:
package Bug::Destroy::System; sub new { my $pkg = shift; bless {}, $pkg; } sub DESTROY { # we need to call some system routine system("echo hello"); } package main; my $t = Bug::Destroy::System->new(); die "Oh, no, bad thing happened!"; __END__
When you run this, you expect your script to exit with non-zero exit status, but watch this:
It is zero! I did not believe that and used strace: Linux:rtg$ perl5.8.8 system-destroy-bug.pl; echo $? Oh, no, bad thing happened! at system-destroy-bug.pl line 15. hello 0
FreeBSD:... waitpid(24613, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0) = 24613 rt_sigaction(SIGINT, {SIG_DFL}, NULL, 8) = 0 rt_sigaction(SIGQUIT, {SIG_DFL}, NULL, 8) = 0 read(3, "", 4) = 0 close(3) = 0 exit_group(0) = ?
So it is definitely 0.... wait4(12266, [{WIFSIGNALED(s) && WTERMSIG(s) == 121} | 0x65747300], 0, + NULL) = 12266 syscall_416(0x2, 0xbfbfe4f0, 0) = 0 syscall_416(0x3, 0xbfbfe4d0, 0) = 0 read(3, "", 4) = 0 close(3) = 0 exit(0) = ?
In this very case if you modify the app for the system to "/this/app/does/not/exists", then the exit code of the process will be 255, i.e. directly from system(), that is the value of $? variable.
By local()izing $? we get somehow reliable behavior but I thought that the only block that is capable of changing the exit status is the END{} one.
Was it intended (i.e. not a bug) and if yes, how can I be sure that some nasty DESTROY{} block somewhere in the code will not alter my dear $? variable set by die() or my own exit()?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: system() in DESTROY bug?
by Corion (Patriarch) on Apr 04, 2008 at 11:35 UTC |