Use PERL=../miniperl
[p5sagit/p5-mst-13.2.git] / mg.c
diff --git a/mg.c b/mg.c
index 1b69701..9461515 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -80,6 +80,7 @@ SV* sv;
     U32 savemagic = SvMAGICAL(sv);
 
     SvMAGICAL_off(sv);
+    SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
 
     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
        MGVTBL* vtbl = mg->mg_virtual;
@@ -530,6 +531,49 @@ MAGIC* mg;
     return 0;
 }
 
+#ifdef HAS_SIGACTION
+/* set up reliable signal() clone */
+
+typedef void (*Sigfunc) _((int));
+
+static
+Sigfunc rsignal(signo,handler)
+int signo;
+Sigfunc handler;
+{
+    struct sigaction act,oact;
+    
+    act.sa_handler = handler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = 0;
+#ifdef SIGALRM    
+    if (signo == SIGALRM) {
+#else
+    if (0) {
+#endif        
+#ifdef SA_INTERRUPT
+       act.sa_flags |= SA_INTERRUPT;   /* SunOS */
+#endif 
+    } else {
+#ifdef SA_RESTART
+       act.sa_flags |= SA_RESTART;     /* SVR4, 4.3+BSD */
+#endif
+    }
+    if (sigaction(signo, &act, &oact) < 0)
+       return(SIG_ERR);
+    else
+       return(oact.sa_handler);
+}
+
+#else
+
+/* ah well, so much for reliability */
+
+#define rsignal(x,y) signal(x,y)
+
+#endif
+
+
 int
 magic_setsig(sv,mg)
 SV* sv;
@@ -550,6 +594,10 @@ MAGIC* mg;
        else
            croak("No such hook: %s", s);
        i = 0;
+       if (*svp) {
+           SvREFCNT_dec(*svp);
+           *svp = 0;
+       }
     }
     else {
        i = whichsig(s);        /* ...no, a brick */
@@ -561,7 +609,7 @@ MAGIC* mg;
     }
     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
        if (i)
-           (void)signal(i,sighandler);
+           (void)rsignal(i,sighandler);
        else
            *svp = SvREFCNT_inc(sv);
        return 0;
@@ -569,13 +617,13 @@ MAGIC* mg;
     s = SvPV_force(sv,na);
     if (strEQ(s,"IGNORE")) {
        if (i)
-           (void)signal(i,SIG_IGN);
+           (void)rsignal(i,SIG_IGN);
        else
            *svp = 0;
     }
     else if (strEQ(s,"DEFAULT") || !*s) {
        if (i)
-           (void)signal(i,SIG_DFL);
+           (void)rsignal(i,SIG_DFL);
        else
            *svp = 0;
     }
@@ -585,7 +633,7 @@ MAGIC* mg;
            sv_setpv(sv,tokenbuf);
        }
        if (i)
-           (void)signal(i,sighandler);
+           (void)rsignal(i,sighandler);
        else
            *svp = SvREFCNT_inc(sv);
     }
@@ -1093,7 +1141,7 @@ MAGIC* mg;
 #endif
 #endif
        uid = (I32)getuid();
-       tainting |= (euid != uid || egid != gid);
+       tainting |= (uid && (euid != uid || egid != gid));
        break;
     case '>':
        euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
@@ -1120,7 +1168,7 @@ MAGIC* mg;
 #endif
 #endif
        euid = (I32)geteuid();
-       tainting |= (euid != uid || egid != gid);
+       tainting |= (uid && (euid != uid || egid != gid));
        break;
     case '(':
        gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
@@ -1147,7 +1195,7 @@ MAGIC* mg;
 #endif
 #endif
        gid = (I32)getgid();
-       tainting |= (euid != uid || egid != gid);
+       tainting |= (uid && (euid != uid || egid != gid));
        break;
     case ')':
        egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
@@ -1174,7 +1222,7 @@ MAGIC* mg;
 #endif
 #endif
        egid = (I32)getegid();
-       tainting |= (euid != uid || egid != gid);
+       tainting |= (uid && (euid != uid || egid != gid));
        break;
     case ':':
        chopset = SvPV_force(sv,na);
@@ -1240,17 +1288,6 @@ char *sig;
     return 0;
 }
 
-char *
-whichsigname(sig)
-int sig;
-{
-    register int i;
-    for (i = 1; sig_num[i]; i++)  /* sig_num[] is a 0-terminated list */
-       if (sig_num[i] == sig)
-           return sig_name[i];
-    return Nullch;
-}
-
 Signal_t
 sighandler(sig)
 int sig;
@@ -1267,7 +1304,7 @@ int sig;
     signal(sig, SIG_ACK);
 #endif
 
-    signame = whichsigname(sig);
+    signame = sig_name[sig];
     cv = sv_2cv(*hv_fetch(GvHVn(siggv),signame,strlen(signame),
                          TRUE),
                &st, &gv, TRUE);