Fix a typo, un-shout, and reformat the installation output.
[p5sagit/p5-mst-13.2.git] / mg.c
diff --git a/mg.c b/mg.c
index 2906a4c..695272d 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -1,6 +1,6 @@
 /*    mg.c
  *
- *    Copyright (c) 1991-1997, Larry Wall
+ *    Copyright (c) 1991-1999, Larry Wall
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -13,6 +13,7 @@
  */
 
 #include "EXTERN.h"
+#define PERL_IN_MG_C
 #include "perl.h"
 
 /* XXX If this causes problems, set i_unistd=undef in the hint file.  */
 #  define VTBL            this->*vtbl
 #else
 #  define VTBL                 *vtbl
-static void restore_magic _((void *p));
-static int magic_methcall(SV *sv, MAGIC *mg, char *meth, I32 f, int n, SV *val);
 #endif
 
+static void restore_magic(pTHXo_ void *p);
+static void unwind_handler_stack(pTHXo_ void *p);
+
 /*
  * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
  */
@@ -46,7 +48,7 @@ struct magic_state {
 /* MGS is typedef'ed to struct magic_state in perl.h */
 
 STATIC void
-save_magic(I32 mgs_ix, SV *sv)
+S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
 {
     dTHR;
     MGS* mgs;
@@ -64,50 +66,8 @@ save_magic(I32 mgs_ix, SV *sv)
     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
 }
 
-STATIC void
-restore_magic(void *p)
-{
-    dTHR;
-    MGS* mgs = SSPTR((I32)p, MGS*);
-    SV* sv = mgs->mgs_sv;
-
-    if (!sv)
-        return;
-
-    if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
-    {
-       if (mgs->mgs_flags)
-           SvFLAGS(sv) |= mgs->mgs_flags;
-       else
-           mg_magical(sv);
-       if (SvGMAGICAL(sv))
-           SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
-    }
-
-    mgs->mgs_sv = NULL;  /* mark the MGS structure as restored */
-
-    /* If we're still on top of the stack, pop us off.  (That condition
-     * will be satisfied if restore_magic was called explicitly, but *not*
-     * if it's being called via leave_scope.)
-     * The reason for doing this is that otherwise, things like sv_2cv()
-     * may leave alloc gunk on the savestack, and some code
-     * (e.g. sighandler) doesn't expect that...
-     */
-    if (PL_savestack_ix == mgs->mgs_ss_ix)
-    {
-       I32 popval = SSPOPINT;
-        assert(popval == SAVEt_DESTRUCTOR);
-        PL_savestack_ix -= 2;
-       popval = SSPOPINT;
-        assert(popval == SAVEt_ALLOC);
-       popval = SSPOPINT;
-        PL_savestack_ix -= popval;
-    }
-
-}
-
 void
-mg_magical(SV *sv)
+Perl_mg_magical(pTHX_ SV *sv)
 {
     MAGIC* mg;
     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
@@ -124,7 +84,7 @@ mg_magical(SV *sv)
 }
 
 int
-mg_get(SV *sv)
+Perl_mg_get(pTHX_ SV *sv)
 {
     dTHR;
     I32 mgs_ix;
@@ -139,7 +99,7 @@ mg_get(SV *sv)
     while ((mg = *mgp) != 0) {
        MGVTBL* vtbl = mg->mg_virtual;
        if (!(mg->mg_flags & MGf_GSKIP) && vtbl && (vtbl->svt_get != NULL)) {
-           (VTBL->svt_get)(sv, mg);
+           (VTBL->svt_get)(aTHX_ sv, mg);
            /* Ignore this magic if it's been deleted */
            if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) &&
                  (mg->mg_flags & MGf_GSKIP))
@@ -154,12 +114,12 @@ mg_get(SV *sv)
            mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
     }
 
-    restore_magic((void*)mgs_ix);
+    restore_magic(aTHXo_ (void*)mgs_ix);
     return 0;
 }
 
 int
-mg_set(SV *sv)
+Perl_mg_set(pTHX_ SV *sv)
 {
     dTHR;
     I32 mgs_ix;
@@ -177,15 +137,15 @@ mg_set(SV *sv)
            (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
        }
        if (vtbl && (vtbl->svt_set != NULL))
-           (VTBL->svt_set)(sv, mg);
+           (VTBL->svt_set)(aTHX_ sv, mg);
     }
 
-    restore_magic((void*)mgs_ix);
+    restore_magic(aTHXo_ (void*)mgs_ix);
     return 0;
 }
 
 U32
-mg_length(SV *sv)
+Perl_mg_length(pTHX_ SV *sv)
 {
     MAGIC* mg;
     char *junk;
@@ -199,8 +159,8 @@ mg_length(SV *sv)
            mgs_ix = SSNEW(sizeof(MGS));
            save_magic(mgs_ix, sv);
            /* omit MGf_GSKIP -- not changed here */
-           len = (VTBL->svt_len)(sv, mg);
-           restore_magic((void*)mgs_ix);
+           len = (VTBL->svt_len)(aTHX_ sv, mg);
+           restore_magic(aTHXo_ (void*)mgs_ix);
            return len;
        }
     }
@@ -210,7 +170,7 @@ mg_length(SV *sv)
 }
 
 I32
-mg_size(SV *sv)
+Perl_mg_size(pTHX_ SV *sv)
 {
     MAGIC* mg;
     I32 len;
@@ -223,8 +183,8 @@ mg_size(SV *sv)
            mgs_ix = SSNEW(sizeof(MGS));
            save_magic(mgs_ix, sv);
            /* omit MGf_GSKIP -- not changed here */
-           len = (VTBL->svt_len)(sv, mg);
-           restore_magic((void*)mgs_ix);
+           len = (VTBL->svt_len)(aTHX_ sv, mg);
+           restore_magic(aTHXo_ (void*)mgs_ix);
            return len;
        }
     }
@@ -236,14 +196,14 @@ mg_size(SV *sv)
        case SVt_PVHV:
            /* FIXME */
        default:
-           croak("Size magic not implemented");
+           Perl_croak(aTHX_ "Size magic not implemented");
            break;
     }
     return 0;
 }
 
 int
-mg_clear(SV *sv)
+Perl_mg_clear(pTHX_ SV *sv)
 {
     I32 mgs_ix;
     MAGIC* mg;
@@ -256,15 +216,15 @@ mg_clear(SV *sv)
        /* omit GSKIP -- never set here */
        
        if (vtbl && (vtbl->svt_clear != NULL))
-           (VTBL->svt_clear)(sv, mg);
+           (VTBL->svt_clear)(aTHX_ sv, mg);
     }
 
-    restore_magic((void*)mgs_ix);
+    restore_magic(aTHXo_ (void*)mgs_ix);
     return 0;
 }
 
 MAGIC*
