# include <sys/pstat.h>
#endif
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+Signal_t Perl_csighandler(int sig, ...);
+#else
Signal_t Perl_csighandler(int sig);
-
-static void restore_magic(pTHX_ const void *p);
-static void unwind_handler_stack(pTHX_ const void *p);
+#endif
#ifdef __Lynx__
/* Missing protos on LynxOS */
sv_force_normal(sv);
#endif
- SAVEDESTRUCTOR_X(restore_magic, INT2PTR(void*, (IV)mgs_ix));
+ SAVEDESTRUCTOR_X(S_restore_magic, INT2PTR(void*, (IV)mgs_ix));
mgs = SSPTR(mgs_ix, MGS*);
mgs->mgs_sv = sv;
}
}
- restore_magic(aTHX_ INT2PTR(void *, (IV)mgs_ix));
+ restore_magic(INT2PTR(void *, (IV)mgs_ix));
if (SvREFCNT(sv) == 1) {
/* We hold the last reference to this SV, which implies that the
CALL_FPTR(vtbl->svt_set)(aTHX_ sv, mg);
}
- restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
+ restore_magic(INT2PTR(void*, (IV)mgs_ix));
return 0;
}
save_magic(mgs_ix, sv);
/* omit MGf_GSKIP -- not changed here */
len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
- restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
+ restore_magic(INT2PTR(void*, (IV)mgs_ix));
return len;
}
}
save_magic(mgs_ix, sv);
/* omit MGf_GSKIP -- not changed here */
len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
- restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
+ restore_magic(INT2PTR(void*, (IV)mgs_ix));
return len;
}
}
CALL_FPTR(vtbl->svt_clear)(aTHX_ sv, mg);
}
- restore_magic(aTHX_ INT2PTR(void*, (IV)mgs_ix));
+ restore_magic(INT2PTR(void*, (IV)mgs_ix));
return 0;
}
}
/*
+=for apidoc mg_localize
+
+Copy some of the magic from an existing SV to new localized version of
+that SV. Container magic (eg %ENV, $1, tie) gets copied, value magic
+doesn't (eg taint, pos).
+
+=cut
+*/
+
+void
+Perl_mg_localize(pTHX_ SV *sv, SV *nsv)
+{
+ MAGIC *mg;
+ for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
+ const MGVTBL* const vtbl = mg->mg_virtual;
+ switch (mg->mg_type) {
+ /* value magic types: don't copy */
+ case PERL_MAGIC_bm:
+ case PERL_MAGIC_fm:
+ case PERL_MAGIC_regex_global:
+ case PERL_MAGIC_nkeys:
+#ifdef USE_LOCALE_COLLATE
+ case PERL_MAGIC_collxfrm:
+#endif
+ case PERL_MAGIC_qr:
+ case PERL_MAGIC_taint:
+ case PERL_MAGIC_vec:
+ case PERL_MAGIC_vstring:
+ case PERL_MAGIC_utf8:
+ case PERL_MAGIC_substr:
+ case PERL_MAGIC_defelem:
+ case PERL_MAGIC_arylen:
+ case PERL_MAGIC_pos:
+ case PERL_MAGIC_backref:
+ case PERL_MAGIC_arylen_p:
+ case PERL_MAGIC_rhash:
+ case PERL_MAGIC_symtab:
+ continue;
+ }
+
+ if ((mg->mg_flags & MGf_COPY) && vtbl->svt_copy) {
+ /* XXX calling the copy method is probably not correct. DAPM */
+ (void)CALL_FPTR(vtbl->svt_copy)(aTHX_ sv, mg, nsv,
+ mg->mg_ptr, mg->mg_len);
+ }
+ else {
+ sv_magicext(nsv, mg->mg_obj, mg->mg_type, vtbl,
+ mg->mg_ptr, mg->mg_len);
+ }
+ /* container types should remain read-only across localization */
+ SvFLAGS(nsv) |= SvREADONLY(sv);
+ }
+
+ if (SvTYPE(nsv) >= SVt_PVMG && SvMAGIC(nsv)) {
+ SvFLAGS(nsv) |= SvMAGICAL(sv);
+ PL_localizing = 1;
+ SvSETMAGIC(nsv);
+ PL_localizing = 0;
+ }
+}
+
+/*
=for apidoc mg_free
Free any magic storage used by the SV. See C<sv_magic>.
Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
{
register const REGEXP *rx;
- (void)sv;
+ PERL_UNUSED_ARG(sv);
if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
if (mg->mg_obj) /* @+ */
i = s;
if (i > 0 && RX_MATCH_UTF8(rx)) {
- char *b = rx->subbeg;
+ const char * const b = rx->subbeg;
if (b)
i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i));
}
int
Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg)
{
- (void)sv; (void)mg;
+ PERL_UNUSED_ARG(sv); PERL_UNUSED_ARG(mg);
Perl_croak(aTHX_ PL_no_modify);
NORETURN_FUNCTION_END;
}
}
#else
{
- int saveerrno = errno;
+ const int saveerrno = errno;
sv_setnv(sv, (NV)errno);
sv_setpv(sv, errno ? Strerror(errno) : "");
errno = saveerrno;
sv_setpv(sv, errno ? Strerror(errno) : "");
#else
{
- int saveerrno = errno;
+ const int saveerrno = errno;
sv_setnv(sv, (NV)errno);
#ifdef OS2
if (errno == errno_isOS2 || errno == errno_isOS2_set)
int
Perl_magic_getuvar(pTHX_ SV *sv, MAGIC *mg)
{
- struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
+ struct ufuncs * const uf = (struct ufuncs *)mg->mg_ptr;
if (uf && uf->uf_val)
(*uf->uf_val)(aTHX_ uf->uf_index, sv);
MgTAINTEDDIR_off(mg);
#ifdef VMS
if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
- char pathbuf[256], eltbuf[256], *cp, *elt = s;
+ char pathbuf[256], eltbuf[256], *cp, *elt;
Stat_t sbuf;
int i = 0, j = 0;
+ strncpy(eltbuf, s, 255);
+ eltbuf[255] = 0;
+ elt = eltbuf;
do { /* DCL$PATH may be a search list */
while (1) { /* as may dev portion of any element */
if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
}
#endif /* VMS */
if (s && klen == 4 && strEQ(ptr,"PATH")) {
- const char *strend = s + len;
+ const char * const strend = s + len;
while (s < strend) {
char tmpbuf[256];
int
Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
{
- (void)sv;
+ PERL_UNUSED_ARG(sv);
my_setenv(MgPV_nolen_const(mg),Nullch);
return 0;
}
# endif /* PERL_IMPLICIT_SYS || WIN32 */
#endif /* VMS || EPOC */
#endif /* !PERL_MICRO */
- (void)sv;
- (void)mg;
+ PERL_UNUSED_ARG(sv);
+ PERL_UNUSED_ARG(mg);
return 0;
}
int
Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
{
- I32 i;
/* Are we fetching a signal entry? */
- i = whichsig(MgPV_nolen_const(mg));
+ const I32 i = whichsig(MgPV_nolen_const(mg));
if (i > 0) {
if(PL_psig_ptr[i])
sv_setsv(sv,PL_psig_ptr[i]);
if (PL_sig_handlers_initted && PL_sig_defaulting[i]) sigstate = SIG_DFL;
#endif
/* cache state so we don't fetch it again */
- if(sigstate == SIG_IGN)
+ if(sigstate == (Sighandler_t) SIG_IGN)
sv_setpv(sv,"IGNORE");
else
sv_setsv(sv,&PL_sv_undef);
* refactoring might be in order.
*/
dVAR;
- register const char *s = MgPV_nolen_const(mg);
- (void)sv;
+ register const char * const s = MgPV_nolen_const(mg);
+ PERL_UNUSED_ARG(sv);
if (*s == '_') {
SV** svp = 0;
if (strEQ(s,"__DIE__"))
else
Perl_croak(aTHX_ "No such hook: %s", s);
if (svp && *svp) {
- SV *to_dec = *svp;
+ SV * const to_dec = *svp;
*svp = 0;
SvREFCNT_dec(to_dec);
}
}
else {
- I32 i;
/* Are we clearing a signal entry? */
- i = whichsig(s);
+ const I32 i = whichsig(s);
if (i > 0) {
#ifdef HAS_SIGPROCMASK
sigset_t set, save;
PL_sig_defaulting[i] = 1;
(void)rsignal(i, PL_csighandlerp);
#else
- (void)rsignal(i, SIG_DFL);
+ (void)rsignal(i, (Sighandler_t) SIG_DFL);
#endif
if(PL_psig_name[i]) {
SvREFCNT_dec(PL_psig_name[i]);
}
Signal_t
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+Perl_csighandler(int sig, ...)
+#else
Perl_csighandler(int sig)
+#endif
{
#ifdef PERL_GET_SIG_CONTEXT
dTHXa(PERL_GET_SIG_CONTEXT);
PL_sig_ignoring[i] = 1;
(void)rsignal(i, PL_csighandlerp);
#else
- (void)rsignal(i, SIG_IGN);
+ (void)rsignal(i, (Sighandler_t) SIG_IGN);
#endif
}
}
(void)rsignal(i, PL_csighandlerp);
}
#else
- (void)rsignal(i, SIG_DFL);
+ (void)rsignal(i, (Sighandler_t) SIG_DFL);
#endif
}
else {
int
Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
{
- (void)sv;
- (void)mg;
+ PERL_UNUSED_ARG(sv);
+ PERL_UNUSED_ARG(mg);
PL_sub_generation++;
return 0;
}
int
Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
{
- (void)sv;
- (void)mg;
+ PERL_UNUSED_ARG(sv);
+ PERL_UNUSED_ARG(mg);
/* HV_badAMAGIC_on(Sv_STASH(sv)); */
PL_amagic_generation++;
{
HV * const hv = (HV*)LvTARG(sv);
I32 i = 0;
- (void)mg;
+ PERL_UNUSED_ARG(mg);
if (hv) {
(void) hv_iterinit(hv);
int
Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
{
- (void)mg;
+ PERL_UNUSED_ARG(mg);
if (LvTARG(sv)) {
hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
}
{
dVAR; dSP;
SV *retval = &PL_sv_undef;
- SV *tied = SvTIED_obj((SV*)hv, mg);
- HV *pkg = SvSTASH((SV*)SvRV(tied));
+ SV * const tied = SvTIED_obj((SV*)hv, mg);
+ HV * const pkg = SvSTASH((SV*)SvRV(tied));
if (!gv_fetchmethod_autoload(pkg, "SCALAR", FALSE)) {
SV *key;
int
Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
{
- OP *o;
- I32 i;
- GV* gv;
- SV** svp;
-
- gv = PL_DBline;
- i = SvTRUE(sv);
- svp = av_fetch(GvAV(gv),
+ GV * const gv = PL_DBline;
+ const I32 i = SvTRUE(sv);
+ SV ** const svp = av_fetch(GvAV(gv),
atoi(MgPV_nolen_const(mg)), FALSE);
- if (svp && SvIOKp(*svp) && (o = INT2PTR(OP*,SvIVX(*svp)))) {
- /* set or clear breakpoint in the relevant control op */
- if (i)
- o->op_flags |= OPf_SPECIAL;
- else
- o->op_flags &= ~OPf_SPECIAL;
+ if (svp && SvIOKp(*svp)) {
+ OP * const o = INT2PTR(OP*,SvIVX(*svp));
+ if (o) {
+ /* set or clear breakpoint in the relevant control op */
+ if (i)
+ o->op_flags |= OPf_SPECIAL;
+ else
+ o->op_flags &= ~OPf_SPECIAL;
+ }
}
return 0;
}
int
-Perl_magic_getarylen(pTHX_ SV *sv, MAGIC *mg)
+Perl_magic_getarylen(pTHX_ SV *sv, const MAGIC *mg)
{
- AV *obj = (AV*)mg->mg_obj;
+ const AV * const obj = (AV*)mg->mg_obj;
if (obj) {
sv_setiv(sv, AvFILL(obj) + PL_curcop->cop_arybase);
} else {
int
Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
{
- AV *obj = (AV*)mg->mg_obj;
+ AV * const obj = (AV*)mg->mg_obj;
if (obj) {
av_fill(obj, SvIV(sv) - PL_curcop->cop_arybase);
} else {
int
Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
{
- SV* lsv = LvTARG(sv);
+ SV* const lsv = LvTARG(sv);
if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
mg = mg_find(lsv, PERL_MAGIC_regex_global);
int
Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
{
- SV* lsv = LvTARG(sv);
+ SV* const lsv = LvTARG(sv);
SSize_t pos;
STRLEN len;
STRLEN ulen = 0;
int
Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
{
- (void)mg;
+ PERL_UNUSED_ARG(mg);
if (SvFAKE(sv)) { /* FAKE globs can get coerced */
SvFAKE_off(sv);
gv_efullname3(sv,((GV*)sv), "*");
Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
{
GV* gv;
- (void)mg;
-
+ PERL_UNUSED_ARG(mg);
+
if (!SvOK(sv))
return 0;
gv = gv_fetchsv(sv,TRUE, SVt_PVGV);
const char * const tmps = SvPV_const(lsv,len);
I32 offs = LvTARGOFF(sv);
I32 rem = LvTARGLEN(sv);
- (void)mg;
+ PERL_UNUSED_ARG(mg);
if (SvUTF8(lsv))
sv_pos_u2b(lsv, &offs, &rem);
SV * const lsv = LvTARG(sv);
I32 lvoff = LvTARGOFF(sv);
I32 lvlen = LvTARGLEN(sv);
- (void)mg;
+ PERL_UNUSED_ARG(mg);
if (DO_UTF8(sv)) {
sv_utf8_upgrade(lsv);
int
Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
{
- TAINT_IF((mg->mg_len & 1) ||
- ((mg->mg_len & 2) && mg->mg_obj == sv)); /* kludge */
+ PERL_UNUSED_ARG(sv);
+ TAINT_IF((PL_localizing != 1) && (mg->mg_len & 1));
return 0;
}
int
Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
{
- (void)sv;
- if (PL_localizing) {
- if (PL_localizing == 1)
- mg->mg_len <<= 1;
+ PERL_UNUSED_ARG(sv);
+ /* update taint status unless we're restoring at scope exit */
+ if (PL_localizing != 2) {
+ if (PL_tainted)
+ mg->mg_len |= 1;
else
- mg->mg_len >>= 1;
+ mg->mg_len &= ~1;
}
- else if (PL_tainted)
- mg->mg_len |= 1;
- else
- mg->mg_len &= ~1;
return 0;
}
Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
{
SV * const lsv = LvTARG(sv);
- (void)mg;
+ PERL_UNUSED_ARG(mg);
if (!lsv) {
SvOK_off(sv);
int
Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
{
- (void)mg;
+ PERL_UNUSED_ARG(mg);
do_vecset(sv); /* XXX slurp this routine */
return 0;
}
SV *targ = Nullsv;
if (LvTARGLEN(sv)) {
if (mg->mg_obj) {
- SV *ahv = LvTARG(sv);
- HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
+ SV * const ahv = LvTARG(sv);
+ HE * const he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
if (he)
targ = HeVAL(he);
}
else {
- AV* av = (AV*)LvTARG(sv);
+ AV* const av = (AV*)LvTARG(sv);
if ((I32)LvTARGOFF(sv) <= AvFILL(av))
targ = AvARRAY(av)[LvTARGOFF(sv)];
}
int
Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
{
- (void)mg;
+ PERL_UNUSED_ARG(mg);
if (LvTARGLEN(sv))
vivify_defelem(sv);
if (LvTARG(sv)) {
if (!LvTARGLEN(sv) || !(mg = mg_find(sv, PERL_MAGIC_defelem)))
return;
if (mg->mg_obj) {
- SV *ahv = LvTARG(sv);
- HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
+ SV * const ahv = LvTARG(sv);
+ HE * const he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
if (he)
value = HeVAL(he);
if (!value || value == &PL_sv_undef)
Perl_croak(aTHX_ PL_no_helem_sv, mg->mg_obj);
}
else {
- AV* av = (AV*)LvTARG(sv);
+ AV* const av = (AV*)LvTARG(sv);
if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
LvTARG(sv) = Nullsv; /* array can't be extended */
else {
- SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
+ SV** const svp = av_fetch(av, LvTARGOFF(sv), TRUE);
if (!svp || (value = *svp) == &PL_sv_undef)
Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
}
int
Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
{
- AV *av = (AV*)mg->mg_obj;
+ AV *const av = (AV*)mg->mg_obj;
SV **svp = AvARRAY(av);
- I32 i = AvFILLp(av);
- (void)sv;
+ PERL_UNUSED_ARG(sv);
+
+ if (svp) {
+ SV *const *const last = svp + AvFILLp(av);
+
+ while (svp <= last) {
+ if (*svp) {
+ SV *const referrer = *svp;
+ if (SvWEAKREF(referrer)) {
+ /* XXX Should we check that it hasn't changed? */
+ SvRV_set(referrer, 0);
+ SvOK_off(referrer);
+ SvWEAKREF_off(referrer);
+ } else if (SvTYPE(referrer) == SVt_PVGV ||
+ SvTYPE(referrer) == SVt_PVLV) {
+ /* You lookin' at me? */
+ assert(GvSTASH(referrer));
+ assert(GvSTASH(referrer) == (HV*)sv);
+ GvSTASH(referrer) = 0;
+ } else {
+ Perl_croak(aTHX_
+ "panic: magic_killbackrefs (flags=%"UVxf")",
+ (UV)SvFLAGS(referrer));
+ }
- while (i >= 0) {
- if (svp[i]) {
- if (!SvWEAKREF(svp[i]))
- Perl_croak(aTHX_ "panic: magic_killbackrefs");
- /* XXX Should we check that it hasn't changed? */
- SvRV_set(svp[i], 0);
- SvOK_off(svp[i]);
- SvWEAKREF_off(svp[i]);
- svp[i] = Nullsv;
+ *svp = Nullsv;
+ }
+ svp++;
}
- i--;
}
SvREFCNT_dec(av); /* remove extra count added by sv_add_backref() */
return 0;
int
Perl_magic_setbm(pTHX_ SV *sv, MAGIC *mg)
{
- (void)mg;
+ PERL_UNUSED_ARG(mg);
sv_unmagic(sv, PERL_MAGIC_bm);
SvVALID_off(sv);
return 0;
int
Perl_magic_setfm(pTHX_ SV *sv, MAGIC *mg)
{
- (void)mg;
+ PERL_UNUSED_ARG(mg);
sv_unmagic(sv, PERL_MAGIC_fm);
SvCOMPILED_off(sv);
return 0;
int
Perl_magic_setregexp(pTHX_ SV *sv, MAGIC *mg)
{
- (void)mg;
+ PERL_UNUSED_ARG(mg);
sv_unmagic(sv, PERL_MAGIC_qr);
return 0;
}
int
Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
{
- regexp *re = (regexp *)mg->mg_obj;
+ regexp * const re = (regexp *)mg->mg_obj;
+ PERL_UNUSED_ARG(sv);
+
ReREFCNT_dec(re);
- (void)sv;
return 0;
}
* RenE<eacute> Descartes said "I think not."
* and vanished with a faint plop.
*/
- (void)sv;
+ PERL_UNUSED_ARG(sv);
if (mg->mg_ptr) {
Safefree(mg->mg_ptr);
mg->mg_ptr = NULL;
int
Perl_magic_setutf8(pTHX_ SV *sv, MAGIC *mg)
{
- (void)sv;
+ PERL_UNUSED_ARG(sv);
Safefree(mg->mg_ptr); /* The mg_ptr holds the pos cache. */
mg->mg_ptr = 0;
mg->mg_len = -1; /* The mg_len holds the len cache. */
PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
break;
case '\011': /* ^I */ /* NOT \t in EBCDIC */
- if (PL_inplace)
- Safefree(PL_inplace);
- if (SvOK(sv))
- PL_inplace = savesvpv(sv);
- else
- PL_inplace = Nullch;
+ Safefree(PL_inplace);
+ PL_inplace = SvOK(sv) ? savesvpv(sv) : Nullch;
break;
case '\017': /* ^O */
if (*(mg->mg_ptr+1) == '\0') {
- if (PL_osname) {
- Safefree(PL_osname);
- PL_osname = Nullch;
- }
+ Safefree(PL_osname);
+ PL_osname = Nullch;
if (SvOK(sv)) {
TAINT_PROPER("assigning to $^O");
PL_osname = savesvpv(sv);
break;
case '|':
{
- IO *io = GvIOp(PL_defoutgv);
+ IO * const io = GvIOp(PL_defoutgv);
if(!io)
break;
if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
}
Signal_t
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+Perl_sighandler(int sig, ...)
+#else
Perl_sighandler(int sig)
+#endif
{
#ifdef PERL_GET_SIG_CONTEXT
dTHXa(PERL_GET_SIG_CONTEXT);
#endif
dSP;
GV *gv = Nullgv;
- HV *st;
- SV *sv = Nullsv, *tSv = PL_Sv;
+ SV *sv = Nullsv;
+ SV * const tSv = PL_Sv;
CV *cv = Nullcv;
OP *myop = PL_op;
U32 flags = 0;
- XPV *tXpv = PL_Xpv;
+ XPV * const tXpv = PL_Xpv;
if (PL_savestack_ix + 15 <= PL_savestack_max)
flags |= 1;
infinity, so we fix 4 (in fact 5): */
if (flags & 1) {
PL_savestack_ix += 5; /* Protect save in progress. */
- SAVEDESTRUCTOR_X(unwind_handler_stack, (void*)&flags);
+ SAVEDESTRUCTOR_X(S_unwind_handler_stack, (void*)&flags);
}
if (flags & 4)
PL_markstack_ptr++; /* Protect mark. */
PL_scopestack_ix += 1;
/* sv_2cv is too complicated, try a simpler variant first: */
if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig]))
- || SvTYPE(cv) != SVt_PVCV)
+ || SvTYPE(cv) != SVt_PVCV) {
+ HV *st;
cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE);
+ }
if (!cv || !CvROOT(cv)) {
if (ckWARN(WARN_SIGNAL))
PUSHSTACKi(PERLSI_SIGNAL);
PUSHMARK(SP);
PUSHs(sv);
+#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
+ {
+ struct sigaction oact;
+
+ if (sigaction(sig, 0, &oact) == 0 && oact.sa_flags & SA_SIGINFO) {
+ siginfo_t *sip;
+ va_list args;
+
+ va_start(args, sig);
+ sip = (siginfo_t*)va_arg(args, siginfo_t*);
+ if (sip) {
+ HV *sih = newHV();
+ SV *rv = newRV_noinc((SV*)sih);
+ /* The siginfo fields signo, code, errno, pid, uid,
+ * addr, status, and band are defined by POSIX/SUSv3. */
+ hv_store(sih, "signo", 5, newSViv(sip->si_signo), 0);
+ hv_store(sih, "code", 4, newSViv(sip->si_code), 0);
+#if 0 /* XXX TODO: Configure scan for the existence of these, but even that does not help if the SA_SIGINFO is not implemented according to the spec. */
+ hv_store(sih, "errno", 5, newSViv(sip->si_errno), 0);
+ hv_store(sih, "status", 6, newSViv(sip->si_status), 0);
+ hv_store(sih, "uid", 3, newSViv(sip->si_uid), 0);
+ hv_store(sih, "pid", 3, newSViv(sip->si_pid), 0);
+ hv_store(sih, "addr", 4, newSVuv(PTR2UV(sip->si_addr)), 0);
+ hv_store(sih, "band", 4, newSViv(sip->si_band), 0);
+#endif
+ EXTEND(SP, 2);
+ PUSHs((SV*)rv);
+ PUSHs(newSVpv((void*)sip, sizeof(*sip)));
+ }
+ }
+ }
+#endif
PUTBACK;
call_sv((SV*)cv, G_DISCARD|G_EVAL);
(void)rsignal(sig, PL_csighandlerp);
#endif
#endif /* !PERL_MICRO */
- DieNull;
+ Perl_die(aTHX_ Nullch);
}
cleanup:
if (flags & 1)
static void
-restore_magic(pTHX_ const void *p)
+S_restore_magic(pTHX_ const void *p)
{
- MGS* mgs = SSPTR(PTR2IV(p), MGS*);
- SV* sv = mgs->mgs_sv;
+ MGS* const mgs = SSPTR(PTR2IV(p), MGS*);
+ SV* const sv = mgs->mgs_sv;
if (!sv)
return;
SvFLAGS(sv) |= mgs->mgs_flags;
else
mg_magical(sv);
- if (SvGMAGICAL(sv))
- SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
+ if (SvGMAGICAL(sv)) {
+ /* downgrade public flags to private,
+ and discard any other private flags */
+
+ U32 public = SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK);
+ if (public) {
+ SvFLAGS(sv) &= ~( public | SVp_IOK|SVp_NOK|SVp_POK );
+ SvFLAGS(sv) |= ( public << PRIVSHIFT );
+ }
+ }
}
mgs->mgs_sv = NULL; /* mark the MGS structure as restored */
}
static void
-unwind_handler_stack(pTHX_ const void *p)
+S_unwind_handler_stack(pTHX_ const void *p)
{
dVAR;
const U32 flags = *(const U32*)p;