Improve description of the -s switch.
[p5sagit/p5-mst-13.2.git] / mg.c
diff --git a/mg.c b/mg.c
index 0722f44..d1bed8e 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -1,7 +1,7 @@
 /*    mg.c
  *
  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005 by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -40,14 +40,17 @@ tie.
 #include "perl.h"
 
 #if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
-#  ifndef NGROUPS
-#    define NGROUPS 32
-#  endif
 #  ifdef I_GRP
 #    include <grp.h>
 #  endif
 #endif
 
+#if defined(HAS_SETGROUPS)
+#  ifndef NGROUPS
+#    define NGROUPS 32
+#  endif
+#endif
+
 #ifdef __hpux
 #  include <sys/pstat.h>
 #endif
@@ -427,15 +430,12 @@ Perl_mg_localize(pTHX_ SV *sv, SV *nsv)
            continue;
        }
                
-       if ((mg->mg_flags & MGf_COPY) && vtbl->svt_copy) {
-           /* XXX calling the copy method is probably not correct. DAPM */
-           (void)CALL_FPTR(vtbl->svt_copy)(aTHX_ sv, mg, nsv,
-                                   mg->mg_ptr, mg->mg_len);
-       }
-       else {
+       if ((mg->mg_flags & MGf_LOCAL) && vtbl->svt_local)
+           (void)CALL_FPTR(vtbl->svt_local)(aTHX_ nsv, mg);
+       else
            sv_magicext(nsv, mg->mg_obj, mg->mg_type, vtbl,
                            mg->mg_ptr, mg->mg_len);
-       }
+
        /* container types should remain read-only across localization */
        SvFLAGS(nsv) |= SvREADONLY(sv);
     }
@@ -843,7 +843,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 
              getrx:
                if (i >= 0) {
-                   int oldtainted = PL_tainted;
+                   const int oldtainted = PL_tainted;
                    TAINT_NOT;
                    sv_setpvn(sv, s, i);
                    PL_tainted = oldtainted;
@@ -1006,10 +1006,14 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
       add_groups:
 #ifdef HAS_GETGROUPS
        {
-           Groups_t gary[NGROUPS];
-           I32 j = getgroups(NGROUPS,gary);
-           while (--j >= 0)
-               Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, (long unsigned int)gary[j]);
+           Groups_t *gary = NULL;
+           I32 num_groups = getgroups(0, gary);
+            Newx(gary, num_groups, Groups_t);
+            num_groups = getgroups(num_groups, gary);
+           while (--num_groups >= 0)
+               Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f,
+                    (long unsigned int)gary[num_groups]);
+            Safefree(gary);
        }
 #endif
        (void)SvIOK_on(sv);     /* what a wonderful hack! */
@@ -1036,20 +1040,17 @@ int
 Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg)
 {
     dVAR;
-    const char *s;
-    const char *ptr;
     STRLEN len, klen;
-
-    s = SvPV_const(sv,len);
-    ptr = MgPV_const(mg,klen);
+    const char *s = SvPV_const(sv,len);
+    const char * const ptr = MgPV_const(mg,klen);
     my_setenv(ptr, s);
 
 #ifdef DYNAMIC_ENV_FETCH
      /* We just undefd an environment var.  Is a replacement */
      /* waiting in the wings? */
     if (!len) {
-       SV **valp;
-       if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
+       SV ** const valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE);
+       if (valp)
            s = SvPV_const(*valp, len);
     }
 #endif
@@ -1202,7 +1203,7 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
     register const char * const s = MgPV_nolen_const(mg);
     PERL_UNUSED_ARG(sv);
     if (*s == '_') {
-       SV** svp = 0;
+       SV** svp = NULL;
        if (strEQ(s,"__DIE__"))
            svp = &PL_diehook;
        else if (strEQ(s,"__WARN__"))
@@ -1211,7 +1212,7 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
            Perl_croak(aTHX_ "No such hook: %s", s);
        if (svp && *svp) {
             SV * const to_dec = *svp;
-           *svp = 0;
+           *svp = NULL;
            SvREFCNT_dec(to_dec);
        }
     }