-mg_find(SV *sv, int type)
+Perl_mg_find(pTHX_ SV *sv, int type)
 {
     MAGIC* mg;
     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
@@ -275,7 +235,7 @@ mg_find(SV *sv, int type)
 }
 
 int
-mg_copy(SV *sv, SV *nsv, char *key, I32 klen)
+Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen)
 {
     int count = 0;
     MAGIC* mg;
@@ -291,7 +251,7 @@ mg_copy(SV *sv, SV *nsv, char *key, I32 klen)
 }
 
 int
-mg_free(SV *sv)
+Perl_mg_free(pTHX_ SV *sv)
 {
     MAGIC* mg;
     MAGIC* moremagic;
@@ -299,7 +259,7 @@ mg_free(SV *sv)
        MGVTBL* vtbl = mg->mg_virtual;
        moremagic = mg->mg_moremagic;
        if (vtbl && (vtbl->svt_free != NULL))
-           (VTBL->svt_free)(sv, mg);
+           (VTBL->svt_free)(aTHX_ sv, mg);
        if (mg->mg_ptr && mg->mg_type != 'g')
            if (mg->mg_len >= 0)
                Safefree(mg->mg_ptr);
@@ -318,7 +278,7 @@ mg_free(SV *sv)
 #endif
 
 U32
-magic_regdata_cnt(SV *sv, MAGIC *mg)
+Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     register char *s;
@@ -326,33 +286,38 @@ magic_regdata_cnt(SV *sv, MAGIC *mg)
     register REGEXP *rx;
     char *t;
 
-    if (PL_curpm && (rx = PL_curpm->op_pmregexp))
-       return rx->lastparen;
+    if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
+       if (mg->mg_obj)         /* @+ */
+           return rx->nparens;
+       else                    /* @- */
+           return rx->lastparen;
+    }
+    
     return (U32)-1;
 }
 
 int
-magic_regdatum_get(SV *sv, MAGIC *mg)
+Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     register I32 paren;
-    register char *s;
+    register I32 s;
     register I32 i;
     register REGEXP *rx;
-    char *t;
+    I32 t;
 
     if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
        paren = mg->mg_len;
        if (paren < 0)
            return 0;
        if (paren <= rx->nparens &&
-           (s = rx->startp[paren]) &&
-           (t = rx->endp[paren]))
+           (s = rx->startp[paren]) != -1 &&
+           (t = rx->endp[paren]) != -1)
            {
                if (mg->mg_obj)         /* @+ */
-                   i = t - rx->subbase;
+                   i = t;
                else                    /* @- */
-                   i = s - rx->subbase;
+                   i = s;
                sv_setiv(sv,i);
            }
     }
@@ -360,7 +325,7 @@ magic_regdatum_get(SV *sv, MAGIC *mg)
 }
 
 U32
-magic_len(SV *sv, MAGIC *mg)
+Perl_magic_len(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     register I32 paren;
@@ -373,13 +338,15 @@ magic_len(SV *sv, MAGIC *mg)
     case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9': case '&':
        if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
+           I32 s1, t1;
+
            paren = atoi(mg->mg_ptr);
          getparen:
            if (paren <= rx->nparens &&
-               (s = rx->startp[paren]) &&
-               (t = rx->endp[paren]))
+               (s1 = rx->startp[paren]) != -1 &&
+               (t1 = rx->endp[paren]) != -1)
            {
-               i = t - s;
+               i = t1 - s1;
                if (i >= 0)
                    return i;
            }
@@ -394,8 +361,8 @@ magic_len(SV *sv, MAGIC *mg)
        return 0;
     case '`':
        if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
-           if ((s = rx->subbeg) && rx->startp[0]) {
-               i = rx->startp[0] - s;
+           if (rx->startp[0] != -1) {
+               i = rx->startp[0];
                if (i >= 0)
                    return i;
            }
@@ -403,8 +370,8 @@ magic_len(SV *sv, MAGIC *mg)
        return 0;
     case '\'':
        if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
-           if (rx->subend && (s = rx->endp[0])) {
-               i = rx->subend - s;
+           if (rx->endp[0] != -1) {
+               i = rx->sublen - rx->endp[0];
                if (i >= 0)
                    return i;
            }
@@ -416,43 +383,17 @@ magic_len(SV *sv, MAGIC *mg)
        return (STRLEN)PL_orslen;
     }
     magic_get(sv,mg);
-    if (!SvPOK(sv) && SvNIOK(sv))
-       sv_2pv(sv, &PL_na);
+    if (!SvPOK(sv) && SvNIOK(sv)) {
+       STRLEN n_a;
+       sv_2pv(sv, &n_a);
+    }
     if (SvPOK(sv))
        return SvCUR(sv);
     return 0;
 }
 
-#if 0
-static char * 
-printW(sv)
-SV * sv ;
-{
-#if 1
-    return "" ;
-
-#else
-    int i ;
-    static char buffer[50] ;
-    char buf1[20] ;
-    char * p ;
-
-
-    sprintf(buffer, "Buffer %d, Length = %d - ", sv, SvCUR(sv)) ;
-    p = SvPVX(sv) ;
-    for (i = 0; i < SvCUR(sv) ; ++ i) {
-        sprintf (buf1, " %x [%x]", (p+i), *(p+i)) ;
-       strcat(buffer, buf1) ;
-    } 
-
-    return buffer ;
-
-#endif
-}
-#endif
-
 int
-magic_get(SV *sv, MAGIC *mg)
+Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     register I32 paren;
@@ -466,17 +407,22 @@ magic_get(SV *sv, MAGIC *mg)
        sv_setsv(sv, PL_bodytarget);
        break;
     case '\002':               /* ^B */
-       /* printf("magic_get $^B: ") ; */
-       if (PL_curcop->cop_warnings == WARN_NONE)
-           /* printf("WARN_NONE\n"), */
+       if (PL_curcop->cop_warnings == WARN_NONE ||
+           PL_curcop->cop_warnings == WARN_STD)
+       {
            sv_setpvn(sv, WARN_NONEstring, WARNsize) ;
-        else if (PL_curcop->cop_warnings == WARN_ALL)
-           /* printf("WARN_ALL\n"), */
+        }
+        else if (PL_curcop->cop_warnings == WARN_ALL) {
            sv_setpvn(sv, WARN_ALLstring, WARNsize) ;
-        else 
-           /* printf("some %s\n", printW(PL_curcop->cop_warnings)), */
+       }    
+        else {
            sv_setsv(sv, PL_curcop->cop_warnings);
+       }    
        break;
+    case '\003':               /* ^C */
+       sv_setiv(sv, (IV)PL_minus_c);
+       break;
+
     case '\004':               /* ^D */
        sv_setiv(sv, (IV)(PL_debug & 32767));
        break;
