I've a cgi script, which I wish to run under FastCGI. That script call exit() in several places (normal output, redirect, sendfile, die on error). And these places can be called inside eval (maybe - several evals each inside another). And there no guarantee 'unknown' errors catched by eval will be always propagated. Here pseudocode example:
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() }
Now, in my FastCGI application, I must call this cgi script. Of course, I must intercept exit(), to prevent exiting to continue with FCGI->Accept(). There two options how to do this - with 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 q{} && $@ ne $FCGI_EXIT; $CGI::Fast::Ext_Request->Finish(); }
and with goto():
BEGIN { *CORE::GLOBAL::exit = sub { goto EXIT }; } while (CGI::Fast->new()) { eval { that_cgi_script(); }; die $@ if $@ ne q{}; EXIT: $CGI::Fast::Ext_Request->Finish(); }
AFAIK recommended is first solution with die(), and it used in mod_perl. But die() unable to break more than one eval, and in example above in case "3) may redirect" after calling exit I'll not return into my FastCGI loop, but continue executing inside that_cgi_script() after it eval (which will not propagate my die()). Second solution with goto() will work correctly. But I'm not sure is it safe. 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 also can't be used to go into a construct that is optimized away, or to get out of a block or subroutine given to "sort".
Looks like only possible case in my situation is calling exit() inside sort(). :) I believe this cgi script will not do this. Amen. Is there any other possible issues with goto() from CORE::GLOBAL::exit() handler?

P.S. A little offtopic, but any recommendations about CPAN modules for FastCGI support are welcome. Maybe it's better to use some other module instead of CGI::Fast because of some reason, etc.


In reply to goto in CORE::GLOBAL::exit - is it safe? by powerman

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.