This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
avoid leaking lexicals into program being debugged (from Ilya
[perl5.git] / util.c
diff --git a/util.c b/util.c
index 5835556..13b0010 100644 (file)
--- a/util.c
+++ b/util.c
@@ -95,7 +95,8 @@ Perl_safesysmalloc(MEM_SIZE size)
        Perl_croak_nocontext("panic: malloc");
 #endif
     ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
-    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) malloc %ld bytes\n",ptr,PL_an++,(long)size));
+    PERL_ALLOC_CHECK(ptr);
+    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) malloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
     if (ptr != Nullch)
        return ptr;
     else if (PL_nomemok)
@@ -138,9 +139,10 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
        Perl_croak_nocontext("panic: realloc");
 #endif
     ptr = PerlMem_realloc(where,size);
-
-    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) rfree\n",where,PL_an++));
-    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) realloc %ld bytes\n",ptr,PL_an++,(long)size));
+    PERL_ALLOC_CHECK(ptr);
+    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) rfree\n",PTR2UV(where),(long)PL_an++));
+    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) realloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
 
     if (ptr != Nullch)
        return ptr;
@@ -160,7 +162,7 @@ Free_t
 Perl_safesysfree(Malloc_t where)
 {
     dTHX;
-    DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",(char *) where,PL_an++));
+    DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) free\n",PTR2UV(where),(long)PL_an++));
     if (where) {
        /*SUPPRESS 701*/
        PerlMem_free(where);
@@ -188,7 +190,8 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size)
 #endif
     size *= count;
     ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
-    DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) calloc %ld x %ld bytes\n",ptr,PL_an++,(long)count,(long)size));
+    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)size));
     if (ptr != Nullch) {
        memset((void*)ptr, 0, size);
        return ptr;
@@ -544,8 +547,6 @@ Perl_set_numeric_radix(pTHX)
     else
        PL_numeric_radix = 0;
 # endif /* HAS_LOCALECONV */
-#else
-    PL_numeric_radix = 0;
 #endif /* USE_LOCALE_NUMERIC */
 }
 
@@ -911,6 +912,15 @@ Perl_mem_collxfrm(pTHX_ const char *s, STRLEN len, STRLEN *xlen)
 
    If FBMcf_TAIL, the table is created as if the string has a trailing \n. */
 