@@ -487,7 +433,7 @@ magic_get(SV *sv, MAGIC *mg)
 #          include <starlet.h>
            char msg[255];
            $DESCRIPTOR(msgdsc,msg);
-           sv_setnv(sv,(double) vaxc$errno);
+           sv_setnv(sv,(NV) vaxc$errno);
            if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
                sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
            else
@@ -496,7 +442,7 @@ magic_get(SV *sv, MAGIC *mg)
 #else
 #ifdef OS2
        if (!(_emx_env & 0x200)) {      /* Under DOS */
-           sv_setnv(sv, (double)errno);
+           sv_setnv(sv, (NV)errno);
            sv_setpv(sv, errno ? Strerror(errno) : "");
        } else {
            if (errno != errno_isOS2) {
@@ -504,32 +450,24 @@ magic_get(SV *sv, MAGIC *mg)
                if (tmp)        /* 2nd call to _syserrno() makes it 0 */
                    Perl_rc = tmp;
            }
-           sv_setnv(sv, (double)Perl_rc);
+           sv_setnv(sv, (NV)Perl_rc);
            sv_setpv(sv, os2error(Perl_rc));
        }
 #else
 #ifdef WIN32
        {
            DWORD dwErr = GetLastError();
-           sv_setnv(sv, (double)dwErr);
+           sv_setnv(sv, (NV)dwErr);
            if (dwErr)
            {
-#ifdef PERL_OBJECT
-               char *sMsg;
-               DWORD dwLen;
-               PerlProc_GetSysMsg(sMsg, dwLen, dwErr);
-               sv_setpvn(sv, sMsg, dwLen);
-               PerlProc_FreeBuf(sMsg);
-#else
-               win32_str_os_error(sv, dwErr);
-#endif
+               PerlProc_GetOSError(sv, dwErr);
            }
            else
                sv_setpv(sv, "");
            SetLastError(dwErr);
        }
 #else
-       sv_setnv(sv, (double)errno);
+       sv_setnv(sv, (NV)errno);
        sv_setpv(sv, errno ? Strerror(errno) : "");
 #endif
 #endif
@@ -573,11 +511,13 @@ magic_get(SV *sv, MAGIC *mg)
 #endif
        break;
     case '\027':               /* ^W */
-       sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) == G_WARN_ON));
+       sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE));
        break;
     case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9': case '&':
        if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
+           I32 s1, t1;
+
            /*
             * Pre-threads, this was paren = atoi(GvENAME((GV*)mg->mg_obj));
             * XXX Does the new way break anything?
@@ -585,10 +525,11 @@ magic_get(SV *sv, MAGIC *mg)
            paren = atoi(mg->mg_ptr);
          getparen:
            if (paren <= rx->nparens &&
-               (s = rx->startp[paren]) &&
-               (t = rx->endp[paren]))
+               (s1 = rx->startp[paren]) != -1 &&
+               (t1 = rx->endp[paren]) != -1)
            {
-               i = t - s;
+               i = t1 - s1;
+               s = rx->subbeg + s1;
              getrx:
                if (i >= 0) {
                    bool was_tainted;
@@ -596,7 +537,7 @@ magic_get(SV *sv, MAGIC *mg)
                        was_tainted = PL_tainted;
                        PL_tainted = FALSE;
                    }
-                   sv_setpvn(sv,s,i);
+                   sv_setpvn(sv, s, i);
                    if (PL_tainting)
                        PL_tainted = (was_tainted || RX_MATCH_TAINTED(rx));
                    break;
@@ -615,8 +556,8 @@ magic_get(SV *sv, MAGIC *mg)
        break;
     case '`':
        if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
-           if ((s = rx->subbeg) && rx->startp[0]) {
-               i = rx->startp[0] - s;
+           if ((s = rx->subbeg) && rx->startp[0] != -1) {
+               i = rx->startp[0];
                goto getrx;
            }
        }
@@ -624,8 +565,9 @@ magic_get(SV *sv, MAGIC *mg)
        break;
     case '\'':
        if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
-           if (rx->subend && (s = rx->endp[0])) {
-               i = rx->subend - s;
+           if (rx->subbeg && rx->endp[0] != -1) {
+               s = rx->subbeg + rx->endp[0];
+               i = rx->sublen - rx->endp[0];
                goto getrx;
            }
        }
@@ -694,12 +636,12 @@ magic_get(SV *sv, MAGIC *mg)
        break;
     case '!':
 #ifdef VMS
-       sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
+       sv_setnv(sv, (NV)((errno == EVMSERR) ? vaxc$errno : errno));
        sv_setpv(sv, errno ? Strerror(errno) : "");
 #else
        {
        int saveerrno = errno;
-       sv_setnv(sv, (double)errno);
+       sv_setnv(sv, (NV)errno);
 #ifdef OS2
        if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
        else
@@ -718,18 +660,18 @@ magic_get(SV *sv, MAGIC *mg)
        break;
     case '(':
        sv_setiv(sv, (IV)PL_gid);
-       sv_setpvf(sv, "%Vd", (IV)PL_gid);
+       Perl_sv_setpvf(aTHX_ sv, "%Vd", (IV)PL_gid);
        goto add_groups;
     case ')':
        sv_setiv(sv, (IV)PL_egid);
-       sv_setpvf(sv, "%Vd", (IV)PL_egid);
+       Perl_sv_setpvf(aTHX_ sv, "%Vd", (IV)PL_egid);
       add_groups:
 #ifdef HAS_GETGROUPS
        {
            Groups_t gary[NGROUPS];
            i = getgroups(NGROUPS,gary);
            while (--i >= 0)
-               sv_catpvf(sv, " %Vd", (IV)gary[i]);
+               Perl_sv_catpvf(aTHX_ sv, " %Vd", (IV)gary[i]);
        }
 #endif
        SvIOK_on(sv);   /* what a wonderful hack! */
@@ -748,7 +690,7 @@ magic_get(SV *sv, MAGIC *mg)
 }
 
 int
