xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/mg.c (revision 11134:8aa0c4ca6639)
1*11134SCasper.Dik@Sun.COM /*
2*11134SCasper.Dik@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3*11134SCasper.Dik@Sun.COM  * Use is subject to license terms.
4*11134SCasper.Dik@Sun.COM  */
50Sstevel@tonic-gate /*    mg.c
60Sstevel@tonic-gate  *
70Sstevel@tonic-gate  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
80Sstevel@tonic-gate  *    2000, 2001, 2002, 2003, 2004, by Larry Wall and others
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  *    You may distribute under the terms of either the GNU General Public
110Sstevel@tonic-gate  *    License or the Artistic License, as specified in the README file.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  */
140Sstevel@tonic-gate 
150Sstevel@tonic-gate /*
160Sstevel@tonic-gate  * "Sam sat on the ground and put his head in his hands.  'I wish I had never
170Sstevel@tonic-gate  * come here, and I don't want to see no more magic,' he said, and fell silent."
180Sstevel@tonic-gate  */
190Sstevel@tonic-gate 
200Sstevel@tonic-gate /*
210Sstevel@tonic-gate =head1 Magical Functions
220Sstevel@tonic-gate */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate #include "EXTERN.h"
250Sstevel@tonic-gate #define PERL_IN_MG_C
260Sstevel@tonic-gate #include "perl.h"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
290Sstevel@tonic-gate #  ifndef NGROUPS
300Sstevel@tonic-gate #    define NGROUPS 32
310Sstevel@tonic-gate #  endif
320Sstevel@tonic-gate #  ifdef I_GRP
330Sstevel@tonic-gate #    include <grp.h>
340Sstevel@tonic-gate #  endif
35*11134SCasper.Dik@Sun.COM #ifdef __sun
36*11134SCasper.Dik@Sun.COM #include <alloca.h>
37*11134SCasper.Dik@Sun.COM #include <unistd.h>
38*11134SCasper.Dik@Sun.COM #endif
390Sstevel@tonic-gate #endif
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #ifdef __hpux
420Sstevel@tonic-gate #  include <sys/pstat.h>
430Sstevel@tonic-gate #endif
440Sstevel@tonic-gate 
450Sstevel@tonic-gate Signal_t Perl_csighandler(int sig);
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /* if you only have signal() and it resets on each signal, FAKE_PERSISTENT_SIGNAL_HANDLERS fixes */
480Sstevel@tonic-gate #if !defined(HAS_SIGACTION) && defined(VMS)
490Sstevel@tonic-gate #  define  FAKE_PERSISTENT_SIGNAL_HANDLERS
500Sstevel@tonic-gate #endif
510Sstevel@tonic-gate /* if we're doing kill() with sys$sigprc on VMS, FAKE_DEFAULT_SIGNAL_HANDLERS */
520Sstevel@tonic-gate #if defined(KILL_BY_SIGPRC)
530Sstevel@tonic-gate #  define  FAKE_DEFAULT_SIGNAL_HANDLERS
540Sstevel@tonic-gate #endif
550Sstevel@tonic-gate 
560Sstevel@tonic-gate static void restore_magic(pTHX_ void *p);
570Sstevel@tonic-gate static void unwind_handler_stack(pTHX_ void *p);
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #ifdef __Lynx__
600Sstevel@tonic-gate /* Missing protos on LynxOS */
610Sstevel@tonic-gate void setruid(uid_t id);
620Sstevel@tonic-gate void seteuid(uid_t id);
630Sstevel@tonic-gate void setrgid(uid_t id);
640Sstevel@tonic-gate void setegid(uid_t id);
650Sstevel@tonic-gate #endif
660Sstevel@tonic-gate 
670Sstevel@tonic-gate /*
680Sstevel@tonic-gate  * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
690Sstevel@tonic-gate  */
700Sstevel@tonic-gate 
710Sstevel@tonic-gate struct magic_state {
720Sstevel@tonic-gate     SV* mgs_sv;
730Sstevel@tonic-gate     U32 mgs_flags;
740Sstevel@tonic-gate     I32 mgs_ss_ix;
750Sstevel@tonic-gate };
760Sstevel@tonic-gate /* MGS is typedef'ed to struct magic_state in perl.h */
770Sstevel@tonic-gate 
780Sstevel@tonic-gate STATIC void
S_save_magic(pTHX_ I32 mgs_ix,SV * sv)790Sstevel@tonic-gate S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
800Sstevel@tonic-gate {
810Sstevel@tonic-gate     MGS* mgs;
820Sstevel@tonic-gate     assert(SvMAGICAL(sv));
830Sstevel@tonic-gate 
840Sstevel@tonic-gate     SAVEDESTRUCTOR_X(restore_magic, INT2PTR(void*, (IV)mgs_ix));
850Sstevel@tonic-gate 
860Sstevel@tonic-gate     mgs = SSPTR(mgs_ix, MGS*);
870Sstevel@tonic-gate     mgs->mgs_sv = sv;
880Sstevel@tonic-gate     mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
890Sstevel@tonic-gate     mgs->mgs_ss_ix = PL_savestack_ix;   /* points after the saved destructor */
900Sstevel@tonic-gate 
910Sstevel@tonic-gate     SvMAGICAL_off(sv);
920Sstevel@tonic-gate     SvREADONLY_off(sv);
930Sstevel@tonic-gate     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_NOK|SVp_POK)) >> PRIVSHIFT;
940Sstevel@tonic-gate }
950Sstevel@tonic-gate 
960Sstevel@tonic-gate /*
970Sstevel@tonic-gate =for apidoc mg_magical
980Sstevel@tonic-gate 
990Sstevel@tonic-gate Turns on the magical status of an SV.  See C<sv_magic>.
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate =cut
1020Sstevel@tonic-gate */
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate void
Perl_mg_magical(pTHX_ SV * sv)1050Sstevel@tonic-gate Perl_mg_magical(pTHX_ SV *sv)
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate     MAGIC* mg;
1080Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
1090Sstevel@tonic-gate 	MGVTBL* vtbl = mg->mg_virtual;
1100Sstevel@tonic-gate 	if (vtbl) {
1110Sstevel@tonic-gate 	    if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
1120Sstevel@tonic-gate 		SvGMAGICAL_on(sv);
1130Sstevel@tonic-gate 	    if (vtbl->svt_set)
1140Sstevel@tonic-gate 		SvSMAGICAL_on(sv);
1150Sstevel@tonic-gate 	    if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
1160Sstevel@tonic-gate 		SvRMAGICAL_on(sv);
1170Sstevel@tonic-gate 	}
1180Sstevel@tonic-gate     }
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate /*
1220Sstevel@tonic-gate =for apidoc mg_get
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate Do magic after a value is retrieved from the SV.  See C<sv_magic>.
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate =cut
1270Sstevel@tonic-gate */
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate int
Perl_mg_get(pTHX_ SV * sv)1300Sstevel@tonic-gate Perl_mg_get(pTHX_ SV *sv)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate     int new = 0;
1330Sstevel@tonic-gate     MAGIC *newmg, *head, *cur, *mg;
1340Sstevel@tonic-gate     I32 mgs_ix = SSNEW(sizeof(MGS));
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate     save_magic(mgs_ix, sv);
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate     /* We must call svt_get(sv, mg) for each valid entry in the linked
1390Sstevel@tonic-gate        list of magic. svt_get() may delete the current entry, add new
1400Sstevel@tonic-gate        magic to the head of the list, or upgrade the SV. AMS 20010810 */
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate     newmg = cur = head = mg = SvMAGIC(sv);
1430Sstevel@tonic-gate     while (mg) {
1440Sstevel@tonic-gate 	MGVTBL *vtbl = mg->mg_virtual;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
1470Sstevel@tonic-gate 	    CALL_FPTR(vtbl->svt_get)(aTHX_ sv, mg);
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 	    /* guard against sv having been freed */
1500Sstevel@tonic-gate 	    if (SvTYPE(sv) == SVTYPEMASK) {
1510Sstevel@tonic-gate 		Perl_croak(aTHX_ "Tied variable freed while still in use");
1520Sstevel@tonic-gate 	    }
1530Sstevel@tonic-gate 	    /* guard against magic having been deleted - eg FETCH calling
1540Sstevel@tonic-gate 	     * untie */
1550Sstevel@tonic-gate 	    if (!SvMAGIC(sv))
1560Sstevel@tonic-gate 		break;
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate 	    /* Don't restore the flags for this entry if it was deleted. */
1590Sstevel@tonic-gate 	    if (mg->mg_flags & MGf_GSKIP)
1600Sstevel@tonic-gate 		(SSPTR(mgs_ix, MGS *))->mgs_flags = 0;
1610Sstevel@tonic-gate 	}
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	mg = mg->mg_moremagic;
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	if (new) {
1660Sstevel@tonic-gate 	    /* Have we finished with the new entries we saw? Start again
1670Sstevel@tonic-gate 	       where we left off (unless there are more new entries). */
1680Sstevel@tonic-gate 	    if (mg == head) {
1690Sstevel@tonic-gate 		new  = 0;
1700Sstevel@tonic-gate 		mg   = cur;
1710Sstevel@tonic-gate 		head = newmg;
1720Sstevel@tonic-gate 	    }
1730Sstevel@tonic-gate 	}
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	/* Were any new entries added? */
1760Sstevel@tonic-gate 	if (!new && (newmg = SvMAGIC(sv)) != head) {
1770Sstevel@tonic-gate 	    new = 1;
1780Sstevel@tonic-gate 	    cur = mg;
1790Sstevel@tonic-gate 	    mg  = newmg;
1800Sstevel@tonic-gate 	}
1810Sstevel@tonic-gate     }
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate     restore_magic(aTHX_ INT2PTR(void *, (IV)mgs_ix));
1840Sstevel@tonic-gate     return 0;
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate /*
1880Sstevel@tonic-gate =for apidoc mg_set
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate Do magic after a value is assigned to the SV.  See C<sv_magic>.
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate =cut
1930Sstevel@tonic-gate */
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate int
Perl_mg_set(pTHX_ SV * sv)1960Sstevel@tonic-gate Perl_mg_set(pTHX_ SV *sv)
1970Sstevel@tonic-gate {
1980Sstevel@tonic-gate     I32 mgs_ix;
1990Sstevel@tonic-gate     MAGIC* mg;
2000Sstevel@tonic-gate     MAGIC* nextmg;
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate     mgs_ix = SSNEW(sizeof(MGS));
2030Sstevel@tonic-gate     save_magic(mgs_ix, sv);
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
2060Sstevel@tonic-gate 	MGVTBL* vtbl = mg->mg_virtual;
2070Sstevel@tonic-gate 	nextmg = mg->mg_moremagic;	/* it may delete itself */
2080Sstevel@tonic-gate 	if (mg->mg_flags & MGf_GSKIP) {
2090Sstevel@tonic-gate 	    mg->mg_flags &= ~MGf_GSKIP;	/* setting requires another read */
2100Sstevel@tonic-gate 	    (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
2110Sstevel@tonic-gate 	}
2120Sstevel@tonic-gate 	if (vtbl && vtbl->svt_set)
2130Sstevel@tonic-gate 	    CALL_FPTR(vtbl->svt_set)(aTHX_ sv, mg);
2140Sstevel@tonic-gate     }
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate     restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
2170Sstevel@tonic-gate     return 0;
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate /*
2210Sstevel@tonic-gate =for apidoc mg_length
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate Report on the SV's length.  See C<sv_magic>.
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate =cut
2260Sstevel@tonic-gate */
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate U32
Perl_mg_length(pTHX_ SV * sv)2290Sstevel@tonic-gate Perl_mg_length(pTHX_ SV *sv)
2300Sstevel@tonic-gate {
2310Sstevel@tonic-gate     MAGIC* mg;
2320Sstevel@tonic-gate     STRLEN len;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
2350Sstevel@tonic-gate 	MGVTBL* vtbl = mg->mg_virtual;
2360Sstevel@tonic-gate 	if (vtbl && vtbl->svt_len) {
2370Sstevel@tonic-gate             I32 mgs_ix;
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 	    mgs_ix = SSNEW(sizeof(MGS));
2400Sstevel@tonic-gate 	    save_magic(mgs_ix, sv);
2410Sstevel@tonic-gate 	    /* omit MGf_GSKIP -- not changed here */
2420Sstevel@tonic-gate 	    len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
2430Sstevel@tonic-gate 	    restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
2440Sstevel@tonic-gate 	    return len;
2450Sstevel@tonic-gate 	}
2460Sstevel@tonic-gate     }
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate     if (DO_UTF8(sv))
2490Sstevel@tonic-gate     {
2500Sstevel@tonic-gate         U8 *s = (U8*)SvPV(sv, len);
2510Sstevel@tonic-gate         len = Perl_utf8_length(aTHX_ s, s + len);
2520Sstevel@tonic-gate     }
2530Sstevel@tonic-gate     else
2540Sstevel@tonic-gate         (void)SvPV(sv, len);
2550Sstevel@tonic-gate     return len;
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate I32
Perl_mg_size(pTHX_ SV * sv)2590Sstevel@tonic-gate Perl_mg_size(pTHX_ SV *sv)
2600Sstevel@tonic-gate {
2610Sstevel@tonic-gate     MAGIC* mg;
2620Sstevel@tonic-gate     I32 len;
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
2650Sstevel@tonic-gate 	MGVTBL* vtbl = mg->mg_virtual;
2660Sstevel@tonic-gate 	if (vtbl && vtbl->svt_len) {
2670Sstevel@tonic-gate             I32 mgs_ix;
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 	    mgs_ix = SSNEW(sizeof(MGS));
2700Sstevel@tonic-gate 	    save_magic(mgs_ix, sv);
2710Sstevel@tonic-gate 	    /* omit MGf_GSKIP -- not changed here */
2720Sstevel@tonic-gate 	    len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
2730Sstevel@tonic-gate 	    restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
2740Sstevel@tonic-gate 	    return len;
2750Sstevel@tonic-gate 	}
2760Sstevel@tonic-gate     }
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate     switch(SvTYPE(sv)) {
2790Sstevel@tonic-gate 	case SVt_PVAV:
2800Sstevel@tonic-gate 	    len = AvFILLp((AV *) sv); /* Fallback to non-tied array */
2810Sstevel@tonic-gate 	    return len;
2820Sstevel@tonic-gate 	case SVt_PVHV:
2830Sstevel@tonic-gate 	    /* FIXME */
2840Sstevel@tonic-gate 	default:
2850Sstevel@tonic-gate 	    Perl_croak(aTHX_ "Size magic not implemented");
2860Sstevel@tonic-gate 	    break;
2870Sstevel@tonic-gate     }
2880Sstevel@tonic-gate     return 0;
2890Sstevel@tonic-gate }
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate /*
2920Sstevel@tonic-gate =for apidoc mg_clear
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate Clear something magical that the SV represents.  See C<sv_magic>.
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate =cut
2970Sstevel@tonic-gate */
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate int
Perl_mg_clear(pTHX_ SV * sv)3000Sstevel@tonic-gate Perl_mg_clear(pTHX_ SV *sv)
3010Sstevel@tonic-gate {
3020Sstevel@tonic-gate     I32 mgs_ix;
3030Sstevel@tonic-gate     MAGIC* mg;
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate     mgs_ix = SSNEW(sizeof(MGS));
3060Sstevel@tonic-gate     save_magic(mgs_ix, sv);
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
3090Sstevel@tonic-gate 	MGVTBL* vtbl = mg->mg_virtual;
3100Sstevel@tonic-gate 	/* omit GSKIP -- never set here */
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 	if (vtbl && vtbl->svt_clear)
3130Sstevel@tonic-gate 	    CALL_FPTR(vtbl->svt_clear)(aTHX_ sv, mg);
3140Sstevel@tonic-gate     }
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate     restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
3170Sstevel@tonic-gate     return 0;
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate /*
3210Sstevel@tonic-gate =for apidoc mg_find
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate Finds the magic pointer for type matching the SV.  See C<sv_magic>.
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate =cut
3260Sstevel@tonic-gate */
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate MAGIC*
Perl_mg_find(pTHX_ SV * sv,int type)3290Sstevel@tonic-gate Perl_mg_find(pTHX_ SV *sv, int type)
3300Sstevel@tonic-gate {
3310Sstevel@tonic-gate     MAGIC* mg;
3320Sstevel@tonic-gate     if (!sv)
3330Sstevel@tonic-gate         return 0;
3340Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
3350Sstevel@tonic-gate 	if (mg->mg_type == type)
3360Sstevel@tonic-gate 	    return mg;
3370Sstevel@tonic-gate     }
3380Sstevel@tonic-gate     return 0;
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate /*
3420Sstevel@tonic-gate =for apidoc mg_copy
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate Copies the magic from one SV to another.  See C<sv_magic>.
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate =cut
3470Sstevel@tonic-gate */
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate int
Perl_mg_copy(pTHX_ SV * sv,SV * nsv,const char * key,I32 klen)3500Sstevel@tonic-gate Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen)
3510Sstevel@tonic-gate {
3520Sstevel@tonic-gate     int count = 0;
3530Sstevel@tonic-gate     MAGIC* mg;
3540Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
3550Sstevel@tonic-gate 	MGVTBL* vtbl = mg->mg_virtual;
3560Sstevel@tonic-gate 	if ((mg->mg_flags & MGf_COPY) && vtbl->svt_copy){
3570Sstevel@tonic-gate 	    count += CALL_FPTR(vtbl->svt_copy)(aTHX_ sv, mg, nsv, key, klen);
3580Sstevel@tonic-gate 	}
3590Sstevel@tonic-gate 	else if (isUPPER(mg->mg_type)) {
3600Sstevel@tonic-gate 	    sv_magic(nsv,
3610Sstevel@tonic-gate 		     mg->mg_type == PERL_MAGIC_tied ? SvTIED_obj(sv, mg) :
3620Sstevel@tonic-gate 		     (mg->mg_type == PERL_MAGIC_regdata && mg->mg_obj)
3630Sstevel@tonic-gate 							? sv : mg->mg_obj,
3640Sstevel@tonic-gate 		     toLOWER(mg->mg_type), key, klen);
3650Sstevel@tonic-gate 	    count++;
3660Sstevel@tonic-gate 	}
3670Sstevel@tonic-gate     }
3680Sstevel@tonic-gate     return count;
3690Sstevel@tonic-gate }
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate /*
3720Sstevel@tonic-gate =for apidoc mg_free
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate Free any magic storage used by the SV.  See C<sv_magic>.
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate =cut
3770Sstevel@tonic-gate */
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate int
Perl_mg_free(pTHX_ SV * sv)3800Sstevel@tonic-gate Perl_mg_free(pTHX_ SV *sv)
3810Sstevel@tonic-gate {
3820Sstevel@tonic-gate     MAGIC* mg;
3830Sstevel@tonic-gate     MAGIC* moremagic;
3840Sstevel@tonic-gate     for (mg = SvMAGIC(sv); mg; mg = moremagic) {
3850Sstevel@tonic-gate 	MGVTBL* vtbl = mg->mg_virtual;
3860Sstevel@tonic-gate 	moremagic = mg->mg_moremagic;
3870Sstevel@tonic-gate 	if (vtbl && vtbl->svt_free)
3880Sstevel@tonic-gate 	    CALL_FPTR(vtbl->svt_free)(aTHX_ sv, mg);
3890Sstevel@tonic-gate 	if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) {
3900Sstevel@tonic-gate 	    if (mg->mg_len > 0 || mg->mg_type == PERL_MAGIC_utf8)
3910Sstevel@tonic-gate 		Safefree(mg->mg_ptr);
3920Sstevel@tonic-gate 	    else if (mg->mg_len == HEf_SVKEY)
3930Sstevel@tonic-gate 		SvREFCNT_dec((SV*)mg->mg_ptr);
3940Sstevel@tonic-gate 	}
3950Sstevel@tonic-gate 	if (mg->mg_flags & MGf_REFCOUNTED)
3960Sstevel@tonic-gate 	    SvREFCNT_dec(mg->mg_obj);
3970Sstevel@tonic-gate 	Safefree(mg);
3980Sstevel@tonic-gate     }
3990Sstevel@tonic-gate     SvMAGIC(sv) = 0;
4000Sstevel@tonic-gate     return 0;
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate #include <signal.h>
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate U32
Perl_magic_regdata_cnt(pTHX_ SV * sv,MAGIC * mg)4060Sstevel@tonic-gate Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
4070Sstevel@tonic-gate {
4080Sstevel@tonic-gate     register REGEXP *rx;
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate     if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
4110Sstevel@tonic-gate 	if (mg->mg_obj)		/* @+ */
4120Sstevel@tonic-gate 	    return rx->nparens;
4130Sstevel@tonic-gate 	else			/* @- */
4140Sstevel@tonic-gate 	    return rx->lastparen;
4150Sstevel@tonic-gate     }
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate     return (U32)-1;
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate int
Perl_magic_regdatum_get(pTHX_ SV * sv,MAGIC * mg)4210Sstevel@tonic-gate Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
4220Sstevel@tonic-gate {
4230Sstevel@tonic-gate     register I32 paren;
4240Sstevel@tonic-gate     register I32 s;
4250Sstevel@tonic-gate     register I32 i;
4260Sstevel@tonic-gate     register REGEXP *rx;
4270Sstevel@tonic-gate     I32 t;
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate     if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
4300Sstevel@tonic-gate 	paren = mg->mg_len;
4310Sstevel@tonic-gate 	if (paren < 0)
4320Sstevel@tonic-gate 	    return 0;
4330Sstevel@tonic-gate 	if (paren <= (I32)rx->nparens &&
4340Sstevel@tonic-gate 	    (s = rx->startp[paren]) != -1 &&
4350Sstevel@tonic-gate 	    (t = rx->endp[paren]) != -1)
4360Sstevel@tonic-gate 	    {
4370Sstevel@tonic-gate 		if (mg->mg_obj)		/* @+ */
4380Sstevel@tonic-gate 		    i = t;
4390Sstevel@tonic-gate 		else			/* @- */
4400Sstevel@tonic-gate 		    i = s;
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 		if (i > 0 && RX_MATCH_UTF8(rx)) {
4430Sstevel@tonic-gate 		    char *b = rx->subbeg;
4440Sstevel@tonic-gate 		    if (b)
4450Sstevel@tonic-gate 		        i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i));
4460Sstevel@tonic-gate 		}
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate 		sv_setiv(sv, i);
4490Sstevel@tonic-gate 	    }
4500Sstevel@tonic-gate     }
4510Sstevel@tonic-gate     return 0;
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate int
Perl_magic_regdatum_set(pTHX_ SV * sv,MAGIC * mg)4550Sstevel@tonic-gate Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg)
4560Sstevel@tonic-gate {
4570Sstevel@tonic-gate     Perl_croak(aTHX_ PL_no_modify);
4580Sstevel@tonic-gate     /* NOT REACHED */
4590Sstevel@tonic-gate     return 0;
4600Sstevel@tonic-gate }
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate U32
Perl_magic_len(pTHX_ SV * sv,MAGIC * mg)4630Sstevel@tonic-gate Perl_magic_len(pTHX_ SV *sv, MAGIC *mg)
4640Sstevel@tonic-gate {
4650Sstevel@tonic-gate     register I32 paren;
4660Sstevel@tonic-gate     register I32 i;
4670Sstevel@tonic-gate     register REGEXP *rx;
4680Sstevel@tonic-gate     I32 s1, t1;
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate     switch (*mg->mg_ptr) {
4710Sstevel@tonic-gate     case '1': case '2': case '3': case '4':
4720Sstevel@tonic-gate     case '5': case '6': case '7': case '8': case '9': case '&':
4730Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
4740Sstevel@tonic-gate 
4750Sstevel@tonic-gate 	    paren = atoi(mg->mg_ptr); /* $& is in [0] */
4760Sstevel@tonic-gate 	  getparen:
4770Sstevel@tonic-gate 	    if (paren <= (I32)rx->nparens &&
4780Sstevel@tonic-gate 		(s1 = rx->startp[paren]) != -1 &&
4790Sstevel@tonic-gate 		(t1 = rx->endp[paren]) != -1)
4800Sstevel@tonic-gate 	    {
4810Sstevel@tonic-gate 		i = t1 - s1;
4820Sstevel@tonic-gate 	      getlen:
4830Sstevel@tonic-gate 		if (i > 0 && RX_MATCH_UTF8(rx)) {
4840Sstevel@tonic-gate 		    char *s    = rx->subbeg + s1;
4850Sstevel@tonic-gate 		    char *send = rx->subbeg + t1;
4860Sstevel@tonic-gate 
4870Sstevel@tonic-gate                     i = t1 - s1;
4880Sstevel@tonic-gate 		    if (is_utf8_string((U8*)s, i))
4890Sstevel@tonic-gate 			i = Perl_utf8_length(aTHX_ (U8*)s, (U8*)send);
4900Sstevel@tonic-gate 		}
4910Sstevel@tonic-gate 		if (i < 0)
4920Sstevel@tonic-gate 		    Perl_croak(aTHX_ "panic: magic_len: %"IVdf, (IV)i);
4930Sstevel@tonic-gate 		return i;
4940Sstevel@tonic-gate 	    }
4950Sstevel@tonic-gate 	    else {
4960Sstevel@tonic-gate 		if (ckWARN(WARN_UNINITIALIZED))
4970Sstevel@tonic-gate 		    report_uninit();
4980Sstevel@tonic-gate 	    }
4990Sstevel@tonic-gate 	}
5000Sstevel@tonic-gate 	else {
5010Sstevel@tonic-gate 	    if (ckWARN(WARN_UNINITIALIZED))
5020Sstevel@tonic-gate 		report_uninit();
5030Sstevel@tonic-gate 	}
5040Sstevel@tonic-gate 	return 0;
5050Sstevel@tonic-gate     case '+':
5060Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
5070Sstevel@tonic-gate 	    paren = rx->lastparen;
5080Sstevel@tonic-gate 	    if (paren)
5090Sstevel@tonic-gate 		goto getparen;
5100Sstevel@tonic-gate 	}
5110Sstevel@tonic-gate 	return 0;
5120Sstevel@tonic-gate     case '\016': /* ^N */
5130Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
5140Sstevel@tonic-gate 	    paren = rx->lastcloseparen;
5150Sstevel@tonic-gate 	    if (paren)
5160Sstevel@tonic-gate 		goto getparen;
5170Sstevel@tonic-gate 	}
5180Sstevel@tonic-gate 	return 0;
5190Sstevel@tonic-gate     case '`':
5200Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
5210Sstevel@tonic-gate 	    if (rx->startp[0] != -1) {
5220Sstevel@tonic-gate 		i = rx->startp[0];
5230Sstevel@tonic-gate 		if (i > 0) {
5240Sstevel@tonic-gate 		    s1 = 0;
5250Sstevel@tonic-gate 		    t1 = i;
5260Sstevel@tonic-gate 		    goto getlen;
5270Sstevel@tonic-gate 		}
5280Sstevel@tonic-gate 	    }
5290Sstevel@tonic-gate 	}
5300Sstevel@tonic-gate 	return 0;
5310Sstevel@tonic-gate     case '\'':
5320Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
5330Sstevel@tonic-gate 	    if (rx->endp[0] != -1) {
5340Sstevel@tonic-gate 		i = rx->sublen - rx->endp[0];
5350Sstevel@tonic-gate 		if (i > 0) {
5360Sstevel@tonic-gate 		    s1 = rx->endp[0];
5370Sstevel@tonic-gate 		    t1 = rx->sublen;
5380Sstevel@tonic-gate 		    goto getlen;
5390Sstevel@tonic-gate 		}
5400Sstevel@tonic-gate 	    }
5410Sstevel@tonic-gate 	}
5420Sstevel@tonic-gate 	return 0;
5430Sstevel@tonic-gate     }
5440Sstevel@tonic-gate     magic_get(sv,mg);
5450Sstevel@tonic-gate     if (!SvPOK(sv) && SvNIOK(sv)) {
5460Sstevel@tonic-gate 	STRLEN n_a;
5470Sstevel@tonic-gate 	sv_2pv(sv, &n_a);
5480Sstevel@tonic-gate     }
5490Sstevel@tonic-gate     if (SvPOK(sv))
5500Sstevel@tonic-gate 	return SvCUR(sv);
5510Sstevel@tonic-gate     return 0;
5520Sstevel@tonic-gate }
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate int
Perl_magic_get(pTHX_ SV * sv,MAGIC * mg)5550Sstevel@tonic-gate Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
5560Sstevel@tonic-gate {
5570Sstevel@tonic-gate     register I32 paren;
5580Sstevel@tonic-gate     register char *s = NULL;
5590Sstevel@tonic-gate     register I32 i;
5600Sstevel@tonic-gate     register REGEXP *rx;
5610Sstevel@tonic-gate 
5620Sstevel@tonic-gate     switch (*mg->mg_ptr) {
5630Sstevel@tonic-gate     case '\001':		/* ^A */
5640Sstevel@tonic-gate 	sv_setsv(sv, PL_bodytarget);
5650Sstevel@tonic-gate 	break;
5660Sstevel@tonic-gate     case '\003':		/* ^C */
5670Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_minus_c);
5680Sstevel@tonic-gate 	break;
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate     case '\004':		/* ^D */
5710Sstevel@tonic-gate 	sv_setiv(sv, (IV)(PL_debug & DEBUG_MASK));
5720Sstevel@tonic-gate #if defined(YYDEBUG) && defined(DEBUGGING)
5730Sstevel@tonic-gate 	PL_yydebug = DEBUG_p_TEST;
5740Sstevel@tonic-gate #endif
5750Sstevel@tonic-gate 	break;
5760Sstevel@tonic-gate     case '\005':  /* ^E */
5770Sstevel@tonic-gate 	 if (*(mg->mg_ptr+1) == '\0') {
5780Sstevel@tonic-gate #ifdef MACOS_TRADITIONAL
5790Sstevel@tonic-gate 	     {
5800Sstevel@tonic-gate 		  char msg[256];
5810Sstevel@tonic-gate 
5820Sstevel@tonic-gate 		  sv_setnv(sv,(double)gMacPerl_OSErr);
5830Sstevel@tonic-gate 		  sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : "");
5840Sstevel@tonic-gate 	     }
5850Sstevel@tonic-gate #else
5860Sstevel@tonic-gate #ifdef VMS
5870Sstevel@tonic-gate 	     {
5880Sstevel@tonic-gate #	          include <descrip.h>
5890Sstevel@tonic-gate #	          include <starlet.h>
5900Sstevel@tonic-gate 		  char msg[255];
5910Sstevel@tonic-gate 		  $DESCRIPTOR(msgdsc,msg);
5920Sstevel@tonic-gate 		  sv_setnv(sv,(NV) vaxc$errno);
5930Sstevel@tonic-gate 		  if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
5940Sstevel@tonic-gate 		       sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
5950Sstevel@tonic-gate 		  else
5960Sstevel@tonic-gate 		       sv_setpv(sv,"");
5970Sstevel@tonic-gate 	     }
5980Sstevel@tonic-gate #else
5990Sstevel@tonic-gate #ifdef OS2
6000Sstevel@tonic-gate 	     if (!(_emx_env & 0x200)) {	/* Under DOS */
6010Sstevel@tonic-gate 		  sv_setnv(sv, (NV)errno);
6020Sstevel@tonic-gate 		  sv_setpv(sv, errno ? Strerror(errno) : "");
6030Sstevel@tonic-gate 	     } else {
6040Sstevel@tonic-gate 		  if (errno != errno_isOS2) {
6050Sstevel@tonic-gate 		       int tmp = _syserrno();
6060Sstevel@tonic-gate 		       if (tmp)	/* 2nd call to _syserrno() makes it 0 */
6070Sstevel@tonic-gate 			    Perl_rc = tmp;
6080Sstevel@tonic-gate 		  }
6090Sstevel@tonic-gate 		  sv_setnv(sv, (NV)Perl_rc);
6100Sstevel@tonic-gate 		  sv_setpv(sv, os2error(Perl_rc));
6110Sstevel@tonic-gate 	     }
6120Sstevel@tonic-gate #else
6130Sstevel@tonic-gate #ifdef WIN32
6140Sstevel@tonic-gate 	     {
6150Sstevel@tonic-gate 		  DWORD dwErr = GetLastError();
6160Sstevel@tonic-gate 		  sv_setnv(sv, (NV)dwErr);
6170Sstevel@tonic-gate 		  if (dwErr)
6180Sstevel@tonic-gate 		  {
6190Sstevel@tonic-gate 		       PerlProc_GetOSError(sv, dwErr);
6200Sstevel@tonic-gate 		  }
6210Sstevel@tonic-gate 		  else
6220Sstevel@tonic-gate 		       sv_setpv(sv, "");
6230Sstevel@tonic-gate 		  SetLastError(dwErr);
6240Sstevel@tonic-gate 	     }
6250Sstevel@tonic-gate #else
6260Sstevel@tonic-gate 	     {
6270Sstevel@tonic-gate 		 int saveerrno = errno;
6280Sstevel@tonic-gate 		 sv_setnv(sv, (NV)errno);
6290Sstevel@tonic-gate 		 sv_setpv(sv, errno ? Strerror(errno) : "");
6300Sstevel@tonic-gate 		 errno = saveerrno;
6310Sstevel@tonic-gate 	     }
6320Sstevel@tonic-gate #endif
6330Sstevel@tonic-gate #endif
6340Sstevel@tonic-gate #endif
6350Sstevel@tonic-gate #endif
6360Sstevel@tonic-gate 	     SvNOK_on(sv);	/* what a wonderful hack! */
6370Sstevel@tonic-gate 	 }
6380Sstevel@tonic-gate 	 else if (strEQ(mg->mg_ptr+1, "NCODING"))
6390Sstevel@tonic-gate 	      sv_setsv(sv, PL_encoding);
6400Sstevel@tonic-gate 	 break;
6410Sstevel@tonic-gate     case '\006':		/* ^F */
6420Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_maxsysfd);
6430Sstevel@tonic-gate 	break;
6440Sstevel@tonic-gate     case '\010':		/* ^H */
6450Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_hints);
6460Sstevel@tonic-gate 	break;
6470Sstevel@tonic-gate     case '\011':		/* ^I */ /* NOT \t in EBCDIC */
6480Sstevel@tonic-gate 	if (PL_inplace)
6490Sstevel@tonic-gate 	    sv_setpv(sv, PL_inplace);
6500Sstevel@tonic-gate 	else
6510Sstevel@tonic-gate 	    sv_setsv(sv, &PL_sv_undef);
6520Sstevel@tonic-gate 	break;
6530Sstevel@tonic-gate     case '\017':		/* ^O & ^OPEN */
6540Sstevel@tonic-gate 	if (*(mg->mg_ptr+1) == '\0') {
6550Sstevel@tonic-gate 	    sv_setpv(sv, PL_osname);
6560Sstevel@tonic-gate 	    SvTAINTED_off(sv);
6570Sstevel@tonic-gate 	}
6580Sstevel@tonic-gate 	else if (strEQ(mg->mg_ptr, "\017PEN")) {
6590Sstevel@tonic-gate 	    if (!PL_compiling.cop_io)
6600Sstevel@tonic-gate 		sv_setsv(sv, &PL_sv_undef);
6610Sstevel@tonic-gate             else {
6620Sstevel@tonic-gate 	        sv_setsv(sv, PL_compiling.cop_io);
6630Sstevel@tonic-gate 	    }
6640Sstevel@tonic-gate 	}
6650Sstevel@tonic-gate 	break;
6660Sstevel@tonic-gate     case '\020':		/* ^P */
6670Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_perldb);
6680Sstevel@tonic-gate 	break;
6690Sstevel@tonic-gate     case '\023':		/* ^S */
6700Sstevel@tonic-gate         if (*(mg->mg_ptr+1) == '\0') {
6710Sstevel@tonic-gate 	    if (PL_lex_state != LEX_NOTPARSING)
6720Sstevel@tonic-gate 		(void)SvOK_off(sv);
6730Sstevel@tonic-gate 	    else if (PL_in_eval)
6740Sstevel@tonic-gate  		sv_setiv(sv, PL_in_eval & ~(EVAL_INREQUIRE));
6750Sstevel@tonic-gate 	    else
6760Sstevel@tonic-gate 		sv_setiv(sv, 0);
6770Sstevel@tonic-gate 	}
6780Sstevel@tonic-gate 	break;
6790Sstevel@tonic-gate     case '\024':		/* ^T */
6800Sstevel@tonic-gate         if (*(mg->mg_ptr+1) == '\0') {
6810Sstevel@tonic-gate #ifdef BIG_TIME
6820Sstevel@tonic-gate             sv_setnv(sv, PL_basetime);
6830Sstevel@tonic-gate #else
6840Sstevel@tonic-gate             sv_setiv(sv, (IV)PL_basetime);
6850Sstevel@tonic-gate #endif
6860Sstevel@tonic-gate         }
6870Sstevel@tonic-gate         else if (strEQ(mg->mg_ptr, "\024AINT"))
6880Sstevel@tonic-gate             sv_setiv(sv, PL_tainting
6890Sstevel@tonic-gate 		    ? (PL_taint_warn || PL_unsafe ? -1 : 1)
6900Sstevel@tonic-gate 		    : 0);
6910Sstevel@tonic-gate         break;
6920Sstevel@tonic-gate     case '\025':		/* $^UNICODE */
6930Sstevel@tonic-gate         if (strEQ(mg->mg_ptr, "\025NICODE"))
6940Sstevel@tonic-gate 	    sv_setuv(sv, (UV) PL_unicode);
6950Sstevel@tonic-gate         break;
6960Sstevel@tonic-gate     case '\027':		/* ^W  & $^WARNING_BITS */
6970Sstevel@tonic-gate 	if (*(mg->mg_ptr+1) == '\0')
6980Sstevel@tonic-gate 	    sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE));
6990Sstevel@tonic-gate 	else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) {
7000Sstevel@tonic-gate 	    if (PL_compiling.cop_warnings == pWARN_NONE ||
7010Sstevel@tonic-gate 	        PL_compiling.cop_warnings == pWARN_STD)
7020Sstevel@tonic-gate 	    {
7030Sstevel@tonic-gate 	        sv_setpvn(sv, WARN_NONEstring, WARNsize) ;
7040Sstevel@tonic-gate             }
7050Sstevel@tonic-gate             else if (PL_compiling.cop_warnings == pWARN_ALL) {
7060Sstevel@tonic-gate 	        sv_setpvn(sv, WARN_ALLstring, WARNsize) ;
7070Sstevel@tonic-gate 	    }
7080Sstevel@tonic-gate             else {
7090Sstevel@tonic-gate 	        sv_setsv(sv, PL_compiling.cop_warnings);
7100Sstevel@tonic-gate 	    }
7110Sstevel@tonic-gate 	    SvPOK_only(sv);
7120Sstevel@tonic-gate 	}
7130Sstevel@tonic-gate 	break;
7140Sstevel@tonic-gate     case '1': case '2': case '3': case '4':
7150Sstevel@tonic-gate     case '5': case '6': case '7': case '8': case '9': case '&':
7160Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
7170Sstevel@tonic-gate 	    I32 s1, t1;
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 	    /*
7200Sstevel@tonic-gate 	     * Pre-threads, this was paren = atoi(GvENAME((GV*)mg->mg_obj));
7210Sstevel@tonic-gate 	     * XXX Does the new way break anything?
7220Sstevel@tonic-gate 	     */
7230Sstevel@tonic-gate 	    paren = atoi(mg->mg_ptr); /* $& is in [0] */
7240Sstevel@tonic-gate 	  getparen:
7250Sstevel@tonic-gate 	    if (paren <= (I32)rx->nparens &&
7260Sstevel@tonic-gate 		(s1 = rx->startp[paren]) != -1 &&
7270Sstevel@tonic-gate 		(t1 = rx->endp[paren]) != -1)
7280Sstevel@tonic-gate 	    {
7290Sstevel@tonic-gate 		i = t1 - s1;
7300Sstevel@tonic-gate 		s = rx->subbeg + s1;
7310Sstevel@tonic-gate 		if (!rx->subbeg)
7320Sstevel@tonic-gate 		    break;
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate 	      getrx:
7350Sstevel@tonic-gate 		if (i >= 0) {
7360Sstevel@tonic-gate 		    sv_setpvn(sv, s, i);
7370Sstevel@tonic-gate 		    if (RX_MATCH_UTF8(rx) && is_utf8_string((U8*)s, i))
7380Sstevel@tonic-gate 			SvUTF8_on(sv);
7390Sstevel@tonic-gate 		    else
7400Sstevel@tonic-gate 			SvUTF8_off(sv);
7410Sstevel@tonic-gate 		    if (PL_tainting) {
7420Sstevel@tonic-gate 			if (RX_MATCH_TAINTED(rx)) {
7430Sstevel@tonic-gate 			    MAGIC* mg = SvMAGIC(sv);
7440Sstevel@tonic-gate 			    MAGIC* mgt;
7450Sstevel@tonic-gate 			    PL_tainted = 1;
7460Sstevel@tonic-gate 			    SvMAGIC(sv) = mg->mg_moremagic;
7470Sstevel@tonic-gate 			    SvTAINT(sv);
7480Sstevel@tonic-gate 			    if ((mgt = SvMAGIC(sv))) {
7490Sstevel@tonic-gate 				mg->mg_moremagic = mgt;
7500Sstevel@tonic-gate 				SvMAGIC(sv) = mg;
7510Sstevel@tonic-gate 			    }
7520Sstevel@tonic-gate 			} else
7530Sstevel@tonic-gate 			    SvTAINTED_off(sv);
7540Sstevel@tonic-gate 		    }
7550Sstevel@tonic-gate 		    break;
7560Sstevel@tonic-gate 		}
7570Sstevel@tonic-gate 	    }
7580Sstevel@tonic-gate 	}
7590Sstevel@tonic-gate 	sv_setsv(sv,&PL_sv_undef);
7600Sstevel@tonic-gate 	break;
7610Sstevel@tonic-gate     case '+':
7620Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
7630Sstevel@tonic-gate 	    paren = rx->lastparen;
7640Sstevel@tonic-gate 	    if (paren)
7650Sstevel@tonic-gate 		goto getparen;
7660Sstevel@tonic-gate 	}
7670Sstevel@tonic-gate 	sv_setsv(sv,&PL_sv_undef);
7680Sstevel@tonic-gate 	break;
7690Sstevel@tonic-gate     case '\016':		/* ^N */
7700Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
7710Sstevel@tonic-gate 	    paren = rx->lastcloseparen;
7720Sstevel@tonic-gate 	    if (paren)
7730Sstevel@tonic-gate 		goto getparen;
7740Sstevel@tonic-gate 	}
7750Sstevel@tonic-gate 	sv_setsv(sv,&PL_sv_undef);
7760Sstevel@tonic-gate 	break;
7770Sstevel@tonic-gate     case '`':
7780Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
7790Sstevel@tonic-gate 	    if ((s = rx->subbeg) && rx->startp[0] != -1) {
7800Sstevel@tonic-gate 		i = rx->startp[0];
7810Sstevel@tonic-gate 		goto getrx;
7820Sstevel@tonic-gate 	    }
7830Sstevel@tonic-gate 	}
7840Sstevel@tonic-gate 	sv_setsv(sv,&PL_sv_undef);
7850Sstevel@tonic-gate 	break;
7860Sstevel@tonic-gate     case '\'':
7870Sstevel@tonic-gate 	if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
7880Sstevel@tonic-gate 	    if (rx->subbeg && rx->endp[0] != -1) {
7890Sstevel@tonic-gate 		s = rx->subbeg + rx->endp[0];
7900Sstevel@tonic-gate 		i = rx->sublen - rx->endp[0];
7910Sstevel@tonic-gate 		goto getrx;
7920Sstevel@tonic-gate 	    }
7930Sstevel@tonic-gate 	}
7940Sstevel@tonic-gate 	sv_setsv(sv,&PL_sv_undef);
7950Sstevel@tonic-gate 	break;
7960Sstevel@tonic-gate     case '.':
7970Sstevel@tonic-gate #ifndef lint
7980Sstevel@tonic-gate 	if (GvIO(PL_last_in_gv)) {
7990Sstevel@tonic-gate 	    sv_setiv(sv, (IV)IoLINES(GvIOp(PL_last_in_gv)));
8000Sstevel@tonic-gate 	}
8010Sstevel@tonic-gate #endif
8020Sstevel@tonic-gate 	break;
8030Sstevel@tonic-gate     case '?':
8040Sstevel@tonic-gate 	{
8050Sstevel@tonic-gate 	    sv_setiv(sv, (IV)STATUS_CURRENT);
8060Sstevel@tonic-gate #ifdef COMPLEX_STATUS
8070Sstevel@tonic-gate 	    LvTARGOFF(sv) = PL_statusvalue;
8080Sstevel@tonic-gate 	    LvTARGLEN(sv) = PL_statusvalue_vms;
8090Sstevel@tonic-gate #endif
8100Sstevel@tonic-gate 	}
8110Sstevel@tonic-gate 	break;
8120Sstevel@tonic-gate     case '^':
8130Sstevel@tonic-gate 	if (GvIOp(PL_defoutgv))
8140Sstevel@tonic-gate 	    s = IoTOP_NAME(GvIOp(PL_defoutgv));
8150Sstevel@tonic-gate 	if (s)
8160Sstevel@tonic-gate 	    sv_setpv(sv,s);
8170Sstevel@tonic-gate 	else {
8180Sstevel@tonic-gate 	    sv_setpv(sv,GvENAME(PL_defoutgv));
8190Sstevel@tonic-gate 	    sv_catpv(sv,"_TOP");
8200Sstevel@tonic-gate 	}
8210Sstevel@tonic-gate 	break;
8220Sstevel@tonic-gate     case '~':
8230Sstevel@tonic-gate 	if (GvIOp(PL_defoutgv))
8240Sstevel@tonic-gate 	    s = IoFMT_NAME(GvIOp(PL_defoutgv));
8250Sstevel@tonic-gate 	if (!s)
8260Sstevel@tonic-gate 	    s = GvENAME(PL_defoutgv);
8270Sstevel@tonic-gate 	sv_setpv(sv,s);
8280Sstevel@tonic-gate 	break;
8290Sstevel@tonic-gate #ifndef lint
8300Sstevel@tonic-gate     case '=':
8310Sstevel@tonic-gate 	if (GvIOp(PL_defoutgv))
8320Sstevel@tonic-gate 	    sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
8330Sstevel@tonic-gate 	break;
8340Sstevel@tonic-gate     case '-':
8350Sstevel@tonic-gate 	if (GvIOp(PL_defoutgv))
8360Sstevel@tonic-gate 	    sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
8370Sstevel@tonic-gate 	break;
8380Sstevel@tonic-gate     case '%':
8390Sstevel@tonic-gate 	if (GvIOp(PL_defoutgv))
8400Sstevel@tonic-gate 	    sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
8410Sstevel@tonic-gate 	break;
8420Sstevel@tonic-gate #endif
8430Sstevel@tonic-gate     case ':':
8440Sstevel@tonic-gate 	break;
8450Sstevel@tonic-gate     case '/':
8460Sstevel@tonic-gate 	break;
8470Sstevel@tonic-gate     case '[':
8480Sstevel@tonic-gate 	WITH_THR(sv_setiv(sv, (IV)PL_curcop->cop_arybase));
8490Sstevel@tonic-gate 	break;
8500Sstevel@tonic-gate     case '|':
8510Sstevel@tonic-gate 	if (GvIOp(PL_defoutgv))
8520Sstevel@tonic-gate 	    sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
8530Sstevel@tonic-gate 	break;
8540Sstevel@tonic-gate     case ',':
8550Sstevel@tonic-gate 	break;
8560Sstevel@tonic-gate     case '\\':
8570Sstevel@tonic-gate 	if (PL_ors_sv)
8580Sstevel@tonic-gate 	    sv_copypv(sv, PL_ors_sv);
8590Sstevel@tonic-gate 	break;
8600Sstevel@tonic-gate     case '#':
8610Sstevel@tonic-gate 	sv_setpv(sv,PL_ofmt);
8620Sstevel@tonic-gate 	break;
8630Sstevel@tonic-gate     case '!':
8640Sstevel@tonic-gate #ifdef VMS
8650Sstevel@tonic-gate 	sv_setnv(sv, (NV)((errno == EVMSERR) ? vaxc$errno : errno));
8660Sstevel@tonic-gate 	sv_setpv(sv, errno ? Strerror(errno) : "");
8670Sstevel@tonic-gate #else
8680Sstevel@tonic-gate 	{
8690Sstevel@tonic-gate 	int saveerrno = errno;
8700Sstevel@tonic-gate 	sv_setnv(sv, (NV)errno);
8710Sstevel@tonic-gate #ifdef OS2
8720Sstevel@tonic-gate 	if (errno == errno_isOS2 || errno == errno_isOS2_set)
8730Sstevel@tonic-gate 	    sv_setpv(sv, os2error(Perl_rc));
8740Sstevel@tonic-gate 	else
8750Sstevel@tonic-gate #endif
8760Sstevel@tonic-gate 	sv_setpv(sv, errno ? Strerror(errno) : "");
8770Sstevel@tonic-gate 	errno = saveerrno;
8780Sstevel@tonic-gate 	}
8790Sstevel@tonic-gate #endif
8800Sstevel@tonic-gate 	SvNOK_on(sv);	/* what a wonderful hack! */
8810Sstevel@tonic-gate 	break;
8820Sstevel@tonic-gate     case '<':
8830Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_uid);
8840Sstevel@tonic-gate 	break;
8850Sstevel@tonic-gate     case '>':
8860Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_euid);
8870Sstevel@tonic-gate 	break;
8880Sstevel@tonic-gate     case '(':
8890Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_gid);
8900Sstevel@tonic-gate #ifdef HAS_GETGROUPS
8910Sstevel@tonic-gate 	Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_gid);
8920Sstevel@tonic-gate #endif
8930Sstevel@tonic-gate 	goto add_groups;
8940Sstevel@tonic-gate     case ')':
8950Sstevel@tonic-gate 	sv_setiv(sv, (IV)PL_egid);
8960Sstevel@tonic-gate #ifdef HAS_GETGROUPS
8970Sstevel@tonic-gate 	Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_egid);
8980Sstevel@tonic-gate #endif
8990Sstevel@tonic-gate       add_groups:
9000Sstevel@tonic-gate #ifdef HAS_GETGROUPS
9010Sstevel@tonic-gate 	{
902*11134SCasper.Dik@Sun.COM #ifdef __sun
903*11134SCasper.Dik@Sun.COM 	    int maxgrp = getgroups(0, NULL);
904*11134SCasper.Dik@Sun.COM 	    Groups_t *gary = alloca(maxgrp * sizeof (Groups_t));
905*11134SCasper.Dik@Sun.COM 	    i = getgroups(maxgrp,gary);
906*11134SCasper.Dik@Sun.COM #else
9070Sstevel@tonic-gate 	    Groups_t gary[NGROUPS];
9080Sstevel@tonic-gate 	    i = getgroups(NGROUPS,gary);
909*11134SCasper.Dik@Sun.COM #endif
9100Sstevel@tonic-gate 	    while (--i >= 0)
9110Sstevel@tonic-gate 		Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, gary[i]);
9120Sstevel@tonic-gate 	}
9130Sstevel@tonic-gate #endif
9140Sstevel@tonic-gate 	(void)SvIOK_on(sv);	/* what a wonderful hack! */
9150Sstevel@tonic-gate 	break;
9160Sstevel@tonic-gate     case '*':
9170Sstevel@tonic-gate 	break;
9180Sstevel@tonic-gate #ifndef MACOS_TRADITIONAL
9190Sstevel@tonic-gate     case '0':
9200Sstevel@tonic-gate 	break;
9210Sstevel@tonic-gate #endif
9220Sstevel@tonic-gate #ifdef USE_5005THREADS
9230Sstevel@tonic-gate     case '@':
9240Sstevel@tonic-gate 	sv_setsv(sv, thr->errsv);
9250Sstevel@tonic-gate 	break;
9260Sstevel@tonic-gate #endif /* USE_5005THREADS */
9270Sstevel@tonic-gate     }
9280Sstevel@tonic-gate     return 0;
9290Sstevel@tonic-gate }
9300Sstevel@tonic-gate 
9310Sstevel@tonic-gate int
Perl_magic_getuvar(pTHX_ SV * sv,MAGIC * mg)9320Sstevel@tonic-gate Perl_magic_getuvar(pTHX_ SV *sv, MAGIC *mg)
9330Sstevel@tonic-gate {
9340Sstevel@tonic-gate     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
9350Sstevel@tonic-gate 
9360Sstevel@tonic-gate     if (uf && uf->uf_val)
9370Sstevel@tonic-gate 	(*uf->uf_val)(aTHX_ uf->uf_index, sv);
9380Sstevel@tonic-gate     return 0;
9390Sstevel@tonic-gate }
9400Sstevel@tonic-gate 
9410Sstevel@tonic-gate int
Perl_magic_setenv(pTHX_ SV * sv,MAGIC * mg)9420Sstevel@tonic-gate Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg)
9430Sstevel@tonic-gate {
9440Sstevel@tonic-gate     register char *s;
9450Sstevel@tonic-gate     char *ptr;
9460Sstevel@tonic-gate     STRLEN len, klen;
9470Sstevel@tonic-gate 
9480Sstevel@tonic-gate     s = SvPV(sv,len);
9490Sstevel@tonic-gate     ptr = MgPV(mg,klen);
9500Sstevel@tonic-gate     my_setenv(ptr, s);
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate #ifdef DYNAMIC_ENV_FETCH
9530Sstevel@tonic-gate      /* We just undefd an environment var.  Is a replacement */
9540Sstevel@tonic-gate      /* waiting in the wings? */
9550Sstevel@tonic-gate     if (!len) {
9560Sstevel@tonic-gate 	SV **valp;
9570Sstevel@tonic-gate 	if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
9580Sstevel@tonic-gate 	    s = SvPV(*valp, len);
9590Sstevel@tonic-gate     }
9600Sstevel@tonic-gate #endif
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate #if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
9630Sstevel@tonic-gate 			    /* And you'll never guess what the dog had */
9640Sstevel@tonic-gate 			    /*   in its mouth... */
9650Sstevel@tonic-gate     if (PL_tainting) {
9660Sstevel@tonic-gate 	MgTAINTEDDIR_off(mg);
9670Sstevel@tonic-gate #ifdef VMS
9680Sstevel@tonic-gate 	if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
9690Sstevel@tonic-gate 	    char pathbuf[256], eltbuf[256], *cp, *elt = s;
9700Sstevel@tonic-gate 	    Stat_t sbuf;
9710Sstevel@tonic-gate 	    int i = 0, j = 0;
9720Sstevel@tonic-gate 
9730Sstevel@tonic-gate 	    do {          /* DCL$PATH may be a search list */
9740Sstevel@tonic-gate 		while (1) {   /* as may dev portion of any element */
9750Sstevel@tonic-gate 		    if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
9760Sstevel@tonic-gate 			if ( *(cp+1) == '.' || *(cp+1) == '-' ||
9770Sstevel@tonic-gate 			     cando_by_name(S_IWUSR,0,elt) ) {
9780Sstevel@tonic-gate 			    MgTAINTEDDIR_on(mg);
9790Sstevel@tonic-gate 			    return 0;
9800Sstevel@tonic-gate 			}
9810Sstevel@tonic-gate 		    }
9820Sstevel@tonic-gate 		    if ((cp = strchr(elt, ':')) != Nullch)
9830Sstevel@tonic-gate 			*cp = '\0';
9840Sstevel@tonic-gate 		    if (my_trnlnm(elt, eltbuf, j++))
9850Sstevel@tonic-gate 			elt = eltbuf;
9860Sstevel@tonic-gate 		    else
9870Sstevel@tonic-gate 			break;
9880Sstevel@tonic-gate 		}
9890Sstevel@tonic-gate 		j = 0;
9900Sstevel@tonic-gate 	    } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
9910Sstevel@tonic-gate 	}
9920Sstevel@tonic-gate #endif /* VMS */
9930Sstevel@tonic-gate 	if (s && klen == 4 && strEQ(ptr,"PATH")) {
9940Sstevel@tonic-gate 	    char *strend = s + len;
9950Sstevel@tonic-gate 
9960Sstevel@tonic-gate 	    while (s < strend) {
9970Sstevel@tonic-gate 		char tmpbuf[256];
9980Sstevel@tonic-gate 		Stat_t st;
9990Sstevel@tonic-gate 		I32 i;
10000Sstevel@tonic-gate 		s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
10010Sstevel@tonic-gate 			     s, strend, ':', &i);
10020Sstevel@tonic-gate 		s++;
10030Sstevel@tonic-gate 		if (i >= sizeof tmpbuf   /* too long -- assume the worst */
10040Sstevel@tonic-gate 		      || *tmpbuf != '/'
10050Sstevel@tonic-gate 		      || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
10060Sstevel@tonic-gate 		    MgTAINTEDDIR_on(mg);
10070Sstevel@tonic-gate 		    return 0;
10080Sstevel@tonic-gate 		}
10090Sstevel@tonic-gate 	    }
10100Sstevel@tonic-gate 	}
10110Sstevel@tonic-gate     }
10120Sstevel@tonic-gate #endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
10130Sstevel@tonic-gate 
10140Sstevel@tonic-gate     return 0;
10150Sstevel@tonic-gate }
10160Sstevel@tonic-gate 
10170Sstevel@tonic-gate int
Perl_magic_clearenv(pTHX_ SV * sv,MAGIC * mg)10180Sstevel@tonic-gate Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
10190Sstevel@tonic-gate {
10200Sstevel@tonic-gate     STRLEN n_a;
10210Sstevel@tonic-gate     my_setenv(MgPV(mg,n_a),Nullch);
10220Sstevel@tonic-gate     return 0;
10230Sstevel@tonic-gate }
10240Sstevel@tonic-gate 
10250Sstevel@tonic-gate int
Perl_magic_set_all_env(pTHX_ SV * sv,MAGIC * mg)10260Sstevel@tonic-gate Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg)
10270Sstevel@tonic-gate {
10280Sstevel@tonic-gate #if defined(VMS)
10290Sstevel@tonic-gate     Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
10300Sstevel@tonic-gate #else
10310Sstevel@tonic-gate     if (PL_localizing) {
10320Sstevel@tonic-gate 	HE* entry;
10330Sstevel@tonic-gate 	STRLEN n_a;
10340Sstevel@tonic-gate 	magic_clear_all_env(sv,mg);
10350Sstevel@tonic-gate 	hv_iterinit((HV*)sv);
10360Sstevel@tonic-gate 	while ((entry = hv_iternext((HV*)sv))) {
10370Sstevel@tonic-gate 	    I32 keylen;
10380Sstevel@tonic-gate 	    my_setenv(hv_iterkey(entry, &keylen),
10390Sstevel@tonic-gate 		      SvPV(hv_iterval((HV*)sv, entry), n_a));
10400Sstevel@tonic-gate 	}
10410Sstevel@tonic-gate     }
10420Sstevel@tonic-gate #endif
10430Sstevel@tonic-gate     return 0;
10440Sstevel@tonic-gate }
10450Sstevel@tonic-gate 
10460Sstevel@tonic-gate int
Perl_magic_clear_all_env(pTHX_ SV * sv,MAGIC * mg)10470Sstevel@tonic-gate Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg)
10480Sstevel@tonic-gate {
10490Sstevel@tonic-gate #ifndef PERL_MICRO
10500Sstevel@tonic-gate #if defined(VMS) || defined(EPOC)
10510Sstevel@tonic-gate     Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
10520Sstevel@tonic-gate #else
10530Sstevel@tonic-gate #  if defined(PERL_IMPLICIT_SYS) || defined(WIN32)
10540Sstevel@tonic-gate     PerlEnv_clearenv();
10550Sstevel@tonic-gate #  else
10560Sstevel@tonic-gate #    ifdef USE_ENVIRON_ARRAY
10570Sstevel@tonic-gate #      if defined(USE_ITHREADS)
10580Sstevel@tonic-gate     /* only the parent thread can clobber the process environment */
10590Sstevel@tonic-gate     if (PL_curinterp == aTHX)
10600Sstevel@tonic-gate #      endif
10610Sstevel@tonic-gate     {
10620Sstevel@tonic-gate #      ifndef PERL_USE_SAFE_PUTENV
10630Sstevel@tonic-gate     I32 i;
10640Sstevel@tonic-gate 
10650Sstevel@tonic-gate     if (environ == PL_origenviron)
10660Sstevel@tonic-gate 	environ = (char**)safesysmalloc(sizeof(char*));
10670Sstevel@tonic-gate     else
10680Sstevel@tonic-gate 	for (i = 0; environ[i]; i++)
10690Sstevel@tonic-gate 	    safesysfree(environ[i]);
10700Sstevel@tonic-gate #      endif /* PERL_USE_SAFE_PUTENV */
10710Sstevel@tonic-gate 
10720Sstevel@tonic-gate     environ[0] = Nullch;
10730Sstevel@tonic-gate     }
10740Sstevel@tonic-gate #    endif /* USE_ENVIRON_ARRAY */
10750Sstevel@tonic-gate #   endif /* PERL_IMPLICIT_SYS || WIN32 */
10760Sstevel@tonic-gate #endif /* VMS || EPOC */
10770Sstevel@tonic-gate #endif /* !PERL_MICRO */
10780Sstevel@tonic-gate     return 0;
10790Sstevel@tonic-gate }
10800Sstevel@tonic-gate 
10810Sstevel@tonic-gate #if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS)||defined(FAKE_DEFAULT_SIGNAL_HANDLERS)
10820Sstevel@tonic-gate static int sig_handlers_initted = 0;
10830Sstevel@tonic-gate #endif
10840Sstevel@tonic-gate #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
10850Sstevel@tonic-gate static int sig_ignoring[SIG_SIZE];      /* which signals we are ignoring */
10860Sstevel@tonic-gate #endif
10870Sstevel@tonic-gate #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
10880Sstevel@tonic-gate static int sig_defaulting[SIG_SIZE];
10890Sstevel@tonic-gate #endif
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate #ifndef PERL_MICRO
10920Sstevel@tonic-gate #ifdef HAS_SIGPROCMASK
10930Sstevel@tonic-gate static void
restore_sigmask(pTHX_ SV * save_sv)10940Sstevel@tonic-gate restore_sigmask(pTHX_ SV *save_sv)
10950Sstevel@tonic-gate {
10960Sstevel@tonic-gate     sigset_t *ossetp = (sigset_t *) SvPV_nolen( save_sv );
10970Sstevel@tonic-gate     (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
10980Sstevel@tonic-gate }
10990Sstevel@tonic-gate #endif
11000Sstevel@tonic-gate int
Perl_magic_getsig(pTHX_ SV * sv,MAGIC * mg)11010Sstevel@tonic-gate Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
11020Sstevel@tonic-gate {
11030Sstevel@tonic-gate     I32 i;
11040Sstevel@tonic-gate     STRLEN n_a;
11050Sstevel@tonic-gate     /* Are we fetching a signal entry? */
11060Sstevel@tonic-gate     i = whichsig(MgPV(mg,n_a));
11070Sstevel@tonic-gate     if (i > 0) {
11080Sstevel@tonic-gate     	if(PL_psig_ptr[i])
11090Sstevel@tonic-gate     	    sv_setsv(sv,PL_psig_ptr[i]);
11100Sstevel@tonic-gate     	else {
11110Sstevel@tonic-gate     	    Sighandler_t sigstate;
11120Sstevel@tonic-gate     	    sigstate = rsignal_state(i);
11130Sstevel@tonic-gate #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
11140Sstevel@tonic-gate     	    if (sig_handlers_initted && sig_ignoring[i]) sigstate = SIG_IGN;
11150Sstevel@tonic-gate #endif
11160Sstevel@tonic-gate #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
11170Sstevel@tonic-gate     	    if (sig_handlers_initted && sig_defaulting[i]) sigstate = SIG_DFL;
11180Sstevel@tonic-gate #endif
11190Sstevel@tonic-gate     	    /* cache state so we don't fetch it again */
11200Sstevel@tonic-gate     	    if(sigstate == SIG_IGN)
11210Sstevel@tonic-gate     	    	sv_setpv(sv,"IGNORE");
11220Sstevel@tonic-gate     	    else
11230Sstevel@tonic-gate     	    	sv_setsv(sv,&PL_sv_undef);
11240Sstevel@tonic-gate     	    PL_psig_ptr[i] = SvREFCNT_inc(sv);
11250Sstevel@tonic-gate     	    SvTEMP_off(sv);
11260Sstevel@tonic-gate     	}
11270Sstevel@tonic-gate     }
11280Sstevel@tonic-gate     return 0;
11290Sstevel@tonic-gate }
11300Sstevel@tonic-gate int
Perl_magic_clearsig(pTHX_ SV * sv,MAGIC * mg)11310Sstevel@tonic-gate Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
11320Sstevel@tonic-gate {
11330Sstevel@tonic-gate     /* XXX Some of this code was copied from Perl_magic_setsig. A little
11340Sstevel@tonic-gate      * refactoring might be in order.
11350Sstevel@tonic-gate      */
11360Sstevel@tonic-gate     register char *s;
11370Sstevel@tonic-gate     STRLEN n_a;
11380Sstevel@tonic-gate     SV* to_dec;
11390Sstevel@tonic-gate     s = MgPV(mg,n_a);
11400Sstevel@tonic-gate     if (*s == '_') {
11410Sstevel@tonic-gate 	SV** svp;
11420Sstevel@tonic-gate 	if (strEQ(s,"__DIE__"))
11430Sstevel@tonic-gate 	    svp = &PL_diehook;
11440Sstevel@tonic-gate 	else if (strEQ(s,"__WARN__"))
11450Sstevel@tonic-gate 	    svp = &PL_warnhook;
11460Sstevel@tonic-gate 	else
11470Sstevel@tonic-gate 	    Perl_croak(aTHX_ "No such hook: %s", s);
11480Sstevel@tonic-gate 	if (*svp) {
11490Sstevel@tonic-gate 	    to_dec = *svp;
11500Sstevel@tonic-gate 	    *svp = 0;
11510Sstevel@tonic-gate     	    SvREFCNT_dec(to_dec);
11520Sstevel@tonic-gate 	}
11530Sstevel@tonic-gate     }
11540Sstevel@tonic-gate     else {
11550Sstevel@tonic-gate 	I32 i;
11560Sstevel@tonic-gate 	/* Are we clearing a signal entry? */
11570Sstevel@tonic-gate 	i = whichsig(s);
11580Sstevel@tonic-gate 	if (i > 0) {
11590Sstevel@tonic-gate #ifdef HAS_SIGPROCMASK
11600Sstevel@tonic-gate 	    sigset_t set, save;
11610Sstevel@tonic-gate 	    SV* save_sv;
11620Sstevel@tonic-gate 	    /* Avoid having the signal arrive at a bad time, if possible. */
11630Sstevel@tonic-gate 	    sigemptyset(&set);
11640Sstevel@tonic-gate 	    sigaddset(&set,i);
11650Sstevel@tonic-gate 	    sigprocmask(SIG_BLOCK, &set, &save);
11660Sstevel@tonic-gate 	    ENTER;
11670Sstevel@tonic-gate 	    save_sv = newSVpv((char *)(&save), sizeof(sigset_t));
11680Sstevel@tonic-gate 	    SAVEFREESV(save_sv);
11690Sstevel@tonic-gate 	    SAVEDESTRUCTOR_X(restore_sigmask, save_sv);
11700Sstevel@tonic-gate #endif
11710Sstevel@tonic-gate 	    PERL_ASYNC_CHECK();
11720Sstevel@tonic-gate #if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS)
11730Sstevel@tonic-gate 	    if (!sig_handlers_initted) Perl_csighandler_init();
11740Sstevel@tonic-gate #endif
11750Sstevel@tonic-gate #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
11760Sstevel@tonic-gate 	    sig_defaulting[i] = 1;
11770Sstevel@tonic-gate 	    (void)rsignal(i, PL_csighandlerp);
11780Sstevel@tonic-gate #else
11790Sstevel@tonic-gate 	    (void)rsignal(i, SIG_DFL);
11800Sstevel@tonic-gate #endif
11810Sstevel@tonic-gate     	    if(PL_psig_name[i]) {
11820Sstevel@tonic-gate     		SvREFCNT_dec(PL_psig_name[i]);
11830Sstevel@tonic-gate     		PL_psig_name[i]=0;
11840Sstevel@tonic-gate     	    }
11850Sstevel@tonic-gate     	    if(PL_psig_ptr[i]) {
11860Sstevel@tonic-gate 		to_dec=PL_psig_ptr[i];
11870Sstevel@tonic-gate     		PL_psig_ptr[i]=0;
11880Sstevel@tonic-gate 		LEAVE;
11890Sstevel@tonic-gate     		SvREFCNT_dec(to_dec);
11900Sstevel@tonic-gate     	    }
11910Sstevel@tonic-gate 	    else
11920Sstevel@tonic-gate 		LEAVE;
11930Sstevel@tonic-gate 	}
11940Sstevel@tonic-gate     }
11950Sstevel@tonic-gate     return 0;
11960Sstevel@tonic-gate }
11970Sstevel@tonic-gate 
11980Sstevel@tonic-gate void
Perl_raise_signal(pTHX_ int sig)11990Sstevel@tonic-gate Perl_raise_signal(pTHX_ int sig)
12000Sstevel@tonic-gate {
12010Sstevel@tonic-gate     /* Set a flag to say this signal is pending */
12020Sstevel@tonic-gate     PL_psig_pend[sig]++;
12030Sstevel@tonic-gate     /* And one to say _a_ signal is pending */
12040Sstevel@tonic-gate     PL_sig_pending = 1;
12050Sstevel@tonic-gate }
12060Sstevel@tonic-gate 
12070Sstevel@tonic-gate Signal_t
Perl_csighandler(int sig)12080Sstevel@tonic-gate Perl_csighandler(int sig)
12090Sstevel@tonic-gate {
12100Sstevel@tonic-gate #ifdef PERL_GET_SIG_CONTEXT
12110Sstevel@tonic-gate     dTHXa(PERL_GET_SIG_CONTEXT);
12120Sstevel@tonic-gate #else
12130Sstevel@tonic-gate     dTHX;
12140Sstevel@tonic-gate #endif
12150Sstevel@tonic-gate #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
12160Sstevel@tonic-gate     (void) rsignal(sig, PL_csighandlerp);
12170Sstevel@tonic-gate     if (sig_ignoring[sig]) return;
12180Sstevel@tonic-gate #endif
12190Sstevel@tonic-gate #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
12200Sstevel@tonic-gate     if (sig_defaulting[sig])
12210Sstevel@tonic-gate #ifdef KILL_BY_SIGPRC
12220Sstevel@tonic-gate             exit((Perl_sig_to_vmscondition(sig)&STS$M_COND_ID)|STS$K_SEVERE|STS$M_INHIB_MSG);
12230Sstevel@tonic-gate #else
12240Sstevel@tonic-gate             exit(1);
12250Sstevel@tonic-gate #endif
12260Sstevel@tonic-gate #endif
12270Sstevel@tonic-gate    if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
12280Sstevel@tonic-gate 	/* Call the perl level handler now--
12290Sstevel@tonic-gate 	 * with risk we may be in malloc() etc. */
12300Sstevel@tonic-gate 	(*PL_sighandlerp)(sig);
12310Sstevel@tonic-gate    else
12320Sstevel@tonic-gate 	Perl_raise_signal(aTHX_ sig);
12330Sstevel@tonic-gate }
12340Sstevel@tonic-gate 
12350Sstevel@tonic-gate #if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS)
12360Sstevel@tonic-gate void
Perl_csighandler_init(void)12370Sstevel@tonic-gate Perl_csighandler_init(void)
12380Sstevel@tonic-gate {
12390Sstevel@tonic-gate     int sig;
12400Sstevel@tonic-gate     if (sig_handlers_initted) return;
12410Sstevel@tonic-gate 
12420Sstevel@tonic-gate     for (sig = 1; sig < SIG_SIZE; sig++) {
12430Sstevel@tonic-gate #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
12440Sstevel@tonic-gate         dTHX;
12450Sstevel@tonic-gate         sig_defaulting[sig] = 1;
12460Sstevel@tonic-gate         (void) rsignal(sig, PL_csighandlerp);
12470Sstevel@tonic-gate #endif
12480Sstevel@tonic-gate #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
12490Sstevel@tonic-gate         sig_ignoring[sig] = 0;
12500Sstevel@tonic-gate #endif
12510Sstevel@tonic-gate     }
12520Sstevel@tonic-gate     sig_handlers_initted = 1;
12530Sstevel@tonic-gate }
12540Sstevel@tonic-gate #endif
12550Sstevel@tonic-gate 
12560Sstevel@tonic-gate void
Perl_despatch_signals(pTHX)12570Sstevel@tonic-gate Perl_despatch_signals(pTHX)
12580Sstevel@tonic-gate {
12590Sstevel@tonic-gate     int sig;
12600Sstevel@tonic-gate     PL_sig_pending = 0;
12610Sstevel@tonic-gate     for (sig = 1; sig < SIG_SIZE; sig++) {
12620Sstevel@tonic-gate 	if (PL_psig_pend[sig]) {
12630Sstevel@tonic-gate 	    PERL_BLOCKSIG_ADD(set, sig);
12640Sstevel@tonic-gate  	    PL_psig_pend[sig] = 0;
12650Sstevel@tonic-gate 	    PERL_BLOCKSIG_BLOCK(set);
12660Sstevel@tonic-gate 	    (*PL_sighandlerp)(sig);
12670Sstevel@tonic-gate 	    PERL_BLOCKSIG_UNBLOCK(set);
12680Sstevel@tonic-gate 	}
12690Sstevel@tonic-gate     }
12700Sstevel@tonic-gate }
12710Sstevel@tonic-gate 
12720Sstevel@tonic-gate int
Perl_magic_setsig(pTHX_ SV * sv,MAGIC * mg)12730Sstevel@tonic-gate Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
12740Sstevel@tonic-gate {
12750Sstevel@tonic-gate     register char *s;
12760Sstevel@tonic-gate     I32 i;
12770Sstevel@tonic-gate     SV** svp = 0;
12780Sstevel@tonic-gate     /* Need to be careful with SvREFCNT_dec(), because that can have side
12790Sstevel@tonic-gate      * effects (due to closures). We must make sure that the new disposition
12800Sstevel@tonic-gate      * is in place before it is called.
12810Sstevel@tonic-gate      */
12820Sstevel@tonic-gate     SV* to_dec = 0;
12830Sstevel@tonic-gate     STRLEN len;
12840Sstevel@tonic-gate #ifdef HAS_SIGPROCMASK
12850Sstevel@tonic-gate     sigset_t set, save;
12860Sstevel@tonic-gate     SV* save_sv;
12870Sstevel@tonic-gate #endif
12880Sstevel@tonic-gate 
12890Sstevel@tonic-gate     s = MgPV(mg,len);
12900Sstevel@tonic-gate     if (*s == '_') {
12910Sstevel@tonic-gate 	if (strEQ(s,"__DIE__"))
12920Sstevel@tonic-gate 	    svp = &PL_diehook;
12930Sstevel@tonic-gate 	else if (strEQ(s,"__WARN__"))
12940Sstevel@tonic-gate 	    svp = &PL_warnhook;
12950Sstevel@tonic-gate 	else
12960Sstevel@tonic-gate 	    Perl_croak(aTHX_ "No such hook: %s", s);
12970Sstevel@tonic-gate 	i = 0;
12980Sstevel@tonic-gate 	if (*svp) {
12990Sstevel@tonic-gate 	    to_dec = *svp;
13000Sstevel@tonic-gate 	    *svp = 0;
13010Sstevel@tonic-gate 	}
13020Sstevel@tonic-gate     }
13030Sstevel@tonic-gate     else {
13040Sstevel@tonic-gate 	i = whichsig(s);	/* ...no, a brick */
13050Sstevel@tonic-gate 	if (i < 0) {
13060Sstevel@tonic-gate 	    if (ckWARN(WARN_SIGNAL))
13070Sstevel@tonic-gate 		Perl_warner(aTHX_ packWARN(WARN_SIGNAL), "No such signal: SIG%s", s);
13080Sstevel@tonic-gate 	    return 0;
13090Sstevel@tonic-gate 	}
13100Sstevel@tonic-gate #ifdef HAS_SIGPROCMASK
13110Sstevel@tonic-gate 	/* Avoid having the signal arrive at a bad time, if possible. */
13120Sstevel@tonic-gate 	sigemptyset(&set);
13130Sstevel@tonic-gate 	sigaddset(&set,i);
13140Sstevel@tonic-gate 	sigprocmask(SIG_BLOCK, &set, &save);
13150Sstevel@tonic-gate 	ENTER;
13160Sstevel@tonic-gate 	save_sv = newSVpv((char *)(&save), sizeof(sigset_t));
13170Sstevel@tonic-gate 	SAVEFREESV(save_sv);
13180Sstevel@tonic-gate 	SAVEDESTRUCTOR_X(restore_sigmask, save_sv);
13190Sstevel@tonic-gate #endif
13200Sstevel@tonic-gate 	PERL_ASYNC_CHECK();
13210Sstevel@tonic-gate #if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS)
13220Sstevel@tonic-gate 	if (!sig_handlers_initted) Perl_csighandler_init();
13230Sstevel@tonic-gate #endif
13240Sstevel@tonic-gate #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
13250Sstevel@tonic-gate 	sig_ignoring[i] = 0;
13260Sstevel@tonic-gate #endif
13270Sstevel@tonic-gate #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
13280Sstevel@tonic-gate 	sig_defaulting[i] = 0;
13290Sstevel@tonic-gate #endif
13300Sstevel@tonic-gate 	SvREFCNT_dec(PL_psig_name[i]);
13310Sstevel@tonic-gate 	to_dec = PL_psig_ptr[i];
13320Sstevel@tonic-gate 	PL_psig_ptr[i] = SvREFCNT_inc(sv);
13330Sstevel@tonic-gate 	SvTEMP_off(sv); /* Make sure it doesn't go away on us */
13340Sstevel@tonic-gate 	PL_psig_name[i] = newSVpvn(s, len);
13350Sstevel@tonic-gate 	SvREADONLY_on(PL_psig_name[i]);
13360Sstevel@tonic-gate     }
13370Sstevel@tonic-gate     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
13380Sstevel@tonic-gate 	if (i) {
13390Sstevel@tonic-gate 	    (void)rsignal(i, PL_csighandlerp);
13400Sstevel@tonic-gate #ifdef HAS_SIGPROCMASK
13410Sstevel@tonic-gate 	    LEAVE;
13420Sstevel@tonic-gate #endif
13430Sstevel@tonic-gate 	}
13440Sstevel@tonic-gate 	else
13450Sstevel@tonic-gate 	    *svp = SvREFCNT_inc(sv);
13460Sstevel@tonic-gate 	if(to_dec)
13470Sstevel@tonic-gate 	    SvREFCNT_dec(to_dec);
13480Sstevel@tonic-gate 	return 0;
13490Sstevel@tonic-gate     }
13500Sstevel@tonic-gate     s = SvPV_force(sv,len);
13510Sstevel@tonic-gate     if (strEQ(s,"IGNORE")) {
13520Sstevel@tonic-gate 	if (i) {
13530Sstevel@tonic-gate #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
13540Sstevel@tonic-gate 	    sig_ignoring[i] = 1;
13550Sstevel@tonic-gate 	    (void)rsignal(i, PL_csighandlerp);
13560Sstevel@tonic-gate #else
13570Sstevel@tonic-gate 	    (void)rsignal(i, SIG_IGN);
13580Sstevel@tonic-gate #endif
13590Sstevel@tonic-gate 	}
13600Sstevel@tonic-gate     }
13610Sstevel@tonic-gate     else if (strEQ(s,"DEFAULT") || !*s) {
13620Sstevel@tonic-gate 	if (i)
13630Sstevel@tonic-gate #ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
13640Sstevel@tonic-gate 	  {
13650Sstevel@tonic-gate 	    sig_defaulting[i] = 1;
13660Sstevel@tonic-gate 	    (void)rsignal(i, PL_csighandlerp);
13670Sstevel@tonic-gate 	  }
13680Sstevel@tonic-gate #else
13690Sstevel@tonic-gate 	    (void)rsignal(i, SIG_DFL);
13700Sstevel@tonic-gate #endif
13710Sstevel@tonic-gate     }
13720Sstevel@tonic-gate     else {
13730Sstevel@tonic-gate 	/*
13740Sstevel@tonic-gate 	 * We should warn if HINT_STRICT_REFS, but without
13750Sstevel@tonic-gate 	 * access to a known hint bit in a known OP, we can't
13760Sstevel@tonic-gate 	 * tell whether HINT_STRICT_REFS is in force or not.
13770Sstevel@tonic-gate 	 */
13780Sstevel@tonic-gate 	if (!strchr(s,':') && !strchr(s,'\''))
13790Sstevel@tonic-gate 	    sv_insert(sv, 0, 0, "main::", 6);
13800Sstevel@tonic-gate 	if (i)
13810Sstevel@tonic-gate 	    (void)rsignal(i, PL_csighandlerp);
13820Sstevel@tonic-gate 	else
13830Sstevel@tonic-gate 	    *svp = SvREFCNT_inc(sv);
13840Sstevel@tonic-gate     }
13850Sstevel@tonic-gate #ifdef HAS_SIGPROCMASK
13860Sstevel@tonic-gate     if(i)
13870Sstevel@tonic-gate 	LEAVE;
13880Sstevel@tonic-gate #endif
13890Sstevel@tonic-gate     if(to_dec)
13900Sstevel@tonic-gate 	SvREFCNT_dec(to_dec);
13910Sstevel@tonic-gate     return 0;
13920Sstevel@tonic-gate }
13930Sstevel@tonic-gate #endif /* !PERL_MICRO */
13940Sstevel@tonic-gate 
13950Sstevel@tonic-gate int
Perl_magic_setisa(pTHX_ SV * sv,MAGIC * mg)13960Sstevel@tonic-gate Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
13970Sstevel@tonic-gate {
13980Sstevel@tonic-gate     PL_sub_generation++;
13990Sstevel@tonic-gate     return 0;
14000Sstevel@tonic-gate }
14010Sstevel@tonic-gate 
14020Sstevel@tonic-gate int
Perl_magic_setamagic(pTHX_ SV * sv,MAGIC * mg)14030Sstevel@tonic-gate Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
14040Sstevel@tonic-gate {
14050Sstevel@tonic-gate     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
14060Sstevel@tonic-gate     PL_amagic_generation++;
14070Sstevel@tonic-gate 
14080Sstevel@tonic-gate     return 0;
14090Sstevel@tonic-gate }
14100Sstevel@tonic-gate 
14110Sstevel@tonic-gate int
Perl_magic_getnkeys(pTHX_ SV * sv,MAGIC * mg)14120Sstevel@tonic-gate Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg)
14130Sstevel@tonic-gate {
14140Sstevel@tonic-gate     HV *hv = (HV*)LvTARG(sv);
14150Sstevel@tonic-gate     I32 i = 0;
14160Sstevel@tonic-gate 
14170Sstevel@tonic-gate     if (hv) {
14180Sstevel@tonic-gate          (void) hv_iterinit(hv);
14190Sstevel@tonic-gate          if (! SvTIED_mg((SV*)hv, PERL_MAGIC_tied))
14200Sstevel@tonic-gate 	     i = HvKEYS(hv);
14210Sstevel@tonic-gate          else {
14220Sstevel@tonic-gate 	     while (hv_iternext(hv))
14230Sstevel@tonic-gate 	         i++;
14240Sstevel@tonic-gate          }
14250Sstevel@tonic-gate     }
14260Sstevel@tonic-gate 
14270Sstevel@tonic-gate     sv_setiv(sv, (IV)i);
14280Sstevel@tonic-gate     return 0;
14290Sstevel@tonic-gate }
14300Sstevel@tonic-gate 
14310Sstevel@tonic-gate int
Perl_magic_setnkeys(pTHX_ SV * sv,MAGIC * mg)14320Sstevel@tonic-gate Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
14330Sstevel@tonic-gate {
14340Sstevel@tonic-gate     if (LvTARG(sv)) {
14350Sstevel@tonic-gate 	hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
14360Sstevel@tonic-gate     }
14370Sstevel@tonic-gate     return 0;
14380Sstevel@tonic-gate }
14390Sstevel@tonic-gate 
14400Sstevel@tonic-gate /* caller is responsible for stack switching/cleanup */
14410Sstevel@tonic-gate STATIC int
S_magic_methcall(pTHX_ SV * sv,MAGIC * mg,char * meth,I32 flags,int n,SV * val)14420Sstevel@tonic-gate S_magic_methcall(pTHX_ SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
14430Sstevel@tonic-gate {
14440Sstevel@tonic-gate     dSP;
14450Sstevel@tonic-gate 
14460Sstevel@tonic-gate     PUSHMARK(SP);
14470Sstevel@tonic-gate     EXTEND(SP, n);
14480Sstevel@tonic-gate     PUSHs(SvTIED_obj(sv, mg));
14490Sstevel@tonic-gate     if (n > 1) {
14500Sstevel@tonic-gate 	if (mg->mg_ptr) {
14510Sstevel@tonic-gate 	    if (mg->mg_len >= 0)
14520Sstevel@tonic-gate 		PUSHs(sv_2mortal(newSVpvn(mg->mg_ptr, mg->mg_len)));
14530Sstevel@tonic-gate 	    else if (mg->mg_len == HEf_SVKEY)
14540Sstevel@tonic-gate 		PUSHs((SV*)mg->mg_ptr);
14550Sstevel@tonic-gate 	}
14560Sstevel@tonic-gate 	else if (mg->mg_type == PERL_MAGIC_tiedelem) {
14570Sstevel@tonic-gate 	    PUSHs(sv_2mortal(newSViv(mg->mg_len)));
14580Sstevel@tonic-gate 	}
14590Sstevel@tonic-gate     }
14600Sstevel@tonic-gate     if (n > 2) {
14610Sstevel@tonic-gate 	PUSHs(val);
14620Sstevel@tonic-gate     }
14630Sstevel@tonic-gate     PUTBACK;
14640Sstevel@tonic-gate 
14650Sstevel@tonic-gate     return call_method(meth, flags);
14660Sstevel@tonic-gate }
14670Sstevel@tonic-gate 
14680Sstevel@tonic-gate STATIC int
S_magic_methpack(pTHX_ SV * sv,MAGIC * mg,char * meth)14690Sstevel@tonic-gate S_magic_methpack(pTHX_ SV *sv, MAGIC *mg, char *meth)
14700Sstevel@tonic-gate {
14710Sstevel@tonic-gate     dSP;
14720Sstevel@tonic-gate 
14730Sstevel@tonic-gate     ENTER;
14740Sstevel@tonic-gate     SAVETMPS;
14750Sstevel@tonic-gate     PUSHSTACKi(PERLSI_MAGIC);
14760Sstevel@tonic-gate 
14770Sstevel@tonic-gate     if (magic_methcall(sv, mg, meth, G_SCALAR, 2, NULL)) {
14780Sstevel@tonic-gate 	sv_setsv(sv, *PL_stack_sp--);
14790Sstevel@tonic-gate     }
14800Sstevel@tonic-gate 
14810Sstevel@tonic-gate     POPSTACK;
14820Sstevel@tonic-gate     FREETMPS;
14830Sstevel@tonic-gate     LEAVE;
14840Sstevel@tonic-gate     return 0;
14850Sstevel@tonic-gate }
14860Sstevel@tonic-gate 
14870Sstevel@tonic-gate int
Perl_magic_getpack(pTHX_ SV * sv,MAGIC * mg)14880Sstevel@tonic-gate Perl_magic_getpack(pTHX_ SV *sv, MAGIC *mg)
14890Sstevel@tonic-gate {
14900Sstevel@tonic-gate     if (mg->mg_ptr)
14910Sstevel@tonic-gate 	mg->mg_flags |= MGf_GSKIP;
14920Sstevel@tonic-gate     magic_methpack(sv,mg,"FETCH");
14930Sstevel@tonic-gate     return 0;
14940Sstevel@tonic-gate }
14950Sstevel@tonic-gate 
14960Sstevel@tonic-gate int
Perl_magic_setpack(pTHX_ SV * sv,MAGIC * mg)14970Sstevel@tonic-gate Perl_magic_setpack(pTHX_ SV *sv, MAGIC *mg)
14980Sstevel@tonic-gate {
14990Sstevel@tonic-gate     dSP;
15000Sstevel@tonic-gate     ENTER;
15010Sstevel@tonic-gate     PUSHSTACKi(PERLSI_MAGIC);
15020Sstevel@tonic-gate     magic_methcall(sv, mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
15030Sstevel@tonic-gate     POPSTACK;
15040Sstevel@tonic-gate     LEAVE;
15050Sstevel@tonic-gate     return 0;
15060Sstevel@tonic-gate }
15070Sstevel@tonic-gate 
15080Sstevel@tonic-gate int
Perl_magic_clearpack(pTHX_ SV * sv,MAGIC * mg)15090Sstevel@tonic-gate Perl_magic_clearpack(pTHX_ SV *sv, MAGIC *mg)
15100Sstevel@tonic-gate {
15110Sstevel@tonic-gate     return magic_methpack(sv,mg,"DELETE");
15120Sstevel@tonic-gate }
15130Sstevel@tonic-gate 
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate U32
Perl_magic_sizepack(pTHX_ SV * sv,MAGIC * mg)15160Sstevel@tonic-gate Perl_magic_sizepack(pTHX_ SV *sv, MAGIC *mg)
15170Sstevel@tonic-gate {
15180Sstevel@tonic-gate     dSP;
15190Sstevel@tonic-gate     U32 retval = 0;
15200Sstevel@tonic-gate 
15210Sstevel@tonic-gate     ENTER;
15220Sstevel@tonic-gate     SAVETMPS;
15230Sstevel@tonic-gate     PUSHSTACKi(PERLSI_MAGIC);
15240Sstevel@tonic-gate     if (magic_methcall(sv, mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
15250Sstevel@tonic-gate 	sv = *PL_stack_sp--;
15260Sstevel@tonic-gate 	retval = (U32) SvIV(sv)-1;
15270Sstevel@tonic-gate     }
15280Sstevel@tonic-gate     POPSTACK;
15290Sstevel@tonic-gate     FREETMPS;
15300Sstevel@tonic-gate     LEAVE;
15310Sstevel@tonic-gate     return retval;
15320Sstevel@tonic-gate }
15330Sstevel@tonic-gate 
15340Sstevel@tonic-gate int
Perl_magic_wipepack(pTHX_ SV * sv,MAGIC * mg)15350Sstevel@tonic-gate Perl_magic_wipepack(pTHX_ SV *sv, MAGIC *mg)
15360Sstevel@tonic-gate {
15370Sstevel@tonic-gate     dSP;
15380Sstevel@tonic-gate 
15390Sstevel@tonic-gate     ENTER;
15400Sstevel@tonic-gate     PUSHSTACKi(PERLSI_MAGIC);
15410Sstevel@tonic-gate     PUSHMARK(SP);
15420Sstevel@tonic-gate     XPUSHs(SvTIED_obj(sv, mg));
15430Sstevel@tonic-gate     PUTBACK;
15440Sstevel@tonic-gate     call_method("CLEAR", G_SCALAR|G_DISCARD);
15450Sstevel@tonic-gate     POPSTACK;
15460Sstevel@tonic-gate     LEAVE;
15470Sstevel@tonic-gate 
15480Sstevel@tonic-gate     return 0;
15490Sstevel@tonic-gate }
15500Sstevel@tonic-gate 
15510Sstevel@tonic-gate int
Perl_magic_nextpack(pTHX_ SV * sv,MAGIC * mg,SV * key)15520Sstevel@tonic-gate Perl_magic_nextpack(pTHX_ SV *sv, MAGIC *mg, SV *key)
15530Sstevel@tonic-gate {
15540Sstevel@tonic-gate     dSP;
15550Sstevel@tonic-gate     const char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
15560Sstevel@tonic-gate 
15570Sstevel@tonic-gate     ENTER;
15580Sstevel@tonic-gate     SAVETMPS;
15590Sstevel@tonic-gate     PUSHSTACKi(PERLSI_MAGIC);
15600Sstevel@tonic-gate     PUSHMARK(SP);
15610Sstevel@tonic-gate     EXTEND(SP, 2);
15620Sstevel@tonic-gate     PUSHs(SvTIED_obj(sv, mg));
15630Sstevel@tonic-gate     if (SvOK(key))
15640Sstevel@tonic-gate 	PUSHs(key);
15650Sstevel@tonic-gate     PUTBACK;
15660Sstevel@tonic-gate 
15670Sstevel@tonic-gate     if (call_method(meth, G_SCALAR))
15680Sstevel@tonic-gate 	sv_setsv(key, *PL_stack_sp--);
15690Sstevel@tonic-gate 
15700Sstevel@tonic-gate     POPSTACK;
15710Sstevel@tonic-gate     FREETMPS;
15720Sstevel@tonic-gate     LEAVE;
15730Sstevel@tonic-gate     return 0;
15740Sstevel@tonic-gate }
15750Sstevel@tonic-gate 
15760Sstevel@tonic-gate int
Perl_magic_existspack(pTHX_ SV * sv,MAGIC * mg)15770Sstevel@tonic-gate Perl_magic_existspack(pTHX_ SV *sv, MAGIC *mg)
15780Sstevel@tonic-gate {
15790Sstevel@tonic-gate     return magic_methpack(sv,mg,"EXISTS");
15800Sstevel@tonic-gate }
15810Sstevel@tonic-gate 
15820Sstevel@tonic-gate SV *
Perl_magic_scalarpack(pTHX_ HV * hv,MAGIC * mg)15830Sstevel@tonic-gate Perl_magic_scalarpack(pTHX_ HV *hv, MAGIC *mg)
15840Sstevel@tonic-gate {
15850Sstevel@tonic-gate     dSP;
15860Sstevel@tonic-gate     SV *retval = &PL_sv_undef;
15870Sstevel@tonic-gate     SV *tied = SvTIED_obj((SV*)hv, mg);
15880Sstevel@tonic-gate     HV *pkg = SvSTASH((SV*)SvRV(tied));
15890Sstevel@tonic-gate 
15900Sstevel@tonic-gate     if (!gv_fetchmethod_autoload(pkg, "SCALAR", FALSE)) {
15910Sstevel@tonic-gate         SV *key;
15920Sstevel@tonic-gate         if (HvEITER(hv))
15930Sstevel@tonic-gate             /* we are in an iteration so the hash cannot be empty */
15940Sstevel@tonic-gate             return &PL_sv_yes;
15950Sstevel@tonic-gate         /* no xhv_eiter so now use FIRSTKEY */
15960Sstevel@tonic-gate         key = sv_newmortal();
15970Sstevel@tonic-gate         magic_nextpack((SV*)hv, mg, key);
15980Sstevel@tonic-gate         HvEITER(hv) = NULL;     /* need to reset iterator */
15990Sstevel@tonic-gate         return SvOK(key) ? &PL_sv_yes : &PL_sv_no;
16000Sstevel@tonic-gate     }
16010Sstevel@tonic-gate 
16020Sstevel@tonic-gate     /* there is a SCALAR method that we can call */
16030Sstevel@tonic-gate     ENTER;
16040Sstevel@tonic-gate     PUSHSTACKi(PERLSI_MAGIC);
16050Sstevel@tonic-gate     PUSHMARK(SP);
16060Sstevel@tonic-gate     EXTEND(SP, 1);
16070Sstevel@tonic-gate     PUSHs(tied);
16080Sstevel@tonic-gate     PUTBACK;
16090Sstevel@tonic-gate 
16100Sstevel@tonic-gate     if (call_method("SCALAR", G_SCALAR))
16110Sstevel@tonic-gate         retval = *PL_stack_sp--;
16120Sstevel@tonic-gate     POPSTACK;
16130Sstevel@tonic-gate     LEAVE;
16140Sstevel@tonic-gate     return retval;
16150Sstevel@tonic-gate }
16160Sstevel@tonic-gate 
16170Sstevel@tonic-gate int
Perl_magic_setdbline(pTHX_ SV * sv,MAGIC * mg)16180Sstevel@tonic-gate Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
16190Sstevel@tonic-gate {
16200Sstevel@tonic-gate     OP *o;
16210Sstevel@tonic-gate     I32 i;
16220Sstevel@tonic-gate     GV* gv;
16230Sstevel@tonic-gate     SV** svp;
16240Sstevel@tonic-gate     STRLEN n_a;
16250Sstevel@tonic-gate 
16260Sstevel@tonic-gate     gv = PL_DBline;
16270Sstevel@tonic-gate     i = SvTRUE(sv);
16280Sstevel@tonic-gate     svp = av_fetch(GvAV(gv),
16290Sstevel@tonic-gate 		     atoi(MgPV(mg,n_a)), FALSE);
16300Sstevel@tonic-gate     if (svp && SvIOKp(*svp) && (o = INT2PTR(OP*,SvIVX(*svp)))) {
16310Sstevel@tonic-gate 	/* set or clear breakpoint in the relevant control op */
16320Sstevel@tonic-gate 	if (i)
16330Sstevel@tonic-gate 	    o->op_flags |= OPf_SPECIAL;
16340Sstevel@tonic-gate 	else
16350Sstevel@tonic-gate 	    o->op_flags &= ~OPf_SPECIAL;
16360Sstevel@tonic-gate     }
16370Sstevel@tonic-gate     return 0;
16380Sstevel@tonic-gate }
16390Sstevel@tonic-gate 
16400Sstevel@tonic-gate int
Perl_magic_getarylen(pTHX_ SV * sv,MAGIC * mg)16410Sstevel@tonic-gate Perl_magic_getarylen(pTHX_ SV *sv, MAGIC *mg)
16420Sstevel@tonic-gate {
16430Sstevel@tonic-gate     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + PL_curcop->cop_arybase);
16440Sstevel@tonic-gate     return 0;
16450Sstevel@tonic-gate }
16460Sstevel@tonic-gate 
16470Sstevel@tonic-gate int
Perl_magic_setarylen(pTHX_ SV * sv,MAGIC * mg)16480Sstevel@tonic-gate Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
16490Sstevel@tonic-gate {
16500Sstevel@tonic-gate     av_fill((AV*)mg->mg_obj, SvIV(sv) - PL_curcop->cop_arybase);
16510Sstevel@tonic-gate     return 0;
16520Sstevel@tonic-gate }
16530Sstevel@tonic-gate 
16540Sstevel@tonic-gate int
Perl_magic_getpos(pTHX_ SV * sv,MAGIC * mg)16550Sstevel@tonic-gate Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
16560Sstevel@tonic-gate {
16570Sstevel@tonic-gate     SV* lsv = LvTARG(sv);
16580Sstevel@tonic-gate 
16590Sstevel@tonic-gate     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
16600Sstevel@tonic-gate 	mg = mg_find(lsv, PERL_MAGIC_regex_global);
16610Sstevel@tonic-gate 	if (mg && mg->mg_len >= 0) {
16620Sstevel@tonic-gate 	    I32 i = mg->mg_len;
16630Sstevel@tonic-gate 	    if (DO_UTF8(lsv))
16640Sstevel@tonic-gate 		sv_pos_b2u(lsv, &i);
16650Sstevel@tonic-gate 	    sv_setiv(sv, i + PL_curcop->cop_arybase);
16660Sstevel@tonic-gate 	    return 0;
16670Sstevel@tonic-gate 	}
16680Sstevel@tonic-gate     }
16690Sstevel@tonic-gate     (void)SvOK_off(sv);
16700Sstevel@tonic-gate     return 0;
16710Sstevel@tonic-gate }
16720Sstevel@tonic-gate 
16730Sstevel@tonic-gate int
Perl_magic_setpos(pTHX_ SV * sv,MAGIC * mg)16740Sstevel@tonic-gate Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
16750Sstevel@tonic-gate {
16760Sstevel@tonic-gate     SV* lsv = LvTARG(sv);
16770Sstevel@tonic-gate     SSize_t pos;
16780Sstevel@tonic-gate     STRLEN len;
16790Sstevel@tonic-gate     STRLEN ulen = 0;
16800Sstevel@tonic-gate 
16810Sstevel@tonic-gate     mg = 0;
16820Sstevel@tonic-gate 
16830Sstevel@tonic-gate     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
16840Sstevel@tonic-gate 	mg = mg_find(lsv, PERL_MAGIC_regex_global);
16850Sstevel@tonic-gate     if (!mg) {
16860Sstevel@tonic-gate 	if (!SvOK(sv))
16870Sstevel@tonic-gate 	    return 0;
16880Sstevel@tonic-gate 	sv_magic(lsv, (SV*)0, PERL_MAGIC_regex_global, Nullch, 0);
16890Sstevel@tonic-gate 	mg = mg_find(lsv, PERL_MAGIC_regex_global);
16900Sstevel@tonic-gate     }
16910Sstevel@tonic-gate     else if (!SvOK(sv)) {
16920Sstevel@tonic-gate 	mg->mg_len = -1;
16930Sstevel@tonic-gate 	return 0;
16940Sstevel@tonic-gate     }
16950Sstevel@tonic-gate     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
16960Sstevel@tonic-gate 
16970Sstevel@tonic-gate     pos = SvIV(sv) - PL_curcop->cop_arybase;
16980Sstevel@tonic-gate 
16990Sstevel@tonic-gate     if (DO_UTF8(lsv)) {
17000Sstevel@tonic-gate 	ulen = sv_len_utf8(lsv);
17010Sstevel@tonic-gate 	if (ulen)
17020Sstevel@tonic-gate 	    len = ulen;
17030Sstevel@tonic-gate     }
17040Sstevel@tonic-gate 
17050Sstevel@tonic-gate     if (pos < 0) {
17060Sstevel@tonic-gate 	pos += len;
17070Sstevel@tonic-gate 	if (pos < 0)
17080Sstevel@tonic-gate 	    pos = 0;
17090Sstevel@tonic-gate     }
17100Sstevel@tonic-gate     else if (pos > (SSize_t)len)
17110Sstevel@tonic-gate 	pos = len;
17120Sstevel@tonic-gate 
17130Sstevel@tonic-gate     if (ulen) {
17140Sstevel@tonic-gate 	I32 p = pos;
17150Sstevel@tonic-gate 	sv_pos_u2b(lsv, &p, 0);
17160Sstevel@tonic-gate 	pos = p;
17170Sstevel@tonic-gate     }
17180Sstevel@tonic-gate 
17190Sstevel@tonic-gate     mg->mg_len = pos;
17200Sstevel@tonic-gate     mg->mg_flags &= ~MGf_MINMATCH;
17210Sstevel@tonic-gate 
17220Sstevel@tonic-gate     return 0;
17230Sstevel@tonic-gate }
17240Sstevel@tonic-gate 
17250Sstevel@tonic-gate int
Perl_magic_getglob(pTHX_ SV * sv,MAGIC * mg)17260Sstevel@tonic-gate Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
17270Sstevel@tonic-gate {
17280Sstevel@tonic-gate     if (SvFAKE(sv)) {			/* FAKE globs can get coerced */
17290Sstevel@tonic-gate 	SvFAKE_off(sv);
17300Sstevel@tonic-gate 	gv_efullname3(sv,((GV*)sv), "*");
17310Sstevel@tonic-gate 	SvFAKE_on(sv);
17320Sstevel@tonic-gate     }
17330Sstevel@tonic-gate     else
17340Sstevel@tonic-gate 	gv_efullname3(sv,((GV*)sv), "*");	/* a gv value, be nice */
17350Sstevel@tonic-gate     return 0;
17360Sstevel@tonic-gate }
17370Sstevel@tonic-gate 
17380Sstevel@tonic-gate int
Perl_magic_setglob(pTHX_ SV * sv,MAGIC * mg)17390Sstevel@tonic-gate Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
17400Sstevel@tonic-gate {
17410Sstevel@tonic-gate     register char *s;
17420Sstevel@tonic-gate     GV* gv;
17430Sstevel@tonic-gate     STRLEN n_a;
17440Sstevel@tonic-gate 
17450Sstevel@tonic-gate     if (!SvOK(sv))
17460Sstevel@tonic-gate 	return 0;
17470Sstevel@tonic-gate     s = SvPV(sv, n_a);
17480Sstevel@tonic-gate     if (*s == '*' && s[1])
17490Sstevel@tonic-gate 	s++;
17500Sstevel@tonic-gate     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
17510Sstevel@tonic-gate     if (sv == (SV*)gv)
17520Sstevel@tonic-gate 	return 0;
17530Sstevel@tonic-gate     if (GvGP(sv))
17540Sstevel@tonic-gate 	gp_free((GV*)sv);
17550Sstevel@tonic-gate     GvGP(sv) = gp_ref(GvGP(gv));
17560Sstevel@tonic-gate     return 0;
17570Sstevel@tonic-gate }
17580Sstevel@tonic-gate 
17590Sstevel@tonic-gate int
Perl_magic_getsubstr(pTHX_ SV * sv,MAGIC * mg)17600Sstevel@tonic-gate Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
17610Sstevel@tonic-gate {
17620Sstevel@tonic-gate     STRLEN len;
17630Sstevel@tonic-gate     SV *lsv = LvTARG(sv);
17640Sstevel@tonic-gate     char *tmps = SvPV(lsv,len);
17650Sstevel@tonic-gate     I32 offs = LvTARGOFF(sv);
17660Sstevel@tonic-gate     I32 rem = LvTARGLEN(sv);
17670Sstevel@tonic-gate 
17680Sstevel@tonic-gate     if (SvUTF8(lsv))
17690Sstevel@tonic-gate 	sv_pos_u2b(lsv, &offs, &rem);
17700Sstevel@tonic-gate     if (offs > (I32)len)
17710Sstevel@tonic-gate 	offs = len;
17720Sstevel@tonic-gate     if (rem + offs > (I32)len)
17730Sstevel@tonic-gate 	rem = len - offs;
17740Sstevel@tonic-gate     sv_setpvn(sv, tmps + offs, (STRLEN)rem);
17750Sstevel@tonic-gate     if (SvUTF8(lsv))
17760Sstevel@tonic-gate         SvUTF8_on(sv);
17770Sstevel@tonic-gate     return 0;
17780Sstevel@tonic-gate }
17790Sstevel@tonic-gate 
17800Sstevel@tonic-gate int
Perl_magic_setsubstr(pTHX_ SV * sv,MAGIC * mg)17810Sstevel@tonic-gate Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
17820Sstevel@tonic-gate {
17830Sstevel@tonic-gate     STRLEN len;
17840Sstevel@tonic-gate     char *tmps = SvPV(sv, len);
17850Sstevel@tonic-gate     SV *lsv = LvTARG(sv);
17860Sstevel@tonic-gate     I32 lvoff = LvTARGOFF(sv);
17870Sstevel@tonic-gate     I32 lvlen = LvTARGLEN(sv);
17880Sstevel@tonic-gate 
17890Sstevel@tonic-gate     if (DO_UTF8(sv)) {
17900Sstevel@tonic-gate 	sv_utf8_upgrade(lsv);
17910Sstevel@tonic-gate  	sv_pos_u2b(lsv, &lvoff, &lvlen);
17920Sstevel@tonic-gate 	sv_insert(lsv, lvoff, lvlen, tmps, len);
17930Sstevel@tonic-gate 	SvUTF8_on(lsv);
17940Sstevel@tonic-gate     }
17950Sstevel@tonic-gate     else if (lsv && SvUTF8(lsv)) {
17960Sstevel@tonic-gate 	sv_pos_u2b(lsv, &lvoff, &lvlen);
17970Sstevel@tonic-gate 	tmps = (char*)bytes_to_utf8((U8*)tmps, &len);
17980Sstevel@tonic-gate 	sv_insert(lsv, lvoff, lvlen, tmps, len);
17990Sstevel@tonic-gate 	Safefree(tmps);
18000Sstevel@tonic-gate     }
18010Sstevel@tonic-gate     else
18020Sstevel@tonic-gate         sv_insert(lsv, lvoff, lvlen, tmps, len);
18030Sstevel@tonic-gate 
18040Sstevel@tonic-gate     return 0;
18050Sstevel@tonic-gate }
18060Sstevel@tonic-gate 
18070Sstevel@tonic-gate int
Perl_magic_gettaint(pTHX_ SV * sv,MAGIC * mg)18080Sstevel@tonic-gate Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
18090Sstevel@tonic-gate {
18100Sstevel@tonic-gate     TAINT_IF((mg->mg_len & 1) ||
18110Sstevel@tonic-gate 	     ((mg->mg_len & 2) && mg->mg_obj == sv));	/* kludge */
18120Sstevel@tonic-gate     return 0;
18130Sstevel@tonic-gate }
18140Sstevel@tonic-gate 
18150Sstevel@tonic-gate int
Perl_magic_settaint(pTHX_ SV * sv,MAGIC * mg)18160Sstevel@tonic-gate Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
18170Sstevel@tonic-gate {
18180Sstevel@tonic-gate     if (PL_localizing) {
18190Sstevel@tonic-gate 	if (PL_localizing == 1)
18200Sstevel@tonic-gate 	    mg->mg_len <<= 1;
18210Sstevel@tonic-gate 	else
18220Sstevel@tonic-gate 	    mg->mg_len >>= 1;
18230Sstevel@tonic-gate     }
18240Sstevel@tonic-gate     else if (PL_tainted)
18250Sstevel@tonic-gate 	mg->mg_len |= 1;
18260Sstevel@tonic-gate     else
18270Sstevel@tonic-gate 	mg->mg_len &= ~1;
18280Sstevel@tonic-gate     return 0;
18290Sstevel@tonic-gate }
18300Sstevel@tonic-gate 
18310Sstevel@tonic-gate int
Perl_magic_getvec(pTHX_ SV * sv,MAGIC * mg)18320Sstevel@tonic-gate Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
18330Sstevel@tonic-gate {
18340Sstevel@tonic-gate     SV *lsv = LvTARG(sv);
18350Sstevel@tonic-gate 
18360Sstevel@tonic-gate     if (!lsv) {
18370Sstevel@tonic-gate 	(void)SvOK_off(sv);
18380Sstevel@tonic-gate 	return 0;
18390Sstevel@tonic-gate     }
18400Sstevel@tonic-gate 
18410Sstevel@tonic-gate     sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv)));
18420Sstevel@tonic-gate     return 0;
18430Sstevel@tonic-gate }
18440Sstevel@tonic-gate 
18450Sstevel@tonic-gate int
Perl_magic_setvec(pTHX_ SV * sv,MAGIC * mg)18460Sstevel@tonic-gate Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
18470Sstevel@tonic-gate {
18480Sstevel@tonic-gate     do_vecset(sv);	/* XXX slurp this routine */
18490Sstevel@tonic-gate     return 0;
18500Sstevel@tonic-gate }
18510Sstevel@tonic-gate 
18520Sstevel@tonic-gate int
Perl_magic_getdefelem(pTHX_ SV * sv,MAGIC * mg)18530Sstevel@tonic-gate Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
18540Sstevel@tonic-gate {
18550Sstevel@tonic-gate     SV *targ = Nullsv;
18560Sstevel@tonic-gate     if (LvTARGLEN(sv)) {
18570Sstevel@tonic-gate 	if (mg->mg_obj) {
18580Sstevel@tonic-gate 	    SV *ahv = LvTARG(sv);
18590Sstevel@tonic-gate 	    if (SvTYPE(ahv) == SVt_PVHV) {
18600Sstevel@tonic-gate 		HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
18610Sstevel@tonic-gate 		if (he)
18620Sstevel@tonic-gate 		    targ = HeVAL(he);
18630Sstevel@tonic-gate 	    }
18640Sstevel@tonic-gate 	    else {
18650Sstevel@tonic-gate 		SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, FALSE, 0);
18660Sstevel@tonic-gate 		if (svp)
18670Sstevel@tonic-gate 		    targ = *svp;
18680Sstevel@tonic-gate 	    }
18690Sstevel@tonic-gate 	}
18700Sstevel@tonic-gate 	else {
18710Sstevel@tonic-gate 	    AV* av = (AV*)LvTARG(sv);
18720Sstevel@tonic-gate 	    if ((I32)LvTARGOFF(sv) <= AvFILL(av))
18730Sstevel@tonic-gate 		targ = AvARRAY(av)[LvTARGOFF(sv)];
18740Sstevel@tonic-gate 	}
18750Sstevel@tonic-gate 	if (targ && targ != &PL_sv_undef) {
18760Sstevel@tonic-gate 	    /* somebody else defined it for us */
18770Sstevel@tonic-gate 	    SvREFCNT_dec(LvTARG(sv));
18780Sstevel@tonic-gate 	    LvTARG(sv) = SvREFCNT_inc(targ);
18790Sstevel@tonic-gate 	    LvTARGLEN(sv) = 0;
18800Sstevel@tonic-gate 	    SvREFCNT_dec(mg->mg_obj);
18810Sstevel@tonic-gate 	    mg->mg_obj = Nullsv;
18820Sstevel@tonic-gate 	    mg->mg_flags &= ~MGf_REFCOUNTED;
18830Sstevel@tonic-gate 	}
18840Sstevel@tonic-gate     }
18850Sstevel@tonic-gate     else
18860Sstevel@tonic-gate 	targ = LvTARG(sv);
18870Sstevel@tonic-gate     sv_setsv(sv, targ ? targ : &PL_sv_undef);
18880Sstevel@tonic-gate     return 0;
18890Sstevel@tonic-gate }
18900Sstevel@tonic-gate 
18910Sstevel@tonic-gate int
Perl_magic_setdefelem(pTHX_ SV * sv,MAGIC * mg)18920Sstevel@tonic-gate Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
18930Sstevel@tonic-gate {
18940Sstevel@tonic-gate     if (LvTARGLEN(sv))
18950Sstevel@tonic-gate 	vivify_defelem(sv);
18960Sstevel@tonic-gate     if (LvTARG(sv)) {
18970Sstevel@tonic-gate 	sv_setsv(LvTARG(sv), sv);
18980Sstevel@tonic-gate 	SvSETMAGIC(LvTARG(sv));
18990Sstevel@tonic-gate     }
19000Sstevel@tonic-gate     return 0;
19010Sstevel@tonic-gate }
19020Sstevel@tonic-gate 
19030Sstevel@tonic-gate void
Perl_vivify_defelem(pTHX_ SV * sv)19040Sstevel@tonic-gate Perl_vivify_defelem(pTHX_ SV *sv)
19050Sstevel@tonic-gate {
19060Sstevel@tonic-gate     MAGIC *mg;
19070Sstevel@tonic-gate     SV *value = Nullsv;
19080Sstevel@tonic-gate 
19090Sstevel@tonic-gate     if (!LvTARGLEN(sv) || !(mg = mg_find(sv, PERL_MAGIC_defelem)))
19100Sstevel@tonic-gate 	return;
19110Sstevel@tonic-gate     if (mg->mg_obj) {
19120Sstevel@tonic-gate 	SV *ahv = LvTARG(sv);
19130Sstevel@tonic-gate 	STRLEN n_a;
19140Sstevel@tonic-gate 	if (SvTYPE(ahv) == SVt_PVHV) {
19150Sstevel@tonic-gate 	    HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
19160Sstevel@tonic-gate 	    if (he)
19170Sstevel@tonic-gate 		value = HeVAL(he);
19180Sstevel@tonic-gate 	}
19190Sstevel@tonic-gate 	else {
19200Sstevel@tonic-gate 	    SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, TRUE, 0);
19210Sstevel@tonic-gate 	    if (svp)
19220Sstevel@tonic-gate 		value = *svp;
19230Sstevel@tonic-gate 	}
19240Sstevel@tonic-gate 	if (!value || value == &PL_sv_undef)
19250Sstevel@tonic-gate 	    Perl_croak(aTHX_ PL_no_helem, SvPV(mg->mg_obj, n_a));
19260Sstevel@tonic-gate     }
19270Sstevel@tonic-gate     else {
19280Sstevel@tonic-gate 	AV* av = (AV*)LvTARG(sv);
19290Sstevel@tonic-gate 	if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
19300Sstevel@tonic-gate 	    LvTARG(sv) = Nullsv;	/* array can't be extended */
19310Sstevel@tonic-gate 	else {
19320Sstevel@tonic-gate 	    SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
19330Sstevel@tonic-gate 	    if (!svp || (value = *svp) == &PL_sv_undef)
19340Sstevel@tonic-gate 		Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
19350Sstevel@tonic-gate 	}
19360Sstevel@tonic-gate     }
19370Sstevel@tonic-gate     (void)SvREFCNT_inc(value);
19380Sstevel@tonic-gate     SvREFCNT_dec(LvTARG(sv));
19390Sstevel@tonic-gate     LvTARG(sv) = value;
19400Sstevel@tonic-gate     LvTARGLEN(sv) = 0;
19410Sstevel@tonic-gate     SvREFCNT_dec(mg->mg_obj);
19420Sstevel@tonic-gate     mg->mg_obj = Nullsv;
19430Sstevel@tonic-gate     mg->mg_flags &= ~MGf_REFCOUNTED;
19440Sstevel@tonic-gate }
19450Sstevel@tonic-gate 
19460Sstevel@tonic-gate int
Perl_magic_killbackrefs(pTHX_ SV * sv,MAGIC * mg)19470Sstevel@tonic-gate Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
19480Sstevel@tonic-gate {
19490Sstevel@tonic-gate     AV *av = (AV*)mg->mg_obj;
19500Sstevel@tonic-gate     SV **svp = AvARRAY(av);
19510Sstevel@tonic-gate     I32 i = AvFILLp(av);
19520Sstevel@tonic-gate     while (i >= 0) {
19530Sstevel@tonic-gate 	if (svp[i] && svp[i] != &PL_sv_undef) {
19540Sstevel@tonic-gate 	    if (!SvWEAKREF(svp[i]))
19550Sstevel@tonic-gate 		Perl_croak(aTHX_ "panic: magic_killbackrefs");
19560Sstevel@tonic-gate 	    /* XXX Should we check that it hasn't changed? */
19570Sstevel@tonic-gate 	    SvRV(svp[i]) = 0;
19580Sstevel@tonic-gate 	    (void)SvOK_off(svp[i]);
19590Sstevel@tonic-gate 	    SvWEAKREF_off(svp[i]);
19600Sstevel@tonic-gate 	    svp[i] = &PL_sv_undef;
19610Sstevel@tonic-gate 	}
19620Sstevel@tonic-gate 	i--;
19630Sstevel@tonic-gate     }
19640Sstevel@tonic-gate     SvREFCNT_dec(av); /* remove extra count added by sv_add_backref() */
19650Sstevel@tonic-gate     return 0;
19660Sstevel@tonic-gate }
19670Sstevel@tonic-gate 
19680Sstevel@tonic-gate int
Perl_magic_setmglob(pTHX_ SV * sv,MAGIC * mg)19690Sstevel@tonic-gate Perl_magic_setmglob(pTHX_ SV *sv, MAGIC *mg)
19700Sstevel@tonic-gate {
19710Sstevel@tonic-gate     mg->mg_len = -1;
19720Sstevel@tonic-gate     SvSCREAM_off(sv);
19730Sstevel@tonic-gate     return 0;
19740Sstevel@tonic-gate }
19750Sstevel@tonic-gate 
19760Sstevel@tonic-gate int
Perl_magic_setbm(pTHX_ SV * sv,MAGIC * mg)19770Sstevel@tonic-gate Perl_magic_setbm(pTHX_ SV *sv, MAGIC *mg)
19780Sstevel@tonic-gate {
19790Sstevel@tonic-gate     sv_unmagic(sv, PERL_MAGIC_bm);
19800Sstevel@tonic-gate     SvVALID_off(sv);
19810Sstevel@tonic-gate     return 0;
19820Sstevel@tonic-gate }
19830Sstevel@tonic-gate 
19840Sstevel@tonic-gate int
Perl_magic_setfm(pTHX_ SV * sv,MAGIC * mg)19850Sstevel@tonic-gate Perl_magic_setfm(pTHX_ SV *sv, MAGIC *mg)
19860Sstevel@tonic-gate {
19870Sstevel@tonic-gate     sv_unmagic(sv, PERL_MAGIC_fm);
19880Sstevel@tonic-gate     SvCOMPILED_off(sv);
19890Sstevel@tonic-gate     return 0;
19900Sstevel@tonic-gate }
19910Sstevel@tonic-gate 
19920Sstevel@tonic-gate int
Perl_magic_setuvar(pTHX_ SV * sv,MAGIC * mg)19930Sstevel@tonic-gate Perl_magic_setuvar(pTHX_ SV *sv, MAGIC *mg)
19940Sstevel@tonic-gate {
19950Sstevel@tonic-gate     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
19960Sstevel@tonic-gate 
19970Sstevel@tonic-gate     if (uf && uf->uf_set)
19980Sstevel@tonic-gate 	(*uf->uf_set)(aTHX_ uf->uf_index, sv);
19990Sstevel@tonic-gate     return 0;
20000Sstevel@tonic-gate }
20010Sstevel@tonic-gate 
20020Sstevel@tonic-gate int
Perl_magic_setregexp(pTHX_ SV * sv,MAGIC * mg)20030Sstevel@tonic-gate Perl_magic_setregexp(pTHX_ SV *sv, MAGIC *mg)
20040Sstevel@tonic-gate {
20050Sstevel@tonic-gate     sv_unmagic(sv, PERL_MAGIC_qr);
20060Sstevel@tonic-gate     return 0;
20070Sstevel@tonic-gate }
20080Sstevel@tonic-gate 
20090Sstevel@tonic-gate int
Perl_magic_freeregexp(pTHX_ SV * sv,MAGIC * mg)20100Sstevel@tonic-gate Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
20110Sstevel@tonic-gate {
20120Sstevel@tonic-gate     regexp *re = (regexp *)mg->mg_obj;
20130Sstevel@tonic-gate     ReREFCNT_dec(re);
20140Sstevel@tonic-gate     return 0;
20150Sstevel@tonic-gate }
20160Sstevel@tonic-gate 
20170Sstevel@tonic-gate #ifdef USE_LOCALE_COLLATE
20180Sstevel@tonic-gate int
Perl_magic_setcollxfrm(pTHX_ SV * sv,MAGIC * mg)20190Sstevel@tonic-gate Perl_magic_setcollxfrm(pTHX_ SV *sv, MAGIC *mg)
20200Sstevel@tonic-gate {
20210Sstevel@tonic-gate     /*
20220Sstevel@tonic-gate      * RenE<eacute> Descartes said "I think not."
20230Sstevel@tonic-gate      * and vanished with a faint plop.
20240Sstevel@tonic-gate      */
20250Sstevel@tonic-gate     if (mg->mg_ptr) {
20260Sstevel@tonic-gate 	Safefree(mg->mg_ptr);
20270Sstevel@tonic-gate 	mg->mg_ptr = NULL;
20280Sstevel@tonic-gate 	mg->mg_len = -1;
20290Sstevel@tonic-gate     }
20300Sstevel@tonic-gate     return 0;
20310Sstevel@tonic-gate }
20320Sstevel@tonic-gate #endif /* USE_LOCALE_COLLATE */
20330Sstevel@tonic-gate 
20340Sstevel@tonic-gate /* Just clear the UTF-8 cache data. */
20350Sstevel@tonic-gate int
Perl_magic_setutf8(pTHX_ SV * sv,MAGIC * mg)20360Sstevel@tonic-gate Perl_magic_setutf8(pTHX_ SV *sv, MAGIC *mg)
20370Sstevel@tonic-gate {
20380Sstevel@tonic-gate      Safefree(mg->mg_ptr);	/* The mg_ptr holds the pos cache. */
20390Sstevel@tonic-gate      mg->mg_ptr = 0;
20400Sstevel@tonic-gate      mg->mg_len = -1; 		/* The mg_len holds the len cache. */
20410Sstevel@tonic-gate      return 0;
20420Sstevel@tonic-gate }
20430Sstevel@tonic-gate 
20440Sstevel@tonic-gate int
Perl_magic_set(pTHX_ SV * sv,MAGIC * mg)20450Sstevel@tonic-gate Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
20460Sstevel@tonic-gate {
20470Sstevel@tonic-gate     register char *s;
20480Sstevel@tonic-gate     I32 i;
20490Sstevel@tonic-gate     STRLEN len;
20500Sstevel@tonic-gate     switch (*mg->mg_ptr) {
20510Sstevel@tonic-gate     case '\001':	/* ^A */
20520Sstevel@tonic-gate 	sv_setsv(PL_bodytarget, sv);
20530Sstevel@tonic-gate 	break;
20540Sstevel@tonic-gate     case '\003':	/* ^C */
20550Sstevel@tonic-gate 	PL_minus_c = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
20560Sstevel@tonic-gate 	break;
20570Sstevel@tonic-gate 
20580Sstevel@tonic-gate     case '\004':	/* ^D */
20590Sstevel@tonic-gate #ifdef DEBUGGING
20600Sstevel@tonic-gate 	s = SvPV_nolen(sv);
20610Sstevel@tonic-gate 	PL_debug = get_debug_opts(&s) | DEBUG_TOP_FLAG;
20620Sstevel@tonic-gate 	DEBUG_x(dump_all());
20630Sstevel@tonic-gate #else
20640Sstevel@tonic-gate 	PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | DEBUG_TOP_FLAG;
20650Sstevel@tonic-gate #endif
20660Sstevel@tonic-gate 	break;
20670Sstevel@tonic-gate     case '\005':  /* ^E */
20680Sstevel@tonic-gate 	if (*(mg->mg_ptr+1) == '\0') {
20690Sstevel@tonic-gate #ifdef MACOS_TRADITIONAL
20700Sstevel@tonic-gate 	    gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
20710Sstevel@tonic-gate #else
20720Sstevel@tonic-gate #  ifdef VMS
20730Sstevel@tonic-gate 	    set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
20740Sstevel@tonic-gate #  else
20750Sstevel@tonic-gate #    ifdef WIN32
20760Sstevel@tonic-gate 	    SetLastError( SvIV(sv) );
20770Sstevel@tonic-gate #    else
20780Sstevel@tonic-gate #      ifdef OS2
20790Sstevel@tonic-gate 	    os2_setsyserrno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
20800Sstevel@tonic-gate #      else
20810Sstevel@tonic-gate 	    /* will anyone ever use this? */
20820Sstevel@tonic-gate 	    SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
20830Sstevel@tonic-gate #      endif
20840Sstevel@tonic-gate #    endif
20850Sstevel@tonic-gate #  endif
20860Sstevel@tonic-gate #endif
20870Sstevel@tonic-gate 	}
20880Sstevel@tonic-gate 	else if (strEQ(mg->mg_ptr+1, "NCODING")) {
20890Sstevel@tonic-gate 	    if (PL_encoding)
20900Sstevel@tonic-gate 		SvREFCNT_dec(PL_encoding);
20910Sstevel@tonic-gate 	    if (SvOK(sv) || SvGMAGICAL(sv)) {
20920Sstevel@tonic-gate 		PL_encoding = newSVsv(sv);
20930Sstevel@tonic-gate 	    }
20940Sstevel@tonic-gate 	    else {
20950Sstevel@tonic-gate 		PL_encoding = Nullsv;
20960Sstevel@tonic-gate 	    }
20970Sstevel@tonic-gate 	}
20980Sstevel@tonic-gate 	break;
20990Sstevel@tonic-gate     case '\006':	/* ^F */
21000Sstevel@tonic-gate 	PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
21010Sstevel@tonic-gate 	break;
21020Sstevel@tonic-gate     case '\010':	/* ^H */
21030Sstevel@tonic-gate 	PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
21040Sstevel@tonic-gate 	break;
21050Sstevel@tonic-gate     case '\011':	/* ^I */ /* NOT \t in EBCDIC */
21060Sstevel@tonic-gate 	if (PL_inplace)
21070Sstevel@tonic-gate 	    Safefree(PL_inplace);
21080Sstevel@tonic-gate 	if (SvOK(sv))
21090Sstevel@tonic-gate 	    PL_inplace = savepv(SvPV(sv,len));
21100Sstevel@tonic-gate 	else
21110Sstevel@tonic-gate 	    PL_inplace = Nullch;
21120Sstevel@tonic-gate 	break;
21130Sstevel@tonic-gate     case '\017':	/* ^O */
21140Sstevel@tonic-gate 	if (*(mg->mg_ptr+1) == '\0') {
21150Sstevel@tonic-gate 	    if (PL_osname) {
21160Sstevel@tonic-gate 		Safefree(PL_osname);
21170Sstevel@tonic-gate 		PL_osname = Nullch;
21180Sstevel@tonic-gate 	    }
21190Sstevel@tonic-gate 	    if (SvOK(sv)) {
21200Sstevel@tonic-gate 		TAINT_PROPER("assigning to $^O");
21210Sstevel@tonic-gate 		PL_osname = savepv(SvPV(sv,len));
21220Sstevel@tonic-gate 	    }
21230Sstevel@tonic-gate 	}
21240Sstevel@tonic-gate 	else if (strEQ(mg->mg_ptr, "\017PEN")) {
21250Sstevel@tonic-gate 	    if (!PL_compiling.cop_io)
21260Sstevel@tonic-gate 		PL_compiling.cop_io = newSVsv(sv);
21270Sstevel@tonic-gate 	    else
21280Sstevel@tonic-gate 		sv_setsv(PL_compiling.cop_io,sv);
21290Sstevel@tonic-gate 	}
21300Sstevel@tonic-gate 	break;
21310Sstevel@tonic-gate     case '\020':	/* ^P */
21320Sstevel@tonic-gate 	PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
21330Sstevel@tonic-gate 	if ((PERLDB_SUB || PERLDB_LINE || PERLDB_SUBLINE)
21340Sstevel@tonic-gate 		&& !PL_DBsingle)
21350Sstevel@tonic-gate 	    init_debugger();
21360Sstevel@tonic-gate 	break;
21370Sstevel@tonic-gate     case '\024':	/* ^T */
21380Sstevel@tonic-gate #ifdef BIG_TIME
21390Sstevel@tonic-gate 	PL_basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
21400Sstevel@tonic-gate #else
21410Sstevel@tonic-gate 	PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
21420Sstevel@tonic-gate #endif
21430Sstevel@tonic-gate 	break;
21440Sstevel@tonic-gate     case '\027':	/* ^W & $^WARNING_BITS */
21450Sstevel@tonic-gate 	if (*(mg->mg_ptr+1) == '\0') {
21460Sstevel@tonic-gate 	    if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
21470Sstevel@tonic-gate 	        i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
21480Sstevel@tonic-gate 	        PL_dowarn = (PL_dowarn & ~G_WARN_ON)
21490Sstevel@tonic-gate 		    		| (i ? G_WARN_ON : G_WARN_OFF) ;
21500Sstevel@tonic-gate 	    }
21510Sstevel@tonic-gate 	}
21520Sstevel@tonic-gate 	else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) {
21530Sstevel@tonic-gate 	    if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
21540Sstevel@tonic-gate 		if (!SvPOK(sv) && PL_localizing) {
21550Sstevel@tonic-gate 	            sv_setpvn(sv, WARN_NONEstring, WARNsize);
21560Sstevel@tonic-gate 	            PL_compiling.cop_warnings = pWARN_NONE;
21570Sstevel@tonic-gate 		    break;
21580Sstevel@tonic-gate 		}
21590Sstevel@tonic-gate 		{
21600Sstevel@tonic-gate 		    STRLEN len, i;
21610Sstevel@tonic-gate 		    int accumulate = 0 ;
21620Sstevel@tonic-gate 		    int any_fatals = 0 ;
21630Sstevel@tonic-gate 		    char * ptr = (char*)SvPV(sv, len) ;
21640Sstevel@tonic-gate 		    for (i = 0 ; i < len ; ++i) {
21650Sstevel@tonic-gate 		        accumulate |= ptr[i] ;
21660Sstevel@tonic-gate 		        any_fatals |= (ptr[i] & 0xAA) ;
21670Sstevel@tonic-gate 		    }
21680Sstevel@tonic-gate 		    if (!accumulate)
21690Sstevel@tonic-gate 	                PL_compiling.cop_warnings = pWARN_NONE;
21700Sstevel@tonic-gate 		    else if (isWARN_on(sv, WARN_ALL) && !any_fatals) {
21710Sstevel@tonic-gate 	                PL_compiling.cop_warnings = pWARN_ALL;
21720Sstevel@tonic-gate 	                PL_dowarn |= G_WARN_ONCE ;
21730Sstevel@tonic-gate 	            }
21740Sstevel@tonic-gate                     else {
21750Sstevel@tonic-gate 	                if (specialWARN(PL_compiling.cop_warnings))
21760Sstevel@tonic-gate 		            PL_compiling.cop_warnings = newSVsv(sv) ;
21770Sstevel@tonic-gate 	                else
21780Sstevel@tonic-gate 	                    sv_setsv(PL_compiling.cop_warnings, sv);
21790Sstevel@tonic-gate 	                if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE))
21800Sstevel@tonic-gate 	                    PL_dowarn |= G_WARN_ONCE ;
21810Sstevel@tonic-gate 	            }
21820Sstevel@tonic-gate 
21830Sstevel@tonic-gate 		}
21840Sstevel@tonic-gate 	    }
21850Sstevel@tonic-gate 	}
21860Sstevel@tonic-gate 	break;
21870Sstevel@tonic-gate     case '.':
21880Sstevel@tonic-gate 	if (PL_localizing) {
21890Sstevel@tonic-gate 	    if (PL_localizing == 1)
21900Sstevel@tonic-gate 		SAVESPTR(PL_last_in_gv);
21910Sstevel@tonic-gate 	}
21920Sstevel@tonic-gate 	else if (SvOK(sv) && GvIO(PL_last_in_gv))
21930Sstevel@tonic-gate 	    IoLINES(GvIOp(PL_last_in_gv)) = SvIV(sv);
21940Sstevel@tonic-gate 	break;
21950Sstevel@tonic-gate     case '^':
21960Sstevel@tonic-gate 	Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
21970Sstevel@tonic-gate 	IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
21980Sstevel@tonic-gate 	IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
21990Sstevel@tonic-gate 	break;
22000Sstevel@tonic-gate     case '~':
22010Sstevel@tonic-gate 	Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
22020Sstevel@tonic-gate 	IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
22030Sstevel@tonic-gate 	IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
22040Sstevel@tonic-gate 	break;
22050Sstevel@tonic-gate     case '=':
22060Sstevel@tonic-gate 	IoPAGE_LEN(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
22070Sstevel@tonic-gate 	break;
22080Sstevel@tonic-gate     case '-':
22090Sstevel@tonic-gate 	IoLINES_LEFT(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
22100Sstevel@tonic-gate 	if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L)
22110Sstevel@tonic-gate 	    IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L;
22120Sstevel@tonic-gate 	break;
22130Sstevel@tonic-gate     case '%':
22140Sstevel@tonic-gate 	IoPAGE(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
22150Sstevel@tonic-gate 	break;
22160Sstevel@tonic-gate     case '|':
22170Sstevel@tonic-gate 	{
22180Sstevel@tonic-gate 	    IO *io = GvIOp(PL_defoutgv);
22190Sstevel@tonic-gate 	    if(!io)
22200Sstevel@tonic-gate 	      break;
22210Sstevel@tonic-gate 	    if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
22220Sstevel@tonic-gate 		IoFLAGS(io) &= ~IOf_FLUSH;
22230Sstevel@tonic-gate 	    else {
22240Sstevel@tonic-gate 		if (!(IoFLAGS(io) & IOf_FLUSH)) {
22250Sstevel@tonic-gate 		    PerlIO *ofp = IoOFP(io);
22260Sstevel@tonic-gate 		    if (ofp)
22270Sstevel@tonic-gate 			(void)PerlIO_flush(ofp);
22280Sstevel@tonic-gate 		    IoFLAGS(io) |= IOf_FLUSH;
22290Sstevel@tonic-gate 		}
22300Sstevel@tonic-gate 	    }
22310Sstevel@tonic-gate 	}
22320Sstevel@tonic-gate 	break;
22330Sstevel@tonic-gate     case '*':
22340Sstevel@tonic-gate 	i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
22350Sstevel@tonic-gate 	PL_multiline = (i != 0);
22360Sstevel@tonic-gate 	break;
22370Sstevel@tonic-gate     case '/':
22380Sstevel@tonic-gate 	SvREFCNT_dec(PL_rs);
22390Sstevel@tonic-gate 	PL_rs = newSVsv(sv);
22400Sstevel@tonic-gate 	break;
22410Sstevel@tonic-gate     case '\\':
22420Sstevel@tonic-gate 	if (PL_ors_sv)
22430Sstevel@tonic-gate 	    SvREFCNT_dec(PL_ors_sv);
22440Sstevel@tonic-gate 	if (SvOK(sv) || SvGMAGICAL(sv)) {
22450Sstevel@tonic-gate 	    PL_ors_sv = newSVsv(sv);
22460Sstevel@tonic-gate 	}
22470Sstevel@tonic-gate 	else {
22480Sstevel@tonic-gate 	    PL_ors_sv = Nullsv;
22490Sstevel@tonic-gate 	}
22500Sstevel@tonic-gate 	break;
22510Sstevel@tonic-gate     case ',':
22520Sstevel@tonic-gate 	if (PL_ofs_sv)
22530Sstevel@tonic-gate 	    SvREFCNT_dec(PL_ofs_sv);
22540Sstevel@tonic-gate 	if (SvOK(sv) || SvGMAGICAL(sv)) {
22550Sstevel@tonic-gate 	    PL_ofs_sv = newSVsv(sv);
22560Sstevel@tonic-gate 	}
22570Sstevel@tonic-gate 	else {
22580Sstevel@tonic-gate 	    PL_ofs_sv = Nullsv;
22590Sstevel@tonic-gate 	}
22600Sstevel@tonic-gate 	break;
22610Sstevel@tonic-gate     case '#':
22620Sstevel@tonic-gate 	if (PL_ofmt)
22630Sstevel@tonic-gate 	    Safefree(PL_ofmt);
22640Sstevel@tonic-gate 	PL_ofmt = savepv(SvPV(sv,len));
22650Sstevel@tonic-gate 	break;
22660Sstevel@tonic-gate     case '[':
22670Sstevel@tonic-gate 	PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
22680Sstevel@tonic-gate 	break;
22690Sstevel@tonic-gate     case '?':
22700Sstevel@tonic-gate #ifdef COMPLEX_STATUS
22710Sstevel@tonic-gate 	if (PL_localizing == 2) {
22720Sstevel@tonic-gate 	    PL_statusvalue = LvTARGOFF(sv);
22730Sstevel@tonic-gate 	    PL_statusvalue_vms = LvTARGLEN(sv);
22740Sstevel@tonic-gate 	}
22750Sstevel@tonic-gate 	else
22760Sstevel@tonic-gate #endif
22770Sstevel@tonic-gate #ifdef VMSISH_STATUS
22780Sstevel@tonic-gate 	if (VMSISH_STATUS)
22790Sstevel@tonic-gate 	    STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
22800Sstevel@tonic-gate 	else
22810Sstevel@tonic-gate #endif
22820Sstevel@tonic-gate 	    STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
22830Sstevel@tonic-gate 	break;
22840Sstevel@tonic-gate     case '!':
22850Sstevel@tonic-gate         {
22860Sstevel@tonic-gate #ifdef VMS
22870Sstevel@tonic-gate #   define PERL_VMS_BANG vaxc$errno
22880Sstevel@tonic-gate #else
22890Sstevel@tonic-gate #   define PERL_VMS_BANG 0
22900Sstevel@tonic-gate #endif
22910Sstevel@tonic-gate 	SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
22920Sstevel@tonic-gate 		 (SvIV(sv) == EVMSERR) ? 4 : PERL_VMS_BANG);
22930Sstevel@tonic-gate 	}
22940Sstevel@tonic-gate 	break;
22950Sstevel@tonic-gate     case '<':
22960Sstevel@tonic-gate 	PL_uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
22970Sstevel@tonic-gate 	if (PL_delaymagic) {
22980Sstevel@tonic-gate 	    PL_delaymagic |= DM_RUID;
22990Sstevel@tonic-gate 	    break;				/* don't do magic till later */
23000Sstevel@tonic-gate 	}
23010Sstevel@tonic-gate #ifdef HAS_SETRUID
23020Sstevel@tonic-gate 	(void)setruid((Uid_t)PL_uid);
23030Sstevel@tonic-gate #else
23040Sstevel@tonic-gate #ifdef HAS_SETREUID
23050Sstevel@tonic-gate 	(void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
23060Sstevel@tonic-gate #else
23070Sstevel@tonic-gate #ifdef HAS_SETRESUID
23080Sstevel@tonic-gate       (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
23090Sstevel@tonic-gate #else
23100Sstevel@tonic-gate 	if (PL_uid == PL_euid) {		/* special case $< = $> */
23110Sstevel@tonic-gate #ifdef PERL_DARWIN
23120Sstevel@tonic-gate 	    /* workaround for Darwin's setuid peculiarity, cf [perl #24122] */
23130Sstevel@tonic-gate 	    if (PL_uid != 0 && PerlProc_getuid() == 0)
23140Sstevel@tonic-gate 		(void)PerlProc_setuid(0);
23150Sstevel@tonic-gate #endif
23160Sstevel@tonic-gate 	    (void)PerlProc_setuid(PL_uid);
23170Sstevel@tonic-gate 	} else {
23180Sstevel@tonic-gate 	    PL_uid = PerlProc_getuid();
23190Sstevel@tonic-gate 	    Perl_croak(aTHX_ "setruid() not implemented");
23200Sstevel@tonic-gate 	}
23210Sstevel@tonic-gate #endif
23220Sstevel@tonic-gate #endif
23230Sstevel@tonic-gate #endif
23240Sstevel@tonic-gate 	PL_uid = PerlProc_getuid();
23250Sstevel@tonic-gate 	PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
23260Sstevel@tonic-gate 	break;
23270Sstevel@tonic-gate     case '>':
23280Sstevel@tonic-gate 	PL_euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
23290Sstevel@tonic-gate 	if (PL_delaymagic) {
23300Sstevel@tonic-gate 	    PL_delaymagic |= DM_EUID;
23310Sstevel@tonic-gate 	    break;				/* don't do magic till later */
23320Sstevel@tonic-gate 	}
23330Sstevel@tonic-gate #ifdef HAS_SETEUID
23340Sstevel@tonic-gate 	(void)seteuid((Uid_t)PL_euid);
23350Sstevel@tonic-gate #else
23360Sstevel@tonic-gate #ifdef HAS_SETREUID
23370Sstevel@tonic-gate 	(void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
23380Sstevel@tonic-gate #else
23390Sstevel@tonic-gate #ifdef HAS_SETRESUID
23400Sstevel@tonic-gate 	(void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
23410Sstevel@tonic-gate #else
23420Sstevel@tonic-gate 	if (PL_euid == PL_uid)		/* special case $> = $< */
23430Sstevel@tonic-gate 	    PerlProc_setuid(PL_euid);
23440Sstevel@tonic-gate 	else {
23450Sstevel@tonic-gate 	    PL_euid = PerlProc_geteuid();
23460Sstevel@tonic-gate 	    Perl_croak(aTHX_ "seteuid() not implemented");
23470Sstevel@tonic-gate 	}
23480Sstevel@tonic-gate #endif
23490Sstevel@tonic-gate #endif
23500Sstevel@tonic-gate #endif
23510Sstevel@tonic-gate 	PL_euid = PerlProc_geteuid();
23520Sstevel@tonic-gate 	PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
23530Sstevel@tonic-gate 	break;
23540Sstevel@tonic-gate     case '(':
23550Sstevel@tonic-gate 	PL_gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
23560Sstevel@tonic-gate 	if (PL_delaymagic) {
23570Sstevel@tonic-gate 	    PL_delaymagic |= DM_RGID;
23580Sstevel@tonic-gate 	    break;				/* don't do magic till later */
23590Sstevel@tonic-gate 	}
23600Sstevel@tonic-gate #ifdef HAS_SETRGID
23610Sstevel@tonic-gate 	(void)setrgid((Gid_t)PL_gid);
23620Sstevel@tonic-gate #else
23630Sstevel@tonic-gate #ifdef HAS_SETREGID
23640Sstevel@tonic-gate 	(void)setregid((Gid_t)PL_gid, (Gid_t)-1);
23650Sstevel@tonic-gate #else
23660Sstevel@tonic-gate #ifdef HAS_SETRESGID
23670Sstevel@tonic-gate       (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
23680Sstevel@tonic-gate #else
23690Sstevel@tonic-gate 	if (PL_gid == PL_egid)			/* special case $( = $) */
23700Sstevel@tonic-gate 	    (void)PerlProc_setgid(PL_gid);
23710Sstevel@tonic-gate 	else {
23720Sstevel@tonic-gate 	    PL_gid = PerlProc_getgid();
23730Sstevel@tonic-gate 	    Perl_croak(aTHX_ "setrgid() not implemented");
23740Sstevel@tonic-gate 	}
23750Sstevel@tonic-gate #endif
23760Sstevel@tonic-gate #endif
23770Sstevel@tonic-gate #endif
23780Sstevel@tonic-gate 	PL_gid = PerlProc_getgid();
23790Sstevel@tonic-gate 	PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
23800Sstevel@tonic-gate 	break;
23810Sstevel@tonic-gate     case ')':
23820Sstevel@tonic-gate #ifdef HAS_SETGROUPS
23830Sstevel@tonic-gate 	{
23840Sstevel@tonic-gate 	    char *p = SvPV(sv, len);
2385*11134SCasper.Dik@Sun.COM #ifdef _SC_NGROUPS_MAX
2386*11134SCasper.Dik@Sun.COM 	    int maxgrp = sysconf(_SC_NGROUPS_MAX);
2387*11134SCasper.Dik@Sun.COM 	    Groups_t *gary = alloca(maxgrp * sizeof (Groups_t));
2388*11134SCasper.Dik@Sun.COM #else
2389*11134SCasper.Dik@Sun.COM 	    int maxgrp = NGROUPS;
23900Sstevel@tonic-gate 	    Groups_t gary[NGROUPS];
2391*11134SCasper.Dik@Sun.COM #endif
23920Sstevel@tonic-gate 
23930Sstevel@tonic-gate 	    while (isSPACE(*p))
23940Sstevel@tonic-gate 		++p;
23950Sstevel@tonic-gate 	    PL_egid = Atol(p);
2396*11134SCasper.Dik@Sun.COM 	    for (i = 0; i < maxgrp; ++i) {
23970Sstevel@tonic-gate 		while (*p && !isSPACE(*p))
23980Sstevel@tonic-gate 		    ++p;
23990Sstevel@tonic-gate 		while (isSPACE(*p))
24000Sstevel@tonic-gate 		    ++p;
24010Sstevel@tonic-gate 		if (!*p)
24020Sstevel@tonic-gate 		    break;
24030Sstevel@tonic-gate 		gary[i] = Atol(p);
24040Sstevel@tonic-gate 	    }
24050Sstevel@tonic-gate 	    if (i)
24060Sstevel@tonic-gate 		(void)setgroups(i, gary);
24070Sstevel@tonic-gate 	}
24080Sstevel@tonic-gate #else  /* HAS_SETGROUPS */
24090Sstevel@tonic-gate 	PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
24100Sstevel@tonic-gate #endif /* HAS_SETGROUPS */
24110Sstevel@tonic-gate 	if (PL_delaymagic) {
24120Sstevel@tonic-gate 	    PL_delaymagic |= DM_EGID;
24130Sstevel@tonic-gate 	    break;				/* don't do magic till later */
24140Sstevel@tonic-gate 	}
24150Sstevel@tonic-gate #ifdef HAS_SETEGID
24160Sstevel@tonic-gate 	(void)setegid((Gid_t)PL_egid);
24170Sstevel@tonic-gate #else
24180Sstevel@tonic-gate #ifdef HAS_SETREGID
24190Sstevel@tonic-gate 	(void)setregid((Gid_t)-1, (Gid_t)PL_egid);
24200Sstevel@tonic-gate #else
24210Sstevel@tonic-gate #ifdef HAS_SETRESGID
24220Sstevel@tonic-gate 	(void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
24230Sstevel@tonic-gate #else
24240Sstevel@tonic-gate 	if (PL_egid == PL_gid)			/* special case $) = $( */
24250Sstevel@tonic-gate 	    (void)PerlProc_setgid(PL_egid);
24260Sstevel@tonic-gate 	else {
24270Sstevel@tonic-gate 	    PL_egid = PerlProc_getegid();
24280Sstevel@tonic-gate 	    Perl_croak(aTHX_ "setegid() not implemented");
24290Sstevel@tonic-gate 	}
24300Sstevel@tonic-gate #endif
24310Sstevel@tonic-gate #endif
24320Sstevel@tonic-gate #endif
24330Sstevel@tonic-gate 	PL_egid = PerlProc_getegid();
24340Sstevel@tonic-gate 	PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
24350Sstevel@tonic-gate 	break;
24360Sstevel@tonic-gate     case ':':
24370Sstevel@tonic-gate 	PL_chopset = SvPV_force(sv,len);
24380Sstevel@tonic-gate 	break;
24390Sstevel@tonic-gate #ifndef MACOS_TRADITIONAL
24400Sstevel@tonic-gate     case '0':
24410Sstevel@tonic-gate 	LOCK_DOLLARZERO_MUTEX;
24420Sstevel@tonic-gate #ifdef HAS_SETPROCTITLE
24430Sstevel@tonic-gate 	/* The BSDs don't show the argv[] in ps(1) output, they
24440Sstevel@tonic-gate 	 * show a string from the process struct and provide
24450Sstevel@tonic-gate 	 * the setproctitle() routine to manipulate that. */
24460Sstevel@tonic-gate 	{
24470Sstevel@tonic-gate 	    s = SvPV(sv, len);
24480Sstevel@tonic-gate #   if __FreeBSD_version > 410001
24490Sstevel@tonic-gate 	    /* The leading "-" removes the "perl: " prefix,
24500Sstevel@tonic-gate 	     * but not the "(perl) suffix from the ps(1)
24510Sstevel@tonic-gate 	     * output, because that's what ps(1) shows if the
24520Sstevel@tonic-gate 	     * argv[] is modified. */
24530Sstevel@tonic-gate 	    setproctitle("-%s", s);
24540Sstevel@tonic-gate #   else	/* old FreeBSDs, NetBSD, OpenBSD, anyBSD */
24550Sstevel@tonic-gate 	    /* This doesn't really work if you assume that
24560Sstevel@tonic-gate 	     * $0 = 'foobar'; will wipe out 'perl' from the $0
24570Sstevel@tonic-gate 	     * because in ps(1) output the result will be like
24580Sstevel@tonic-gate 	     * sprintf("perl: %s (perl)", s)
24590Sstevel@tonic-gate 	     * I guess this is a security feature:
24600Sstevel@tonic-gate 	     * one (a user process) cannot get rid of the original name.
24610Sstevel@tonic-gate 	     * --jhi */
24620Sstevel@tonic-gate 	    setproctitle("%s", s);
24630Sstevel@tonic-gate #   endif
24640Sstevel@tonic-gate 	}
24650Sstevel@tonic-gate #endif
24660Sstevel@tonic-gate #if defined(__hpux) && defined(PSTAT_SETCMD)
24670Sstevel@tonic-gate 	{
24680Sstevel@tonic-gate 	     union pstun un;
24690Sstevel@tonic-gate 	     s = SvPV(sv, len);
24700Sstevel@tonic-gate 	     un.pst_command = s;
24710Sstevel@tonic-gate 	     pstat(PSTAT_SETCMD, un, len, 0, 0);
24720Sstevel@tonic-gate 	}
24730Sstevel@tonic-gate #endif
24740Sstevel@tonic-gate 	/* PL_origalen is set in perl_parse(). */
24750Sstevel@tonic-gate 	s = SvPV_force(sv,len);
24760Sstevel@tonic-gate 	if (len >= (STRLEN)PL_origalen) {
24770Sstevel@tonic-gate 	    /* Longer than original, will be truncated. */
24780Sstevel@tonic-gate 	    Copy(s, PL_origargv[0], PL_origalen, char);
24790Sstevel@tonic-gate 	    PL_origargv[0][PL_origalen - 1] = 0;
24800Sstevel@tonic-gate 	}
24810Sstevel@tonic-gate 	else {
24820Sstevel@tonic-gate 	    /* Shorter than original, will be padded. */
24830Sstevel@tonic-gate 	    Copy(s, PL_origargv[0], len, char);
24840Sstevel@tonic-gate 	    PL_origargv[0][len] = 0;
24850Sstevel@tonic-gate 	    memset(PL_origargv[0] + len + 1,
24860Sstevel@tonic-gate 		   /* Is the space counterintuitive?  Yes.
24870Sstevel@tonic-gate 		    * (You were expecting \0?)
24880Sstevel@tonic-gate 		    * Does it work?  Seems to.  (In Linux 2.4.20 at least.)
24890Sstevel@tonic-gate 		    * --jhi */
24900Sstevel@tonic-gate 		   (int)' ',
24910Sstevel@tonic-gate 		   PL_origalen - len - 1);
24920Sstevel@tonic-gate 	    for (i = 1; i < PL_origargc; i++)
24930Sstevel@tonic-gate 		 PL_origargv[i] = 0;
24940Sstevel@tonic-gate 	}
24950Sstevel@tonic-gate 	UNLOCK_DOLLARZERO_MUTEX;
24960Sstevel@tonic-gate 	break;
24970Sstevel@tonic-gate #endif
24980Sstevel@tonic-gate #ifdef USE_5005THREADS
24990Sstevel@tonic-gate     case '@':
25000Sstevel@tonic-gate 	sv_setsv(thr->errsv, sv);
25010Sstevel@tonic-gate 	break;
25020Sstevel@tonic-gate #endif /* USE_5005THREADS */
25030Sstevel@tonic-gate     }
25040Sstevel@tonic-gate     return 0;
25050Sstevel@tonic-gate }
25060Sstevel@tonic-gate 
25070Sstevel@tonic-gate #ifdef USE_5005THREADS
25080Sstevel@tonic-gate int
Perl_magic_mutexfree(pTHX_ SV * sv,MAGIC * mg)25090Sstevel@tonic-gate Perl_magic_mutexfree(pTHX_ SV *sv, MAGIC *mg)
25100Sstevel@tonic-gate {
25110Sstevel@tonic-gate     DEBUG_S(PerlIO_printf(Perl_debug_log,
25120Sstevel@tonic-gate 			  "0x%"UVxf": magic_mutexfree 0x%"UVxf"\n",
25130Sstevel@tonic-gate 			  PTR2UV(thr), PTR2UV(sv)));
25140Sstevel@tonic-gate     if (MgOWNER(mg))
25150Sstevel@tonic-gate 	Perl_croak(aTHX_ "panic: magic_mutexfree");
25160Sstevel@tonic-gate     MUTEX_DESTROY(MgMUTEXP(mg));
25170Sstevel@tonic-gate     COND_DESTROY(MgCONDP(mg));
25180Sstevel@tonic-gate     return 0;
25190Sstevel@tonic-gate }
25200Sstevel@tonic-gate #endif /* USE_5005THREADS */
25210Sstevel@tonic-gate 
25220Sstevel@tonic-gate I32
Perl_whichsig(pTHX_ char * sig)25230Sstevel@tonic-gate Perl_whichsig(pTHX_ char *sig)
25240Sstevel@tonic-gate {
25250Sstevel@tonic-gate     register char **sigv;
25260Sstevel@tonic-gate 
25270Sstevel@tonic-gate     for (sigv = PL_sig_name; *sigv; sigv++)
25280Sstevel@tonic-gate 	if (strEQ(sig,*sigv))
25290Sstevel@tonic-gate 	    return PL_sig_num[sigv - PL_sig_name];
25300Sstevel@tonic-gate #ifdef SIGCLD
25310Sstevel@tonic-gate     if (strEQ(sig,"CHLD"))
25320Sstevel@tonic-gate 	return SIGCLD;
25330Sstevel@tonic-gate #endif
25340Sstevel@tonic-gate #ifdef SIGCHLD
25350Sstevel@tonic-gate     if (strEQ(sig,"CLD"))
25360Sstevel@tonic-gate 	return SIGCHLD;
25370Sstevel@tonic-gate #endif
25380Sstevel@tonic-gate     return -1;
25390Sstevel@tonic-gate }
25400Sstevel@tonic-gate 
25410Sstevel@tonic-gate #if !defined(PERL_IMPLICIT_CONTEXT)
25420Sstevel@tonic-gate static SV* sig_sv;
25430Sstevel@tonic-gate #endif
25440Sstevel@tonic-gate 
25450Sstevel@tonic-gate Signal_t
Perl_sighandler(int sig)25460Sstevel@tonic-gate Perl_sighandler(int sig)
25470Sstevel@tonic-gate {
25480Sstevel@tonic-gate #ifdef PERL_GET_SIG_CONTEXT
25490Sstevel@tonic-gate     dTHXa(PERL_GET_SIG_CONTEXT);
25500Sstevel@tonic-gate #else
25510Sstevel@tonic-gate     dTHX;
25520Sstevel@tonic-gate #endif
25530Sstevel@tonic-gate     dSP;
25540Sstevel@tonic-gate     GV *gv = Nullgv;
25550Sstevel@tonic-gate     HV *st;
25560Sstevel@tonic-gate     SV *sv = Nullsv, *tSv = PL_Sv;
25570Sstevel@tonic-gate     CV *cv = Nullcv;
25580Sstevel@tonic-gate     OP *myop = PL_op;
25590Sstevel@tonic-gate     U32 flags = 0;
25600Sstevel@tonic-gate     XPV *tXpv = PL_Xpv;
25610Sstevel@tonic-gate 
25620Sstevel@tonic-gate     if (PL_savestack_ix + 15 <= PL_savestack_max)
25630Sstevel@tonic-gate 	flags |= 1;
25640Sstevel@tonic-gate     if (PL_markstack_ptr < PL_markstack_max - 2)
25650Sstevel@tonic-gate 	flags |= 4;
25660Sstevel@tonic-gate     if (PL_retstack_ix < PL_retstack_max - 2)
25670Sstevel@tonic-gate 	flags |= 8;
25680Sstevel@tonic-gate     if (PL_scopestack_ix < PL_scopestack_max - 3)
25690Sstevel@tonic-gate 	flags |= 16;
25700Sstevel@tonic-gate 
25710Sstevel@tonic-gate     if (!PL_psig_ptr[sig]) {
25720Sstevel@tonic-gate 		PerlIO_printf(Perl_error_log, "Signal SIG%s received, but no signal handler set.\n",
25730Sstevel@tonic-gate 				 PL_sig_name[sig]);
25740Sstevel@tonic-gate 		exit(sig);
25750Sstevel@tonic-gate 	}
25760Sstevel@tonic-gate 
25770Sstevel@tonic-gate     /* Max number of items pushed there is 3*n or 4. We cannot fix
25780Sstevel@tonic-gate        infinity, so we fix 4 (in fact 5): */
25790Sstevel@tonic-gate     if (flags & 1) {
25800Sstevel@tonic-gate 	PL_savestack_ix += 5;		/* Protect save in progress. */
25810Sstevel@tonic-gate 	SAVEDESTRUCTOR_X(unwind_handler_stack, (void*)&flags);
25820Sstevel@tonic-gate     }
25830Sstevel@tonic-gate     if (flags & 4)
25840Sstevel@tonic-gate 	PL_markstack_ptr++;		/* Protect mark. */
25850Sstevel@tonic-gate     if (flags & 8) {
25860Sstevel@tonic-gate 	PL_retstack_ix++;
25870Sstevel@tonic-gate 	PL_retstack[PL_retstack_ix] = NULL;
25880Sstevel@tonic-gate     }
25890Sstevel@tonic-gate     if (flags & 16)
25900Sstevel@tonic-gate 	PL_scopestack_ix += 1;
25910Sstevel@tonic-gate     /* sv_2cv is too complicated, try a simpler variant first: */
25920Sstevel@tonic-gate     if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig]))
25930Sstevel@tonic-gate 	|| SvTYPE(cv) != SVt_PVCV)
25940Sstevel@tonic-gate 	cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE);
25950Sstevel@tonic-gate 
25960Sstevel@tonic-gate     if (!cv || !CvROOT(cv)) {
25970Sstevel@tonic-gate 	if (ckWARN(WARN_SIGNAL))
25980Sstevel@tonic-gate 	    Perl_warner(aTHX_ packWARN(WARN_SIGNAL), "SIG%s handler \"%s\" not defined.\n",
25990Sstevel@tonic-gate 		PL_sig_name[sig], (gv ? GvENAME(gv)
26000Sstevel@tonic-gate 				: ((cv && CvGV(cv))
26010Sstevel@tonic-gate 				   ? GvENAME(CvGV(cv))
26020Sstevel@tonic-gate 				   : "__ANON__")));
26030Sstevel@tonic-gate 	goto cleanup;
26040Sstevel@tonic-gate     }
26050Sstevel@tonic-gate 
26060Sstevel@tonic-gate     if(PL_psig_name[sig]) {
26070Sstevel@tonic-gate     	sv = SvREFCNT_inc(PL_psig_name[sig]);
26080Sstevel@tonic-gate 	flags |= 64;
26090Sstevel@tonic-gate #if !defined(PERL_IMPLICIT_CONTEXT)
26100Sstevel@tonic-gate 	sig_sv = sv;
26110Sstevel@tonic-gate #endif
26120Sstevel@tonic-gate     } else {
26130Sstevel@tonic-gate 	sv = sv_newmortal();
26140Sstevel@tonic-gate 	sv_setpv(sv,PL_sig_name[sig]);
26150Sstevel@tonic-gate     }
26160Sstevel@tonic-gate 
26170Sstevel@tonic-gate     PUSHSTACKi(PERLSI_SIGNAL);
26180Sstevel@tonic-gate     PUSHMARK(SP);
26190Sstevel@tonic-gate     PUSHs(sv);
26200Sstevel@tonic-gate     PUTBACK;
26210Sstevel@tonic-gate 
26220Sstevel@tonic-gate     call_sv((SV*)cv, G_DISCARD|G_EVAL);
26230Sstevel@tonic-gate 
26240Sstevel@tonic-gate     POPSTACK;
26250Sstevel@tonic-gate     if (SvTRUE(ERRSV)) {
26260Sstevel@tonic-gate #ifndef PERL_MICRO
26270Sstevel@tonic-gate #ifdef HAS_SIGPROCMASK
26280Sstevel@tonic-gate 	/* Handler "died", for example to get out of a restart-able read().
26290Sstevel@tonic-gate 	 * Before we re-do that on its behalf re-enable the signal which was
26300Sstevel@tonic-gate 	 * blocked by the system when we entered.
26310Sstevel@tonic-gate 	 */
26320Sstevel@tonic-gate 	sigset_t set;
26330Sstevel@tonic-gate 	sigemptyset(&set);
26340Sstevel@tonic-gate 	sigaddset(&set,sig);
26350Sstevel@tonic-gate 	sigprocmask(SIG_UNBLOCK, &set, NULL);
26360Sstevel@tonic-gate #else
26370Sstevel@tonic-gate 	/* Not clear if this will work */
26380Sstevel@tonic-gate 	(void)rsignal(sig, SIG_IGN);
26390Sstevel@tonic-gate 	(void)rsignal(sig, PL_csighandlerp);
26400Sstevel@tonic-gate #endif
26410Sstevel@tonic-gate #endif /* !PERL_MICRO */
26420Sstevel@tonic-gate 	Perl_die(aTHX_ Nullformat);
26430Sstevel@tonic-gate     }
26440Sstevel@tonic-gate cleanup:
26450Sstevel@tonic-gate     if (flags & 1)
26460Sstevel@tonic-gate 	PL_savestack_ix -= 8; /* Unprotect save in progress. */
26470Sstevel@tonic-gate     if (flags & 4)
26480Sstevel@tonic-gate 	PL_markstack_ptr--;
26490Sstevel@tonic-gate     if (flags & 8)
26500Sstevel@tonic-gate 	PL_retstack_ix--;
26510Sstevel@tonic-gate     if (flags & 16)
26520Sstevel@tonic-gate 	PL_scopestack_ix -= 1;
26530Sstevel@tonic-gate     if (flags & 64)
26540Sstevel@tonic-gate 	SvREFCNT_dec(sv);
26550Sstevel@tonic-gate     PL_op = myop;			/* Apparently not needed... */
26560Sstevel@tonic-gate 
26570Sstevel@tonic-gate     PL_Sv = tSv;			/* Restore global temporaries. */
26580Sstevel@tonic-gate     PL_Xpv = tXpv;
26590Sstevel@tonic-gate     return;
26600Sstevel@tonic-gate }
26610Sstevel@tonic-gate 
26620Sstevel@tonic-gate 
26630Sstevel@tonic-gate static void
restore_magic(pTHX_ void * p)26640Sstevel@tonic-gate restore_magic(pTHX_ void *p)
26650Sstevel@tonic-gate {
26660Sstevel@tonic-gate     MGS* mgs = SSPTR(PTR2IV(p), MGS*);
26670Sstevel@tonic-gate     SV* sv = mgs->mgs_sv;
26680Sstevel@tonic-gate 
26690Sstevel@tonic-gate     if (!sv)
26700Sstevel@tonic-gate         return;
26710Sstevel@tonic-gate 
26720Sstevel@tonic-gate     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
26730Sstevel@tonic-gate     {
26740Sstevel@tonic-gate 	if (mgs->mgs_flags)
26750Sstevel@tonic-gate 	    SvFLAGS(sv) |= mgs->mgs_flags;
26760Sstevel@tonic-gate 	else
26770Sstevel@tonic-gate 	    mg_magical(sv);
26780Sstevel@tonic-gate 	if (SvGMAGICAL(sv))
26790Sstevel@tonic-gate 	    SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
26800Sstevel@tonic-gate     }
26810Sstevel@tonic-gate 
26820Sstevel@tonic-gate     mgs->mgs_sv = NULL;  /* mark the MGS structure as restored */
26830Sstevel@tonic-gate 
26840Sstevel@tonic-gate     /* If we're still on top of the stack, pop us off.  (That condition
26850Sstevel@tonic-gate      * will be satisfied if restore_magic was called explicitly, but *not*
26860Sstevel@tonic-gate      * if it's being called via leave_scope.)
26870Sstevel@tonic-gate      * The reason for doing this is that otherwise, things like sv_2cv()
26880Sstevel@tonic-gate      * may leave alloc gunk on the savestack, and some code
26890Sstevel@tonic-gate      * (e.g. sighandler) doesn't expect that...
26900Sstevel@tonic-gate      */
26910Sstevel@tonic-gate     if (PL_savestack_ix == mgs->mgs_ss_ix)
26920Sstevel@tonic-gate     {
26930Sstevel@tonic-gate 	I32 popval = SSPOPINT;
26940Sstevel@tonic-gate         assert(popval == SAVEt_DESTRUCTOR_X);
26950Sstevel@tonic-gate         PL_savestack_ix -= 2;
26960Sstevel@tonic-gate 	popval = SSPOPINT;
26970Sstevel@tonic-gate         assert(popval == SAVEt_ALLOC);
26980Sstevel@tonic-gate 	popval = SSPOPINT;
26990Sstevel@tonic-gate         PL_savestack_ix -= popval;
27000Sstevel@tonic-gate     }
27010Sstevel@tonic-gate 
27020Sstevel@tonic-gate }
27030Sstevel@tonic-gate 
27040Sstevel@tonic-gate static void
unwind_handler_stack(pTHX_ void * p)27050Sstevel@tonic-gate unwind_handler_stack(pTHX_ void *p)
27060Sstevel@tonic-gate {
27070Sstevel@tonic-gate     U32 flags = *(U32*)p;
27080Sstevel@tonic-gate 
27090Sstevel@tonic-gate     if (flags & 1)
27100Sstevel@tonic-gate 	PL_savestack_ix -= 5; /* Unprotect save in progress. */
27110Sstevel@tonic-gate     /* cxstack_ix-- Not needed, die already unwound it. */
27120Sstevel@tonic-gate #if !defined(PERL_IMPLICIT_CONTEXT)
27130Sstevel@tonic-gate     if (flags & 64)
27140Sstevel@tonic-gate 	SvREFCNT_dec(sig_sv);
27150Sstevel@tonic-gate #endif
27160Sstevel@tonic-gate }
27170Sstevel@tonic-gate 
27180Sstevel@tonic-gate 
2719