This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[win32] merge change#904 from maintbranch
[perl5.git] / perl.c
diff --git a/perl.c b/perl.c
index 9595fd2..2fdac45 100644 (file)
--- a/perl.c
+++ b/perl.c
 char *getenv _((char *)); /* Usually in <stdlib.h> */
 #endif
 
+#ifdef I_FCNTL
+#include <fcntl.h>
+#endif
+#ifdef I_SYS_FILE
+#include <sys/file.h>
+#endif
+
 dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n";
 
 #ifdef IAMSUID
@@ -130,6 +137,9 @@ perl_construct(register PerlInterpreter *sv_interp)
        COND_INIT(&eval_cond);
        MUTEX_INIT(&threads_mutex);
        COND_INIT(&nthreads_cond);
+#ifdef EMULATE_ATOMIC_REFCOUNTS
+       MUTEX_INIT(&svref_mutex);
+#endif /* EMULATE_ATOMIC_REFCOUNTS */
        
        thr = init_main_thread();
 #endif /* USE_THREADS */
@@ -166,6 +176,7 @@ perl_construct(register PerlInterpreter *sv_interp)
 #endif
     }
 
+    init_stacks(ARGS);
 #ifdef MULTIPLICITY
     I_REINIT;
     perl_destruct_level = 1; 
@@ -197,11 +208,11 @@ perl_construct(register PerlInterpreter *sv_interp)
     localpatches = local_patches;      /* For possible -v */
 #endif
 
-    PerlIO_init();      /* Hook to IO system */
+    PerlIO_init();                     /* Hook to IO system */
 
-    fdpid = newAV();   /* for remembering popen pids by fd */
+    fdpid = newAV();                   /* for remembering popen pids by fd */
+    modglobal = newHV();               /* pointers to per-interpreter module globals */
 
-    init_stacks(ARGS);
     DEBUG( {
        New(51,debname,128,char);
        New(52,debdelim,128,char);
@@ -317,6 +328,7 @@ perl_destruct(register PerlInterpreter *sv_interp)
        op_free(main_root);
        main_root = Nullop;
     }
+    curcop = &compiling;
     main_start = Nullop;
     SvREFCNT_dec(main_cv);
     main_cv = Nullcv;
@@ -340,6 +352,12 @@ perl_destruct(register PerlInterpreter *sv_interp)
     SvREFCNT_dec(parsehook);
     parsehook = Nullsv;
 
+    /* call exit list functions */
+    while (exitlistlen-- > 0)
+       exitlist[exitlistlen].fn(exitlist[exitlistlen].ptr);
+
+    Safefree(exitlist);
+
     if (destruct_level == 0){
 
        DEBUG_P(debprofdump());
@@ -420,10 +438,6 @@ perl_destruct(register PerlInterpreter *sv_interp)
     endav = Nullav;
     initav = Nullav;
 
-    /* temp stack during pp_sort() */
-    SvREFCNT_dec(sortstack);
-    sortstack = Nullav;
-
     /* shortcuts just get cleared */
     envgv = Nullgv;
     siggv = Nullgv;
@@ -545,6 +559,15 @@ perl_free(PerlInterpreter *sv_interp)
     Safefree(sv_interp);
 }
 
+void
+perl_atexit(void (*fn) (void *), void *ptr)
+{
+    Renew(exitlist, exitlistlen+1, PerlExitListEntry);
+    exitlist[exitlistlen].fn = fn;
+    exitlist[exitlistlen].ptr = ptr;
+    ++exitlistlen;
+}
+
 int
 perl_parse(PerlInterpreter *sv_interp, void (*xsinit) (void), int argc, char **argv, char **env)
 {
@@ -556,6 +579,7 @@ perl_parse(PerlInterpreter *sv_interp, void (*xsinit) (void), int argc, char **a
     char *validarg = "";
     I32 oldscope;
     AV* comppadlist;
+    int e_tmpfd = -1;
     dJMPENV;
     int ret;
 
@@ -644,6 +668,7 @@ setuid perl scripts securely.\n");
        s = argv[0]+1;
       reswitch:
        switch (*s) {
+       case ' ':
        case '0':
        case 'F':
        case 'a':
@@ -675,13 +700,36 @@ setuid perl scripts securely.\n");
            if (euid != uid || egid != gid)
                croak("No -e allowed in setuid scripts");
            if (!e_fp) {
+#if defined(HAS_UMASK) && !defined(VMS)
+               int oldumask = PerlLIO_umask(0177);
+#endif
                e_tmpname = savepv(TMPPATH);
+#ifdef HAS_MKSTEMP
+               e_tmpfd = PerlLIO_mkstemp(e_tmpname);
+#else /* use mktemp() */
                (void)PerlLIO_mktemp(e_tmpname);
                if (!*e_tmpname)
-                   croak("Can't mktemp()");
+                   croak("Cannot generate temporary filename");
+# if defined(HAS_OPEN3) && defined(O_EXCL)
+               e_tmpfd = open(e_tmpname,
+                              O_WRONLY | O_CREAT | O_EXCL,
+                              0600);
+# else
+               (void)UNLINK(e_tmpname);
+               /* Yes, potential race.  But at least we can say we tried. */
                e_fp = PerlIO_open(e_tmpname,"w");
-               if (!e_fp)
-                   croak("Cannot open temporary file");
+# endif
+#endif /* ifdef HAS_MKSTEMP */
+#if defined(HAS_MKSTEMP) || (defined(HAS_OPEN3) && defined(O_EXCL))
+               if (e_tmpfd < 0)
+                   croak("Cannot create temporary file \"%s\"", e_tmpname);
+               e_fp = PerlIO_fdopen(e_tmpfd,"w");
+#endif
+               if (!e_fp)
+                   croak("Cannot create temporary file \"%s\"", e_tmpname);
+#if defined(HAS_UMASK) && !defined(VMS)
+               (void)PerlLIO_umask(oldumask);
+#endif
            }
            if (*++s)
                PerlIO_puts(e_fp,s);
@@ -913,6 +961,7 @@ print \"  \\@INC:\\n    @INC\\n\";");
        (void)UNLINK(e_tmpname);
        Safefree(e_tmpname);
        e_tmpname = Nullch;
+       e_tmpfd = -1;
     }
 
     /* now that script is parsed, we can modify record separator */
@@ -942,7 +991,7 @@ print \"  \\@INC:\\n    @INC\\n\";");
 int
 perl_run(PerlInterpreter *sv_interp)
 {
-    dTHR;
+    dSP;
     I32 oldscope;
     dJMPENV;
     int ret;
@@ -978,10 +1027,7 @@ perl_run(PerlInterpreter *sv_interp)
            JMPENV_POP;
            return 1;
        }
-       if (curstack != mainstack) {
-           dSP;
-           SWITCHSTACK(curstack, mainstack);
-       }
+       POPSTACK_TO(mainstack);
        break;
     }
 
