Use PERL=../miniperl
[p5sagit/p5-mst-13.2.git] / mg.c
diff --git a/mg.c b/mg.c
index 555c7a1..9461515 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -21,6 +21,7 @@
 #endif
 */
 
+
 void
 mg_magical(sv)
 SV* sv;
@@ -79,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;
@@ -529,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;
@@ -549,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 */
@@ -560,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;
@@ -568,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;
     }
@@ -584,7 +633,7 @@ MAGIC* mg;
            sv_setpv(sv,tokenbuf);
        }
        if (i)
-           (void)signal(i,sighandler);
+           (void)rsignal(i,sighandler);
        else
            *svp = SvREFCNT_inc(sv);
     }
@@ -1092,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);
@@ -1119,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);
@@ -1146,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);
@@ -1173,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);
@@ -1227,7 +1276,7 @@ char *sig;
 
     for (sigv = sig_name+1; *sigv; sigv++)
        if (strEQ(sig,*sigv))
-           return sigv - sig_name;
+           return sig_num[sigv - sig_name];
 #ifdef SIGCLD
     if (strEQ(sig,"CHLD"))
        return SIGCLD;
@@ -1249,18 +1298,20 @@ int sig;
     SV *sv;
     CV *cv;
     AV *oldstack;
+    char *signame; 
 
 #ifdef OS2             /* or anybody else who requires SIG_ACK */
     signal(sig, SIG_ACK);
 #endif
 
-    cv = sv_2cv(*hv_fetch(GvHVn(siggv),sig_name[sig],strlen(sig_name[sig]),
+    signame = sig_name[sig];
+    cv = sv_2cv(*hv_fetch(GvHVn(siggv),signame,strlen(signame),
                          TRUE),
                &st, &gv, TRUE);
     if (!cv || !CvROOT(cv) &&
-       *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
+       *signame == 'C' && instr(signame,"LD")) {
        
-       if (sig_name[sig][1] == 'H')
+       if (signame[1] == 'H')
            cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE),
                        &st, &gv, TRUE);
        else
@@ -1271,7 +1322,7 @@ int sig;
     if (!cv || !CvROOT(cv)) {
        if (dowarn)
            warn("SIG%s handler \"%s\" not defined.\n",
-               sig_name[sig], GvENAME(gv) );
+               signame, GvENAME(gv) );
        return;
     }
 
@@ -1281,7 +1332,7 @@ int sig;
     SWITCHSTACK(stack, signalstack);
 
     sv = sv_newmortal();
-    sv_setpv(sv,sig_name[sig]);
+    sv_setpv(sv,signame);
     PUSHMARK(sp);
     PUSHs(sv);
     PUTBACK;