PerlLIO_write(PerlIO_fileno(Perl_error_log),
PL_no_mem, strlen(PL_no_mem));
my_exit(1);
- return Nullch;
+ NORETURN_FUNCTION_END;
}
/* paranoid version of system's malloc() */
DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) malloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
if (ptr != NULL) {
#ifdef PERL_TRACK_MEMPOOL
- *(tTHX*)ptr = aTHX;
+ struct perl_memory_debug_header *const header
+ = (struct perl_memory_debug_header *)ptr;
+#endif
+
+#ifdef PERL_POISON
+ Poison(((char *)ptr), size, char);
+#endif
+
+#ifdef PERL_TRACK_MEMPOOL
+ header->interpreter = aTHX;
+ /* Link us into the list. */
+ header->prev = &PL_memory_debug_header;
+ header->next = PL_memory_debug_header.next;
+ PL_memory_debug_header.next = header;
+ header->next->prev = header;
+# ifdef PERL_POISON
+ header->size = size;
+# endif
ptr = (Malloc_t)((char*)ptr+sTHX);
#endif
return ptr;
else if (PL_nomemok)
return NULL;
else {
- return S_write_no_mem(aTHX);
+ return write_no_mem();
}
/*NOTREACHED*/
}
#ifdef PERL_TRACK_MEMPOOL
where = (Malloc_t)((char*)where-sTHX);
size += sTHX;
- if (*(tTHX*)where != aTHX) {
- /* int *nowhere = NULL; *nowhere = 0; */
- Perl_croak_nocontext("panic: realloc from wrong pool");
+ {
+ struct perl_memory_debug_header *const header
+ = (struct perl_memory_debug_header *)where;
+
+ if (header->interpreter != aTHX) {
+ Perl_croak_nocontext("panic: realloc from wrong pool");
+ }
+ assert(header->next->prev == header);
+ assert(header->prev->next == header);
+# ifdef PERL_POISON
+ if (header->size > size) {
+ const MEM_SIZE freed_up = header->size - size;
+ char *start_of_freed = ((char *)where) + size;
+ Poison(start_of_freed, freed_up, char);
+ }
+ header->size = size;
+# endif
}
#endif
#ifdef DEBUGGING
if (ptr != NULL) {
#ifdef PERL_TRACK_MEMPOOL
+ struct perl_memory_debug_header *const header
+ = (struct perl_memory_debug_header *)ptr;
+
+# ifdef PERL_POISON
+ if (header->size < size) {
+ const MEM_SIZE fresh = size - header->size;
+ char *start_of_fresh = ((char *)ptr) + size;
+ Poison(start_of_fresh, fresh, char);
+ }
+# endif
+
+ header->next->prev = header;
+ header->prev->next = header;
+
ptr = (Malloc_t)((char*)ptr+sTHX);
#endif
return ptr;
else if (PL_nomemok)
return NULL;
else {
- return S_write_no_mem(aTHX);
+ return write_no_mem();
}
/*NOTREACHED*/
}
if (where) {
#ifdef PERL_TRACK_MEMPOOL
where = (Malloc_t)((char*)where-sTHX);
- if (*(tTHX*)where != aTHX) {
- /* int *nowhere = NULL; *nowhere = 0; */
- Perl_croak_nocontext("panic: free from wrong pool");
+ {
+ struct perl_memory_debug_header *const header
+ = (struct perl_memory_debug_header *)where;
+
+ if (header->interpreter != aTHX) {
+ Perl_croak_nocontext("panic: free from wrong pool");
+ }
+ if (!header->prev) {
+ Perl_croak_nocontext("panic: duplicate free");
+ }
+ if (!(header->next) || header->next->prev != header
+ || header->prev->next != header) {
+ Perl_croak_nocontext("panic: bad free");
+ }
+ /* Unlink us from the chain. */
+ header->next->prev = header->prev;
+ header->prev->next = header->next;
+# ifdef PERL_POISON
+ Poison(where, header->size, char);
+# endif
+ /* Trigger the duplicate free warning. */
+ header->next = NULL;
}
#endif
PerlMem_free(where);
if (ptr != NULL) {
memset((void*)ptr, 0, size);
#ifdef PERL_TRACK_MEMPOOL
- *(tTHX*)ptr = aTHX;
- ptr = (Malloc_t)((char*)ptr+sTHX);
+ {
+ struct perl_memory_debug_header *const header
+ = (struct perl_memory_debug_header *)ptr;
+
+ header->interpreter = aTHX;
+ /* Link us into the list. */
+ header->prev = &PL_memory_debug_header;
+ header->next = PL_memory_debug_header.next;
+ PL_memory_debug_header.next = header;
+ header->next->prev = header;
+# ifdef PERL_POISON
+ header->size = size;
+# endif
+ ptr = (Malloc_t)((char*)ptr+sTHX);
+ }
#endif
return ptr;
}
else if (PL_nomemok)
return NULL;
- else {
- return S_write_no_mem(aTHX);
- }
- /*NOTREACHED*/
+ return write_no_mem();
}
/* These must be defined when not using Perl's malloc for binary
for (x=big,s=little; *s; /**/ ) {
if (!*x)
return NULL;
- if (*s++ != *x++) {
- s--;
+ if (*s != *x)
break;
+ else {
+ s++;
+ x++;
}
}
if (!*s)
/* same as instr but allow embedded nulls */
char *
-Perl_ninstr(pTHX_ register const char *big, register const char *bigend, const char *little, const char *lend)
+Perl_ninstr(pTHX_ const char *big, const char *bigend, const char *little, const char *lend)
{
- register const I32 first = *little;
- register const char *littleend = lend;
-
- if (!first && little >= littleend)
- return (char*)big;
- if (bigend - big < littleend - little)
- return Nullch;
- bigend -= littleend - little++;
- while (big <= bigend) {
- register const char *s, *x;
- if (*big++ != first)
- continue;
- for (x=big,s=little; s < littleend; /**/ ) {
- if (*s++ != *x++) {
- s--;
- break;
- }
- }
- if (s >= littleend)
- return (char*)(big-1);
+ if (little >= lend)
+ return (char*)big;
+ {
+ char first = *little++;
+ const char *s, *x;
+ bigend -= lend - little;
+ OUTER:
+ while (big <= bigend) {
+ if (*big++ != first)
+ goto OUTER;
+ for (x=big,s=little; s < lend; x++,s++) {
+ if (*s != *x)
+ goto OUTER;
+ }
+ return (char*)(big-1);
+ }
}
return NULL;
}
{
register const char *bigbeg;
register const I32 first = *little;
- register const char *littleend = lend;
+ register const char * const littleend = lend;
- if (!first && little >= littleend)
+ if (little >= littleend)
return (char*)bigend;
bigbeg = big;
big = bigend - (littleend - little++);
if (*big-- != first)
continue;
for (x=big+2,s=little; s < littleend; /**/ ) {
- if (*s++ != *x++) {
- s--;
+ if (*s != *x)
break;
+ else {
+ x++;
+ s++;
}
}
if (s >= littleend)
if (flags & FBMcf_TAIL) {
MAGIC * const mg = SvUTF8(sv) && SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_utf8) : NULL;
- sv_catpvn(sv, "\n", 1); /* Taken into account in fbm_instr() */
+ sv_catpvs(sv, "\n"); /* Taken into account in fbm_instr() */
if (mg && mg->mg_len >= 0)
mg->mg_len++;
}
pvlen = strlen(pv)+1;
newaddr = (char*)PerlMemShared_malloc(pvlen);
if (!newaddr) {
- return S_write_no_mem(aTHX);
+ return write_no_mem();
}
return memcpy(newaddr,pv,pvlen);
}
Perl_savesvpv(pTHX_ SV *sv)
{
STRLEN len;
- const char *pv = SvPV_const(sv, len);
+ const char * const pv = SvPV_const(sv, len);
register char *newaddr;
++len;
XPVMG *any;
if (!PL_dirty)
- return sv_2mortal(newSVpvn("",0));
+ return sv_2mortal(newSVpvs(""));
if (PL_mess_sv)
return PL_mess_sv;
return retval;
}
-STATIC COP*
-S_closest_cop(pTHX_ COP *cop, const OP *o)
+STATIC const COP*
+S_closest_cop(pTHX_ const COP *cop, const OP *o)
{
/* Look for PL_op starting from o. cop is the last COP we've seen. */
- if (!o || o == PL_op) return cop;
+ if (!o || o == PL_op)
+ return cop;
if (o->op_flags & OPf_KIDS) {
- OP *kid;
- for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling)
- {
- COP *new_cop;
+ const OP *kid;
+ for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
+ const COP *new_cop;
/* If the OP_NEXTSTATE has been optimised away we can still use it
* the get the file and line number. */
if (kid->op_type == OP_NULL && kid->op_targ == OP_NEXTSTATE)
- cop = (COP *)kid;
+ cop = (const COP *)kid;
/* Keep searching, and return when we've found something. */
new_cop = closest_cop(cop, kid);
- if (new_cop) return new_cop;
+ if (new_cop)
+ return new_cop;
}
}
/* Nothing found. */
- return Null(COP *);
+ return NULL;
}
SV *
Perl_vmess(pTHX_ const char *pat, va_list *args)
{
SV * const sv = mess_alloc();
- static const char dgd[] = " during global destruction.\n";
- sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
+ sv_vsetpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL);
if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') {
-
/*
* Try and find the file and line for PL_op. This will usually be
* PL_curcop, but it might be a cop that has been optimised away. We
*/
const COP *cop = closest_cop(PL_curcop, PL_curcop->op_sibling);
- if (!cop) cop = PL_curcop;
+ if (!cop)
+ cop = PL_curcop;
if (CopLINE(cop))
Perl_sv_catpvf(aTHX_ sv, " at %s line %"IVdf,
const bool line_mode = (RsSIMPLE(PL_rs) &&
SvCUR(PL_rs) == 1 && *SvPVX_const(PL_rs) == '\n');
Perl_sv_catpvf(aTHX_ sv, ", <%s> %s %"IVdf,
- PL_last_in_gv == PL_argvgv ?
- "" : GvNAME(PL_last_in_gv),
+ PL_last_in_gv == PL_argvgv ? "" : GvNAME(PL_last_in_gv),
line_mode ? "line" : "chunk",
(IV)IoLINES(GvIOp(PL_last_in_gv)));
}
if (thr->tid)
Perl_sv_catpvf(aTHX_ sv, " thread %ld", thr->tid);
#endif
- sv_catpv(sv, PL_dirty ? dgd : ".\n");
+ if (PL_dirty)
+ sv_catpvs(sv, " during global destruction");
+ sv_catpvs(sv, ".\n");
}
return sv;
}
}
}
-/* Common code used by vcroak, vdie and vwarner */
+/* Common code used by vcroak, vdie, vwarn and vwarner */
-/* Whilst this should really be STATIC, it was not in 5.8.7, hence something
- may have linked against it. */
-void
-S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8)
+STATIC bool
+S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8, bool warn)
{
HV *stash;
GV *gv;
CV *cv;
- /* sv_2cv might call Perl_croak() */
- SV * const olddiehook = PL_diehook;
+ SV **const hook = warn ? &PL_warnhook : &PL_diehook;
+ /* sv_2cv might call Perl_croak() or Perl_warner() */
+ SV * const oldhook = *hook;
+
+ assert(oldhook);
- assert(PL_diehook);
ENTER;
- SAVESPTR(PL_diehook);
- PL_diehook = Nullsv;
- cv = sv_2cv(olddiehook, &stash, &gv, 0);
+ SAVESPTR(*hook);
+ *hook = NULL;
+ cv = sv_2cv(oldhook, &stash, &gv, 0);
LEAVE;
if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) {
dSP;
ENTER;
save_re_context();
- if (message) {
+ if (warn) {
+ SAVESPTR(*hook);
+ *hook = NULL;
+ }
+ if (warn || message) {
msg = newSVpvn(message, msglen);
SvFLAGS(msg) |= utf8;
SvREADONLY_on(msg);
msg = ERRSV;
}
- PUSHSTACKi(PERLSI_DIEHOOK);
+ PUSHSTACKi(warn ? PERLSI_WARNHOOK : PERLSI_DIEHOOK);
PUSHMARK(SP);
XPUSHs(msg);
PUTBACK;
call_sv((SV*)cv, G_DISCARD);
POPSTACK;
LEAVE;
+ return TRUE;
}
+ return FALSE;
}
/* Whilst this should really be STATIC, it was not in 5.8.7, hence something
"%p: die/croak: message = %s\ndiehook = %p\n",
thr, message, PL_diehook));
if (PL_diehook) {
- S_vdie_common(aTHX_ message, *msglen, *utf8);
+ S_vdie_common(aTHX_ message, *msglen, *utf8, FALSE);
}
/* Cast because we're not changing function prototypes in maint, and this
function isn't actually static. */
const char * const message = SvPV_const(msv, msglen);
if (PL_warnhook) {
- /* sv_2cv might call Perl_warn() */
- SV * const oldwarnhook = PL_warnhook;
- CV * cv;
- HV * stash;
- GV * gv;
-
- ENTER;
- SAVESPTR(PL_warnhook);
- PL_warnhook = Nullsv;
- cv = sv_2cv(oldwarnhook, &stash, &gv, 0);
- LEAVE;
- if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) {
- dSP;
- SV *msg;
-
- ENTER;
- SAVESPTR(PL_warnhook);
- PL_warnhook = Nullsv;
- save_re_context();
- msg = newSVpvn(message, msglen);
- SvFLAGS(msg) |= utf8;
- SvREADONLY_on(msg);
- SAVEFREESV(msg);
-
- PUSHSTACKi(PERLSI_WARNHOOK);
- PUSHMARK(SP);
- XPUSHs(msg);
- PUTBACK;
- call_sv((SV*)cv, G_DISCARD);
- POPSTACK;
- LEAVE;
+ if (vdie_common(message, msglen, utf8, TRUE))
return;
- }
}
write_to_stderr(message, msglen);
if (ckDEAD(err)) {
SV * const msv = vmess(pat, args);
STRLEN msglen;
- const char *message = SvPV_const(msv, msglen);
+ const char * const message = SvPV_const(msv, msglen);
const I32 utf8 = SvUTF8(msv);
#ifdef USE_5005THREADS
#endif /* USE_5005THREADS */
if (PL_diehook) {
assert(message);
- S_vdie_common(aTHX_ message, msglen, utf8);
+ S_vdie_common(aTHX_ message, msglen, utf8, FALSE);
}
if (PL_in_eval) {
PL_restartop = die_where((char *) message, msglen);
PerlProc__exit(1);
}
#endif /* defined OS2 */
- if ((tmpgv = gv_fetchpv("$",TRUE, SVt_PV))) {
+ if ((tmpgv = gv_fetchpvs("$", GV_ADD|GV_NOTQUAL, SVt_PV))) {
SvREADONLY_off(GvSV(tmpgv));
sv_setiv(GvSV(tmpgv), PerlProc_getpid());
SvREADONLY_on(GvSV(tmpgv));
static int PL_sig_trapped; /* XXX signals are process-wide anyway, so we
ignore the implications of this for threading */
-static
-Signal_t
+static Signal_t
sig_trap(int signo)
{
PL_sig_trapped++;
{
/* Needs work for PerlIO ! */
FILE * const f = PerlIO_findFILE(ptr);
- I32 result = pclose(f);
+ const I32 result = pclose(f);
PerlIO_releaseFILE(ptr,f);
return result;
}
#endif
/* additional extensions to try in each dir if scriptname not found */
#ifdef SEARCH_EXTS
- const char *const exts[] = { SEARCH_EXTS };
+ static const char *const exts[] = { SEARCH_EXTS };
const char *const *const ext =
search_ext ? (const char *const *const)search_ext : exts;
int extidx = 0, i = 0;
PL_in_eval = EVAL_NULL; /* ~(EVAL_INEVAL|EVAL_WARNONLY|EVAL_KEEPERR|EVAL_INREQUIRE) */
PL_restartop = 0;
- PL_statname = NEWSV(66,0);
+ PL_statname = newSV(0);
PL_errors = newSVpvn("", 0);
PL_maxscream = -1;
PL_regcompp = MEMBER_TO_FPTR(Perl_pregcomp);
MGVTBL*
Perl_get_vtbl(pTHX_ int vtbl_id)
{
- const MGVTBL* result = Null(MGVTBL*);
+ const MGVTBL* result;
switch(vtbl_id) {
case want_vtbl_sv:
case want_vtbl_utf8:
result = &PL_vtbl_utf8;
break;
+ default:
+ result = Null(MGVTBL*);
+ break;
}
return (MGVTBL*)result;
}
fd_set rset;
FD_ZERO(&rset);
- FD_SET(sockets[0], &rset);
- FD_SET(sockets[1], &rset);
+ FD_SET((unsigned int)sockets[0], &rset);
+ FD_SET((unsigned int)sockets[1], &rset);
got = PerlSock_select(max + 1, &rset, NULL, NULL, &waitfor);
if (got != 2 || !FD_ISSET(sockets[0], &rset)
#endif
tidy_up_and_fail:
{
- int save_errno = errno;
+ const int save_errno = errno;
if (listener != -1)
PerlLIO_close(listener);
if (connector != -1)