diff options
author | Nicholas Clark <nick@ccl4.org> | 2009-05-20 21:52:58 +0200 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2009-05-20 21:52:58 +0200 |
commit | 38a124f06b8ced6241a4e9b1c3408609d2da87e9 (patch) | |
tree | eef665e16ade6f14475b224ea343fbdff9c01481 /mg.c | |
parent | 179c85a2d774d3be8975d7f80a3ae831be6dc4cd (diff) | |
download | perl-38a124f06b8ced6241a4e9b1c3408609d2da87e9.tar.gz |
Merge the bulk of Perl_magic_clearsig() into Perl_magic_setsig().
The comment at the top of Perl_magic_clearsig() said:
XXX Some of this code was copied from Perl_magic_setsig. A little
refactoring might be in order.
and it was not wrong.
Perl_magic_clearsig() is almost equivalent to Perl_magic_setsig() with the new
signal handler as "DEFAULT". Externally, the sv parameter to Perl_magic_setsig()
was Not NULL, so use a NULL sv to signal that the code is being called as
Perl_magic_clearsig(), for the places where the behaviour of the two diverges.
Diffstat (limited to 'mg.c')
-rw-r--r-- | mg.c | 102 |
1 files changed, 29 insertions, 73 deletions
@@ -1265,70 +1265,10 @@ Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg) { - /* XXX Some of this code was copied from Perl_magic_setsig. A little - * refactoring might be in order. - */ - dVAR; - register const char * const s = MgPV_nolen_const(mg); PERL_ARGS_ASSERT_MAGIC_CLEARSIG; PERL_UNUSED_ARG(sv); - if (*s == '_') { - SV** svp = NULL; - if (strEQ(s,"__DIE__")) - svp = &PL_diehook; - else if (strEQ(s,"__WARN__") && PL_warnhook != PERL_WARNHOOK_FATAL) - svp = &PL_warnhook; - if (svp && *svp) { - SV *const to_dec = *svp; - *svp = NULL; - SvREFCNT_dec(to_dec); - } - } - else { - /* Are we clearing a signal entry? */ - const I32 i = whichsig(s); - if (i > 0) { -#ifdef HAS_SIGPROCMASK - sigset_t set, save; - SV* save_sv; - /* Avoid having the signal arrive at a bad time, if possible. */ - sigemptyset(&set); - sigaddset(&set,i); - sigprocmask(SIG_BLOCK, &set, &save); - ENTER; - save_sv = newSVpvn((char *)(&save), sizeof(sigset_t)); - SAVEFREESV(save_sv); - SAVEDESTRUCTOR_X(restore_sigmask, save_sv); -#endif - PERL_ASYNC_CHECK(); -#if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS) - if (!PL_sig_handlers_initted) Perl_csighandler_init(); -#endif -#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS - PL_sig_defaulting[i] = 1; - (void)rsignal(i, PL_csighandlerp); -#else - (void)rsignal(i, (Sighandler_t) SIG_DFL); -#endif - if(PL_psig_name[i]) { - SvREFCNT_dec(PL_psig_name[i]); - PL_psig_name[i]=0; - } - if(PL_psig_ptr[i]) { - SV * const to_dec=PL_psig_ptr[i]; - PL_psig_ptr[i]=0; -#ifdef HAS_SIGPROCMASK - LEAVE; -#endif - SvREFCNT_dec(to_dec); - } -#ifdef HAS_SIGPROCMASK - else - LEAVE; -#endif - } - } + magic_setsig(NULL, mg); return sv_unmagic(sv, mg->mg_type); } @@ -1431,6 +1371,7 @@ Perl_despatch_signals(pTHX) } } +/* sv of NULL signifies that we're acting as magic_clearsig. */ int Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) { @@ -1454,12 +1395,18 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) if (*s == '_') { if (strEQ(s,"__DIE__")) svp = &PL_diehook; - else if (strEQ(s,"__WARN__")) + else if (strEQ(s,"__WARN__") + && (sv ? 1 : PL_warnhook != PERL_WARNHOOK_FATAL)) { + /* Merge the existing behaviours, which are as follows: + magic_setsig, we always set svp to &PL_warnhook + (hence we always change the warnings handler) + For magic_clearsig, we don't change the warnings handler if it's + set to the &PL_warnhook. */ svp = &PL_warnhook; - else + } else if (sv) Perl_croak(aTHX_ "No such hook: %s", s); i = 0; - if (*svp) { + if (svp && *svp) { if (*svp != PERL_WARNHOOK_FATAL) to_dec = *svp; *svp = NULL; @@ -1468,7 +1415,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) else { i = whichsig(s); /* ...no, a brick */ if (i <= 0) { - if (ckWARN(WARN_SIGNAL)) + if (sv && ckWARN(WARN_SIGNAL)) Perl_warner(aTHX_ packWARN(WARN_SIGNAL), "No such signal: SIG%s", s); return 0; } @@ -1494,12 +1441,17 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) #endif SvREFCNT_dec(PL_psig_name[i]); to_dec = PL_psig_ptr[i]; - PL_psig_ptr[i] = SvREFCNT_inc_simple_NN(sv); - SvTEMP_off(sv); /* Make sure it doesn't go away on us */ - PL_psig_name[i] = newSVpvn(s, len); - SvREADONLY_on(PL_psig_name[i]); + if (sv) { + PL_psig_ptr[i] = SvREFCNT_inc_simple_NN(sv); + SvTEMP_off(sv); /* Make sure it doesn't go away on us */ + PL_psig_name[i] = newSVpvn(s, len); + SvREADONLY_on(PL_psig_name[i]); + } else { + PL_psig_name[i] = NULL; + PL_psig_ptr[i] = NULL; + } } - if (isGV_with_GP(sv) || SvROK(sv)) { + if (sv && (isGV_with_GP(sv) || SvROK(sv))) { if (i) { (void)rsignal(i, PL_csighandlerp); #ifdef HAS_SIGPROCMASK @@ -1512,8 +1464,12 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) SvREFCNT_dec(to_dec); return 0; } - s = SvOK(sv) ? SvPV_force(sv,len) : "DEFAULT"; - if (strEQ(s,"IGNORE")) { + if (sv && SvOK(sv)) { + s = SvPV_force(sv, len); + } else { + sv = NULL; + } + if (sv && strEQ(s,"IGNORE")) { if (i) { #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS PL_sig_ignoring[i] = 1; @@ -1523,7 +1479,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) #endif } } - else if (strEQ(s,"DEFAULT") || !*s) { + else if (!sv || strEQ(s,"DEFAULT") || !len) { if (i) { #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS PL_sig_defaulting[i] = 1; |