"Safe" signals - trial implementation.
Nick Ing-Simmons [Wed, 17 Jan 2001 22:41:10 +0000 (22:41 +0000)]
 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

gv.c
mg.c
perlio.c
util.c

diff --git a/gv.c b/gv.c
index 8b15d41..ea96c6f 100644 (file)
--- 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 (file)
--- 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);
     }
index 72efa36..61af376 100644 (file)
--- 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 (file)
--- 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;