X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/ea1bde1698e6ad6e5f9da28bfbefc2987ec7abcc..e8121b0d0efcf7b0d99f3775e307861be34d07a2:/mg.c?ds=sidebyside diff --git a/mg.c b/mg.c index e3d66be..2de5a86 100644 --- 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 # endif #endif +#if defined(HAS_SETGROUPS) +# ifndef NGROUPS +# define NGROUPS 32 +# endif +#endif + #ifdef __hpux # include #endif @@ -80,13 +83,13 @@ struct magic_state { STATIC void S_save_magic(pTHX_ I32 mgs_ix, SV *sv) { + dVAR; MGS* mgs; assert(SvMAGICAL(sv)); -#ifdef PERL_OLD_COPY_ON_WRITE - /* Turning READONLY off for a copy-on-write scalar is a bad idea. */ + /* Turning READONLY off for a copy-on-write scalar (including shared + hash keys) is a bad idea. */ if (SvIsCOW(sv)) - sv_force_normal(sv); -#endif + sv_force_normal_flags(sv, 0); SAVEDESTRUCTOR_X(S_restore_magic, INT2PTR(void*, (IV)mgs_ix)); @@ -136,6 +139,7 @@ Do magic after a value is retrieved from the SV. See C. int Perl_mg_get(pTHX_ SV *sv) { + dVAR; const I32 mgs_ix = SSNEW(sizeof(MGS)); const bool was_temp = (bool)SvTEMP(sv); int have_new = 0; @@ -216,6 +220,7 @@ Do magic after a value is assigned to the SV. See C. int Perl_mg_set(pTHX_ SV *sv) { + dVAR; const I32 mgs_ix = SSNEW(sizeof(MGS)); MAGIC* mg; MAGIC* nextmg; @@ -248,6 +253,7 @@ Report on the SV's length. See C. U32 Perl_mg_length(pTHX_ SV *sv) { + dVAR; MAGIC* mg; STRLEN len; @@ -369,13 +375,18 @@ Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen) if ((mg->mg_flags & MGf_COPY) && vtbl->svt_copy){ count += CALL_FPTR(vtbl->svt_copy)(aTHX_ sv, mg, nsv, key, klen); } - else if (isUPPER(mg->mg_type)) { - sv_magic(nsv, - mg->mg_type == PERL_MAGIC_tied ? SvTIED_obj(sv, mg) : - (mg->mg_type == PERL_MAGIC_regdata && mg->mg_obj) - ? sv : mg->mg_obj, - toLOWER(mg->mg_type), key, klen); - count++; + else { + const char type = mg->mg_type; + if (isUPPER(type)) { + sv_magic(nsv, + (type == PERL_MAGIC_tied) + ? SvTIED_obj(sv, mg) + : (type == PERL_MAGIC_regdata && mg->mg_obj) + ? sv + : mg->mg_obj, + toLOWER(type), key, klen); + count++; + } } } return count; @@ -394,9 +405,10 @@ doesn't (eg taint, pos). void Perl_mg_localize(pTHX_ SV *sv, SV *nsv) { + dVAR; MAGIC *mg; for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) { - const MGVTBL* const vtbl = mg->mg_virtual; + MGVTBL* const vtbl = mg->mg_virtual; switch (mg->mg_type) { /* value magic types: don't copy */ case PERL_MAGIC_bm: @@ -422,15 +434,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); } @@ -480,14 +489,16 @@ Perl_mg_free(pTHX_ SV *sv) U32 Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg) { - register const REGEXP *rx; + dVAR; PERL_UNUSED_ARG(sv); - if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { - if (mg->mg_obj) /* @+ */ - return rx->nparens; - else /* @- */ - return rx->lastparen; + if (PL_curpm) { + register const REGEXP * const rx = PM_GETRE(PL_curpm); + if (rx) { + return mg->mg_obj + ? rx->nparens /* @+ */ + : rx->lastparen; /* @- */ + } } return (U32)-1; @@ -496,32 +507,34 @@ Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg) { - register REGEXP *rx; - - if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { - register const I32 paren = mg->mg_len; - register I32 s; - register I32 t; - if (paren < 0) - return 0; - if (paren <= (I32)rx->nparens && - (s = rx->startp[paren]) != -1 && - (t = rx->endp[paren]) != -1) - { - register I32 i; - if (mg->mg_obj) /* @+ */ - i = t; - else /* @- */ - i = s; + dVAR; + if (PL_curpm) { + register const REGEXP * const rx = PM_GETRE(PL_curpm); + if (rx) { + register const I32 paren = mg->mg_len; + register I32 s; + register I32 t; + if (paren < 0) + return 0; + if (paren <= (I32)rx->nparens && + (s = rx->startp[paren]) != -1 && + (t = rx->endp[paren]) != -1) + { + register I32 i; + if (mg->mg_obj) /* @+ */ + i = t; + else /* @- */ + i = s; + + if (i > 0 && RX_MATCH_UTF8(rx)) { + const char * const b = rx->subbeg; + if (b) + i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i)); + } - if (i > 0 && RX_MATCH_UTF8(rx)) { - const char * const b = rx->subbeg; - if (b) - i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i)); + sv_setiv(sv, i); } - - sv_setiv(sv, i); - } + } } return 0; } @@ -537,6 +550,7 @@ Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg) U32 Perl_magic_len(pTHX_ SV *sv, MAGIC *mg) { + dVAR; register I32 paren; register I32 i; register const REGEXP *rx; @@ -627,10 +641,14 @@ Perl_magic_len(pTHX_ SV *sv, MAGIC *mg) } #define SvRTRIM(sv) STMT_START { \ - STRLEN len = SvCUR(sv); \ - while (len > 0 && isSPACE(SvPVX(sv)[len-1])) \ - --len; \ - SvCUR_set(sv, len); \ + if (SvPOK(sv)) { \ + STRLEN len = SvCUR(sv); \ + char * const p = SvPVX(sv); \ + while (len > 0 && isSPACE(p[len-1])) \ + --len; \ + SvCUR_set(sv, len); \ + p[len] = '\0'; \ + } \ } STMT_END int @@ -641,16 +659,18 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) register char *s = NULL; register I32 i; register REGEXP *rx; + const char * const remaining = mg->mg_ptr + 1; + const char nextchar = *remaining; switch (*mg->mg_ptr) { case '\001': /* ^A */ sv_setsv(sv, PL_bodytarget); break; case '\003': /* ^C, ^CHILD_ERROR_NATIVE */ - if (*(mg->mg_ptr+1) == '\0') { + if (nextchar == '\0') { sv_setiv(sv, (IV)PL_minus_c); } - else if (strEQ(mg->mg_ptr, "\003HILD_ERROR_NATIVE")) { + else if (strEQ(remaining, "HILD_ERROR_NATIVE")) { sv_setiv(sv, (IV)STATUS_NATIVE); } break; @@ -659,16 +679,15 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) sv_setiv(sv, (IV)(PL_debug & DEBUG_MASK)); break; case '\005': /* ^E */ - if (*(mg->mg_ptr+1) == '\0') { -#ifdef MACOS_TRADITIONAL + if (nextchar == '\0') { +#if defined(MACOS_TRADITIONAL) { char msg[256]; sv_setnv(sv,(double)gMacPerl_OSErr); sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : ""); } -#else -#ifdef VMS +#elif defined(VMS) { # include # include @@ -680,27 +699,24 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) else sv_setpvn(sv,"",0); } -#else -#ifdef OS2 +#elif defined(OS2) if (!(_emx_env & 0x200)) { /* Under DOS */ sv_setnv(sv, (NV)errno); sv_setpv(sv, errno ? Strerror(errno) : ""); } else { if (errno != errno_isOS2) { - int tmp = _syserrno(); + const int tmp = _syserrno(); if (tmp) /* 2nd call to _syserrno() makes it 0 */ Perl_rc = tmp; } sv_setnv(sv, (NV)Perl_rc); sv_setpv(sv, os2error(Perl_rc)); } -#else -#ifdef WIN32 +#elif defined(WIN32) { DWORD dwErr = GetLastError(); sv_setnv(sv, (NV)dwErr); - if (dwErr) - { + if (dwErr) { PerlProc_GetOSError(sv, dwErr); } else @@ -715,13 +731,10 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) errno = saveerrno; } #endif -#endif -#endif -#endif SvRTRIM(sv); SvNOK_on(sv); /* what a wonderful hack! */ } - else if (strEQ(mg->mg_ptr+1, "NCODING")) + else if (strEQ(remaining, "NCODING")) sv_setsv(sv, PL_encoding); break; case '\006': /* ^F */ @@ -737,11 +750,11 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) sv_setsv(sv, &PL_sv_undef); break; case '\017': /* ^O & ^OPEN */ - if (*(mg->mg_ptr+1) == '\0') { + if (nextchar == '\0') { sv_setpv(sv, PL_osname); SvTAINTED_off(sv); } - else if (strEQ(mg->mg_ptr, "\017PEN")) { + else if (strEQ(remaining, "PEN")) { if (!PL_compiling.cop_io) sv_setsv(sv, &PL_sv_undef); else { @@ -753,7 +766,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) sv_setiv(sv, (IV)PL_perldb); break; case '\023': /* ^S */ - if (*(mg->mg_ptr+1) == '\0') { + if (nextchar == '\0') { if (PL_lex_state != LEX_NOTPARSING) SvOK_off(sv); else if (PL_in_eval) @@ -763,39 +776,44 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) } break; case '\024': /* ^T */ - if (*(mg->mg_ptr+1) == '\0') { + if (nextchar == '\0') { #ifdef BIG_TIME sv_setnv(sv, PL_basetime); #else sv_setiv(sv, (IV)PL_basetime); #endif } - else if (strEQ(mg->mg_ptr, "\024AINT")) + else if (strEQ(remaining, "AINT")) sv_setiv(sv, PL_tainting ? (PL_taint_warn || PL_unsafe ? -1 : 1) : 0); break; case '\025': /* $^UNICODE, $^UTF8LOCALE */ - if (strEQ(mg->mg_ptr, "\025NICODE")) + if (strEQ(remaining, "NICODE")) sv_setuv(sv, (UV) PL_unicode); - else if (strEQ(mg->mg_ptr, "\025TF8LOCALE")) + else if (strEQ(remaining, "TF8LOCALE")) sv_setuv(sv, (UV) PL_utf8locale); break; case '\027': /* ^W & $^WARNING_BITS */ - if (*(mg->mg_ptr+1) == '\0') + if (nextchar == '\0') sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE)); - else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) { - if (PL_compiling.cop_warnings == pWARN_NONE || - PL_compiling.cop_warnings == pWARN_STD) - { + else if (strEQ(remaining, "ARNING_BITS")) { + if (PL_compiling.cop_warnings == pWARN_NONE) { sv_setpvn(sv, WARN_NONEstring, WARNsize) ; - } + } + else if (PL_compiling.cop_warnings == pWARN_STD) { + sv_setpvn( + sv, + (PL_dowarn & G_WARN_ON) ? WARN_ALLstring : WARN_NONEstring, + WARNsize + ); + } else if (PL_compiling.cop_warnings == pWARN_ALL) { /* Get the bit mask for $warnings::Bits{all}, because * it could have been extended by warnings::register */ SV **bits_all; - HV *bits=get_hv("warnings::Bits", FALSE); - if (bits && (bits_all=hv_fetch(bits, "all", 3, FALSE))) { + HV * const bits=get_hv("warnings::Bits", FALSE); + if (bits && (bits_all=hv_fetchs(bits, "all", FALSE))) { sv_setsv(sv, *bits_all); } else { @@ -830,14 +848,17 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) getrx: if (i >= 0) { + const int oldtainted = PL_tainted; + TAINT_NOT; sv_setpvn(sv, s, i); + PL_tainted = oldtainted; if (RX_MATCH_UTF8(rx) && is_utf8_string((U8*)s, i)) SvUTF8_on(sv); else SvUTF8_off(sv); if (PL_tainting) { if (RX_MATCH_TAINTED(rx)) { - MAGIC* mg = SvMAGIC(sv); + MAGIC* const mg = SvMAGIC(sv); MAGIC* mgt; PL_tainted = 1; SvMAGIC_set(sv, mg->mg_moremagic); @@ -978,25 +999,22 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) break; case '(': sv_setiv(sv, (IV)PL_gid); -#ifdef HAS_GETGROUPS - Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, (long unsigned int)PL_gid); -#endif goto add_groups; case ')': sv_setiv(sv, (IV)PL_egid); -#ifdef HAS_GETGROUPS - Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, (long unsigned int)PL_egid); -#endif 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 i, num_groups = getgroups(0, gary); + Newx(gary, num_groups, Groups_t); + num_groups = getgroups(num_groups, gary); + for (i = 0; i < num_groups; i++) + Perl_sv_catpvf(aTHX_ sv, " %"IVdf, (IV)gary[i]); + Safefree(gary); } -#endif (void)SvIOK_on(sv); /* what a wonderful hack! */ +#endif break; #ifndef MACOS_TRADITIONAL case '0': @@ -1020,20 +1038,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 @@ -1045,10 +1060,13 @@ Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg) MgTAINTEDDIR_off(mg); #ifdef VMS if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) { - char pathbuf[256], eltbuf[256], *cp, *elt = (char *) s; + char pathbuf[256], eltbuf[256], *cp, *elt; Stat_t sbuf; int i = 0, j = 0; + strncpy(eltbuf, s, 255); + eltbuf[255] = 0; + elt = eltbuf; do { /* DCL$PATH may be a search list */ while (1) { /* as may dev portion of any element */ if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) { @@ -1058,7 +1076,7 @@ Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg) return 0; } } - if ((cp = strchr(elt, ':')) != Nullch) + if ((cp = strchr(elt, ':')) != NULL) *cp = '\0'; if (my_trnlnm(elt, eltbuf, j++)) elt = eltbuf; @@ -1097,19 +1115,21 @@ int Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg) { PERL_UNUSED_ARG(sv); - my_setenv(MgPV_nolen_const(mg),Nullch); + my_setenv(MgPV_nolen_const(mg),NULL); return 0; } int Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg) { -#if defined(VMS) || defined(EPOC) || defined(SYMBIAN) + dVAR; + PERL_UNUSED_ARG(mg); +#if defined(VMS) Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system"); #else if (PL_localizing) { HE* entry; - magic_clear_all_env(sv,mg); + my_clearenv(); hv_iterinit((HV*)sv); while ((entry = hv_iternext((HV*)sv))) { I32 keylen; @@ -1125,39 +1145,13 @@ int Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) { dVAR; -#ifndef PERL_MICRO -#if defined(VMS) || defined(EPOC) || defined(SYMBIAN) - Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system"); -#else -# if defined(PERL_IMPLICIT_SYS) || defined(WIN32) - PerlEnv_clearenv(); -# else -# ifdef USE_ENVIRON_ARRAY -# if defined(USE_ITHREADS) - /* only the parent thread can clobber the process environment */ - if (PL_curinterp == aTHX) -# endif - { -# ifndef PERL_USE_SAFE_PUTENV - if (!PL_use_safe_putenv) { - I32 i; - - if (environ == PL_origenviron) - environ = (char**)safesysmalloc(sizeof(char*)); - else - for (i = 0; environ[i]; i++) - safesysfree(environ[i]); - } -# endif /* PERL_USE_SAFE_PUTENV */ - - environ[0] = Nullch; - } -# endif /* USE_ENVIRON_ARRAY */ -# endif /* PERL_IMPLICIT_SYS || WIN32 */ -#endif /* VMS || EPOC */ -#endif /* !PERL_MICRO */ PERL_UNUSED_ARG(sv); PERL_UNUSED_ARG(mg); +#if defined(VMS) + Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system"); +#else + my_clearenv(); +#endif return 0; } @@ -1166,13 +1160,14 @@ Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) static void restore_sigmask(pTHX_ SV *save_sv) { - const sigset_t *ossetp = (const sigset_t *) SvPV_nolen_const( save_sv ); + const sigset_t * const ossetp = (const sigset_t *) SvPV_nolen_const( save_sv ); (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0); } #endif int Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg) { + dVAR; /* Are we fetching a signal entry? */ const I32 i = whichsig(MgPV_nolen_const(mg)); if (i > 0) { @@ -1208,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__")) @@ -1217,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); } } @@ -1252,7 +1247,7 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg) PL_psig_name[i]=0; } if(PL_psig_ptr[i]) { - SV *to_dec=PL_psig_ptr[i]; + SV * const to_dec=PL_psig_ptr[i]; PL_psig_ptr[i]=0; LEAVE; SvREFCNT_dec(to_dec); @@ -1267,6 +1262,7 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg) static void S_raise_signal(pTHX_ int sig) { + dVAR; /* Set a flag to say this signal is pending */ PL_psig_pend[sig]++; /* And one to say _a_ signal is pending */ @@ -1329,6 +1325,7 @@ Perl_csighandler_init(void) void Perl_despatch_signals(pTHX) { + dVAR; int sig; PL_sig_pending = 0; for (sig = 1; sig < SIG_SIZE; sig++) { @@ -1347,12 +1344,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; @@ -1370,7 +1367,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) i = 0; if (*svp) { to_dec = *svp; - *svp = 0; + *svp = NULL; } } else { @@ -1449,7 +1446,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 @@ -1468,6 +1465,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg) { + dVAR; PERL_UNUSED_ARG(sv); PERL_UNUSED_ARG(mg); PL_sub_generation++; @@ -1477,6 +1475,7 @@ Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg) { + dVAR; PERL_UNUSED_ARG(sv); PERL_UNUSED_ARG(mg); /* HV_badAMAGIC_on(Sv_STASH(sv)); */ @@ -1520,6 +1519,7 @@ Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg) STATIC int S_magic_methcall(pTHX_ SV *sv, const MAGIC *mg, const char *meth, I32 flags, int n, SV *val) { + dVAR; dSP; PUSHMARK(SP); @@ -1696,6 +1696,7 @@ Perl_magic_scalarpack(pTHX_ HV *hv, MAGIC *mg) int Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg) { + dVAR; GV * const gv = PL_DBline; const I32 i = SvTRUE(sv); SV ** const svp = av_fetch(GvAV(gv), @@ -1716,6 +1717,7 @@ Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_getarylen(pTHX_ SV *sv, const MAGIC *mg) { + dVAR; const AV * const obj = (AV*)mg->mg_obj; if (obj) { sv_setiv(sv, AvFILL(obj) + PL_curcop->cop_arybase); @@ -1728,6 +1730,7 @@ Perl_magic_getarylen(pTHX_ SV *sv, const MAGIC *mg) int Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg) { + dVAR; AV * const obj = (AV*)mg->mg_obj; if (obj) { av_fill(obj, SvIV(sv) - PL_curcop->cop_arybase); @@ -1742,6 +1745,7 @@ Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_freearylen_p(pTHX_ SV *sv, MAGIC *mg) { + dVAR; PERL_UNUSED_ARG(sv); /* during global destruction, mg_obj may already have been freed */ if (PL_in_clean_all) @@ -1763,6 +1767,7 @@ Perl_magic_freearylen_p(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg) { + dVAR; SV* const lsv = LvTARG(sv); if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) { @@ -1782,6 +1787,7 @@ Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg) { + dVAR; SV* const lsv = LvTARG(sv); SSize_t pos; STRLEN len; @@ -1794,7 +1800,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)) { @@ -1853,7 +1859,7 @@ Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg) if (!SvOK(sv)) return 0; - gv = gv_fetchsv(sv,TRUE, SVt_PVGV); + gv = gv_fetchsv(sv, GV_ADD, SVt_PVGV); if (sv == (SV*)gv) return 0; if (GvGP(sv)) @@ -1887,6 +1893,7 @@ Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg) { + dVAR; STRLEN len; const char *tmps = SvPV_const(sv, len); SV * const lsv = LvTARG(sv); @@ -1920,6 +1927,7 @@ Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg) { + dVAR; PERL_UNUSED_ARG(sv); TAINT_IF((PL_localizing != 1) && (mg->mg_len & 1)); return 0; @@ -1928,6 +1936,7 @@ Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg) { + dVAR; PERL_UNUSED_ARG(sv); /* update taint status unless we're restoring at scope exit */ if (PL_localizing != 2) { @@ -1945,12 +1954,11 @@ Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg) SV * const lsv = LvTARG(sv); PERL_UNUSED_ARG(mg); - if (!lsv) { + if (lsv) + sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv))); + else SvOK_off(sv); - return 0; - } - sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv))); return 0; } @@ -1965,7 +1973,8 @@ Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg) { - SV *targ = Nullsv; + dVAR; + SV *targ = NULL; if (LvTARGLEN(sv)) { if (mg->mg_obj) { SV * const ahv = LvTARG(sv); @@ -1984,7 +1993,7 @@ Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg) LvTARG(sv) = SvREFCNT_inc(targ); LvTARGLEN(sv) = 0; SvREFCNT_dec(mg->mg_obj); - mg->mg_obj = Nullsv; + mg->mg_obj = NULL; mg->mg_flags &= ~MGf_REFCOUNTED; } } @@ -2010,8 +2019,9 @@ Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg) void Perl_vivify_defelem(pTHX_ SV *sv) { + dVAR; MAGIC *mg; - SV *value = Nullsv; + SV *value = NULL; if (!LvTARGLEN(sv) || !(mg = mg_find(sv, PERL_MAGIC_defelem))) return; @@ -2026,7 +2036,7 @@ Perl_vivify_defelem(pTHX_ SV *sv) else { AV* const av = (AV*)LvTARG(sv); if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av)) - LvTARG(sv) = Nullsv; /* array can't be extended */ + LvTARG(sv) = NULL; /* array can't be extended */ else { SV** const svp = av_fetch(av, LvTARGOFF(sv), TRUE); if (!svp || (value = *svp) == &PL_sv_undef) @@ -2038,47 +2048,14 @@ Perl_vivify_defelem(pTHX_ SV *sv) LvTARG(sv) = value; LvTARGLEN(sv) = 0; SvREFCNT_dec(mg->mg_obj); - mg->mg_obj = Nullsv; + mg->mg_obj = NULL; mg->mg_flags &= ~MGf_REFCOUNTED; } int Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg) { - AV *const av = (AV*)mg->mg_obj; - SV **svp = AvARRAY(av); - PERL_UNUSED_ARG(sv); - - if (svp) { - 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 @@ -2128,6 +2105,7 @@ Perl_magic_setregexp(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg) { + dVAR; regexp * const re = (regexp *)mg->mg_obj; PERL_UNUSED_ARG(sv); @@ -2167,6 +2145,7 @@ Perl_magic_setutf8(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) { + dVAR; register const char *s; I32 i; STRLEN len; @@ -2215,7 +2194,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) PL_encoding = newSVsv(sv); } else { - PL_encoding = Nullsv; + PL_encoding = NULL; } } break; @@ -2227,12 +2206,12 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) break; case '\011': /* ^I */ /* NOT \t in EBCDIC */ Safefree(PL_inplace); - PL_inplace = SvOK(sv) ? savesvpv(sv) : Nullch; + PL_inplace = SvOK(sv) ? savesvpv(sv) : NULL; break; case '\017': /* ^O */ if (*(mg->mg_ptr+1) == '\0') { Safefree(PL_osname); - PL_osname = Nullch; + PL_osname = NULL; if (SvOK(sv)) { TAINT_PROPER("assigning to $^O"); PL_osname = savesvpv(sv); @@ -2311,12 +2290,12 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) case '^': Safefree(IoTOP_NAME(GvIOp(PL_defoutgv))); s = IoTOP_NAME(GvIOp(PL_defoutgv)) = savesvpv(sv); - IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv,TRUE, SVt_PVIO); + IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv, GV_ADD, SVt_PVIO); break; case '~': Safefree(IoFMT_NAME(GvIOp(PL_defoutgv))); s = IoFMT_NAME(GvIOp(PL_defoutgv)) = savesvpv(sv); - IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv,TRUE, SVt_PVIO); + IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv, GV_ADD, SVt_PVIO); break; case '=': IoPAGE_LEN(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); @@ -2357,7 +2336,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) PL_ors_sv = newSVsv(sv); } else { - PL_ors_sv = Nullsv; + PL_ors_sv = NULL; } break; case ',': @@ -2367,7 +2346,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) PL_ofs_sv = newSVsv(sv); } else { - PL_ofs_sv = Nullsv; + PL_ofs_sv = NULL; } break; case '[': @@ -2383,10 +2362,10 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) #endif #ifdef VMSISH_STATUS if (VMSISH_STATUS) - STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv))); + STATUS_NATIVE_CHILD_SET((U32)SvIV(sv)); else #endif - STATUS_UNIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); + STATUS_UNIX_EXIT_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); break; case '!': { @@ -2489,22 +2468,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); @@ -2544,7 +2529,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) /* The BSDs don't show the argv[] in ps(1) output, they * show a string from the process struct and provide * the setproctitle() routine to manipulate that. */ - { + if (PL_origalen != 1) { s = SvPV_const(sv, len); # if __FreeBSD_version > 410001 /* The leading "-" removes the "perl: " prefix, @@ -2565,35 +2550,37 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) } #endif #if defined(__hpux) && defined(PSTAT_SETCMD) - { + if (PL_origalen != 1) { union pstun un; s = SvPV_const(sv, len); un.pst_command = (char *)s; pstat(PSTAT_SETCMD, un, len, 0, 0); } #endif - /* PL_origalen is set in perl_parse(). */ - s = SvPV_force(sv,len); - if (len >= (STRLEN)PL_origalen-1) { - /* Longer than original, will be truncated. We assume that - * PL_origalen bytes are available. */ - Copy(s, PL_origargv[0], PL_origalen-1, char); + if (PL_origalen > 1) { + /* PL_origalen is set in perl_parse(). */ + s = SvPV_force(sv,len); + if (len >= (STRLEN)PL_origalen-1) { + /* Longer than original, will be truncated. We assume that + * PL_origalen bytes are available. */ + Copy(s, PL_origargv[0], PL_origalen-1, char); + } + else { + /* Shorter than original, will be padded. */ + Copy(s, PL_origargv[0], len, char); + PL_origargv[0][len] = 0; + memset(PL_origargv[0] + len + 1, + /* Is the space counterintuitive? Yes. + * (You were expecting \0?) + * Does it work? Seems to. (In Linux 2.4.20 at least.) + * --jhi */ + (int)' ', + PL_origalen - len - 1); + } + PL_origargv[0][PL_origalen-1] = 0; + for (i = 1; i < PL_origargc; i++) + PL_origargv[i] = 0; } - else { - /* Shorter than original, will be padded. */ - Copy(s, PL_origargv[0], len, char); - PL_origargv[0][len] = 0; - memset(PL_origargv[0] + len + 1, - /* Is the space counterintuitive? Yes. - * (You were expecting \0?) - * Does it work? Seems to. (In Linux 2.4.20 at least.) - * --jhi */ - (int)' ', - PL_origalen - len - 1); - } - PL_origargv[0][PL_origalen-1] = 0; - for (i = 1; i < PL_origargc; i++) - PL_origargv[i] = 0; UNLOCK_DOLLARZERO_MUTEX; break; #endif @@ -2633,10 +2620,10 @@ Perl_sighandler(int sig) dTHX; #endif dSP; - GV *gv = Nullgv; - SV *sv = Nullsv; + GV *gv = NULL; + SV *sv = NULL; SV * const tSv = PL_Sv; - CV *cv = Nullcv; + CV *cv = NULL; OP *myop = PL_op; U32 flags = 0; XPV * const tXpv = PL_Xpv; @@ -2668,7 +2655,7 @@ Perl_sighandler(int sig) if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig])) || SvTYPE(cv) != SVt_PVCV) { HV *st; - cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE); + cv = sv_2cv(PL_psig_ptr[sig], &st, &gv, GV_ADD); } if (!cv || !CvROOT(cv)) { @@ -2724,6 +2711,8 @@ Perl_sighandler(int sig) PUSHs((SV*)rv); PUSHs(newSVpv((void*)sip, sizeof(*sip))); } + + va_end(args); } } #endif @@ -2749,7 +2738,7 @@ Perl_sighandler(int sig) (void)rsignal(sig, PL_csighandlerp); #endif #endif /* !PERL_MICRO */ - Perl_die(aTHX_ Nullch); + Perl_die(aTHX_ NULL); } cleanup: if (flags & 1) @@ -2771,6 +2760,7 @@ cleanup: static void S_restore_magic(pTHX_ const void *p) { + dVAR; MGS* const mgs = SSPTR(PTR2IV(p), MGS*); SV* const sv = mgs->mgs_sv; @@ -2783,15 +2773,23 @@ S_restore_magic(pTHX_ const void *p) /* While magic was saved (and off) sv_setsv may well have seen this SV as a prime candidate for COW. */ if (SvIsCOW(sv)) - sv_force_normal(sv); + sv_force_normal_flags(sv, 0); #endif if (mgs->mgs_flags) SvFLAGS(sv) |= mgs->mgs_flags; else mg_magical(sv); - if (SvGMAGICAL(sv)) - SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK); + if (SvGMAGICAL(sv)) { + /* downgrade public flags to private, + and discard any other private flags */ + + U32 public = SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK); + if (public) { + SvFLAGS(sv) &= ~( public | SVp_IOK|SVp_NOK|SVp_POK ); + SvFLAGS(sv) |= ( public << PRIVSHIFT ); + } + } } mgs->mgs_sv = NULL; /* mark the MGS structure as restored */ @@ -2824,7 +2822,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);