Possible cure for
[p5sagit/p5-mst-13.2.git] / perl.c
diff --git a/perl.c b/perl.c
index bc69454..113d3bd 100644 (file)
--- a/perl.c
+++ b/perl.c
 #include "perl.h"
 #include "patchlevel.h"                        /* for local_patches */
 
+#ifdef NETWARE
+#include "nwutil.h"    
+char *nw_get_sitelib(const char *pl);
+#endif
+
 /* XXX If this causes problems, set i_unistd=undef in the hint file.  */
 #ifdef I_UNISTD
 #include <unistd.h>
@@ -303,7 +308,7 @@ no threads.
 */
 
 int
-Perl_nothreadhook(pTHXx)
+Perl_nothreadhook(pTHX)
 {
     return 0;
 }
@@ -425,6 +430,9 @@ perl_destruct(pTHXx)
     LEAVE;
     FREETMPS;
 
+    /* Need to flush since END blocks can produce output */
+    PerlIO_flush((PerlIO*)NULL);
+
     if (CALL_FPTR(PL_threadhook)(aTHX)) {
         /* Threads hook has vetoed further cleanup */
         return STATUS_NATIVE_EXPORT;;
@@ -434,7 +442,8 @@ perl_destruct(pTHXx)
 
     /* Destroy the main CV and syntax tree */
     if (PL_main_root) {
-       PL_curpad = AvARRAY(PL_comppad);
+        /* If running under -d may not have PL_comppad. */
+        PL_curpad = PL_comppad ? AvARRAY(PL_comppad) : NULL;
        op_free(PL_main_root);
        PL_main_root = Nullop;
     }
@@ -490,7 +499,13 @@ perl_destruct(pTHXx)
      * so we certainly shouldn't free it here
      */
 #if defined(USE_ENVIRON_ARRAY) && !defined(PERL_USE_SAFE_PUTENV)
-    if (environ != PL_origenviron) {
+    if (environ != PL_origenviron
+#ifdef USE_ITHREADS
+       /* only main thread can free environ[0] contents */
+       && PL_curinterp == aTHX
+#endif
+       )
+    {
        I32 i;
 
        for (i = 0; environ[i]; i++)
@@ -686,6 +701,8 @@ perl_destruct(pTHXx)
     SvREFCNT_dec(PL_utf8_totitle);
     SvREFCNT_dec(PL_utf8_tolower);
     SvREFCNT_dec(PL_utf8_tofold);
+    SvREFCNT_dec(PL_utf8_idstart);
+    SvREFCNT_dec(PL_utf8_idcont);
     PL_utf8_alnum      = Nullsv;
     PL_utf8_alnumc     = Nullsv;
     PL_utf8_ascii      = Nullsv;
@@ -704,6 +721,8 @@ perl_destruct(pTHXx)
     PL_utf8_totitle    = Nullsv;
     PL_utf8_tolower    = Nullsv;
     PL_utf8_tofold     = Nullsv;
+    PL_utf8_idstart    = Nullsv;
+    PL_utf8_idcont     = Nullsv;
 
     if (!specialWARN(PL_compiling.cop_warnings))
        SvREFCNT_dec(PL_compiling.cop_warnings);
@@ -813,8 +832,15 @@ perl_destruct(pTHXx)
     SvANY(&PL_sv_no) = NULL;
     SvFLAGS(&PL_sv_no) = 0;
 
-    SvREFCNT(&PL_sv_undef) = 0;
-    SvREADONLY_off(&PL_sv_undef);
+    {
+        int i;
+        for (i=0; i<=2; i++) {
+            SvREFCNT(PERL_DEBUG_PAD(i)) = 0;
+            sv_clear(PERL_DEBUG_PAD(i));
+            SvANY(PERL_DEBUG_PAD(i)) = NULL;
+            SvFLAGS(PERL_DEBUG_PAD(i)) = 0;
+        }
+    }
 
     if (PL_sv_count != 0 && ckWARN_d(WARN_INTERNAL))
        Perl_warner(aTHX_ packWARN(WARN_INTERNAL),"Scalars leaked: %ld\n", (long)PL_sv_count);
@@ -824,6 +850,13 @@ perl_destruct(pTHXx)
     PerlIO_cleanup(aTHX);
 #endif
 
+    /* sv_undef needs to stay immortal until after PerlIO_cleanup
+       as currently layers use it rather than Nullsv as a marker
+       for no arg - and will try and SvREFCNT_dec it.
+     */
+    SvREFCNT(&PL_sv_undef) = 0;
+    SvREADONLY_off(&PL_sv_undef);
+
     Safefree(PL_origfilename);
     Safefree(PL_reg_start_tmp);
     if (PL_reg_curpm)
@@ -908,7 +941,7 @@ perl_free(pTHXx)
 #    endif
     PerlMem_free(aTHXx);
 #    ifdef NETWARE
-    nw5_delete_internal_host(host);
+    nw_delete_internal_host(host);
 #    else
     win32_delete_internal_host(host);
 #    endif
@@ -1446,10 +1479,15 @@ print \"  \\@INC:\\n    @INC\\n\";");
     if (!PL_do_undump)
        init_postdump_symbols(argc,argv,env);
 
+    /* PL_wantutf8 is conditionally turned on by
+     * locale.c:Perl_init_i18nl10n() if the environment
+     * look like the user wants to use UTF-8. */
     if (PL_wantutf8) { /* Requires init_predump_symbols(). */
         IO* io;
         PerlIO* fp;
         SV* sv;
+        /* Turn on UTF-8-ness on STDIN, STDOUT, STDERR
+         *  _and_ the default open discipline. */
         if (PL_stdingv  && (io = GvIO(PL_stdingv))  && (fp = IoIFP(io)))
              PerlIO_binmode(aTHX_ fp, IoTYPE(io), 0, ":utf8");
         if (PL_defoutgv && (io = GvIO(PL_defoutgv)) && (fp = IoOFP(io)))
@@ -1616,7 +1654,9 @@ S_run_body(pTHX_ I32 oldscope)
 
        if (PL_minus_c) {
 #ifdef MACOS_TRADITIONAL
-           PerlIO_printf(Perl_error_log, "# %s syntax OK\n", MacPerl_MPWFileName(PL_origfilename));
+           PerlIO_printf(Perl_error_log, "%s%s syntax OK\n",
+               (gMacPerl_ErrorFormat ? "# " : ""),
+               MacPerl_MPWFileName(PL_origfilename));
 #else
            PerlIO_printf(Perl_error_log, "%s syntax OK\n", PL_origfilename);
 #endif
@@ -2240,7 +2280,7 @@ Perl_moreswitches(pTHX_ char *s)
        else if (!rschar && numlen >= 2)
            PL_rs = newSVpvn("", 0);
        else {
-           char ch = rschar;
+           char ch = (char)rschar;
            PL_rs = newSVpvn(&ch, 1);
        }
        return s + numlen;
@@ -2325,10 +2365,16 @@ Perl_moreswitches(pTHX_ char *s)
     }  
     case 'h':
        usage(PL_origargv[0]);
-       PerlProc_exit(0);
+       my_exit(0);
     case 'i':
        if (PL_inplace)
            Safefree(PL_inplace);
+#if defined(__CYGWIN__) /* do backup extension automagically */
+       if (*(s+1) == '\0') {
+       PL_inplace = savepv(".bak");
+       return s+1;
+       }
+#endif /* __CYGWIN__ */
        PL_inplace = savepv(s+1);
        /*SUPPRESS 530*/
        for (s = PL_inplace; *s && !isSPACE(*s); s++) ;
@@ -2557,7 +2603,7 @@ GNU General Public License, which may be found in the Perl 5 source kit.\n\n\
 Complete documentation for Perl, including FAQ lists, should be found on\n\
 this system using `man perl' or `perldoc perl'.  If you have access to the\n\
 Internet, point your browser at http://www.perl.com/, the Perl Home Page.\n\n");
-       PerlProc_exit(0);
+       my_exit(0);
     case 'w':
        if (! (PL_dowarn & G_WARN_ALL_MASK))
            PL_dowarn |= G_WARN_ON;
@@ -2686,8 +2732,6 @@ S_init_main_stash(pTHX)
 {
     GV *gv;
 
-
-
     PL_curstash = PL_defstash = newHV();
     PL_curstname = newSVpvn("main",4);
     gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
@@ -2932,7 +2976,7 @@ S_fd_on_nosuid_fs(pTHX_ int fd)
         defined(HAS_STRUCT_FS_DATA)    && \
         defined(NOSTAT_ONE)
 #   define FD_ON_NOSUID_CHECK_OKAY
-    struct stat fdst;
+    Stat_t fdst;
 
     if (fstat(fd, &fdst) == 0) {
         struct ustat us;
@@ -2962,7 +3006,7 @@ S_fd_on_nosuid_fs(pTHX_ int fd)
 #   define FD_ON_NOSUID_CHECK_OKAY
     FILE                *mtab = fopen("/etc/mtab", "r");
     struct mntent       *entry;
-    struct stat         stb, fsb;
+    Stat_t              stb, fsb;
 
     if (mtab && (fstat(fd, &stb) == 0)) {
         while (entry = getmntent(mtab)) {
@@ -3042,7 +3086,7 @@ S_validate_suid(pTHX_ char *validarg, char *scriptname, int fdscript)
         * Then we just have to make sure he or she can execute it.
         */
        {
-           struct stat tmpstatbuf;
+           Stat_t tmpstatbuf;
 
            if (
 #ifdef HAS_SETREUID
@@ -3485,6 +3529,17 @@ S_procself_val(pTHX_ SV *sv, char *arg0)
 {
     char buf[MAXPATHLEN];
     int len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1);
+
+    /* On Playstation2 Linux V1.0 (kernel 2.2.1) readlink(/proc/self/exe)
+       includes a spurious NUL which will cause $^X to fail in system
+       or backticks (this will prevent extensions from being built and
+       many tests from working). readlink is not meant to add a NUL.
+       Normal readlink works fine.
+     */
+    if (len > 0 && buf[len-1] == '\0') {
+      len--;
+    }
+
     /* FreeBSD's implementation is acknowledged to be imperfect, sometimes
        returning the text "unknown" from the readlink rather than the path
        to the executable (or returning an error from the readlink).  Any valid
@@ -3552,8 +3607,14 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
        */
        if (!env)
            env = environ;
-       if (env != environ)
+       if (env != environ
+#  ifdef USE_ITHREADS
+           && PL_curinterp == aTHX
+#  endif
+          )
+       {
            environ[0] = Nullch;
+       }
        if (env)
          for (; *env; env++) {
            if (!(s = strchr(*env,'=')))
@@ -3576,6 +3637,14 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
        sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
         SvREADONLY_on(GvSV(tmpgv));
     }
+
+    /* touch @F array to prevent spurious warnings 20020415 MJD */
+    if (PL_minus_a) {
+      (void) get_av("main::F", TRUE | GV_ADDMULTI);
+    }
+    /* touch @- and @+ arrays to prevent spurious warnings 20020415 MJD */
+    (void) get_av("main::-", TRUE | GV_ADDMULTI);
+    (void) get_av("main::+", TRUE | GV_ADDMULTI);
 }
 
 STATIC void
@@ -3615,7 +3684,7 @@ S_init_perllib(pTHX)
 #endif
 #ifdef MACOS_TRADITIONAL
     {
-       struct stat tmpstatbuf;
+       Stat_t tmpstatbuf;
        SV * privdir = NEWSV(55, 0);
        char * macperl = PerlEnv_getenv("MACPERL");
        
@@ -3743,8 +3812,11 @@ S_incpush(pTHX_ char *p, int addsubdirs, int addoldvers)
            p = Nullch; /* break out */
        }
 #ifdef MACOS_TRADITIONAL
-       if (!strchr(SvPVX(libdir), ':'))
-           sv_insert(libdir, 0, 0, ":", 1);
+       if (!strchr(SvPVX(libdir), ':')) {
+           char buf[256];
+
+           sv_setpv(libdir, MacPerl_CanonDir(SvPVX(libdir), buf, 0));
+       }
        if (SvPVX(libdir)[SvCUR(libdir)-1] != ':')
            sv_catpv(libdir, ":");
 #endif
@@ -3759,7 +3831,7 @@ S_incpush(pTHX_ char *p, int addsubdirs, int addoldvers)
            const char *incverlist[] = { PERL_INC_VERSION_LIST };
            const char **incver;
 #endif
-           struct stat tmpstatbuf;
+           Stat_t tmpstatbuf;
 #ifdef VMS
            char *unix;
            STRLEN len;