static void restore_magic(pTHX_ void *p);
static void unwind_handler_stack(pTHX_ void *p);
+#ifdef __Lynx__
+/* Missing protos on LynxOS */
+void setruid(uid_t id);
+void seteuid(uid_t id);
+void setrgid(uid_t id);
+void setegid(uid_t id);
+#endif
+
/*
* Use the "DESTRUCTOR" scope cleanup to reinstate magic.
*/
if (SvTYPE(sv) == SVTYPEMASK) {
Perl_croak(aTHX_ "Tied variable freed while still in use");
}
+ /* guard against magic having been deleted - eg FETCH calling
+ * untie */
+ if (!SvMAGIC(sv))
+ break;
/* Don't restore the flags for this entry if it was deleted. */
if (mg->mg_flags & MGf_GSKIP)
if (vtbl && vtbl->svt_free)
CALL_FPTR(vtbl->svt_free)(aTHX_ sv, mg);
if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) {
- if (mg->mg_len > 0)
+ if (mg->mg_len > 0 || mg->mg_type == PERL_MAGIC_utf8)
Safefree(mg->mg_ptr);
else if (mg->mg_len == HEf_SVKEY)
SvREFCNT_dec((SV*)mg->mg_ptr);
return 0;
}
-
-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
#include <signal.h>
-#endif
U32
Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
{
register I32 paren;
- register char *s;
+ register char *s = NULL;
register I32 i;
register REGEXP *rx;
SetLastError(dwErr);
}
#else
- sv_setnv(sv, (NV)errno);
- sv_setpv(sv, errno ? Strerror(errno) : "");
+ {
+ int saveerrno = errno;
+ sv_setnv(sv, (NV)errno);
+ sv_setpv(sv, errno ? Strerror(errno) : "");
+ errno = saveerrno;
+ }
#endif
#endif
#endif
sv_setsv(sv, &PL_sv_undef);
break;
case '\017': /* ^O & ^OPEN */
- if (*(mg->mg_ptr+1) == '\0')
+ if (*(mg->mg_ptr+1) == '\0') {
sv_setpv(sv, PL_osname);
+ SvTAINTED_off(sv);
+ }
else if (strEQ(mg->mg_ptr, "\017PEN")) {
if (!PL_compiling.cop_io)
sv_setsv(sv, &PL_sv_undef);
}
break;
case '^':
- s = IoTOP_NAME(GvIOp(PL_defoutgv));
+ if (GvIOp(PL_defoutgv))
+ s = IoTOP_NAME(GvIOp(PL_defoutgv));
if (s)
sv_setpv(sv,s);
else {
}
break;
case '~':
- s = IoFMT_NAME(GvIOp(PL_defoutgv));
+ if (GvIOp(PL_defoutgv))
+ s = IoFMT_NAME(GvIOp(PL_defoutgv));
if (!s)
s = GvENAME(PL_defoutgv);
sv_setpv(sv,s);
break;
#ifndef lint
case '=':
- sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
+ if (GvIOp(PL_defoutgv))
+ sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
break;
case '-':
- sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
+ if (GvIOp(PL_defoutgv))
+ sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
break;
case '%':
- sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
+ if (GvIOp(PL_defoutgv))
+ sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
break;
#endif
case ':':
WITH_THR(sv_setiv(sv, (IV)PL_curcop->cop_arybase));
break;
case '|':
- sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
+ if (GvIOp(PL_defoutgv))
+ sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
break;
case ',':
break;
int
Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg)
{
+#ifndef PERL_MICRO
#if defined(VMS) || defined(EPOC)
Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
#else
}
# endif /* USE_ENVIRON_ARRAY */
# endif /* PERL_IMPLICIT_SYS || WIN32 */
-#endif /* VMS || EPC */
+#endif /* VMS || EPOC */
+#endif /* !PERL_MICRO */
return 0;
}
#endif
#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
sig_defaulting[i] = 1;
- (void)rsignal(i, &Perl_csighandler);
+ (void)rsignal(i, PL_csighandlerp);
#else
(void)rsignal(i, SIG_DFL);
#endif
dTHX;
#endif
#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
- (void) rsignal(sig, &Perl_csighandler);
+ (void) rsignal(sig, PL_csighandlerp);
if (sig_ignoring[sig]) return;
#endif
#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
dTHX;
sig_defaulting[sig] = 1;
- (void) rsignal(sig, &Perl_csighandler);
+ (void) rsignal(sig, PL_csighandlerp);
#endif
#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
sig_ignoring[sig] = 0;
}
if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
if (i) {
- (void)rsignal(i, &Perl_csighandler);
+ (void)rsignal(i, PL_csighandlerp);
#ifdef HAS_SIGPROCMASK
LEAVE;
#endif
if (i) {
#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
sig_ignoring[i] = 1;
- (void)rsignal(i, &Perl_csighandler);
+ (void)rsignal(i, PL_csighandlerp);
#else
(void)rsignal(i, SIG_IGN);
#endif
#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
{
sig_defaulting[i] = 1;
- (void)rsignal(i, &Perl_csighandler);
+ (void)rsignal(i, PL_csighandlerp);
}
#else
(void)rsignal(i, SIG_DFL);
if (!strchr(s,':') && !strchr(s,'\''))
sv_insert(sv, 0, 0, "main::", 6);
if (i)
- (void)rsignal(i, &Perl_csighandler);
+ (void)rsignal(i, PL_csighandlerp);
else
*svp = SvREFCNT_inc(sv);
}
int
Perl_magic_getpack(pTHX_ SV *sv, MAGIC *mg)
{
- magic_methpack(sv,mg,"FETCH");
if (mg->mg_ptr)
mg->mg_flags |= MGf_GSKIP;
+ magic_methpack(sv,mg,"FETCH");
return 0;
}
call_method("CLEAR", G_SCALAR|G_DISCARD);
POPSTACK;
LEAVE;
+
return 0;
}
return magic_methpack(sv,mg,"EXISTS");
}
+SV *
+Perl_magic_scalarpack(pTHX_ HV *hv, MAGIC *mg)
+{
+ dSP;
+ SV *retval = &PL_sv_undef;
+ SV *tied = SvTIED_obj((SV*)hv, mg);
+ HV *pkg = SvSTASH((SV*)SvRV(tied));
+
+ if (!gv_fetchmethod_autoload(pkg, "SCALAR", FALSE)) {
+ SV *key;
+ if (HvEITER(hv))
+ /* we are in an iteration so the hash cannot be empty */
+ return &PL_sv_yes;
+ /* no xhv_eiter so now use FIRSTKEY */
+ key = sv_newmortal();
+ magic_nextpack((SV*)hv, mg, key);
+ HvEITER(hv) = NULL; /* need to reset iterator */
+ return SvOK(key) ? &PL_sv_yes : &PL_sv_no;
+ }
+
+ /* there is a SCALAR method that we can call */
+ ENTER;
+ PUSHSTACKi(PERLSI_MAGIC);
+ PUSHMARK(SP);
+ EXTEND(SP, 1);
+ PUSHs(tied);
+ PUTBACK;
+
+ if (call_method("SCALAR", G_SCALAR))
+ retval = *PL_stack_sp--;
+ POPSTACK;
+ LEAVE;
+ return retval;
+}
+
int
Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
{
SV **svp = AvARRAY(av);
I32 i = AvFILLp(av);
while (i >= 0) {
- if (svp[i] && svp[i] != &PL_sv_undef) {
+ if (svp[i]) {
if (!SvWEAKREF(svp[i]))
Perl_croak(aTHX_ "panic: magic_killbackrefs");
/* XXX Should we check that it hasn't changed? */
SvRV(svp[i]) = 0;
(void)SvOK_off(svp[i]);
SvWEAKREF_off(svp[i]);
- svp[i] = &PL_sv_undef;
+ svp[i] = Nullsv;
}
i--;
}
+ SvREFCNT_dec(av); /* remove extra count added by sv_add_backref() */
return 0;
}
break;
case '\017': /* ^O */
if (*(mg->mg_ptr+1) == '\0') {
- if (PL_osname)
+ if (PL_osname) {
Safefree(PL_osname);
- if (SvOK(sv))
- PL_osname = savepv(SvPV(sv,len));
- else
PL_osname = Nullch;
+ }
+ if (SvOK(sv)) {
+ TAINT_PROPER("assigning to $^O");
+ PL_osname = savepv(SvPV(sv,len));
+ }
}
else if (strEQ(mg->mg_ptr, "\017PEN")) {
if (!PL_compiling.cop_io)
break;
case '\020': /* ^P */
PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- if (PL_perldb && !PL_DBsingle)
+ if ((PERLDB_SUB || PERLDB_LINE || PERLDB_SUBLINE || PERLDB_ASSERTION)
+ && !PL_DBsingle)
init_debugger();
break;
case '\024': /* ^T */
#ifdef HAS_SETRESUID
(void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
#else
- if (PL_uid == PL_euid) /* special case $< = $> */
+ if (PL_uid == PL_euid) { /* special case $< = $> */
+#ifdef PERL_DARWIN
+ /* workaround for Darwin's setuid peculiarity, cf [perl #24122] */
+ if (PL_uid != 0 && PerlProc_getuid() == 0)
+ (void)PerlProc_setuid(0);
+#endif
(void)PerlProc_setuid(PL_uid);
- else {
+ } else {
PL_uid = PerlProc_getuid();
Perl_croak(aTHX_ "setruid() not implemented");
}
#endif
/* PL_origalen is set in perl_parse(). */
s = SvPV_force(sv,len);
- if (len >= (I32)PL_origalen) {
- /* Longer than original, will be truncated. */
- Copy(s, PL_origargv[0], PL_origalen, char);
- PL_origargv[0][PL_origalen - 1] = 0;
+ if (len >= (STRLEN)PL_origalen-1) {
+ /* Longer than original, will be truncated. We assume that
+ * PL_origalen bytes are available. */
+ Copy(s, PL_origargv[0], PL_origalen-1, char);
}
else {
/* Shorter than original, will be padded. */
* --jhi */
(int)' ',
PL_origalen - len - 1);
- for (i = 1; i < PL_origargc; i++)
- PL_origargv[i] = 0;
}
+ PL_origargv[0][PL_origalen-1] = 0;
+ for (i = 1; i < PL_origargc; i++)
+ PL_origargv[i] = 0;
UNLOCK_DOLLARZERO_MUTEX;
break;
#endif
#else
/* Not clear if this will work */
(void)rsignal(sig, SIG_IGN);
- (void)rsignal(sig, &Perl_csighandler);
+ (void)rsignal(sig, PL_csighandlerp);
#endif
#endif /* !PERL_MICRO */
Perl_die(aTHX_ Nullformat);
if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
{
+#ifdef PERL_COPY_ON_WRITE
+ /* While magic was saved (and off) sv_setsv may well have seen
+ this SV as a prime candidate for COW. */
+ if (SvIsCOW(sv))
+ sv_force_normal(sv);
+#endif
+
if (mgs->mgs_flags)
SvFLAGS(sv) |= mgs->mgs_flags;
else