stas 2004/05/03 23:16:46
Modified: t/modperl .cvsignore ModPerl-Registry/lib/ModPerl RegistryCooker.pm src/modules/perl modperl_util.c t/response/TestModperl exit.pm Added: t/modperl exit.t Log: ModPerl::Util::exit now throws an exception object, so it's possible to rethrow exit if it gets trapped in eval context on the user side Revision Changes Path 1.16 +0 -1 modperl-2.0/t/modperl/.cvsignore Index: .cvsignore =================================================================== RCS file: /home/cvs/modperl-2.0/t/modperl/.cvsignore,v retrieving revision 1.15 retrieving revision 1.16 diff -u -u -r1.15 -r1.16 --- .cvsignore 18 Feb 2004 00:23:36 -0000 1.15 +++ .cvsignore 4 May 2004 06:16:46 -0000 1.16 @@ -1,7 +1,6 @@ current_callback.t env.t endav.t -exit.t printf.t print.t pnotes.t 1.1 modperl-2.0/t/modperl/exit.t Index: exit.t =================================================================== use Apache::TestRequest 'GET_BODY_ASSERT'; use Apache::Test; use Apache::TestUtil; my $location = "/TestModperl__exit"; plan tests => 3; { ok t_cmp('exited', GET_BODY_ASSERT("$location?noneval"), "exit in non eval context"); } { my $body = GET_BODY_ASSERT("$location?eval"); ok t_cmp(qr/^ModPerl::Util::exit: exit was called/, $body, "exit in eval context"); ok !t_cmp(qr/must not be reached/, $body, "exit in eval context"); } 1.47 +5 -4 modperl-2.0/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm Index: RegistryCooker.pm =================================================================== RCS file: /home/cvs/modperl-2.0/ModPerl-Registry/lib/ModPerl/RegistryCooker.pm,v retrieving revision 1.46 retrieving revision 1.47 diff -u -u -r1.46 -r1.47 --- RegistryCooker.pm 2 Apr 2004 02:17:45 -0000 1.46 +++ RegistryCooker.pm 4 May 2004 06:16:46 -0000 1.47 @@ -41,7 +41,8 @@ use File::Spec::Functions (); use File::Basename; -use Apache::Const -compile => qw(:common &OPT_EXECCGI); +use Apache::Const -compile => qw(:common &OPT_EXECCGI); +use ModPerl::Const -compile => 'EXIT'; unless (defined $ModPerl::Registry::MarkLine) { $ModPerl::Registry::MarkLine = 1; @@ -714,10 +715,10 @@ sub error_check { my $self = shift; - # ModPerl::Util::exit() is implemented as croak with no message - # so perl will set $@ to " at /some/path", which is not an error + # ModPerl::Util::exit() throws an exception object whose rc is + # ModPerl::EXIT # (see modperl_perl_exit() and modperl_errsv() C functions) - if ($@ and substr($@, 0, 4) ne " at ") { + if ($@ && !(ref $@ && $@ == ModPerl::EXIT)) { $self->log_error($@); return Apache::SERVER_ERROR; } 1.67 +5 -19 modperl-2.0/src/modules/perl/modperl_util.c Index: modperl_util.c =================================================================== RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_util.c,v retrieving revision 1.66 retrieving revision 1.67 diff -u -u -r1.66 -r1.67 --- modperl_util.c 3 Apr 2004 02:35:47 -0000 1.66 +++ modperl_util.c 4 May 2004 06:16:46 -0000 1.67 @@ -261,25 +261,16 @@ return p; } -char *modperl_apr_strerror(apr_status_t rv) -{ - dTHX; - char buf[256]; - apr_strerror(rv, buf, sizeof(buf)); - return Perl_form(aTHX_ "%d:%s", rv, buf); -} - int modperl_errsv(pTHX_ int status, request_rec *r, server_rec *s) { SV *sv = ERRSV; STRLEN n_a; if (SvTRUE(sv)) { - if (SvMAGICAL(sv) && (SvCUR(sv) > 4) && - strnEQ(SvPVX(sv), " at ", 4)) - { + if (sv_derived_from(sv, "APR::Error") && + SvIVx(sv) == MODPERL_RC_EXIT) { /* ModPerl::Util::exit was called */ - return DECLINED; + return OK; } #if 0 if (modperl_sv_is_http_code(ERRSV, &status)) { @@ -572,15 +563,10 @@ void modperl_perl_exit(pTHX_ int status) { - const char *pat = NULL; ENTER; SAVESPTR(PL_diehook); PL_diehook = Nullsv; - sv_setpv(ERRSV, ""); -#ifdef MP_PERL_5_6_0 - pat = ""; /* NULL segvs in 5.6.0 */ -#endif - Perl_croak(aTHX_ pat); + modperl_croak(aTHX_ MODPERL_RC_EXIT, "ModPerl::Util::exit"); } MP_INLINE SV *modperl_dir_config(pTHX_ request_rec *r, server_rec *s, @@ -716,7 +702,7 @@ if (rc != APR_SUCCESS) { \ SvREFCNT_dec(sv); \ Perl_croak(aTHX_ "Error " action " '%s': %s ", r->filename, \ - modperl_apr_strerror(rc)); \ + modperl_error_strerror(aTHX_ rc)); \ } MP_INLINE SV *modperl_slurp_filename(pTHX_ request_rec *r, int tainted) 1.3 +24 -9 modperl-2.0/t/response/TestModperl/exit.pm Index: exit.pm =================================================================== RCS file: /home/cvs/modperl-2.0/t/response/TestModperl/exit.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- exit.pm 11 Apr 2002 11:08:44 -0000 1.2 +++ exit.pm 4 May 2004 06:16:46 -0000 1.3 @@ -1,25 +1,40 @@ package TestModperl::exit; +# there is no need to call ModPerl::Util::exit() explicitly, a plain +# exit() will do. We do the explicit fully qualified call in this +# test, in case something has messed up with CORE::GLOBAL::exit and we +# want to make sure that we test the right API + use strict; use warnings FATAL => 'all'; use ModPerl::Util (); -use Apache::Test; - -use Apache::Const -compile => 'OK'; +use Apache::Const -compile => 'OK'; +use ModPerl::Const -compile => 'EXIT'; sub handler { my $r = shift; - plan $r, test => 1; - - ok 1; + $r->content_type('text/plain'); + my $args = $r->args; - ModPerl::Util::exit(); + if ($args eq 'eval') { + eval { + my $whatever = 1; + ModPerl::Util::exit(); + }; + # test whether we can stringify our custom error messages + $r->print("$@"); + ModPerl::Util::exit if $@ && ref $@ && $@ == ModPerl::EXIT; + } + elsif ($args eq 'noneval') { + $r->print("exited"); + ModPerl::Util::exit(); + } - #not reached - ok 2; + # must not be reached + $r->print("must not be reached"); Apache::OK; }