-magic_getuvar(SV *sv, MAGIC *mg)
+Perl_magic_getuvar(pTHX_ SV *sv, MAGIC *mg)
 {
     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
 
@@ -758,7 +700,7 @@ magic_getuvar(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setenv(SV *sv, MAGIC *mg)
+Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg)
 {
     register char *s;
     char *ptr;
@@ -834,27 +776,29 @@ magic_setenv(SV *sv, MAGIC *mg)
 }
 
 int
-magic_clearenv(SV *sv, MAGIC *mg)
+Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
 {
-    my_setenv(MgPV(mg,PL_na),Nullch);
+    STRLEN n_a;
+    my_setenv(MgPV(mg,n_a),Nullch);
     return 0;
 }
 
 int
-magic_set_all_env(SV *sv, MAGIC *mg)
+Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg)
 {
 #if defined(VMS)
-    die("Can't make list assignment to %%ENV on this system");
+    Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
 #else
     dTHR;
     if (PL_localizing) {
        HE* entry;
+       STRLEN n_a;
        magic_clear_all_env(sv,mg);
        hv_iterinit((HV*)sv);
        while (entry = hv_iternext((HV*)sv)) {
            I32 keylen;
            my_setenv(hv_iterkey(entry, &keylen),
-                     SvPV(hv_iterval((HV*)sv, entry), PL_na));
+                     SvPV(hv_iterval((HV*)sv, entry), n_a));
        }
     }
 #endif
@@ -862,12 +806,12 @@ magic_set_all_env(SV *sv, MAGIC *mg)
 }
 
 int
-magic_clear_all_env(SV *sv, MAGIC *mg)
+Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg)
 {
 #if defined(VMS)
-    die("Can't make list assignment to %%ENV on this system");
+    Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
 #else
-#ifdef WIN32
+#  ifdef WIN32
     char *envv = GetEnvironmentStrings();
     char *cur = envv;
     STRLEN len;
@@ -877,36 +821,40 @@ magic_clear_all_env(SV *sv, MAGIC *mg)
            *end = '\0';
            my_setenv(cur,Nullch);
            *end = '=';
-           cur += strlen(end+1)+1;
+           cur = end + strlen(end+1)+2;
        }
        else if ((len = strlen(cur)))
            cur += len+1;
     }
     FreeEnvironmentStrings(envv);
-#else
+#  else
+#    ifndef PERL_USE_SAFE_PUTENV
     I32 i;
 
     if (environ == PL_origenviron)
-       New(901, environ, 1, char*);
+       environ = (char**)safesysmalloc(sizeof(char*));
     else
        for (i = 0; environ[i]; i++)
-           Safefree(environ[i]);
+           safesysfree(environ[i]);
+#    endif /* PERL_USE_SAFE_PUTENV */
+
     environ[0] = Nullch;
 
-#endif
-#endif
+#  endif /* WIN32 */
+#endif /* VMS */
     return 0;
 }
 
 int
-magic_getsig(SV *sv, MAGIC *mg)
+Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
 {
     I32 i;
+    STRLEN n_a;
     /* Are we fetching a signal entry? */
-    i = whichsig(MgPV(mg,PL_na));
+    i = whichsig(MgPV(mg,n_a));
     if (i) {
-       if(psig_ptr[i])
-           sv_setsv(sv,psig_ptr[i]);
+       if(PL_psig_ptr[i])
+           sv_setsv(sv,PL_psig_ptr[i]);
        else {
            Sighandler_t sigstate = rsignal_state(i);
 
@@ -915,40 +863,42 @@ magic_getsig(SV *sv, MAGIC *mg)
                sv_setpv(sv,"IGNORE");
            else
                sv_setsv(sv,&PL_sv_undef);
-           psig_ptr[i] = SvREFCNT_inc(sv);
+           PL_psig_ptr[i] = SvREFCNT_inc(sv);
            SvTEMP_off(sv);
        }
     }
     return 0;
 }
 int
