X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/41715441c03ba3cca251b6bba5fecee19073b7ae..255b632a2a78b37a9400b7f7509a23f0e040de5c:/util.c diff --git a/util.c b/util.c index 647f533..165d13a 100644 --- a/util.c +++ b/util.c @@ -132,6 +132,7 @@ Perl_safesysmalloc(MEM_SIZE size) dTHX; #endif Malloc_t ptr; + dSAVEDERRNO; #ifdef USE_MDH if (size + PERL_MEMORY_DEBUG_HEADER_SIZE < size) @@ -143,6 +144,7 @@ Perl_safesysmalloc(MEM_SIZE size) Perl_croak_nocontext("panic: malloc, size=%" UVuf, (UV) size); #endif if (!size) size = 1; /* malloc(0) is NASTY on our system */ + SAVE_ERRNO; #ifdef PERL_DEBUG_READONLY_COW if ((ptr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { @@ -182,6 +184,11 @@ Perl_safesysmalloc(MEM_SIZE size) ptr = (Malloc_t)((char*)ptr+PERL_MEMORY_DEBUG_HEADER_SIZE); DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%" UVxf ": (%05ld) malloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size)); + /* malloc() can modify errno() even on success, but since someone + writing perl code doesn't have any control over when perl calls + malloc() we need to hide that. + */ + RESTORE_ERRNO; } else { #ifdef USE_MDH @@ -223,6 +230,7 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size) ptr = safesysmalloc(size); } else { + dSAVE_ERRNO; #ifdef USE_MDH where = (Malloc_t)((char*)where-PERL_MEMORY_DEBUG_HEADER_SIZE); if (size + PERL_MEMORY_DEBUG_HEADER_SIZE < size) @@ -296,6 +304,12 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size) maybe_protect_ro(header->prev); #endif ptr = (Malloc_t)((char*)ptr+PERL_MEMORY_DEBUG_HEADER_SIZE); + + /* realloc() can modify errno() even on success, but since someone + writing perl code doesn't have any control over when perl calls + realloc() we need to hide that. + */ + RESTORE_ERRNO; } /* In particular, must do that fixup above before logging anything via @@ -439,7 +453,7 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size) ptr = (Malloc_t)PerlMem_calloc(count ? count : 1, size ? size : 1); #endif PERL_ALLOC_CHECK(ptr); - DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%" UVxf ": (%05ld) calloc %ld x %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)count,(long)total_size)); + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%" UVxf ": (%05ld) calloc %zu x %zu = %zu bytes\n",PTR2UV(ptr),(long)PL_an++, count, size, total_size)); if (ptr != NULL) { #ifdef USE_MDH { @@ -577,7 +591,7 @@ Perl_delimcpy_no_escape(char *to, const char *toend, const char *from, /* =head1 Miscellaneous Functions -=for apidoc Am|char *|ninstr|char * big|char * bigend|char * little|char * little_end +=for apidoc ninstr Find the first (leftmost) occurrence of a sequence of bytes within another sequence. This is the Perl version of C, extended to handle @@ -638,7 +652,7 @@ Perl_ninstr(const char *big, const char *bigend, const char *little, const char /* =head1 Miscellaneous Functions -=for apidoc Am|char *|rninstr|char * big|char * bigend|char * little|char * little_end +=for apidoc rninstr Like C>, but instead finds the final (rightmost) occurrence of a sequence of bytes within another sequence, returning C if there is no @@ -1273,7 +1287,7 @@ Perl_vform(pTHX_ const char *pat, va_list *args) } /* -=for apidoc Am|SV *|mess|const char *pat|... +=for apidoc mess Take a sprintf-style format pattern and argument list. These are used to generate a string message. If the message does not end with a newline, @@ -1354,7 +1368,7 @@ Perl_closest_cop(pTHX_ const COP *cop, const OP *o, const OP *curop, } /* -=for apidoc Am|SV *|mess_sv|SV *basemsg|bool consume +=for apidoc mess_sv Expands a message, intended for the user, to include an indication of the current location in the code, if the message does not already appear @@ -1458,7 +1472,7 @@ Perl_mess_sv(pTHX_ SV *basemsg, bool consume) } /* -=for apidoc Am|SV *|vmess|const char *pat|va_list *args +=for apidoc vmess C and C are a sprintf-style format pattern and encapsulated argument list, respectively. These are used to generate a string message. If @@ -1527,6 +1541,7 @@ S_with_queued_errors(pTHX_ SV *ex) STATIC bool S_invoke_exception_hook(pTHX_ SV *ex, bool warn) { + dVAR; HV *stash; GV *gv; CV *cv; @@ -1534,7 +1549,7 @@ S_invoke_exception_hook(pTHX_ SV *ex, bool warn) /* sv_2cv might call Perl_croak() or Perl_warner() */ SV * const oldhook = *hook; - if (!oldhook) + if (!oldhook || oldhook == PERL_WARNHOOK_FATAL) return FALSE; ENTER; @@ -1569,7 +1584,7 @@ S_invoke_exception_hook(pTHX_ SV *ex, bool warn) } /* -=for apidoc Am|OP *|die_sv|SV *baseex +=for apidoc die_sv Behaves the same as L, except for the return type. It should be used only where the C return type is required. @@ -1578,13 +1593,8 @@ The function never actually returns. =cut */ -#ifdef _MSC_VER -# pragma warning( push ) -# pragma warning( disable : 4646 ) /* warning C4646: function declared with - __declspec(noreturn) has non-void return type */ -# pragma warning( disable : 4645 ) /* warning C4645: function declared with -__declspec(noreturn) has a return statement */ -#endif +/* silence __declspec(noreturn) warnings */ +MSVC_DIAG_IGNORE(4646 4645) OP * Perl_die_sv(pTHX_ SV *baseex) { @@ -1593,12 +1603,10 @@ Perl_die_sv(pTHX_ SV *baseex) /* NOTREACHED */ NORETURN_FUNCTION_END; } -#ifdef _MSC_VER -# pragma warning( pop ) -#endif +MSVC_DIAG_RESTORE /* -=for apidoc Am|OP *|die|const char *pat|... +=for apidoc die Behaves the same as L, except for the return type. It should be used only where the C return type is required. @@ -1608,13 +1616,9 @@ The function never actually returns. */ #if defined(PERL_IMPLICIT_CONTEXT) -#ifdef _MSC_VER -# pragma warning( push ) -# pragma warning( disable : 4646 ) /* warning C4646: function declared with - __declspec(noreturn) has non-void return type */ -# pragma warning( disable : 4645 ) /* warning C4645: function declared with -__declspec(noreturn) has a return statement */ -#endif + +/* silence __declspec(noreturn) warnings */ +MSVC_DIAG_IGNORE(4646 4645) OP * Perl_die_nocontext(const char* pat, ...) { @@ -1626,18 +1630,12 @@ Perl_die_nocontext(const char* pat, ...) va_end(args); NORETURN_FUNCTION_END; } -#ifdef _MSC_VER -# pragma warning( pop ) -#endif +MSVC_DIAG_RESTORE + #endif /* PERL_IMPLICIT_CONTEXT */ -#ifdef _MSC_VER -# pragma warning( push ) -# pragma warning( disable : 4646 ) /* warning C4646: function declared with - __declspec(noreturn) has non-void return type */ -# pragma warning( disable : 4645 ) /* warning C4645: function declared with -__declspec(noreturn) has a return statement */ -#endif +/* silence __declspec(noreturn) warnings */ +MSVC_DIAG_IGNORE(4646 4645) OP * Perl_die(pTHX_ const char* pat, ...) { @@ -1648,12 +1646,10 @@ Perl_die(pTHX_ const char* pat, ...) va_end(args); NORETURN_FUNCTION_END; } -#ifdef _MSC_VER -# pragma warning( pop ) -#endif +MSVC_DIAG_RESTORE /* -=for apidoc Am|void|croak_sv|SV *baseex +=for apidoc croak_sv This is an XS interface to Perl's C function. @@ -1683,7 +1679,7 @@ Perl_croak_sv(pTHX_ SV *baseex) } /* -=for apidoc Am|void|vcroak|const char *pat|va_list *args +=for apidoc vcroak This is an XS interface to Perl's C function. @@ -1716,7 +1712,7 @@ Perl_vcroak(pTHX_ const char* pat, va_list *args) } /* -=for apidoc Am|void|croak|const char *pat|... +=for apidoc croak This is an XS interface to Perl's C function. @@ -1763,7 +1759,7 @@ Perl_croak(pTHX_ const char *pat, ...) } /* -=for apidoc Am|void|croak_no_modify +=for apidoc croak_no_modify Exactly equivalent to C, but generates terser object code than using C. Less code used on exception code @@ -1806,7 +1802,7 @@ Perl_croak_popstack(void) } /* -=for apidoc Am|void|warn_sv|SV *baseex +=for apidoc warn_sv This is an XS interface to Perl's C function. @@ -1834,7 +1830,7 @@ Perl_warn_sv(pTHX_ SV *baseex) } /* -=for apidoc Am|void|vwarn|const char *pat|va_list *args +=for apidoc vwarn This is an XS interface to Perl's C function. @@ -1862,7 +1858,7 @@ Perl_vwarn(pTHX_ const char* pat, va_list *args) } /* -=for apidoc Am|void|warn|const char *pat|... +=for apidoc warn This is an XS interface to Perl's C function. @@ -2060,149 +2056,207 @@ Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits, Copy(val, s+(nlen+1), vlen, char); \ *(s+(nlen+1+vlen)) = '\0' + + #ifdef USE_ENVIRON_ARRAY - /* VMS' my_setenv() is in vms.c */ -#if !defined(WIN32) && !defined(NETWARE) +/* NB: VMS' my_setenv() is in vms.c */ + +/* Configure doesn't test for HAS_SETENV yet, so decide based on platform. + * For Solaris, setenv() and unsetenv() were introduced in Solaris 9, so + * testing for HAS UNSETENV is sufficient. + */ +# if defined(__CYGWIN__)|| defined(__SYMBIAN32__) || defined(__riscos__) || (defined(__sun) && defined(HAS_UNSETENV)) || defined(PERL_DARWIN) +# define MY_HAS_SETENV +# endif + +/* small wrapper for use by Perl_my_setenv that mallocs, or reallocs if + * 'current' is non-null, with up to three sizes that are added together. + * It handles integer overflow. + */ +# ifndef MY_HAS_SETENV +static char * +S_env_alloc(void *current, Size_t l1, Size_t l2, Size_t l3, Size_t size) +{ + void *p; + Size_t sl, l = l1 + l2; + + if (l < l2) + goto panic; + l += l3; + if (l < l3) + goto panic; + sl = l * size; + if (sl < l) + goto panic; + + p = current + ? safesysrealloc(current, sl) + : safesysmalloc(sl); + if (p) + return (char*)p; + + panic: + croak_memory_wrap(); +} +# endif + + +# if !defined(WIN32) && !defined(NETWARE) + void Perl_my_setenv(pTHX_ const char *nam, const char *val) { dVAR; -#ifdef __amigaos4__ +# ifdef __amigaos4__ amigaos4_obtain_environ(__FUNCTION__); -#endif -#ifdef USE_ITHREADS +# endif + +# ifdef USE_ITHREADS /* only parent thread can modify process environment */ if (PL_curinterp == aTHX) -#endif +# endif { -#ifndef PERL_USE_SAFE_PUTENV + +# ifndef PERL_USE_SAFE_PUTENV if (!PL_use_safe_putenv) { /* most putenv()s leak, so we manipulate environ directly */ - I32 i; - const I32 len = strlen(nam); - int nlen, vlen; + UV i; + Size_t vlen, nlen = strlen(nam); /* where does it go? */ for (i = 0; environ[i]; i++) { - if (strnEQ(environ[i],nam,len) && environ[i][len] == '=') + if (strnEQ(environ[i], nam, nlen) && environ[i][nlen] == '=') break; } if (environ == PL_origenviron) { /* need we copy environment? */ - I32 j; - I32 max; + UV j, max; char **tmpenv; max = i; while (environ[max]) max++; - tmpenv = (char**)safesysmalloc((max+2) * sizeof(char*)); + + /* XXX shouldn't that be max+1 rather than max+2 ??? - DAPM */ + tmpenv = (char**)S_env_alloc(NULL, max, 2, 0, sizeof(char*)); + for (j=0; j