📜 ⬆️ ⬇️

goto in CORE :: GLOBAL :: exit - where is the rake?

I have a CGI card I want to run under FastCGI.

It uses a framework that processes html templates, displays errors (die) to the browser, makes all redirects, gives files, etc. - everything is as usual. This framework, after generating and displaying the answer to STDOUT, does exit() - which is also, in general, not original.

This exit() can be called inside eval() , or even several nested evals - for example, if CGIshka decides to give the user a redirect somewhere in the depth of the calculations. At the same time, it calls the framework function, it does the print "Location: ..." and exit() .
')
But under FastCGI exit() cannot be done.

Therefore, it is necessary to intercept this exit, and do either die() (just like it does , for example, mod_perl), or goto . The problem with die() is that if exit() was called inside eval() , and after calling eval, the user will not pass an unknown error above by calling die() again (and guarantee this behavior after each eval in this CGI file I can not - I can rather guarantee that this usually does not happen), then exit() will simply lead to exit from the nearest eval() , which the CGI card that caused the redirect obviously did not expect!

Pseudo CGIshki


sub that_cgi_script {
...
eval { do_something() };
...
}
sub do_something {
# 1) may return if everything ok
# 2) may die on error, but such error non-important to
# calling code in above case and will be catched by
# eval and ignored
# 3) may redirect: print Location header and call exit()
}

Option exit through die


my $FCGI_EXIT = "FCGI NORMAL EXIT\n";
BEGIN { *CORE::GLOBAL::exit = sub { die $FCGI_EXIT }; }
while (CGI::Fast->new()) {
eval { that_cgi_script(); };
die $@ if $@ && $@ ne $FCGI_EXIT;
$CGI::Fast::Ext_Request->Finish();
}

Option exit through goto


BEGIN { *CORE::GLOBAL::exit = sub { goto EXIT }; }
while (CGI::Fast->new()) {
eval { that_cgi_script(); };
die $@ if $@;
EXIT:
$CGI::Fast::Ext_Request->Finish();
}

What perldoc -f goto says


It may not be used to go into any construct that requires initialization, such as a subroutine or a “foreach” loop. It is given that it is given to “sort”.

So where is the rake?


It seems that the only goto problem that applies to this situation is the exit() call inside the sort . :) I sincerely believe that this CGIshka does not allow this to itself. Amen.

What else can be a rake when using goto in CORE::GLOBAL::exit ? It is alarming to me that goto does not use mod_perl, although it seems to be a more efficient solution than die() .

Source: https://habr.com/ru/post/13681/


All Articles