-magic_clearsig(SV *sv, MAGIC *mg)
+Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
 {
     I32 i;
+    STRLEN n_a;
     /* Are we clearing a signal entry? */
-    i = whichsig(MgPV(mg,PL_na));
+    i = whichsig(MgPV(mg,n_a));
     if (i) {
-       if(psig_ptr[i]) {
-           SvREFCNT_dec(psig_ptr[i]);
-           psig_ptr[i]=0;
+       if(PL_psig_ptr[i]) {
+           SvREFCNT_dec(PL_psig_ptr[i]);
+           PL_psig_ptr[i]=0;
        }
-       if(psig_name[i]) {
-           SvREFCNT_dec(psig_name[i]);
-           psig_name[i]=0;
+       if(PL_psig_name[i]) {
+           SvREFCNT_dec(PL_psig_name[i]);
+           PL_psig_name[i]=0;
        }
     }
     return 0;
 }
 
 int
-magic_setsig(SV *sv, MAGIC *mg)
+Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     register char *s;
     I32 i;
     SV** svp;
+    STRLEN len;
 
-    s = MgPV(mg,PL_na);
+    s = MgPV(mg,len);
     if (*s == '_') {
        if (strEQ(s,"__DIE__"))
            svp = &PL_diehook;
@@ -957,7 +907,7 @@ magic_setsig(SV *sv, MAGIC *mg)
        else if (strEQ(s,"__PARSE__"))
            svp = &PL_parsehook;
        else
-           croak("No such hook: %s", s);
+           Perl_croak(aTHX_ "No such hook: %s", s);
        i = 0;
        if (*svp) {
            SvREFCNT_dec(*svp);
@@ -968,15 +918,15 @@ magic_setsig(SV *sv, MAGIC *mg)
        i = whichsig(s);        /* ...no, a brick */
        if (!i) {
            if (ckWARN(WARN_SIGNAL) || strEQ(s,"ALARM"))
-               warner(WARN_SIGNAL, "No such signal: SIG%s", s);
+               Perl_warner(aTHX_ WARN_SIGNAL, "No such signal: SIG%s", s);
            return 0;
        }
-       SvREFCNT_dec(psig_name[i]);
-       SvREFCNT_dec(psig_ptr[i]);
-       psig_ptr[i] = SvREFCNT_inc(sv);
+       SvREFCNT_dec(PL_psig_name[i]);
+       SvREFCNT_dec(PL_psig_ptr[i]);
+       PL_psig_ptr[i] = SvREFCNT_inc(sv);
        SvTEMP_off(sv); /* Make sure it doesn't go away on us */
-       psig_name[i] = newSVpv(s, strlen(s));
-       SvREADONLY_on(psig_name[i]);
+       PL_psig_name[i] = newSVpvn(s, len);
+       SvREADONLY_on(PL_psig_name[i]);
     }
     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
        if (i)
@@ -985,7 +935,7 @@ magic_setsig(SV *sv, MAGIC *mg)
            *svp = SvREFCNT_inc(sv);
        return 0;
     }
-    s = SvPV_force(sv,PL_na);
+    s = SvPV_force(sv,len);
     if (strEQ(s,"IGNORE")) {
        if (i)
            (void)rsignal(i, SIG_IGN);
@@ -1005,7 +955,7 @@ magic_setsig(SV *sv, MAGIC *mg)
         * tell whether HINT_STRICT_REFS is in force or not.
         */
        if (!strchr(s,':') && !strchr(s,'\''))
-           sv_setpv(sv, form("main::%s", s));
+           sv_insert(sv, 0, 0, "main::", 6);
        if (i)
            (void)rsignal(i, PL_sighandlerp);
        else
@@ -1015,26 +965,23 @@ magic_setsig(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setisa(SV *sv, MAGIC *mg)
+Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
 {
     PL_sub_generation++;
     return 0;
 }
 
-#ifdef OVERLOAD
-
 int
-magic_setamagic(SV *sv, MAGIC *mg)
+Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
 {
     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
     PL_amagic_generation++;
 
     return 0;
 }
-#endif /* OVERLOAD */
 
 int
-magic_getnkeys(SV *sv, MAGIC *mg)
+Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg)
 {
     HV *hv = (HV*)LvTARG(sv);
     HE *entry;
@@ -1057,7 +1004,7 @@ magic_getnkeys(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setnkeys(SV *sv, MAGIC *mg)
+Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
 {
     if (LvTARG(sv)) {
        hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
@@ -1067,7 +1014,7 @@ magic_setnkeys(SV *sv, MAGIC *mg)
 
 /* caller is responsible for stack switching/cleanup */
 STATIC int
-magic_methcall(SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
+S_magic_methcall(pTHX_ SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
 {
     dSP;
 
@@ -1077,7 +1024,7 @@ magic_methcall(SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
     if (n > 1) { 
        if (mg->mg_ptr) {
            if (mg->mg_len >= 0)
-               PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
+               PUSHs(sv_2mortal(newSVpvn(mg->mg_ptr, mg->mg_len)));
            else if (mg->mg_len == HEf_SVKEY)
                PUSHs((SV*)mg->mg_ptr);
        }
@@ -1090,11 +1037,11 @@ magic_methcall(SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
     }
     PUTBACK;
 
-    return perl_call_method(meth, flags);
+    return call_method(meth, flags);
 }
 
 STATIC int
-magic_methpack(SV *sv, MAGIC *mg, char *meth)
+S_magic_methpack(pTHX_ SV *sv, MAGIC *mg, char *meth)
 {
     dSP;
 
@@ -1113,7 +1060,7 @@ magic_methpack(SV *sv, MAGIC *mg, char *meth)
 }
 
 int
-magic_getpack(SV *sv, MAGIC *mg)
+Perl_magic_getpack(pTHX_ SV *sv, MAGIC *mg)
 {
     magic_methpack(sv,mg,"FETCH");
     if (mg->mg_ptr)
@@ -1122,7 +1069,7 @@ magic_getpack(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setpack(SV *sv, MAGIC *mg)
+Perl_magic_setpack(pTHX_ SV *sv, MAGIC *mg)
 {
     dSP;
     ENTER;
@@ -1134,14 +1081,14 @@ magic_setpack(SV *sv, MAGIC *mg)
 }
 
 int
-magic_clearpack(SV *sv, MAGIC *mg)
+Perl_magic_clearpack(pTHX_ SV *sv, MAGIC *mg)
 {
     return magic_methpack(sv,mg,"DELETE");
 }
 
 
 U32
-magic_sizepack(SV *sv, MAGIC *mg)
+Perl_magic_sizepack(pTHX_ SV *sv, MAGIC *mg)
 {         
     dSP;
     U32 retval = 0;
@@ -1159,7 +1106,8 @@ magic_sizepack(SV *sv, MAGIC *mg)
     return retval;
 }
 
-int magic_wipepack(SV *sv, MAGIC *mg)
+int
+Perl_magic_wipepack(pTHX_ SV *sv, MAGIC *mg)
 {
     dSP;
 
@@ -1168,14 +1116,14 @@ int magic_wipepack(SV *sv, MAGIC *mg)
     PUSHMARK(SP);
     XPUSHs(SvTIED_obj(sv, mg));
     PUTBACK;
-    perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
+    call_method("CLEAR", G_SCALAR|G_DISCARD);
     POPSTACK;
     LEAVE;
     return 0;
 }
 
 int
-magic_nextpack(SV *sv, MAGIC *mg, SV *key)
+Perl_magic_nextpack(pTHX_ SV *sv, MAGIC *mg, SV *key)
 {
     dSP;
     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
@@ -1190,7 +1138,7 @@ magic_nextpack(SV *sv, MAGIC *mg, SV *key)
        PUSHs(key);
     PUTBACK;
 
-    if (perl_call_method(meth, G_SCALAR))
+    if (call_method(meth, G_SCALAR))
        sv_setsv(key, *PL_stack_sp--);
 
     POPSTACK;
@@ -1200,33 +1148,34 @@ magic_nextpack(SV *sv, MAGIC *mg, SV *key)
 }
 
 int
-magic_existspack(SV *sv, MAGIC *mg)
+Perl_magic_existspack(pTHX_ SV *sv, MAGIC *mg)
 {
     return magic_methpack(sv,mg,"EXISTS");
 } 
 
 int
-magic_setdbline(SV *sv, MAGIC *mg)
+Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     OP *o;
     I32 i;
     GV* gv;
     SV** svp;
+    STRLEN n_a;
 
     gv = PL_DBline;
     i = SvTRUE(sv);
     svp = av_fetch(GvAV(gv),
-                    atoi(MgPV(mg,PL_na)), FALSE);
+                    atoi(MgPV(mg,n_a)), FALSE);
     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
        o->op_private = i;
-    else
-       warn("Can't break at that line\n");
+    else if (ckWARN_d(WARN_INTERNAL))
+       Perl_warner(aTHX_ WARN_INTERNAL, "Can't break at that line\n");
     return 0;
 }
 
 int
-magic_getarylen(SV *sv, MAGIC *mg)
+Perl_magic_getarylen(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + PL_curcop->cop_arybase);
@@ -1234,7 +1183,7 @@ magic_getarylen(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setarylen(SV *sv, MAGIC *mg)
+Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     av_fill((AV*)mg->mg_obj, SvIV(sv) - PL_curcop->cop_arybase);
@@ -1242,7 +1191,7 @@ magic_setarylen(SV *sv, MAGIC *mg)
 }
 
 int
-magic_getpos(SV *sv, MAGIC *mg)
+Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
 {
     SV* lsv = LvTARG(sv);
     
@@ -1262,7 +1211,7 @@ magic_getpos(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setpos(SV *sv, MAGIC *mg)
+Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
 {
     SV* lsv = LvTARG(sv);
     SSize_t pos;
@@ -1317,7 +1266,7 @@ magic_setpos(SV *sv, MAGIC *mg)
 }
 
 int
-magic_getglob(SV *sv, MAGIC *mg)
+Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
 {
     if (SvFAKE(sv)) {                  /* FAKE globs can get coerced */
        SvFAKE_off(sv);
@@ -1330,14 +1279,15 @@ magic_getglob(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setglob(SV *sv, MAGIC *mg)
+Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
 {
     register char *s;
     GV* gv;
+    STRLEN n_a;
 
     if (!SvOK(sv))
        return 0;
-    s = SvPV(sv, PL_na);
+    s = SvPV(sv, n_a);
     if (*s == '*' && s[1])
        s++;
     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
@@ -1350,7 +1300,7 @@ magic_setglob(SV *sv, MAGIC *mg)
 }
 
 int
-magic_getsubstr(SV *sv, MAGIC *mg)
+Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
 {
     STRLEN len;
     SV *lsv = LvTARG(sv);
@@ -1367,7 +1317,7 @@ magic_getsubstr(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setsubstr(SV *sv, MAGIC *mg)
+Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
 {
     STRLEN len;
     char *tmps = SvPV(sv,len);
@@ -1376,7 +1326,7 @@ magic_setsubstr(SV *sv, MAGIC *mg)
 }
 
 int
-magic_gettaint(SV *sv, MAGIC *mg)
+Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     TAINT_IF((mg->mg_len & 1) ||
@@ -1385,7 +1335,7 @@ magic_gettaint(SV *sv, MAGIC *mg)
 }
 
 int
-magic_settaint(SV *sv, MAGIC *mg)
+Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     if (PL_localizing) {
@@ -1402,7 +1352,7 @@ magic_settaint(SV *sv, MAGIC *mg)
 }
 
 int
-magic_getvec(SV *sv, MAGIC *mg)
+Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
 {
     SV *lsv = LvTARG(sv);
     unsigned char *s;
@@ -1468,14 +1418,14 @@ magic_getvec(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setvec(SV *sv, MAGIC *mg)
+Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
 {
     do_vecset(sv);     /* XXX slurp this routine */
     return 0;
 }
 
 int
-magic_getdefelem(SV *sv, MAGIC *mg)
+Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
 {
     SV *targ = Nullsv;
     if (LvTARGLEN(sv)) {
@@ -1515,7 +1465,7 @@ magic_getdefelem(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setdefelem(SV *sv, MAGIC *mg)
+Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
 {
     if (LvTARGLEN(sv))
        vivify_defelem(sv);
@@ -1527,7 +1477,7 @@ magic_setdefelem(SV *sv, MAGIC *mg)
 }
 
 void
-vivify_defelem(SV *sv)
+Perl_vivify_defelem(pTHX_ SV *sv)
 {
     dTHR;                      /* just for SvREFCNT_inc and SvREFCNT_dec*/
     MAGIC *mg;
@@ -1537,6 +1487,7 @@ vivify_defelem(SV *sv)
        return;
     if (mg->mg_obj) {
        SV *ahv = LvTARG(sv);
+       STRLEN n_a;
        if (SvTYPE(ahv) == SVt_PVHV) {
            HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
            if (he)
@@ -1548,7 +1499,7 @@ vivify_defelem(SV *sv)
                value = *svp;
        }
        if (!value || value == &PL_sv_undef)
-           croak(no_helem, SvPV(mg->mg_obj, PL_na));
+           Perl_croak(aTHX_ PL_no_helem, SvPV(mg->mg_obj, n_a));
     }
     else {
        AV* av = (AV*)LvTARG(sv);
@@ -1557,7 +1508,7 @@ vivify_defelem(SV *sv)
        else {
            SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
            if (!svp || (value = *svp) == &PL_sv_undef)
-               croak(no_aelem, (I32)LvTARGOFF(sv));
+               Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
        }
     }
     (void)SvREFCNT_inc(value);
@@ -1570,7 +1521,28 @@ vivify_defelem(SV *sv)
 }
 
 int
-magic_setmglob(SV *sv, MAGIC *mg)
+Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
+{
+    AV *av = (AV*)mg->mg_obj;
+    SV **svp = AvARRAY(av);
+    I32 i = AvFILLp(av);
+    while (i >= 0) {
+       if (svp[i] && svp[i] != &PL_sv_undef) {
+           if (!SvWEAKREF(svp[i]))
+               Perl_croak(aTHX_ "panic: magic_killbackrefs");
+           /* XXX Should we check that it hasn't changed? */
+           SvRV(svp[i]) = 0;
+           SvOK_off(svp[i]);
+           SvWEAKREF_off(svp[i]);
+           svp[i] = &PL_sv_undef;
+       }
+       i--;
+    }
+    return 0;
+}
+
+int
+Perl_magic_setmglob(pTHX_ SV *sv, MAGIC *mg)
 {
     mg->mg_len = -1;
     SvSCREAM_off(sv);
@@ -1578,7 +1550,7 @@ magic_setmglob(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setbm(SV *sv, MAGIC *mg)
+Perl_magic_setbm(pTHX_ SV *sv, MAGIC *mg)
 {
     sv_unmagic(sv, 'B');
     SvVALID_off(sv);
@@ -1586,7 +1558,7 @@ magic_setbm(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setfm(SV *sv, MAGIC *mg)
+Perl_magic_setfm(pTHX_ SV *sv, MAGIC *mg)
 {
     sv_unmagic(sv, 'f');
     SvCOMPILED_off(sv);
@@ -1594,7 +1566,7 @@ magic_setfm(SV *sv, MAGIC *mg)
 }
 
 int
-magic_setuvar(SV *sv, MAGIC *mg)
+Perl_magic_setuvar(pTHX_ SV *sv, MAGIC *mg)
 {
     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
 
@@ -1604,7 +1576,7 @@ magic_setuvar(SV *sv, MAGIC *mg)
 }
 
 int
-magic_freeregexp(SV *sv, MAGIC *mg)
+Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
 {
     regexp *re = (regexp *)mg->mg_obj;
     ReREFCNT_dec(re);
@@ -1613,7 +1585,7 @@ magic_freeregexp(SV *sv, MAGIC *mg)
 
 #ifdef USE_LOCALE_COLLATE
 int
-magic_setcollxfrm(SV *sv, MAGIC *mg)
+Perl_magic_setcollxfrm(pTHX_ SV *sv, MAGIC *mg)
 {
     /*
      * RenE<eacute> Descartes said "I think not."
@@ -1629,7 +1601,7 @@ magic_setcollxfrm(SV *sv, MAGIC *mg)
 #endif /* USE_LOCALE_COLLATE */
 
 int
-magic_set(SV *sv, MAGIC *mg)
+Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     register char *s;
@@ -1641,19 +1613,27 @@ magic_set(SV *sv, MAGIC *mg)
        break;
     case '\002':       /* ^B */
        if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
-            if (memEQ(SvPVX(sv), WARN_ALLstring, WARNsize))
+            if (memEQ(SvPVX(sv), WARN_ALLstring, WARNsize)) {
                PL_compiling.cop_warnings = WARN_ALL;
+               PL_dowarn |= G_WARN_ONCE ;
+           }   
            else if (memEQ(SvPVX(sv), WARN_NONEstring, WARNsize))
                PL_compiling.cop_warnings = WARN_NONE;
             else {
-               if (PL_compiling.cop_warnings != WARN_NONE && 
-                   PL_compiling.cop_warnings != WARN_ALL)
-                   sv_setsv(PL_compiling.cop_warnings, sv);
-               else
+               if (specialWARN(PL_compiling.cop_warnings))
                    PL_compiling.cop_warnings = newSVsv(sv) ;
+               else
+                   sv_setsv(PL_compiling.cop_warnings, sv);
+               if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE))
+                   PL_dowarn |= G_WARN_ONCE ;
            }
        }
        break;
+
+    case '\003':       /* ^C */
+       PL_minus_c = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
+       break;
+
     case '\004':       /* ^D */
        PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
        DEBUG_x(dump_all());
@@ -1662,12 +1642,14 @@ magic_set(SV *sv, MAGIC *mg)
 #ifdef VMS
        set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
 #else
-#ifdef WIN32
+#  ifdef WIN32
        SetLastError( SvIV(sv) );
-#else
+#  else
+#    ifndef OS2
        /* will anyone ever use this? */
        SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
-#endif
+#    endif
+#  endif
 #endif
        break;
     case '\006':       /* ^F */
@@ -1680,7 +1662,7 @@ magic_set(SV *sv, MAGIC *mg)
        if (PL_inplace)
            Safefree(PL_inplace);
        if (SvOK(sv))
-           PL_inplace = savepv(SvPV(sv,PL_na));
+           PL_inplace = savepv(SvPV(sv,len));
        else
            PL_inplace = Nullch;
        break;
@@ -1688,12 +1670,14 @@ magic_set(SV *sv, MAGIC *mg)
        if (PL_osname)
            Safefree(PL_osname);
        if (SvOK(sv))
-           PL_osname = savepv(SvPV(sv,PL_na));
+           PL_osname = savepv(SvPV(sv,len));
        else
            PL_osname = Nullch;
        break;
     case '\020':       /* ^P */
        PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
+       if (PL_perldb && !PL_DBsingle)
+           init_debugger();
        break;
     case '\024':       /* ^T */
 #ifdef BIG_TIME
@@ -1705,7 +1689,8 @@ magic_set(SV *sv, MAGIC *mg)
     case '\027':       /* ^W */
        if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
            i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
-           PL_dowarn = (i ? G_WARN_ON : G_WARN_OFF) ;
+           PL_dowarn = (PL_dowarn & ~G_WARN_ON) 
+                               | (i ? G_WARN_ON : G_WARN_OFF) ;
        }
        break;
     case '.':
@@ -1718,12 +1703,12 @@ magic_set(SV *sv, MAGIC *mg)
        break;
     case '^':
        Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
-       IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,PL_na));
+       IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
        IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
        break;
     case '~':
        Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
-       IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,PL_na));
+       IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
        IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
        break;
     case '=':
@@ -1780,7 +1765,7 @@ magic_set(SV *sv, MAGIC *mg)
     case '#':
        if (PL_ofmt)
            Safefree(PL_ofmt);
-       PL_ofmt = savepv(SvPV(sv,PL_na));
+       PL_ofmt = savepv(SvPV(sv,len));
        break;
     case '[':
        PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
@@ -1823,7 +1808,7 @@ magic_set(SV *sv, MAGIC *mg)
            (void)PerlProc_setuid(PL_uid);
        else {
            PL_uid = (I32)PerlProc_getuid();
-           croak("setruid() not implemented");
+           Perl_croak(aTHX_ "setruid() not implemented");
        }
 #endif
 #endif
@@ -1850,7 +1835,7 @@ magic_set(SV *sv, MAGIC *mg)
            PerlProc_setuid(PL_euid);
        else {
            PL_euid = (I32)PerlProc_geteuid();
-           croak("seteuid() not implemented");
+           Perl_croak(aTHX_ "seteuid() not implemented");
        }
 #endif
 #endif
@@ -1877,7 +1862,7 @@ magic_set(SV *sv, MAGIC *mg)
            (void)PerlProc_setgid(PL_gid);
        else {
            PL_gid = (I32)PerlProc_getgid();
-           croak("setrgid() not implemented");
+           Perl_croak(aTHX_ "setrgid() not implemented");
        }
 #endif
 #endif
@@ -1888,13 +1873,12 @@ magic_set(SV *sv, MAGIC *mg)
     case ')':
 #ifdef HAS_SETGROUPS
        {
-           char *p = SvPV(sv, PL_na);
+           char *p = SvPV(sv, len);
            Groups_t gary[NGROUPS];
 
-           SET_NUMERIC_STANDARD();
            while (isSPACE(*p))
                ++p;
-           PL_egid = I_V(atof(p));
+           PL_egid = I_V(atol(p));
            for (i = 0; i < NGROUPS; ++i) {
                while (*p && !isSPACE(*p))
                    ++p;
@@ -1902,7 +1886,7 @@ magic_set(SV *sv, MAGIC *mg)
                    ++p;
                if (!*p)
                    break;
-               gary[i] = I_V(atof(p));
+               gary[i] = I_V(atol(p));
            }
            if (i)
                (void)setgroups(i, gary);
@@ -1927,7 +1911,7 @@ magic_set(SV *sv, MAGIC *mg)
            (void)PerlProc_setgid(PL_egid);
        else {
            PL_egid = (I32)PerlProc_getegid();
-           croak("setegid() not implemented");
+           Perl_croak(aTHX_ "setegid() not implemented");
        }
 #endif
 #endif
@@ -1936,7 +1920,7 @@ magic_set(SV *sv, MAGIC *mg)
        PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
        break;
     case ':':
-       PL_chopset = SvPV_force(sv,PL_na);
+       PL_chopset = SvPV_force(sv,len);
        break;
     case '0':
        if (!PL_origalen) {
@@ -1949,7 +1933,10 @@ magic_set(SV *sv, MAGIC *mg)
                    || PL_origargv[i] == s + 2
 #endif 
                   )
-                   s += strlen(++s);   /* this one is ok too */
+               {
+                   ++s;
+                   s += strlen(s);     /* this one is ok too */
+               }
                else
                    break;
            }
@@ -1962,8 +1949,10 @@ magic_set(SV *sv, MAGIC *mg)
                my_setenv("NoNe  SuCh", Nullch);
                                            /* force copy of environment */
                for (i = 0; PL_origenviron[i]; i++)
-                   if (PL_origenviron[i] == s + 1)
-                       s += strlen(++s);
+                   if (PL_origenviron[i] == s + 1) {
+                       ++s;
+                       s += strlen(s);
+                   }
                    else
                        break;
            }
@@ -2001,13 +1990,13 @@ magic_set(SV *sv, MAGIC *mg)
 
 #ifdef USE_THREADS
 int
-magic_mutexfree(SV *sv, MAGIC *mg)
+Perl_magic_mutexfree(pTHX_ SV *sv, MAGIC *mg)
 {
     dTHR;
     DEBUG_S(PerlIO_printf(PerlIO_stderr(), "0x%lx: magic_mutexfree 0x%lx\n",
                          (unsigned long)thr, (unsigned long)sv);)
     if (MgOWNER(mg))
-       croak("panic: magic_mutexfree");
+       Perl_croak(aTHX_ "panic: magic_mutexfree");
     MUTEX_DESTROY(MgMUTEXP(mg));
     COND_DESTROY(MgCONDP(mg));
     return 0;
@@ -2015,13 +2004,13 @@ magic_mutexfree(SV *sv, MAGIC *mg)
 #endif /* USE_THREADS */
 
 I32
-whichsig(char *sig)
+Perl_whichsig(pTHX_ char *sig)
 {
     register char **sigv;
 
-    for (sigv = sig_name+1; *sigv; sigv++)
+    for (sigv = PL_sig_name+1; *sigv; sigv++)
        if (strEQ(sig,*sigv))
-           return sig_num[sigv - sig_name];
+           return PL_sig_num[sigv - PL_sig_name];
 #ifdef SIGCLD
     if (strEQ(sig,"CHLD"))
        return SIGCLD;
@@ -2035,22 +2024,10 @@ whichsig(char *sig)
 
 static SV* sig_sv;
 
-STATIC void
-unwind_handler_stack(void *p)
-{
-    dTHR;
-    U32 flags = *(U32*)p;
-
-    if (flags & 1)
-       PL_savestack_ix -= 5; /* Unprotect save in progress. */
-    /* cxstack_ix-- Not needed, die already unwound it. */
-    if (flags & 64)
-       SvREFCNT_dec(sig_sv);
-}
-
 Signal_t
-sighandler(int sig)
+Perl_sighandler(int sig)
 {
+    dTHX;
     dSP;
     GV *gv = Nullgv;
     HV *st;
@@ -2070,9 +2047,9 @@ sighandler(int sig)
     if (PL_scopestack_ix < PL_scopestack_max - 3)
        flags |= 16;
 
-    if (!psig_ptr[sig])
-       die("Signal SIG%s received, but no signal handler set.\n",
-           sig_name[sig]);
+    if (!PL_psig_ptr[sig])
+       Perl_die(aTHX_ "Signal SIG%s received, but no signal handler set.\n",
+           PL_sig_name[sig]);
 
     /* Max number of items pushed there is 3*n or 4. We cannot fix
        infinity, so we fix 4 (in fact 5): */
@@ -2090,27 +2067,27 @@ sighandler(int sig)
     if (flags & 16)
        PL_scopestack_ix += 1;
     /* sv_2cv is too complicated, try a simpler variant first: */
-    if (!SvROK(psig_ptr[sig]) || !(cv = (CV*)SvRV(psig_ptr[sig])) 
+    if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig])) 
        || SvTYPE(cv) != SVt_PVCV)
-       cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
+       cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE);
 
     if (!cv || !CvROOT(cv)) {
        if (ckWARN(WARN_SIGNAL))
-           warner(WARN_SIGNAL, "SIG%s handler \"%s\" not defined.\n",
-               sig_name[sig], (gv ? GvENAME(gv)
+           Perl_warner(aTHX_ WARN_SIGNAL, "SIG%s handler \"%s\" not defined.\n",
+               PL_sig_name[sig], (gv ? GvENAME(gv)
                                : ((cv && CvGV(cv))
                                   ? GvENAME(CvGV(cv))
                                   : "__ANON__")));
        goto cleanup;
     }
 
-    if(psig_name[sig]) {
-       sv = SvREFCNT_inc(psig_name[sig]);
+    if(PL_psig_name[sig]) {
+       sv = SvREFCNT_inc(PL_psig_name[sig]);
        flags |= 64;
        sig_sv = sv;
     } else {
        sv = sv_newmortal();
-       sv_setpv(sv,sig_name[sig]);
+       sv_setpv(sv,PL_sig_name[sig]);
     }
 
     PUSHSTACKi(PERLSI_SIGNAL);
@@ -2118,7 +2095,7 @@ sighandler(int sig)
     PUSHs(sv);
     PUTBACK;
 
-    perl_call_sv((SV*)cv, G_DISCARD);
+    call_sv((SV*)cv, G_DISCARD);
 
     POPSTACK;
 cleanup:
@@ -2140,3 +2117,62 @@ cleanup:
 }
 
 
+#ifdef PERL_OBJECT
+#define NO_XSLOCKS
+#include "XSUB.h"
+#endif
+
+static void
+restore_magic(pTHXo_ void *p)
+{
+    dTHR;
+    MGS* mgs = SSPTR((I32)p, MGS*);
+    SV* sv = mgs->mgs_sv;
+
+    if (!sv)
+        return;
+
+    if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
+    {
+       if (mgs->mgs_flags)
+           SvFLAGS(sv) |= mgs->mgs_flags;
+       else
+           mg_magical(sv);
+       if (SvGMAGICAL(sv))
+           SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
+    }
+
+    mgs->mgs_sv = NULL;  /* mark the MGS structure as restored */
+
+    /* If we're still on top of the stack, pop us off.  (That condition
+     * will be satisfied if restore_magic was called explicitly, but *not*
+     * if it's being called via leave_scope.)
+     * The reason for doing this is that otherwise, things like sv_2cv()
+     * may leave alloc gunk on the savestack, and some code
+     * (e.g. sighandler) doesn't expect that...
+     */
+    if (PL_savestack_ix == mgs->mgs_ss_ix)
+    {
+       I32 popval = SSPOPINT;
+        assert(popval == SAVEt_DESTRUCTOR);
+        PL_savestack_ix -= 2;
+       popval = SSPOPINT;
+        assert(popval == SAVEt_ALLOC);
+       popval = SSPOPINT;
+        PL_savestack_ix -= popval;
+    }
+
+}
+
+static void
+unwind_handler_stack(pTHXo_ void *p)
+{
+    dTHR;
+    U32 flags = *(U32*)p;
+
+    if (flags & 1)
+       PL_savestack_ix -= 5; /* Unprotect save in progress. */
+    /* cxstack_ix-- Not needed, die already unwound it. */
+    if (flags & 64)
+       SvREFCNT_dec(sig_sv);
+}