X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/2bcd6579c4ef6796b83fd758613f3e686e7418a7..f556af6c048b2769e0a588d55ef54f5949171836:/util.c diff --git a/util.c b/util.c index c0d1091..ffd41b9 100644 --- a/util.c +++ b/util.c @@ -24,6 +24,7 @@ #include "EXTERN.h" #define PERL_IN_UTIL_C #include "perl.h" +#include "reentr.h" #ifdef USE_PERLIO #include "perliol.h" /* For PerlIOUnix_refcnt */ @@ -296,12 +297,12 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size) #endif } else - croak_memory_wrap(); + Perl_croak_memory_wrap(); #ifdef PERL_TRACK_MEMPOOL if (sTHX <= MEM_SIZE_MAX - (MEM_SIZE)total_size) total_size += sTHX; else - croak_memory_wrap(); + Perl_croak_memory_wrap(); #endif #ifdef HAS_64K_LIMIT if (total_size > 0xffff) { @@ -395,7 +396,7 @@ Free_t Perl_mfree (Malloc_t where) /* copy a string up to some (non-backslashed) delimiter, if any */ char * -Perl_delimcpy(register char *to, register const char *toend, register const char *from, register const char *fromend, register int delim, I32 *retlen) +Perl_delimcpy(char *to, const char *toend, const char *from, const char *fromend, int delim, I32 *retlen) { I32 tolen; @@ -425,35 +426,15 @@ Perl_delimcpy(register char *to, register const char *toend, register const char /* This routine was donated by Corey Satten. */ char * -Perl_instr(register const char *big, register const char *little) +Perl_instr(const char *big, const char *little) { - I32 first; PERL_ARGS_ASSERT_INSTR; + /* libc prior to 4.6.27 did not work properly on a NULL 'little' */ if (!little) return (char*)big; - first = *little++; - if (!first) - return (char*)big; - while (*big) { - const char *s, *x; - if (*big++ != first) - continue; - for (x=big,s=little; *s; /**/ ) { - if (!*x) - return NULL; - if (*s != *x) - break; - else { - s++; - x++; - } - } - if (!*s) - return (char*)(big-1); - } - return NULL; + return strstr((char*)big, (char*)little); } /* same as instr but allow embedded nulls. The end pointers point to 1 beyond @@ -486,7 +467,7 @@ Perl_ninstr(const char *big, const char *bigend, const char *little, const char /* reverse of the above--find last substring */ char * -Perl_rninstr(register const char *big, const char *bigend, const char *little, const char *lend) +Perl_rninstr(const char *big, const char *bigend, const char *little, const char *lend) { const char *bigbeg; const I32 first = *little; @@ -540,13 +521,13 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags) const U8 *s; STRLEN i; STRLEN len; - STRLEN rarest = 0; U32 frequency = 256; MAGIC *mg; + PERL_DEB( STRLEN rarest = 0 ); PERL_ARGS_ASSERT_FBM_COMPILE; - if (isGV_with_GP(sv)) + if (isGV_with_GP(sv) || SvROK(sv)) return; if (SvVALID(sv)) @@ -558,7 +539,9 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags) if (mg && mg->mg_len >= 0) mg->mg_len++; } - s = (U8*)SvPV_force_mutable(sv, len); + if (!SvPOK(sv) || SvNIOKp(sv) || SvIsCOW(sv)) + s = (U8*)SvPV_force_mutable(sv, len); + else s = (U8 *)SvPV_mutable(sv, len); if (len == 0) /* TAIL might be on a zero-length string. */ return; SvUPGRADE(sv, SVt_PVMG); @@ -608,17 +591,15 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags) s = (const unsigned char*)(SvPVX_const(sv)); /* deeper magic */ for (i = 0; i < len; i++) { if (PL_freq[s[i]] < frequency) { - rarest = i; + PERL_DEB( rarest = i ); frequency = PL_freq[s[i]]; } } - BmRARE(sv) = s[rarest]; - BmPREVIOUS(sv) = rarest; BmUSEFUL(sv) = 100; /* Initial value */ if (flags & FBMcf_TAIL) SvTAIL_on(sv); DEBUG_r(PerlIO_printf(Perl_debug_log, "rarest char %c at %"UVuf"\n", - BmRARE(sv), BmPREVIOUS(sv))); + s[rarest], (UV)rarest)); } /* If SvTAIL(littlestr), it has a fake '\n' at end. */ @@ -637,7 +618,7 @@ then. */ char * -Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *littlestr, U32 flags) +Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U32 flags) { unsigned char *s; STRLEN l; @@ -853,7 +834,7 @@ range bytes match only themselves. I32 -Perl_foldEQ(const char *s1, const char *s2, register I32 len) +Perl_foldEQ(const char *s1, const char *s2, I32 len) { const U8 *a = (const U8 *)s1; const U8 *b = (const U8 *)s2; @@ -870,7 +851,7 @@ Perl_foldEQ(const char *s1, const char *s2, register I32 len) return 1; } I32 -Perl_foldEQ_latin1(const char *s1, const char *s2, register I32 len) +Perl_foldEQ_latin1(const char *s1, const char *s2, I32 len) { /* Compare non-utf8 using Unicode (Latin1) semantics. Does not work on * MICRO_SIGN, LATIN_SMALL_LETTER_SHARP_S, nor @@ -903,7 +884,7 @@ case-insensitively in the current locale; false otherwise. */ I32 -Perl_foldEQ_locale(const char *s1, const char *s2, register I32 len) +Perl_foldEQ_locale(const char *s1, const char *s2, I32 len) { dVAR; const U8 *a = (const U8 *)s1; @@ -964,7 +945,7 @@ the new string can be freed with the C function. */ char * -Perl_savepvn(pTHX_ const char *pv, register I32 len) +Perl_savepvn(pTHX_ const char *pv, I32 len) { char *newaddr; PERL_UNUSED_CONTEXT; @@ -1359,7 +1340,7 @@ Perl_write_to_stderr(pTHX_ SV* msv) if (PL_stderrgv && SvREFCNT(PL_stderrgv) && (io = GvIO(PL_stderrgv)) && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar))) - Perl_magic_methcall(aTHX_ MUTABLE_SV(io), mg, "PRINT", + Perl_magic_methcall(aTHX_ MUTABLE_SV(io), mg, SV_CONST(PRINT), G_SCALAR | G_DISCARD | G_WRITING_TO_STDERR, 1, msv); else { #ifdef USE_SFIO @@ -1626,13 +1607,30 @@ void Perl_croak_no_mem() { dTHX; - dVAR; + /* Can't use PerlIO to write as it allocates memory */ PerlLIO_write(PerlIO_fileno(Perl_error_log), PL_no_mem, sizeof(PL_no_mem)-1); my_exit(1); } +/* saves machine code for a common noreturn idiom typically used in Newx*() */ +void +Perl_croak_memory_wrap(void) +{ + Perl_croak_nocontext("%s",PL_memory_wrap); +} + + +/* does not return, used only in POPSTACK */ +void +Perl_croak_popstack(void) +{ + dTHX; + PerlIO_printf(Perl_error_log, "panic: POPSTACK\n"); + my_exit(1); +} + /* =for apidoc Am|void|warn_sv|SV *baseex @@ -1946,7 +1944,7 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) my_setenv_format(environ[i], nam, nlen, val, vlen); } else { # endif -# if defined(__CYGWIN__) || defined(EPOC) || defined(__SYMBIAN32__) || defined(__riscos__) +# if defined(__CYGWIN__)|| defined(__SYMBIAN32__) || defined(__riscos__) # if defined(HAS_UNSETENV) if (val == NULL) { (void)unsetenv(nam); @@ -1959,7 +1957,8 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) # else # if defined(HAS_UNSETENV) if (val == NULL) { - (void)unsetenv(nam); + if (environ) /* old glibc can crash with null environ */ + (void)unsetenv(nam); } else { const int nlen = strlen(nam); const int vlen = strlen(val); @@ -2010,7 +2009,7 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) #endif /* WIN32 || NETWARE */ -#endif /* !VMS && !EPOC*/ +#endif /* !VMS */ #ifdef UNLINK_ALL_VERSIONS I32 @@ -2029,7 +2028,7 @@ Perl_unlnk(pTHX_ const char *f) /* unlink all versions of a file */ /* this is a drop-in replacement for bcopy() */ #if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY)) char * -Perl_my_bcopy(register const char *from,register char *to,register I32 len) +Perl_my_bcopy(const char *from, char *to, I32 len) { char * const retval = to; @@ -2054,7 +2053,7 @@ Perl_my_bcopy(register const char *from,register char *to,register I32 len) /* this is a drop-in replacement for memset() */ #ifndef HAS_MEMSET void * -Perl_my_memset(register char *loc, register I32 ch, register I32 len) +Perl_my_memset(char *loc, I32 ch, I32 len) { char * const retval = loc; @@ -2071,7 +2070,7 @@ Perl_my_memset(register char *loc, register I32 ch, register I32 len) /* this is a drop-in replacement for bzero() */ #if !defined(HAS_BZERO) && !defined(HAS_MEMSET) char * -Perl_my_bzero(register char *loc, register I32 len) +Perl_my_bzero(char *loc, I32 len) { char * const retval = loc; @@ -2088,7 +2087,7 @@ Perl_my_bzero(register char *loc, register I32 len) /* this is a drop-in replacement for memcmp() */ #if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP) I32 -Perl_my_memcmp(const char *s1, const char *s2, register I32 len) +Perl_my_memcmp(const char *s1, const char *s2, I32 len) { const U8 *a = (const U8 *)s1; const U8 *b = (const U8 *)s2; @@ -2161,339 +2160,10 @@ vsprintf(char *dest, const char *pat, void *args) #endif /* HAS_VPRINTF */ -#ifdef MYSWAP -#if BYTEORDER != 0x4321 -short -Perl_my_swap(pTHX_ short s) -{ -#if (BYTEORDER & 1) == 0 - short result; - - result = ((s & 255) << 8) + ((s >> 8) & 255); - return result; -#else - return s; -#endif -} - -long -Perl_my_htonl(pTHX_ long l) -{ - union { - long result; - char c[sizeof(long)]; - } u; - -#if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 -#if BYTEORDER == 0x12345678 - u.result = 0; -#endif - u.c[0] = (l >> 24) & 255; - u.c[1] = (l >> 16) & 255; - u.c[2] = (l >> 8) & 255; - u.c[3] = l & 255; - return u.result; -#else -#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf) - Perl_croak(aTHX_ "Unknown BYTEORDER\n"); -#else - I32 o; - I32 s; - - for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) { - u.c[o & 0xf] = (l >> s) & 255; - } - return u.result; -#endif -#endif -} - -long -Perl_my_ntohl(pTHX_ long l) -{ - union { - long l; - char c[sizeof(long)]; - } u; - -#if BYTEORDER == 0x1234 - u.c[0] = (l >> 24) & 255; - u.c[1] = (l >> 16) & 255; - u.c[2] = (l >> 8) & 255; - u.c[3] = l & 255; - return u.l; -#else -#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf) - Perl_croak(aTHX_ "Unknown BYTEORDER\n"); -#else - I32 o; - I32 s; - - u.l = l; - l = 0; - for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) { - l |= (u.c[o & 0xf] & 255) << s; - } - return l; -#endif -#endif -} - -#endif /* BYTEORDER != 0x4321 */ -#endif /* MYSWAP */ - -/* - * Little-endian byte order functions - 'v' for 'VAX', or 'reVerse'. - * If these functions are defined, - * the BYTEORDER is neither 0x1234 nor 0x4321. - * However, this is not assumed. - * -DWS - */ - -#define HTOLE(name,type) \ - type \ - name (register type n) \ - { \ - union { \ - type value; \ - char c[sizeof(type)]; \ - } u; \ - U32 i; \ - U32 s = 0; \ - for (i = 0; i < sizeof(u.c); i++, s += 8) { \ - u.c[i] = (n >> s) & 0xFF; \ - } \ - return u.value; \ - } - -#define LETOH(name,type) \ - type \ - name (register type n) \ - { \ - union { \ - type value; \ - char c[sizeof(type)]; \ - } u; \ - U32 i; \ - U32 s = 0; \ - u.value = n; \ - n = 0; \ - for (i = 0; i < sizeof(u.c); i++, s += 8) { \ - n |= ((type)(u.c[i] & 0xFF)) << s; \ - } \ - return n; \ - } - -/* - * Big-endian byte order functions. - */ - -#define HTOBE(name,type) \ - type \ - name (register type n) \ - { \ - union { \ - type value; \ - char c[sizeof(type)]; \ - } u; \ - U32 i; \ - U32 s = 8*(sizeof(u.c)-1); \ - for (i = 0; i < sizeof(u.c); i++, s -= 8) { \ - u.c[i] = (n >> s) & 0xFF; \ - } \ - return u.value; \ - } - -#define BETOH(name,type) \ - type \ - name (register type n) \ - { \ - union { \ - type value; \ - char c[sizeof(type)]; \ - } u; \ - U32 i; \ - U32 s = 8*(sizeof(u.c)-1); \ - u.value = n; \ - n = 0; \ - for (i = 0; i < sizeof(u.c); i++, s -= 8) { \ - n |= ((type)(u.c[i] & 0xFF)) << s; \ - } \ - return n; \ - } - -/* - * If we just can't do it... - */ - -#define NOT_AVAIL(name,type) \ - type \ - name (register type n) \ - { \ - Perl_croak_nocontext(#name "() not available"); \ - return n; /* not reached */ \ - } - - -#if defined(HAS_HTOVS) && !defined(htovs) -HTOLE(htovs,short) -#endif -#if defined(HAS_HTOVL) && !defined(htovl) -HTOLE(htovl,long) -#endif -#if defined(HAS_VTOHS) && !defined(vtohs) -LETOH(vtohs,short) -#endif -#if defined(HAS_VTOHL) && !defined(vtohl) -LETOH(vtohl,long) -#endif - -#ifdef PERL_NEED_MY_HTOLE16 -# if U16SIZE == 2 -HTOLE(Perl_my_htole16,U16) -# else -NOT_AVAIL(Perl_my_htole16,U16) -# endif -#endif -#ifdef PERL_NEED_MY_LETOH16 -# if U16SIZE == 2 -LETOH(Perl_my_letoh16,U16) -# else -NOT_AVAIL(Perl_my_letoh16,U16) -# endif -#endif -#ifdef PERL_NEED_MY_HTOBE16 -# if U16SIZE == 2 -HTOBE(Perl_my_htobe16,U16) -# else -NOT_AVAIL(Perl_my_htobe16,U16) -# endif -#endif -#ifdef PERL_NEED_MY_BETOH16 -# if U16SIZE == 2 -BETOH(Perl_my_betoh16,U16) -# else -NOT_AVAIL(Perl_my_betoh16,U16) -# endif -#endif - -#ifdef PERL_NEED_MY_HTOLE32 -# if U32SIZE == 4 -HTOLE(Perl_my_htole32,U32) -# else -NOT_AVAIL(Perl_my_htole32,U32) -# endif -#endif -#ifdef PERL_NEED_MY_LETOH32 -# if U32SIZE == 4 -LETOH(Perl_my_letoh32,U32) -# else -NOT_AVAIL(Perl_my_letoh32,U32) -# endif -#endif -#ifdef PERL_NEED_MY_HTOBE32 -# if U32SIZE == 4 -HTOBE(Perl_my_htobe32,U32) -# else -NOT_AVAIL(Perl_my_htobe32,U32) -# endif -#endif -#ifdef PERL_NEED_MY_BETOH32 -# if U32SIZE == 4 -BETOH(Perl_my_betoh32,U32) -# else -NOT_AVAIL(Perl_my_betoh32,U32) -# endif -#endif - -#ifdef PERL_NEED_MY_HTOLE64 -# if U64SIZE == 8 -HTOLE(Perl_my_htole64,U64) -# else -NOT_AVAIL(Perl_my_htole64,U64) -# endif -#endif -#ifdef PERL_NEED_MY_LETOH64 -# if U64SIZE == 8 -LETOH(Perl_my_letoh64,U64) -# else -NOT_AVAIL(Perl_my_letoh64,U64) -# endif -#endif -#ifdef PERL_NEED_MY_HTOBE64 -# if U64SIZE == 8 -HTOBE(Perl_my_htobe64,U64) -# else -NOT_AVAIL(Perl_my_htobe64,U64) -# endif -#endif -#ifdef PERL_NEED_MY_BETOH64 -# if U64SIZE == 8 -BETOH(Perl_my_betoh64,U64) -# else -NOT_AVAIL(Perl_my_betoh64,U64) -# endif -#endif - -#ifdef PERL_NEED_MY_HTOLES -HTOLE(Perl_my_htoles,short) -#endif -#ifdef PERL_NEED_MY_LETOHS -LETOH(Perl_my_letohs,short) -#endif -#ifdef PERL_NEED_MY_HTOBES -HTOBE(Perl_my_htobes,short) -#endif -#ifdef PERL_NEED_MY_BETOHS -BETOH(Perl_my_betohs,short) -#endif - -#ifdef PERL_NEED_MY_HTOLEI -HTOLE(Perl_my_htolei,int) -#endif -#ifdef PERL_NEED_MY_LETOHI -LETOH(Perl_my_letohi,int) -#endif -#ifdef PERL_NEED_MY_HTOBEI -HTOBE(Perl_my_htobei,int) -#endif -#ifdef PERL_NEED_MY_BETOHI -BETOH(Perl_my_betohi,int) -#endif - -#ifdef PERL_NEED_MY_HTOLEL -HTOLE(Perl_my_htolel,long) -#endif -#ifdef PERL_NEED_MY_LETOHL -LETOH(Perl_my_letohl,long) -#endif -#ifdef PERL_NEED_MY_HTOBEL -HTOBE(Perl_my_htobel,long) -#endif -#ifdef PERL_NEED_MY_BETOHL -BETOH(Perl_my_betohl,long) -#endif - -void -Perl_my_swabn(void *ptr, int n) -{ - char *s = (char *)ptr; - char *e = s + (n-1); - char tc; - - PERL_ARGS_ASSERT_MY_SWABN; - - for (n /= 2; n > 0; s++, e--, n--) { - tc = *s; - *s = *e; - *e = tc; - } -} - PerlIO * Perl_my_popen_list(pTHX_ const char *mode, int n, SV **args) { -#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(OS2) && !defined(VMS) && !defined(EPOC) && !defined(NETWARE) && !defined(__LIBCATAMOUNT__) +#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(OS2) && !defined(VMS) && !defined(NETWARE) && !defined(__LIBCATAMOUNT__) dVAR; int p[2]; I32 This, that; @@ -2630,7 +2300,7 @@ Perl_my_popen_list(pTHX_ const char *mode, int n, SV **args) } /* VMS' my_popen() is in VMS.c, same with OS/2. */ -#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(EPOC) && !defined(__LIBCATAMOUNT__) +#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__LIBCATAMOUNT__) PerlIO * Perl_my_popen(pTHX_ const char *cmd, const char *mode) { @@ -2777,20 +2447,6 @@ Perl_my_popen(pTHX_ const char *cmd, const char *mode) return PerlIO_fdopen(p[This], mode); } #else -#if defined(EPOC) -FILE *popen(); -PerlIO * -Perl_my_popen(pTHX_ const char *cmd, const char *mode) -{ - PERL_ARGS_ASSERT_MY_POPEN; - PERL_FLUSHALL_FOR_CHILD; - /* Call system's popen() to get a FILE *, then import it. - used 0 for 2nd parameter to PerlIO_importFILE; - apparently not used - */ - return PerlIO_importFILE(popen(cmd, mode), 0); -} -#else #if defined(DJGPP) FILE *djgpp_popen(); PerlIO * @@ -2812,7 +2468,6 @@ Perl_my_popen(pTHX_ const char *cmd, const char *mode) } #endif #endif -#endif #endif /* !DOSISH */ @@ -2823,6 +2478,9 @@ Perl_atfork_lock(void) dVAR; #if defined(USE_ITHREADS) /* locks must be held in locking order (if any) */ +# ifdef USE_PERLIO + MUTEX_LOCK(&PL_perlio_mutex); +# endif # ifdef MYMALLOC MUTEX_LOCK(&PL_malloc_mutex); # endif @@ -2837,6 +2495,9 @@ Perl_atfork_unlock(void) dVAR; #if defined(USE_ITHREADS) /* locks must be released in same order as in atfork_lock() */ +# ifdef USE_PERLIO + MUTEX_UNLOCK(&PL_perlio_mutex); +# endif # ifdef MYMALLOC MUTEX_UNLOCK(&PL_malloc_mutex); # endif @@ -3072,12 +2733,11 @@ Perl_rsignal_restore(pTHX_ int signo, Sigsave_t *save) #endif /* !PERL_MICRO */ /* VMS' my_pclose() is in VMS.c; same with OS/2 */ -#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(EPOC) && !defined(__LIBCATAMOUNT__) +#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__LIBCATAMOUNT__) I32 Perl_my_pclose(pTHX_ PerlIO *ptr) { dVAR; - Sigsave_t hstat, istat, qstat; int status; SV **svp; Pid_t pid; @@ -3105,19 +2765,9 @@ Perl_my_pclose(pTHX_ PerlIO *ptr) #endif close_failed = (PerlIO_close(ptr) == EOF); SAVE_ERRNO; -#ifndef PERL_MICRO - rsignal_save(SIGHUP, (Sighandler_t) SIG_IGN, &hstat); - rsignal_save(SIGINT, (Sighandler_t) SIG_IGN, &istat); - rsignal_save(SIGQUIT, (Sighandler_t) SIG_IGN, &qstat); -#endif if (should_wait) do { pid2 = wait4pid(pid, &status, 0); } while (pid2 == -1 && errno == EINTR); -#ifndef PERL_MICRO - rsignal_restore(SIGHUP, &hstat); - rsignal_restore(SIGINT, &istat); - rsignal_restore(SIGQUIT, &qstat); -#endif if (close_failed) { RESTORE_ERRNO; return -1; @@ -3236,7 +2886,7 @@ S_pidgone(pTHX_ Pid_t pid, int status) } #endif -#if defined(OS2) || defined(EPOC) +#if defined(OS2) int pclose(); #ifdef HAS_FORK int /* Cannot prototype with I32 @@ -3271,14 +2921,14 @@ Perl_my_pclose(pTHX_ PerlIO *ptr) #define PERL_REPEATCPY_LINEAR 4 void -Perl_repeatcpy(register char *to, register const char *from, I32 len, register IV count) +Perl_repeatcpy(char *to, const char *from, I32 len, IV count) { PERL_ARGS_ASSERT_REPEATCPY; assert(len >= 0); if (count < 0) - croak_memory_wrap(); + Perl_croak_memory_wrap(); if (len == 1) memset(to, *from, count); @@ -4135,7 +3785,7 @@ Fill the sv with current working directory * back into. */ int -Perl_getcwd_sv(pTHX_ register SV *sv) +Perl_getcwd_sv(pTHX_ SV *sv) { #ifndef PERL_MICRO dVAR; @@ -4525,7 +4175,7 @@ it doesn't. const char * Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) { - const char *start; + const char *start = s; const char *pos; const char *last; const char *errstr = NULL; @@ -4533,17 +4183,11 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) int width = 3; bool alpha = FALSE; bool vinf = FALSE; - AV * const av = newAV(); - SV * const hv = newSVrv(rv, "version"); /* create an SV and upgrade the RV */ + AV * av; + SV * hv; PERL_ARGS_ASSERT_SCAN_VERSION; - (void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */ - -#ifndef NODEFAULT_SHAREKEYS - HvSHAREKEYS_on(hv); /* key-sharing on by default */ -#endif - while (isSPACE(*s)) /* leading whitespace is OK */ s++; @@ -4551,6 +4195,7 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) if (errstr) { /* "undef" is a special case and not an error */ if ( ! ( *s == 'u' && strEQ(s,"undef")) ) { + Safefree(start); Perl_croak(aTHX_ "%s", errstr); } } @@ -4560,13 +4205,22 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) s++; pos = s; + /* Now that we are through the prescan, start creating the object */ + av = newAV(); + hv = newSVrv(rv, "version"); /* create an SV and upgrade the RV */ + (void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */ + +#ifndef NODEFAULT_SHAREKEYS + HvSHAREKEYS_on(hv); /* key-sharing on by default */ +#endif + if ( qv ) (void)hv_stores(MUTABLE_HV(hv), "qv", newSViv(qv)); if ( alpha ) (void)hv_stores(MUTABLE_HV(hv), "alpha", newSViv(alpha)); if ( !qv && width < 3 ) (void)hv_stores(MUTABLE_HV(hv), "width", newSViv(width)); - + while (isDIGIT(*pos)) pos++; if (!isALPHA(*pos)) { @@ -4737,7 +4391,7 @@ Perl_new_version(pTHX_ SV *ver) if ( hv_exists(MUTABLE_HV(ver), "alpha", 5) ) (void)hv_stores(MUTABLE_HV(hv), "alpha", newSViv(1)); - + if ( hv_exists(MUTABLE_HV(ver), "width", 5 ) ) { const I32 width = SvIV(*hv_fetchs(MUTABLE_HV(ver), "width", FALSE)); @@ -4815,8 +4469,11 @@ Perl_upg_version(pTHX_ SV *ver, bool qv) SV *sv = SvNVX(ver) > 10e50 ? newSV(64) : 0; char *buf; #ifdef USE_LOCALE_NUMERIC - char *loc = savepv(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, "C"); + char *loc = NULL; + if (! PL_numeric_standard) { + loc = savepv(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); + } #endif if (sv) { Perl_sv_setpvf(aTHX_ sv, "%.9"NVff, SvNVX(ver)); @@ -4827,8 +4484,10 @@ Perl_upg_version(pTHX_ SV *ver, bool qv) buf = tbuf; } #ifdef USE_LOCALE_NUMERIC - setlocale(LC_NUMERIC, loc); - Safefree(loc); + if (loc) { + setlocale(LC_NUMERIC, loc); + Safefree(loc); + } #endif while (buf[len-1] == '0' && len > 0) len--; if ( buf[len-1] == '.' ) len--; /* eat the trailing decimal */ @@ -4871,7 +4530,7 @@ Perl_upg_version(pTHX_ SV *ver, bool qv) } /* is definitely a v-string */ - if ( saw_decimal >= 2 ) { + if ( saw_decimal >= 2 ) { Safefree(version); version = nver; } @@ -5666,43 +5325,85 @@ Perl_seed(pTHX) return u; } -UV -Perl_get_hash_seed(pTHX) +void +Perl_get_hash_seed(pTHX_ unsigned char * const seed_buffer) { dVAR; - const char *s = PerlEnv_getenv("PERL_HASH_SEED"); - UV myseed = 0; - - if (s) - while (isSPACE(*s)) - s++; - if (s && isDIGIT(*s)) - myseed = (UV)Atoul(s); - else -#ifdef USE_HASH_SEED_EXPLICIT - if (s) -#endif - { - /* Compute a random seed */ - (void)seedDrand01((Rand_seed_t)seed()); - myseed = (UV)(Drand01() * (NV)UV_MAX); -#if RANDBITS < (UVSIZE * 8) - /* Since there are not enough randbits to to reach all - * the bits of a UV, the low bits might need extra - * help. Sum in another random number that will - * fill in the low bits. */ - myseed += - (UV)(Drand01() * (NV)((((UV)1) << ((UVSIZE * 8 - RANDBITS))) - 1)); -#endif /* RANDBITS < (UVSIZE * 8) */ - if (myseed == 0) { /* Superparanoia. */ - myseed = (UV)(Drand01() * (NV)UV_MAX); /* One more chance. */ - if (myseed == 0) - Perl_croak(aTHX_ "Your random numbers are not that random"); - } - } - PL_rehash_seed_set = TRUE; - - return myseed; + const char *env_pv; + unsigned long i; + + PERL_ARGS_ASSERT_GET_HASH_SEED; + + env_pv= PerlEnv_getenv("PERL_HASH_SEED"); + + if ( env_pv ) +#ifndef USE_HASH_SEED_EXPLICIT + { + /* ignore leading spaces */ + while (isSPACE(*env_pv)) + env_pv++; +#ifdef USE_PERL_PERTURB_KEYS + /* if they set it to "0" we disable key traversal randomization completely */ + if (strEQ(env_pv,"0")) { + PL_hash_rand_bits_enabled= 0; + } else { + /* otherwise switch to deterministic mode */ + PL_hash_rand_bits_enabled= 2; + } +#endif + /* ignore a leading 0x... if it is there */ + if (env_pv[0] == '0' && env_pv[1] == 'x') + env_pv += 2; + + for( i = 0; isXDIGIT(*env_pv) && i < PERL_HASH_SEED_BYTES; i++ ) { + seed_buffer[i] = READ_XDIGIT(env_pv) << 4; + if ( isXDIGIT(*env_pv)) { + seed_buffer[i] |= READ_XDIGIT(env_pv); + } + } + while (isSPACE(*env_pv)) + env_pv++; + + if (*env_pv && !isXDIGIT(*env_pv)) { + Perl_warn(aTHX_ "perl: warning: Non hex character in '$ENV{PERL_HASH_SEED}', seed only partially set\n"); + } + /* should we check for unparsed crap? */ + /* should we warn about unused hex? */ + /* should we warn about insufficient hex? */ + } + else +#endif + { + (void)seedDrand01((Rand_seed_t)seed()); + + for( i = 0; i < PERL_HASH_SEED_BYTES; i++ ) { + seed_buffer[i] = (unsigned char)(Drand01() * (U8_MAX+1)); + } + } +#ifdef USE_PERL_PERTURB_KEYS + { /* initialize PL_hash_rand_bits from the hash seed. + * This value is highly volatile, it is updated every + * hash insert, and is used as part of hash bucket chain + * randomization and hash iterator randomization. */ + PL_hash_rand_bits= 0xbe49d17f; /* I just picked a number */ + for( i = 0; i < sizeof(UV) ; i++ ) { + PL_hash_rand_bits += seed_buffer[i % PERL_HASH_SEED_BYTES]; + PL_hash_rand_bits = ROTL_UV(PL_hash_rand_bits,8); + } + } + env_pv= PerlEnv_getenv("PERL_PERTURB_KEYS"); + if (env_pv) { + if (strEQ(env_pv,"0") || strEQ(env_pv,"NO")) { + PL_hash_rand_bits_enabled= 0; + } else if (strEQ(env_pv,"1") || strEQ(env_pv,"RANDOM")) { + PL_hash_rand_bits_enabled= 1; + } else if (strEQ(env_pv,"2") || strEQ(env_pv,"DETERMINISTIC")) { + PL_hash_rand_bits_enabled= 2; + } else { + Perl_warn(aTHX_ "perl: warning: strange setting in '$ENV{PERL_PERTURB_KEYS}': '%s'\n", env_pv); + } + } +#endif } #ifdef PERL_GLOBAL_STRUCT @@ -6107,15 +5808,14 @@ Perl_my_clearenv(pTHX) (void)clearenv(); # elif defined(HAS_UNSETENV) int bsiz = 80; /* Most envvar names will be shorter than this. */ - int bufsiz = bsiz * sizeof(char); /* sizeof(char) paranoid? */ - char *buf = (char*)safesysmalloc(bufsiz); + char *buf = (char*)safesysmalloc(bsiz); while (*environ != NULL) { char *e = strchr(*environ, '='); int l = e ? e - *environ : (int)strlen(*environ); if (bsiz < l + 1) { (void)safesysfree(buf); bsiz = l + 1; /* + 1 for the \0. */ - buf = (char*)safesysmalloc(bufsiz); + buf = (char*)safesysmalloc(bsiz); } memcpy(buf, *environ, l); buf[l] = '\0'; @@ -6386,7 +6086,7 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv) { dVAR; SV * const dbsv = GvSVn(PL_DBsub); - const bool save_taint = TAINT_get; /* Accepted unused var warning under NO_TAINT_SUPPORT */ + const bool save_taint = TAINT_get; /* When we are called from pp_goto (svp is null), * we do not care about using dbsv to call CV; @@ -6437,6 +6137,9 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv) SvIV_set(dbsv, PTR2IV(cv)); /* Do it the quickest way */ } TAINT_IF(save_taint); +#ifdef NO_TAINT_SUPPORT + PERL_UNUSED_VAR(save_taint); +#endif } int