From: Nick Ing-Simmons Date: Wed, 17 Jan 2001 22:41:10 +0000 (+0000) Subject: "Safe" signals - trial implementation. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0a8e0eff0300ee74cef43b18ff11d05a6376450e;p=p5sagit%2Fp5-mst-13.2.git "Safe" signals - trial implementation. gv.c tweaked to zero PL_sig_pend array perlio.c tweaked to PERL_ASYNC_CHECK() on EINTR util.c tweaked to not set SA_RESTART to give perlio.c a chance. Odd thing is that it "works" with PERLIO=stdio as well (linux). p4raw-id: //depot/perlio@8467 --- diff --git a/gv.c b/gv.c index 8b15d41..ea96c6f 100644 --- a/gv.c +++ b/gv.c @@ -750,9 +750,9 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) HV *hv; I32 i; if (!PL_psig_ptr) { - New(73, PL_psig_ptr, SIG_SIZE, SV*); - New(73, PL_psig_name, SIG_SIZE, SV*); - New(73, PL_psig_pend, SIG_SIZE, int); + Newz(73, PL_psig_ptr, SIG_SIZE, SV*); + Newz(73, PL_psig_name, SIG_SIZE, SV*); + Newz(73, PL_psig_pend, SIG_SIZE, int); } GvMULTI_on(gv); hv = GvHVn(gv); @@ -764,6 +764,7 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type) sv_setsv(*init, &PL_sv_undef); PL_psig_ptr[i] = 0; PL_psig_name[i] = 0; + PL_psig_pend[i] = 0; } } break; diff --git a/mg.c b/mg.c index 50136e2..8165302 100644 --- a/mg.c +++ b/mg.c @@ -996,6 +996,40 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg) return 0; } +void +Perl_raise_signal(pTHX_ int sig) +{ + /* Set a flag to say this signal is pending */ + PL_psig_pend[sig]++; + /* And one to say _a_ signal is pending */ + PL_sig_pending = 1; +} + +Signal_t +Perl_csighandler(int sig) +{ +#ifdef PERL_OLD_SIGNALS + /* Call the perl level handler now with risk we may be in malloc() etc. */ + (*PL_sighandlerp)(sig); +#else + dTHX; + Perl_raise_signal(aTHX_ sig); +#endif +} + +void +Perl_despatch_signals(pTHX) +{ + int sig; + PL_sig_pending = 0; + for (sig = 1; sig < SIG_SIZE; sig++) { + if (PL_psig_pend[sig]) { + PL_psig_pend[sig] = 0; + (*PL_sighandlerp)(sig); + } + } +} + int Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) { @@ -1034,7 +1068,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) } if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) { if (i) - (void)rsignal(i, PL_sighandlerp); + (void)rsignal(i, &Perl_csighandler); else *svp = SvREFCNT_inc(sv); return 0; @@ -1061,7 +1095,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) if (!strchr(s,':') && !strchr(s,'\'')) sv_insert(sv, 0, 0, "main::", 6); if (i) - (void)rsignal(i, PL_sighandlerp); + (void)rsignal(i, &Perl_csighandler); else *svp = SvREFCNT_inc(sv); } @@ -2145,15 +2179,6 @@ Perl_whichsig(pTHX_ char *sig) return 0; } -void -Perl_despatch_signals(pTHX) -{ -#ifndef PERL_OLD_SIGNALS - /* This is just a dummy for now */ -#endif - PL_sig_pending = 0; -} - static SV* sig_sv; Signal_t @@ -2251,7 +2276,7 @@ Perl_sighandler(int sig) #else /* Not clear if this will work */ (void)rsignal(sig, SIG_IGN); - (void)rsignal(sig, PL_sighandlerp); + (void)rsignal(sig, &Perl_csighandler); #endif Perl_die(aTHX_ Nullch); } diff --git a/perlio.c b/perlio.c index 72efa36..61af376 100644 --- a/perlio.c +++ b/perlio.c @@ -1279,6 +1279,7 @@ PerlIOUnix_read(PerlIO *f, void *vbuf, Size_t count) PerlIOBase(f)->flags |= PERLIO_F_EOF; return len; } + PERL_ASYNC_CHECK(); } } @@ -1296,6 +1297,7 @@ PerlIOUnix_write(PerlIO *f, const void *vbuf, Size_t count) PerlIOBase(f)->flags |= PERLIO_F_ERROR; return len; } + PERL_ASYNC_CHECK(); } } @@ -1329,6 +1331,7 @@ PerlIOUnix_close(PerlIO *f) code = -1; break; } + PERL_ASYNC_CHECK(); } if (code == 0) { diff --git a/util.c b/util.c index b163b05..ca7cacf 100644 --- a/util.c +++ b/util.c @@ -2548,8 +2548,10 @@ Perl_rsignal(pTHX_ int signo, Sighandler_t handler) sigemptyset(&act.sa_mask); act.sa_flags = 0; #ifdef SA_RESTART +#if !defined(USE_PERLIO) || defined(PERL_OLD_SIGNALS) act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ #endif +#endif #ifdef SA_NOCLDWAIT if (signo == SIGCHLD && handler == (Sighandler_t)SIG_IGN) act.sa_flags |= SA_NOCLDWAIT; @@ -2580,8 +2582,10 @@ Perl_rsignal_save(pTHX_ int signo, Sighandler_t handler, Sigsave_t *save) sigemptyset(&act.sa_mask); act.sa_flags = 0; #ifdef SA_RESTART +#if !defined(USE_PERLIO) || defined(PERL_OLD_SIGNALS) act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ #endif +#endif #ifdef SA_NOCLDWAIT if (signo == SIGCHLD && handler == (Sighandler_t)SIG_IGN) act.sa_flags |= SA_NOCLDWAIT;