@@ -1089,7 +1135,7 @@ perl_call_argv(char *sub_name, I32 flags, register char **argv)
 {
     dSP;
 
-    PUSHMARK(sp);
+    PUSHMARK(SP);
     if (argv) {
        while (*argv) {
            XPUSHs(sv_2mortal(newSVpv(*argv,0)));
@@ -1129,9 +1175,8 @@ perl_call_sv(SV *sv, I32 flags)
        
                        /* See G_* flags in cop.h */
 {
-    dTHR;
+    dSP;
     LOGOP myop;                /* fake syntax tree node */
-    SV** sp = stack_sp;
     I32 oldmark;
     I32 retval;
     I32 oldscope;
@@ -1166,7 +1211,8 @@ perl_call_sv(SV *sv, I32 flags)
          && (DBcv || (DBcv = GvCV(DBsub)))
           /* Try harder, since this may have been a sighandler, thus
            * curstash may be meaningless. */
-         && (SvTYPE(sv) != SVt_PVCV || CvSTASH((CV*)sv) != debstash))
+         && (SvTYPE(sv) != SVt_PVCV || CvSTASH((CV*)sv) != debstash)
+         && !(flags & G_NODEBUG))
        op->op_private |= OPpENTERSUB_DB;
 
     if (flags & G_EVAL) {
@@ -1273,10 +1319,9 @@ perl_eval_sv(SV *sv, I32 flags)
        
                        /* See G_* flags in cop.h */
 {
-    dTHR;
+    dSP;
     UNOP myop;         /* fake syntax tree node */
-    SV** sp = stack_sp;
-    I32 oldmark = sp - stack_base;
+    I32 oldmark = SP - stack_base;
     I32 retval;
     I32 oldscope;
     dJMPENV;
@@ -1363,7 +1408,7 @@ perl_eval_pv(char *p, I32 croak_on_error)
     dSP;
     SV* sv = newSVpv(p, 0);
 
-    PUSHMARK(sp);
+    PUSHMARK(SP);
     perl_eval_sv(sv, G_SCALAR);
     SvREFCNT_dec(sv);
 
@@ -1425,7 +1470,7 @@ usage(char *name)         /* XXX move this out into a module ? */
 "-T              turn on tainting checks",
 "-u              dump core after parsing script",
 "-U              allow unsafe operations",
-"-v              print version number and patchlevel of perl",
+"-v              print version number, patchlevel plus VERY IMPORTANT perl info",
 "-V[:variable]   print perl configuration information",
 "-w              TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT. Recommended.",
 "-x[directory]   strip off text before #!perl line and perhaps cd to directory",
@@ -1518,8 +1563,11 @@ moreswitches(char *s)
        inplace = savepv(s+1);
        /*SUPPRESS 530*/
        for (s = inplace; *s && !isSPACE(*s); s++) ;
-       if (*s)
+       if (*s) {
            *s++ = '\0';
+           if (*s == '-')      /* Additional switches on #! line. */
+               s++;
+       }
        return s;
     case 'I':  /* -I handled both here and in parse_perl() */
        forbid_setid("-I");
@@ -1641,7 +1689,7 @@ moreswitches(char *s)
 #endif
 #ifdef DJGPP
        printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n");
-       printf("djgpp v2 port (perl5004) by Laszlo Molnar, 1997\n");
+       printf("djgpp v2 port (perl5004+) by Laszlo Molnar, 1997-1998\n");
 #endif
 #ifdef OS2
        printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
@@ -1652,7 +1700,10 @@ moreswitches(char *s)
 #endif
        printf("\n\
 Perl may be copied only under the terms of either the Artistic License or the\n\
-GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n");
+GNU General Public License, which may be found in the Perl 5.0 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);
     case 'w':
        dowarn = TRUE;
@@ -1688,6 +1739,7 @@ GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n")
 /* compliments of Tom Christiansen */
 
 /* unexec() can be found in the Gnu emacs distribution */
+/* Known to work with -DUNEXEC and using unexelf.c from GNU emacs-20.2 */
 
 void
 my_unexec(void)
@@ -1695,18 +1747,16 @@ my_unexec(void)
 #ifdef UNEXEC
     SV*    prog;
     SV*    file;
-    int    status;
+    int    status = 1;
     extern int etext;
 
-    prog = newSVpv(BIN_EXP);
+    prog = newSVpv(BIN_EXP, 0);
     sv_catpv(prog, "/perl");
-    file = newSVpv(origfilename);
+    file = newSVpv(origfilename, 0);
     sv_catpv(file, ".perldump");
 
-    status = unexec(SvPVX(file), SvPVX(prog), &etext, sbrk(0), 0);
-    if (status)
-       PerlIO_printf(PerlIO_stderr(), "unexec of %s into %s failed!\n",
-                     SvPVX(prog), SvPVX(file));
+    unexec(SvPVX(file), SvPVX(prog), &etext, sbrk(0), 0);
+    /* unexec prints msg to stderr in case of failure */
     PerlProc_exit(status);
 #else
 #  ifdef VMS
@@ -1759,201 +1809,9 @@ static void
 open_script(char *scriptname, bool dosearch, SV *sv)
 {
     dTHR;
-    char *xfound = Nullch;
-    char *xfailed = Nullch;
     register char *s;
-    I32 len;
-    int retval;
-#if defined(DOSISH) && !defined(OS2) && !defined(atarist)
-#  define SEARCH_EXTS ".bat", ".cmd", NULL
-#  define MAX_EXT_LEN 4
-#endif
-#ifdef OS2
-#  define SEARCH_EXTS ".cmd", ".btm", ".bat", ".pl", NULL
-#  define MAX_EXT_LEN 4
-#endif
-#ifdef VMS
-#  define SEARCH_EXTS ".pl", ".com", NULL
-#  define MAX_EXT_LEN 4
-#endif
-    /* additional extensions to try in each dir if scriptname not found */
-#ifdef SEARCH_EXTS
-    char *ext[] = { SEARCH_EXTS };
-    int extidx = 0, i = 0;
-    char *curext = Nullch;
-#else
-#  define MAX_EXT_LEN 0
-#endif
-
-    /*
-     * If dosearch is true and if scriptname does not contain path
-     * delimiters, search the PATH for scriptname.
-     *
-     * If SEARCH_EXTS is also defined, will look for each
-     * scriptname{SEARCH_EXTS} whenever scriptname is not found
-     * while searching the PATH.
-     *
-     * Assuming SEARCH_EXTS is C<".foo",".bar",NULL>, PATH search
-     * proceeds as follows:
-     *   If DOSISH or VMSISH:
-     *     + look for ./scriptname{,.foo,.bar}
-     *     + search the PATH for scriptname{,.foo,.bar}
-     *
-     *   If !DOSISH:
-     *     + look *only* in the PATH for scriptname{,.foo,.bar} (note
-     *       this will not look in '.' if it's not in the PATH)
-     */
 
-#ifdef VMS
-#  ifdef ALWAYS_DEFTYPES
-    len = strlen(scriptname);
-    if (!(len == 1 && *scriptname == '-') && scriptname[len-1] != ':') {
-       int hasdir, idx = 0, deftypes = 1;
-       bool seen_dot = 1;
-
-       hasdir = !dosearch || (strpbrk(scriptname,":[</") != Nullch) ;
-#  else
-    if (dosearch) {
-       int hasdir, idx = 0, deftypes = 1;
-       bool seen_dot = 1;
-
-       hasdir = (strpbrk(scriptname,":[</") != Nullch) ;
-#  endif
-       /* The first time through, just add SEARCH_EXTS to whatever we
-        * already have, so we can check for default file types. */
-       while (deftypes ||
-              (!hasdir && my_trnlnm("DCL$PATH",tokenbuf,idx++)) )
-       {
-           if (deftypes) {
-               deftypes = 0;
-               *tokenbuf = '\0';
-           }
-           if ((strlen(tokenbuf) + strlen(scriptname)
-                + MAX_EXT_LEN) >= sizeof tokenbuf)
-               continue;       /* don't search dir with too-long name */
-           strcat(tokenbuf, scriptname);
-#else  /* !VMS */
-
-#ifdef DOSISH
-    if (strEQ(scriptname, "-"))
-       dosearch = 0;
-    if (dosearch) {            /* Look in '.' first. */
-       char *cur = scriptname;
-#ifdef SEARCH_EXTS
-       if ((curext = strrchr(scriptname,'.'))) /* possible current ext */
-           while (ext[i])
-               if (strEQ(ext[i++],curext)) {
-                   extidx = -1;                /* already has an ext */
-                   break;
-               }
-       do {
-#endif
-           DEBUG_p(PerlIO_printf(Perl_debug_log,
-                                 "Looking for %s\n",cur));
-           if (Stat(cur,&statbuf) >= 0) {
-               dosearch = 0;
-               scriptname = cur;
-#ifdef SEARCH_EXTS
-               break;
-#endif
-           }
-#ifdef SEARCH_EXTS
-           if (cur == scriptname) {
-               len = strlen(scriptname);
-               if (len+MAX_EXT_LEN+1 >= sizeof(tokenbuf))
-                   break;
-               cur = strcpy(tokenbuf, scriptname);
-           }
-       } while (extidx >= 0 && ext[extidx]     /* try an extension? */
-                && strcpy(tokenbuf+len, ext[extidx++]));
-#endif
-    }
-#endif
-
-    if (dosearch && !strchr(scriptname, '/')
-#ifdef DOSISH
-                && !strchr(scriptname, '\\')
-#endif
-                && (s = PerlEnv_getenv("PATH"))) {
-       bool seen_dot = 0;
-       
-       bufend = s + strlen(s);
-       while (s < bufend) {
-#if defined(atarist) || defined(DOSISH)
-           for (len = 0; *s
-#  ifdef atarist
-                   && *s != ','
-#  endif
-                   && *s != ';'; len++, s++) {
-               if (len < sizeof tokenbuf)
-                   tokenbuf[len] = *s;
-           }
-           if (len < sizeof tokenbuf)
-               tokenbuf[len] = '\0';
-#else  /* ! (atarist || DOSISH) */
-           s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend,
-                       ':',
-                       &len);
-#endif /* ! (atarist || DOSISH) */
-           if (s < bufend)
-               s++;
-           if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tokenbuf)
-               continue;       /* don't search dir with too-long name */
-           if (len
-#if defined(atarist) || defined(DOSISH)
-               && tokenbuf[len - 1] != '/'
-               && tokenbuf[len - 1] != '\\'
-#endif
-              )
-               tokenbuf[len++] = '/';
-           if (len == 2 && tokenbuf[0] == '.')
-               seen_dot = 1;
-           (void)strcpy(tokenbuf + len, scriptname);
-#endif  /* !VMS */
-
-#ifdef SEARCH_EXTS
-           len = strlen(tokenbuf);
-           if (extidx > 0)     /* reset after previous loop */
-               extidx = 0;
-           do {
-#endif
-               DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tokenbuf));
-               retval = Stat(tokenbuf,&statbuf);
-#ifdef SEARCH_EXTS
-           } while (  retval < 0               /* not there */
-                   && extidx>=0 && ext[extidx] /* try an extension? */
-                   && strcpy(tokenbuf+len, ext[extidx++])
-               );
-#endif
-           if (retval < 0)
-               continue;
-           if (S_ISREG(statbuf.st_mode)
-               && cando(S_IRUSR,TRUE,&statbuf)
-#ifndef DOSISH
-               && cando(S_IXUSR,TRUE,&statbuf)
-#endif
-               )
-           {
-               xfound = tokenbuf;              /* bingo! */
-               break;
-           }
-           if (!xfailed)
-               xfailed = savepv(tokenbuf);
-       }
-#ifndef DOSISH
-       if (!xfound && !seen_dot && !xfailed && (Stat(scriptname,&statbuf) < 0))
-#endif
-           seen_dot = 1;                       /* Disable message. */
-       if (!xfound)
-           croak("Can't %s %s%s%s",
-                 (xfailed ? "execute" : "find"),
-                 (xfailed ? xfailed : scriptname),
-                 (xfailed ? "" : " on PATH"),
-                 (xfailed || seen_dot) ? "" : ", '.' not in PATH");
-       if (xfailed)
-           Safefree(xfailed);
-       scriptname = xfound;
-    }
+    scriptname = find_script(scriptname, dosearch, NULL, 0);
 
     if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
        char *s = scriptname + 8;
@@ -2066,7 +1924,7 @@ sed %s -e \"/^[^#]/b\" \
     if (!rsfp) {
 #ifdef DOSUID
 #ifndef IAMSUID                /* in case script is not readable before setuid */
-       if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
+       if (euid && PerlLIO_stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
          statbuf.st_mode & (S_ISUID|S_ISGID)) {
            /* try again */
            PerlProc_execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv);
@@ -2144,7 +2002,7 @@ validate_suid(char *validarg, char *scriptname)
 #endif
                || getuid() != euid || geteuid() != uid)
                croak("Can't swap uid and euid");       /* really paranoid */
-           if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
+           if (PerlLIO_stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
                croak("Permission denied");     /* testing full pathname here */
            if (tmpstatbuf.st_dev != statbuf.st_dev ||
                tmpstatbuf.st_ino != statbuf.st_ino) {
@@ -2390,26 +2248,30 @@ init_debugger(void)
     curstash = defstash;
 }
 
+#ifndef STRESS_REALLOC
+#define REASONABLE(size) (size)
+#else
+#define REASONABLE(size) (1) /* unreasonable */
+#endif
+
 void
 init_stacks(ARGSproto)
 {
-    curstack = newAV();
+    /* start with 128-item stack and 8K cxstack */
+    curstackinfo = new_stackinfo(REASONABLE(128),
+                                REASONABLE(8192/sizeof(PERL_CONTEXT) - 1));
+    curstackinfo->si_type = SI_MAIN;
+    curstack = curstackinfo->si_stack;
     mainstack = curstack;              /* remember in case we switch stacks */
-    AvREAL_off(curstack);              /* not a real array */
-    av_extend(curstack,127);
 
     stack_base = AvARRAY(curstack);
     stack_sp = stack_base;
-    stack_max = stack_base + 127;
+    stack_max = stack_base + AvMAX(curstack);
 
-    cxstack_max = 8192 / sizeof(PERL_CONTEXT) - 2;     /* Use most of 8K. */
-    New(50,cxstack,cxstack_max + 1,PERL_CONTEXT);
-    cxstack_ix = -1;
-
-    New(50,tmps_stack,128,SV*);
+    New(50,tmps_stack,REASONABLE(128),SV*);
     tmps_floor = -1;
     tmps_ix = -1;
-    tmps_max = 128;
+    tmps_max = REASONABLE(128);
 
     /*
      * The following stacks almost certainly should be per-interpreter,
@@ -2419,41 +2281,53 @@ init_stacks(ARGSproto)
     if (markstack) {
        markstack_ptr = markstack;
     } else {
-       New(54,markstack,64,I32);
+       New(54,markstack,REASONABLE(32),I32);
        markstack_ptr = markstack;
-       markstack_max = markstack + 64;
+       markstack_max = markstack + REASONABLE(32);
     }
 
+    SET_MARKBASE;
+
     if (scopestack) {
        scopestack_ix = 0;
     } else {
-       New(54,scopestack,32,I32);
+       New(54,scopestack,REASONABLE(32),I32);
        scopestack_ix = 0;
-       scopestack_max = 32;
+       scopestack_max = REASONABLE(32);
     }
 
     if (savestack) {
        savestack_ix = 0;
     } else {
-       New(54,savestack,128,ANY);
+       New(54,savestack,REASONABLE(128),ANY);
        savestack_ix = 0;
-       savestack_max = 128;
+       savestack_max = REASONABLE(128);
     }
 
     if (retstack) {
        retstack_ix = 0;
     } else {
-       New(54,retstack,16,OP*);
+       New(54,retstack,REASONABLE(16),OP*);
        retstack_ix = 0;
-       retstack_max = 16;
+       retstack_max = REASONABLE(16);
     }
 }
 
+#undef REASONABLE
+
 static void
 nuke_stacks(void)
 {
     dTHR;
-    Safefree(cxstack);
+    while (curstackinfo->si_next)
+       curstackinfo = curstackinfo->si_next;
+    while (curstackinfo) {
+       PERL_SI *p = curstackinfo->si_prev;
+       /* curstackinfo->si_stack got nuked by sv_free_arenas() */
+       Safefree(curstackinfo->si_cxstack);
+       Safefree(curstackinfo);
+       curstackinfo = p;
+    }
     Safefree(tmps_stack);
     DEBUG( {
        Safefree(debname);
@@ -2626,7 +2500,7 @@ init_perllib(void)
     ARCHLIB PRIVLIB SITEARCH and SITELIB 
 */
 #ifdef APPLLIB_EXP
-    incpush(APPLLIB_EXP, FALSE);
+    incpush(APPLLIB_EXP, TRUE);
 #endif
 
 #ifdef ARCHLIB_EXP
@@ -2729,7 +2603,7 @@ incpush(char *p, int addsubdirs)
            /* .../archname/version if -d .../archname/version/auto */
            sv_setsv(subdir, libdir);
            sv_catpv(subdir, archpat_auto);
-           if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
+           if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
                  S_ISDIR(tmpstatbuf.st_mode))
                av_push(GvAVn(incgv),
                        newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto"));
@@ -2737,7 +2611,7 @@ incpush(char *p, int addsubdirs)
            /* .../archname if -d .../archname/auto */
            sv_insert(subdir, SvCUR(libdir) + sizeof(ARCHNAME),
                      strlen(patchlevel) + 1, "", 0);
-           if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
+           if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
                  S_ISDIR(tmpstatbuf.st_mode))
                av_push(GvAVn(incgv),
                        newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto"));
@@ -2777,7 +2651,6 @@ init_main_thread()
     SvLEN_set(thrsv, sizeof(thr));
     *SvEND(thrsv) = '\0';      /* in the trailing_nul field */
     thr->oursv = thrsv;
-    curcop = &compiling;
     chopset = " \n-";
 
     MUTEX_LOCK(&threads_mutex);
@@ -2925,10 +2798,16 @@ my_failure_exit(void)
            STATUS_NATIVE_SET(vaxc$errno);
     }
 #else
+    int exitstatus;
     if (errno & 255)
        STATUS_POSIX_SET(errno);
-    else if (STATUS_POSIX == 0)
-       STATUS_POSIX_SET(255);
+    else {
+       exitstatus = STATUS_POSIX >> 8; 
+       if (exitstatus & 255)
+           STATUS_POSIX_SET(exitstatus);
+       else
+           STATUS_POSIX_SET(255);
+    }
 #endif
     my_exit_jump();
 }
@@ -2936,7 +2815,7 @@ my_failure_exit(void)
 static void
 my_exit_jump(void)
 {
-    dTHR;
+    dSP;
     register PERL_CONTEXT *cx;
     I32 gimme;
     SV **newsp;
@@ -2951,6 +2830,7 @@ my_exit_jump(void)
        e_tmpname = Nullch;
     }
 
+    POPSTACK_TO(mainstack);
     if (cxstack_ix >= 0) {
        if (cxstack_ix > 0)
            dounwind(0);