@@ -1341,12 +1342,12 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
 {
     dVAR;
     I32 i;
-    SV** svp = 0;
+    SV** svp = NULL;
     /* Need to be careful with SvREFCNT_dec(), because that can have side
      * effects (due to closures). We must make sure that the new disposition
      * is in place before it is called.
      */
-    SV* to_dec = 0;
+    SV* to_dec = NULL;
     STRLEN len;
 #ifdef HAS_SIGPROCMASK
     sigset_t set, save;
@@ -1364,7 +1365,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
        i = 0;
        if (*svp) {
            to_dec = *svp;
-           *svp = 0;
+           *svp = NULL;
        }
     }
     else {
@@ -1443,7 +1444,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
         * tell whether HINT_STRICT_REFS is in force or not.
         */
        if (!strchr(s,':') && !strchr(s,'\''))
-           sv_insert(sv, 0, 0, "main::", 6);
+           Perl_sv_insert(aTHX_ sv, 0, 0, STR_WITH_LEN("main::"));
        if (i)
            (void)rsignal(i, PL_csighandlerp);
        else
@@ -1788,7 +1789,7 @@ Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
     if (!mg) {
        if (!SvOK(sv))
            return 0;
-       sv_magic(lsv, (SV*)0, PERL_MAGIC_regex_global, Nullch, 0);
+       sv_magic(lsv, NULL, PERL_MAGIC_regex_global, NULL, 0);
        mg = mg_find(lsv, PERL_MAGIC_regex_global);
     }
     else if (!SvOK(sv)) {
@@ -2039,42 +2040,7 @@ Perl_vivify_defelem(pTHX_ SV *sv)
 int
 Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
 {
-    AV *const av = (AV*)mg->mg_obj;
-    SV **svp = AvARRAY(av);
-    PERL_UNUSED_ARG(sv);
-
-    /* Not sure why the av can get freed ahead of its sv, but somehow it does
-       in ext/B/t/bytecode.t test 15 (involving print <DATA>)  */
-    if (svp && !SvIS_FREED(av)) {
-       SV *const *const last = svp + AvFILLp(av);
-
-       while (svp <= last) {
-           if (*svp) {
-               SV *const referrer = *svp;
-               if (SvWEAKREF(referrer)) {
-                   /* XXX Should we check that it hasn't changed? */
-                   SvRV_set(referrer, 0);
-                   SvOK_off(referrer);
-                   SvWEAKREF_off(referrer);
-               } else if (SvTYPE(referrer) == SVt_PVGV ||
-                          SvTYPE(referrer) == SVt_PVLV) {
-                   /* You lookin' at me?  */
-                   assert(GvSTASH(referrer));
-                   assert(GvSTASH(referrer) == (HV*)sv);
-                   GvSTASH(referrer) = 0;
-               } else {
-                   Perl_croak(aTHX_
-                              "panic: magic_killbackrefs (flags=%"UVxf")",
-                              (UV)SvFLAGS(referrer));
-               }
-
-               *svp = Nullsv;
-           }
-           svp++;
-       }
-    }
-    SvREFCNT_dec(av); /* remove extra count added by sv_add_backref() */
-    return 0;
+    return Perl_sv_kill_backrefs(aTHX_ sv, (AV*)mg->mg_obj);
 }
 
 int
@@ -2485,22 +2451,28 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
 #ifdef HAS_SETGROUPS
        {
            const char *p = SvPV_const(sv, len);
-           Groups_t gary[NGROUPS];
-
-           while (isSPACE(*p))
-               ++p;
-           PL_egid = Atol(p);
-           for (i = 0; i < NGROUPS; ++i) {
-               while (*p && !isSPACE(*p))
-                   ++p;
-               while (isSPACE(*p))
-                   ++p;
-               if (!*p)
-                   break;
-               gary[i] = Atol(p);
-           }
-           if (i)
-               (void)setgroups(i, gary);
+            Groups_t *gary = NULL;
+
+            while (isSPACE(*p))
+                ++p;
+            PL_egid = Atol(p);
+            for (i = 0; i < NGROUPS; ++i) {
+                while (*p && !isSPACE(*p))
+                    ++p;
+                while (isSPACE(*p))
+                    ++p;
+                if (!*p)
+                    break;
+                if(!gary)
+                    Newx(gary, i + 1, Groups_t);
+                else
+                    Renew(gary, i + 1, Groups_t);
+                gary[i] = Atol(p);
+            }
+            if (i)
+                (void)setgroups(i, gary);
+            if (gary)
+                Safefree(gary);
        }
 #else  /* HAS_SETGROUPS */
        PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
@@ -2830,7 +2802,6 @@ S_unwind_handler_stack(pTHX_ const void *p)
 
     if (flags & 1)
        PL_savestack_ix -= 5; /* Unprotect save in progress. */
-    /* cxstack_ix-- Not needed, die already unwound it. */
 #if !defined(PERL_IMPLICIT_CONTEXT)
     if (flags & 64)
        SvREFCNT_dec(PL_sig_sv);