+/*
+=for apidoc fbm_compile
+
+Analyses the string in order to make fast searches on it using fbm_instr()
+-- the Boyer-Moore algorithm.
+
+=cut
+*/
+
 void
 Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
 {
@@ -971,6 +981,17 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
 /* If SvTAIL is actually due to \Z or \z, this gives false positives
    if multiline */
 
+/*
+=for apidoc fbm_instr
+
+Returns the location of the SV in the string delimited by C<str> and
+C<strend>.  It returns C<Nullch> if the string can't be found.  The C<sv>
+does not have to be fbm_compiled, but the search will not be as fast
+then.
+
+=cut
+*/
+
 char *
 Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *littlestr, U32 flags)
 {
@@ -1303,6 +1324,14 @@ Perl_ibcmp_locale(pTHX_ const char *s1, const char *s2, register I32 len)
 
 /* copy a string to a safe spot */
 
+/*
+=for apidoc savepv
+
+Copy a string to a safe spot.  This does not use an SV.
+
+=cut
+*/
+
 char *
 Perl_savepv(pTHX_ const char *sv)
 {
@@ -1315,6 +1344,15 @@ Perl_savepv(pTHX_ const char *sv)
 
 /* same thing but with a known length */
 
+/*
+=for apidoc savepvn
+
+Copy a string to a safe spot.  The C<len> indicates number of bytes to
+copy.  This does not use an SV.
+
+=cut
+*/
+
 char *
 Perl_savepvn(pTHX_ const char *sv, register I32 len)
 {
@@ -1418,9 +1456,9 @@ Perl_vmess(pTHX_ const char *pat, va_list *args)
     sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
     if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') {
        dTHR;
-       if (PL_curcop->cop_line)
-           Perl_sv_catpvf(aTHX_ sv, " at %_ line %"IVdf,
-                     GvSV(PL_curcop->cop_filegv), (IV)PL_curcop->cop_line);
+       if (CopLINE(PL_curcop))
+           Perl_sv_catpvf(aTHX_ sv, " at %s line %"IVdf,
+                          CopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
        if (GvIO(PL_last_in_gv) && IoLINES(GvIOp(PL_last_in_gv))) {
            bool line_mode = (RsSIMPLE(PL_rs) &&
                              SvCUR(PL_rs) == 1 && *SvPVX(PL_rs) == '\n');
@@ -1497,11 +1535,7 @@ Perl_vdie(pTHX_ const char* pat, va_list *args)
            PUSHMARK(SP);
            XPUSHs(msg);
            PUTBACK;
-           /* HACK - REVISIT - avoid CATCH_SET(TRUE) in call_sv()
-              or we come back here due to a JMPENV_JMP() and do 
-              a POPSTACK - but die_where() will have already done 
-              one as it unwound - NI-S 1999/08/14 */
-           call_sv((SV*)cv, G_DISCARD|G_NOCATCH);
+           call_sv((SV*)cv, G_DISCARD);
            POPSTACK;
            LEAVE;
        }
@@ -1561,8 +1595,8 @@ Perl_vcroak(pTHX_ const char* pat, va_list *args)
     else
        message = SvPV(msv,msglen);
 
-    DEBUG_S(PerlIO_printf(Perl_debug_log, "croak: 0x%lx %s",
-                         (unsigned long) thr, message));
+    DEBUG_S(PerlIO_printf(Perl_debug_log, "croak: 0x%"UVxf" %s",
+                         PTR2UV(thr), message));
 
     if (PL_diehook) {
        /* sv_2cv might call Perl_croak() */
@@ -1623,6 +1657,16 @@ Perl_croak_nocontext(const char *pat, ...)
 }
 #endif /* PERL_IMPLICIT_CONTEXT */
 
+/*
+=for apidoc croak
+
+This is the XSUB-writer's interface to Perl's C<die> function.  Use this
+function the same way you use the C C<printf> function.  See
+C<warn>.
+
+=cut
+*/
+
 void
 Perl_croak(pTHX_ const char *pat, ...)
 {
@@ -1702,6 +1746,16 @@ Perl_warn_nocontext(const char *pat, ...)
 }
 #endif /* PERL_IMPLICIT_CONTEXT */
 
+/*
+=for apidoc warn
+
+This is the XSUB-writer's interface to Perl's C<warn> function.  Use this
+function the same way you use the C C<printf> function.  See
+C<croak>.
+
+=cut
+*/
+
 void
 Perl_warn(pTHX_ const char *pat, ...)
 {
@@ -1748,7 +1802,7 @@ Perl_vwarner(pTHX_ U32  err, const char* pat, va_list* args)
 
     if (ckDEAD(err)) {
 #ifdef USE_THREADS
-        DEBUG_S(PerlIO_printf(Perl_debug_log, "croak: 0x%lx %s", (unsigned long) thr, message));
+        DEBUG_S(PerlIO_printf(Perl_debug_log, "croak: 0x%"UVxf" %s", PTR2UV(thr), message));
 #endif /* USE_THREADS */
         if (PL_diehook) {
             /* sv_2cv might call Perl_croak() */
@@ -1892,7 +1946,7 @@ Perl_my_setenv_init(char ***penviron)
 }
 
 void
-my_setenv(char *nam, char *val)
+Perl_my_setenv(pTHX_ char *nam, char *val)
 {
     /* You can not directly manipulate the environ[] array because
      * the routines do some additional work that syncs the Cygwin
@@ -1904,13 +1958,13 @@ my_setenv(char *nam, char *val)
        if (!oldstr)
            return;
        unsetenv(nam);
-       Safefree(oldstr);
+       safesysfree(oldstr);
        return;
     }
     setenv(nam, val, 1);
     environ = *Perl_main_environ; /* environ realloc can occur in setenv */
     if(oldstr && environ[setenv_getix(nam)] != oldstr)
-       Safefree(oldstr);
+       safesysfree(oldstr);
 }
 #else /* if WIN32 */
 
@@ -2006,9 +2060,10 @@ Perl_unlnk(pTHX_ char *f)        /* unlink all versions of a file */
 }
 #endif
 
+/* this is a drop-in replacement for bcopy() */
 #if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY)
 char *
-Perl_my_bcopy(pTHX_ register const char *from,register char *to,register I32 len)
+Perl_my_bcopy(register const char *from,register char *to,register I32 len)
 {
     char *retval = to;
 
@@ -2026,9 +2081,10 @@ Perl_my_bcopy(pTHX_ register const char *from,register char *to,register I32 len
 }
 #endif
 
+/* this is a drop-in replacement for memset() */
 #ifndef HAS_MEMSET
 void *
-Perl_my_memset(pTHX_ register char *loc, register I32 ch, register I32 len)
+Perl_my_memset(register char *loc, register I32 ch, register I32 len)
 {
     char *retval = loc;
 
@@ -2038,9 +2094,10 @@ Perl_my_memset(pTHX_ register char *loc, register I32 ch, register I32 len)
 }
 #endif
 
+/* this is a drop-in replacement for bzero() */
 #if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
 char *
-Perl_my_bzero(pTHX_ register char *loc, register I32 len)
+Perl_my_bzero(register char *loc, register I32 len)
 {
     char *retval = loc;
 
@@ -2050,9 +2107,10 @@ Perl_my_bzero(pTHX_ register char *loc, register I32 len)
 }
 #endif
 
+/* this is a drop-in replacement for memcmp() */
 #if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
 I32
-Perl_my_memcmp(pTHX_ const char *s1, const char *s2, register I32 len)
+Perl_my_memcmp(const char *s1, const char *s2, register I32 len)
 {
     register U8 *a = (U8 *)s1;
     register U8 *b = (U8 *)s2;
@@ -2228,7 +2286,7 @@ VTOH(vtohl,long)
 #endif
 
     /* VMS' my_popen() is in VMS.c, same with OS/2. */
-#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC)
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
 PerlIO *
 Perl_my_popen(pTHX_ char *cmd, char *mode)
 {
@@ -2305,7 +2363,7 @@ Perl_my_popen(pTHX_ char *cmd, char *mode)
 #endif /* defined OS2 */
        /*SUPPRESS 560*/
        if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
-           sv_setiv(GvSV(tmpgv), getpid());
+           sv_setiv(GvSV(tmpgv), PerlProc_getpid());
        PL_forkprocess = 0;
        hv_clear(PL_pidstatus); /* we have no children */
        return Nullfp;
@@ -2500,7 +2558,7 @@ Perl_rsignal_state(pTHX_ int signo)
     oldsig = PerlProc_signal(signo, sig_trap);
     PerlProc_signal(signo, oldsig);
     if (sig_trapped)
-        PerlProc_kill(getpid(), signo);
+        PerlProc_kill(PerlProc_getpid(), signo);
     return oldsig;
 }
 
@@ -2520,7 +2578,7 @@ Perl_rsignal_restore(pTHX_ int signo, Sigsave_t *save)
 #endif /* !HAS_SIGACTION */
 
     /* VMS' my_pclose() is in VMS.c; same with OS/2 */
-#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC)
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
 I32
 Perl_my_pclose(pTHX_ PerlIO *ptr)
 {
@@ -2576,7 +2634,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr)
 }
 #endif /* !DOSISH */
 
-#if  !defined(DOSISH) || defined(OS2) || defined(WIN32)
+#if  (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
 I32
 Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
 {
@@ -2587,7 +2645,7 @@ Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
     if (!pid)
        return -1;
     if (pid > 0) {
-       sprintf(spid, "%d", pid);
+       sprintf(spid, "%"IVdf, (IV)pid);
        svp = hv_fetch(PL_pidstatus,spid,strlen(spid),FALSE);
        if (svp && *svp != &PL_sv_undef) {
            *statusp = SvIVX(*svp);
@@ -2603,7 +2661,7 @@ Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
            pid = atoi(hv_iterkey(entry,(I32*)statusp));
            sv = hv_iterval(PL_pidstatus,entry);
            *statusp = SvIVX(sv);
-           sprintf(spid, "%d", pid);
+           sprintf(spid, "%"IVdf, (IV)pid);
            (void)hv_delete(PL_pidstatus,spid,strlen(spid),G_DISCARD);
            return pid;
        }
@@ -2643,7 +2701,7 @@ Perl_pidgone(pTHX_ Pid_t pid, int status)
     register SV *sv;
     char spid[TYPE_CHARS(int)];
 
-    sprintf(spid, "%d", pid);
+    sprintf(spid, "%"IVdf, (IV)pid);
     sv = *hv_fetch(PL_pidstatus,spid,strlen(spid),TRUE);
     (void)SvUPGRADE(sv,SVt_IV);
     SvIVX(sv) = status;
@@ -3126,15 +3184,26 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
     }
 #endif
 
+#ifdef MACOS_TRADITIONAL
+    if (dosearch && !strchr(scriptname, ':') &&
+       (s = PerlEnv_getenv("Commands")))
+#else
     if (dosearch && !strchr(scriptname, '/')
 #ifdef DOSISH
                 && !strchr(scriptname, '\\')
 #endif
-                && (s = PerlEnv_getenv("PATH"))) {
+                && (s = PerlEnv_getenv("PATH")))
+#endif
+    {
        bool seen_dot = 0;
        
        PL_bufend = s + strlen(s);
        while (s < PL_bufend) {
+#ifdef MACOS_TRADITIONAL
+           s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf, s, PL_bufend,
+                       ',',
+                       &len);
+#else
 #if defined(atarist) || defined(DOSISH)
            for (len = 0; *s
 #  ifdef atarist
@@ -3151,10 +3220,15 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
                        ':',
                        &len);
 #endif /* ! (atarist || DOSISH) */
+#endif /* MACOS_TRADITIONAL */
            if (s < PL_bufend)
                s++;
            if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tmpbuf)
                continue;       /* don't search dir with too-long name */
+#ifdef MACOS_TRADITIONAL
+           if (len && tmpbuf[len - 1] != ':')
+               tmpbuf[len++] = ':';
+#else
            if (len
 #if defined(atarist) || defined(__MINT__) || defined(DOSISH)
                && tmpbuf[len - 1] != '/'
@@ -3164,6 +3238,7 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
                tmpbuf[len++] = '/';
            if (len == 2 && tmpbuf[0] == '.')
                seen_dot = 1;
+#endif
            (void)strcpy(tmpbuf + len, scriptname);
 #endif  /* !VMS */
 
@@ -3188,7 +3263,7 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
                continue;
            if (S_ISREG(PL_statbuf.st_mode)
                && cando(S_IRUSR,TRUE,&PL_statbuf)
-#ifndef DOSISH
+#if !defined(DOSISH) && !defined(MACOS_TRADITIONAL)
                && cando(S_IXUSR,TRUE,&PL_statbuf)
 #endif
                )
@@ -3325,11 +3400,11 @@ Perl_condpair_magic(pTHX_ SV *sv)
        COND_INIT(&cp->owner_cond);
        COND_INIT(&cp->cond);
        cp->owner = 0;
-       MUTEX_LOCK(&PL_cred_mutex);             /* XXX need separate mutex? */
+       LOCK_CRED_MUTEX;                /* XXX need separate mutex? */
        mg = mg_find(sv, 'm');
        if (mg) {
            /* someone else beat us to initialising it */
-           MUTEX_UNLOCK(&PL_cred_mutex);       /* XXX need separate mutex? */
+           UNLOCK_CRED_MUTEX;          /* XXX need separate mutex? */
            MUTEX_DESTROY(&cp->mutex);
            COND_DESTROY(&cp->owner_cond);
            COND_DESTROY(&cp->cond);
@@ -3340,7 +3415,7 @@ Perl_condpair_magic(pTHX_ SV *sv)
            mg = SvMAGIC(sv);
            mg->mg_ptr = (char *)cp;
            mg->mg_len = sizeof(cp);
-           MUTEX_UNLOCK(&PL_cred_mutex);       /* XXX need separate mutex? */
+           UNLOCK_CRED_MUTEX;          /* XXX need separate mutex? */
            DEBUG_S(WITH_THR(PerlIO_printf(Perl_debug_log,
                                           "%p: condpair_magic %p\n", thr, sv));)
        }
@@ -3382,8 +3457,6 @@ Perl_new_struct_thread(pTHX_ struct perl_thread *t)
     Zero(thr, 1, struct perl_thread);
 #endif
 
-    PL_protect = MEMBER_TO_FPTR(Perl_default_protect);
-
     thr->oursv = sv;
     init_stacks();
 
@@ -3396,18 +3469,7 @@ Perl_new_struct_thread(pTHX_ struct perl_thread *t)
     thr->flags = THRf_R_JOINABLE;
     MUTEX_INIT(&thr->mutex);
 
-    /* top_env needs to be non-zero. It points to an area
-       in which longjmp() stuff is stored, as C callstack
-       info there at least is thread specific this has to
-       be per-thread. Otherwise a 'die' in a thread gives
-       that thread the C stack of last thread to do an eval {}!
-       See comments in scope.h    
-       Initialize top entry (as in perl.c for main thread)
-     */
-    PL_start_env.je_prev = NULL;
-    PL_start_env.je_ret = -1;
-    PL_start_env.je_mustcatch = TRUE;
-    PL_top_env  = &PL_start_env;
+    JMPENV_BOOTSTRAP;
 
     PL_in_eval = EVAL_NULL;    /* ~(EVAL_INEVAL|EVAL_WARNONLY|EVAL_KEEPERR) */
     PL_restartop = 0;
@@ -3447,9 +3509,12 @@ Perl_new_struct_thread(pTHX_ struct perl_thread *t)
     PL_ofs = savepvn(t->Tofs, PL_ofslen);
     PL_defoutgv = (GV*)SvREFCNT_inc(t->Tdefoutgv);
     PL_chopset = t->Tchopset;
-    PL_formtarget = newSVsv(t->Tformtarget);
     PL_bodytarget = newSVsv(t->Tbodytarget);
     PL_toptarget = newSVsv(t->Ttoptarget);
+    if (t->Tformtarget == t->Ttoptarget)
+       PL_formtarget = PL_toptarget;
+    else
+       PL_formtarget = PL_bodytarget;
 
     /* Initialise all per-thread SVs that the template thread used */
     svp = AvARRAY(t->threadsv);
@@ -3459,7 +3524,8 @@ Perl_new_struct_thread(pTHX_ struct perl_thread *t)
            av_store(thr->threadsv, i, sv);
            sv_magic(sv, 0, 0, &PL_threadsv_names[i], 1);
            DEBUG_S(PerlIO_printf(Perl_debug_log,
-               "new_struct_thread: copied threadsv %d %p->%p\n",i, t, thr));
+               "new_struct_thread: copied threadsv %"IVdf" %p->%p\n",
+                                 (IV)i, t, thr));
        }
     } 
     thr->threadsvp = AvARRAY(thr->threadsv);
@@ -3693,7 +3759,8 @@ Perl_my_fflush_all(pTHX)
 }
 
 NV
-Perl_my_atof(pTHX_ const char* s) {
+Perl_my_atof(pTHX_ const char* s)
+{
 #ifdef USE_LOCALE_NUMERIC
     if ((PL_hints & HINT_LOCALE) && PL_numeric_local) {
        NV x, y;
@@ -3712,3 +3779,23 @@ Perl_my_atof(pTHX_ const char* s) {
     return Perl_atof(s);
 #endif
 }
+
+void
+Perl_report_closed_fh(pTHX_ GV *gv, IO *io, const char *func, const char *obj)
+{
+    SV *sv;
+    char *name;
+
+    assert(gv);
+
+    sv = sv_newmortal();
+    gv_efullname3(sv, gv, Nullch);
+    name = SvPVX(sv);
+
+    Perl_warner(aTHX_ WARN_CLOSED, "%s() on closed %s %s", func, obj, name);
+
+    if (io && IoDIRP(io))
+       Perl_warner(aTHX_ WARN_CLOSED,
+                   "(Are you trying to call %s() on dirhandle %s?)\n",
+                   func, name);
+}