diff options
author | Chip Salzenberg <chip@atlantic.net> | 1997-01-11 16:26:37 +1200 |
---|---|---|
committer | Chip Salzenberg <chip@atlantic.net> | 1997-01-16 07:24:00 +1200 |
commit | 1738f5c4253ffe12a0b11f6d2cf605cc15234b17 (patch) | |
tree | b154c1afe78775f06b0d718b8d9d3fb63dc2cd12 /util.c | |
parent | 3115e423b9deb8a52c4e316da80b3a3279b6b4bb (diff) | |
download | perl-1738f5c4253ffe12a0b11f6d2cf605cc15234b17.tar.gz |
Fix infinite loop for undef function in @SIG{__WARN__,__DIE__}
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 60 |
1 files changed, 33 insertions, 27 deletions
@@ -1181,18 +1181,26 @@ die(pat, va_alist) message = mess(pat, &args); va_end(args); - if (diehook && (cv = sv_2cv(diehook, &stash, &gv, 0)) && !CvDEPTH(cv)) { - dSP; - SV *msg = sv_2mortal(newSVpv(message, 0)); + if (diehook) { + /* sv_2cv might call croak() */ + SV *olddiehook = diehook; + ENTER; + SAVESPTR(diehook); + diehook = Nullsv; + cv = sv_2cv(olddiehook, &stash, &gv, 0); + LEAVE; + if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) { + dSP; + SV *msg = sv_2mortal(newSVpv(message, 0)); - PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(msg); - PUTBACK; - perl_call_sv((SV*)cv, G_DISCARD); + PUSHMARK(sp); + XPUSHs(msg); + PUTBACK; + perl_call_sv((SV*)cv, G_DISCARD); - /* It's okay for the __DIE__ hook to modify the message. */ - message = SvPV(msg, na); + /* It's okay for the __DIE__ hook to modify the message. */ + message = SvPV(msg, na); + } } restartop = die_where(message); @@ -1226,17 +1234,19 @@ croak(pat, va_alist) message = mess(pat, &args); va_end(args); if (diehook) { + /* sv_2cv might call croak() */ SV *olddiehook = diehook; - diehook = Nullsv; /* sv_2cv might call croak() */ + ENTER; + SAVESPTR(diehook); + diehook = Nullsv; cv = sv_2cv(olddiehook, &stash, &gv, 0); - diehook = olddiehook; - if (cv && !CvDEPTH(cv)) { + LEAVE; + if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) { dSP; SV *msg = sv_2mortal(newSVpv(message, 0)); PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(msg); + XPUSHs(msg); PUTBACK; perl_call_sv((SV*)cv, G_DISCARD); @@ -1292,16 +1302,17 @@ warn(pat,va_alist) va_end(args); if (warnhook) { + /* sv_2cv might call warn() */ SV *oldwarnhook = warnhook; - warnhook = Nullsv; /* sv_2cv might end up calling warn() */ + ENTER; + SAVESPTR(warnhook); + warnhook = Nullsv; cv = sv_2cv(oldwarnhook, &stash, &gv, 0); - warnhook = oldwarnhook; - if (cv && !CvDEPTH(cv)) { + LEAVE; + if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) { dSP; - PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(sv_2mortal(newSVpv(message,0))); + XPUSHs(sv_2mortal(newSVpv(message,0))); PUTBACK; perl_call_sv((SV*)cv, G_DISCARD); return; @@ -1637,12 +1648,7 @@ char *mode; register I32 this, that; register I32 pid; SV *sv; - I32 doexec = -#ifdef AMIGAOS - 1; -#else - strNE(cmd,"-"); -#endif + I32 doexec = strNE(cmd,"-"); #ifdef OS2 if (doexec) { |