new_body_type doesn't need to subtract the offset, that's what
[p5sagit/p5-mst-13.2.git] / perl.c
diff --git a/perl.c b/perl.c
index 26382e9..2d687be 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -181,6 +181,7 @@ perl_alloc_using(struct IPerlMem* ipM, struct IPerlMem* ipMS,
     PL_Dir = ipD;
     PL_Sock = ipS;
     PL_Proc = ipP;
+    INIT_TRACK_MEMPOOL(PL_memory_debug_header, my_perl);
 
     return my_perl;
 }
@@ -205,7 +206,13 @@ perl_alloc(void)
     my_perl = (PerlInterpreter*)PerlMem_malloc(sizeof(PerlInterpreter));
 
     S_init_tls_and_interp(my_perl);
+#ifndef PERL_TRACK_MEMPOOL
     return (PerlInterpreter *) ZeroD(my_perl, 1, PerlInterpreter);
+#else
+    Zero(my_perl, 1, PerlInterpreter);
+    INIT_TRACK_MEMPOOL(PL_memory_debug_header, my_perl);
+    return my_perl;
+#endif
 }
 #endif /* PERL_IMPLICIT_SYS */
 
@@ -726,7 +733,7 @@ perl_destruct(pTHXx)
     }
     PL_main_start = Nullop;
     SvREFCNT_dec(PL_main_cv);
-    PL_main_cv = Nullcv;
+    PL_main_cv = NULL;
     PL_dirty = TRUE;
 
     /* Tell PerlIO we are about to tear things apart in case
@@ -745,14 +752,14 @@ perl_destruct(pTHXx)
        sv_clean_objs();
        PL_sv_objcount = 0;
        if (PL_defoutgv && !SvREFCNT(PL_defoutgv))
-           PL_defoutgv = Nullgv; /* may have been freed */
+           PL_defoutgv = NULL; /* may have been freed */
     }
 
     /* unhook hooks which will soon be, or use, destroyed data */
     SvREFCNT_dec(PL_warnhook);
-    PL_warnhook = Nullsv;
+    PL_warnhook = NULL;
     SvREFCNT_dec(PL_diehook);
-    PL_diehook = Nullsv;
+    PL_diehook = NULL;
 
     /* call exit list functions */
     while (PL_exitlistlen-- > 0)
@@ -803,7 +810,7 @@ perl_destruct(pTHXx)
 #endif /* !PERL_MICRO */
 
     /* reset so print() ends up where we expect */
-    setdefout(Nullgv);
+    setdefout(NULL);
 
 #ifdef USE_ITHREADS
     /* the syntax tree is shared between clones
@@ -871,7 +878,7 @@ perl_destruct(pTHXx)
 
     if (PL_e_script) {
        SvREFCNT_dec(PL_e_script);
-       PL_e_script = Nullsv;
+       PL_e_script = NULL;
     }
 
     PL_perldb = 0;
@@ -879,27 +886,27 @@ perl_destruct(pTHXx)
     /* magical thingies */
 
     SvREFCNT_dec(PL_ofs_sv);   /* $, */
-    PL_ofs_sv = Nullsv;
+    PL_ofs_sv = NULL;
 
     SvREFCNT_dec(PL_ors_sv);   /* $\ */
-    PL_ors_sv = Nullsv;
+    PL_ors_sv = NULL;
 
     SvREFCNT_dec(PL_rs);       /* $/ */
-    PL_rs = Nullsv;
+    PL_rs = NULL;
 
     PL_multiline = 0;          /* $* */
     Safefree(PL_osname);       /* $^O */
     PL_osname = NULL;
 
     SvREFCNT_dec(PL_statname);
-    PL_statname = Nullsv;
-    PL_statgv = Nullgv;
+    PL_statname = NULL;
+    PL_statgv = NULL;
 
     /* defgv, aka *_ should be taken care of elsewhere */
 
     /* clean up after study() */
     SvREFCNT_dec(PL_lastscream);
-    PL_lastscream = Nullsv;
+    PL_lastscream = NULL;
     Safefree(PL_screamfirst);
     PL_screamfirst = 0;
     Safefree(PL_screamnext);
@@ -925,24 +932,24 @@ perl_destruct(pTHXx)
     PL_initav = NULL;
 
     /* shortcuts just get cleared */
-    PL_envgv = Nullgv;
-    PL_incgv = Nullgv;
-    PL_hintgv = Nullgv;
-    PL_errgv = Nullgv;
-    PL_argvgv = Nullgv;
-    PL_argvoutgv = Nullgv;
-    PL_stdingv = Nullgv;
-    PL_stderrgv = Nullgv;
-    PL_last_in_gv = Nullgv;
-    PL_replgv = Nullgv;
-    PL_DBgv = Nullgv;
-    PL_DBline = Nullgv;
-    PL_DBsub = Nullgv;
-    PL_DBsingle = Nullsv;
-    PL_DBtrace = Nullsv;
-    PL_DBsignal = Nullsv;
-    PL_DBassertion = Nullsv;
-    PL_DBcv = Nullcv;
+    PL_envgv = NULL;
+    PL_incgv = NULL;
+    PL_hintgv = NULL;
+    PL_errgv = NULL;
+    PL_argvgv = NULL;
+    PL_argvoutgv = NULL;
+    PL_stdingv = NULL;
+    PL_stderrgv = NULL;
+    PL_last_in_gv = NULL;
+    PL_replgv = NULL;
+    PL_DBgv = NULL;
+    PL_DBline = NULL;
+    PL_DBsub = NULL;
+    PL_DBsingle = NULL;
+    PL_DBtrace = NULL;
+    PL_DBsignal = NULL;
+    PL_DBassertion = NULL;
+    PL_DBcv = NULL;
     PL_dbargs = NULL;
     PL_debstash = NULL;
 
@@ -954,18 +961,18 @@ perl_destruct(pTHXx)
     SvREFCNT_dec(PL_preambleav);
     PL_preambleav = NULL;
     SvREFCNT_dec(PL_subname);
-    PL_subname = Nullsv;
+    PL_subname = NULL;
     SvREFCNT_dec(PL_linestr);
-    PL_linestr = Nullsv;
+    PL_linestr = NULL;
 #ifdef PERL_USES_PL_PIDSTATUS
     SvREFCNT_dec(PL_pidstatus);
     PL_pidstatus = NULL;
 #endif
     SvREFCNT_dec(PL_toptarget);
-    PL_toptarget = Nullsv;
+    PL_toptarget = NULL;
     SvREFCNT_dec(PL_bodytarget);
-    PL_bodytarget = Nullsv;
-    PL_formtarget = Nullsv;
+    PL_bodytarget = NULL;
+    PL_formtarget = NULL;
 
     /* free locale stuff */
 #ifdef USE_LOCALE_COLLATE
@@ -977,7 +984,7 @@ perl_destruct(pTHXx)
     Safefree(PL_numeric_name);
     PL_numeric_name = NULL;
     SvREFCNT_dec(PL_numeric_radix_sv);
-    PL_numeric_radix_sv = Nullsv;
+    PL_numeric_radix_sv = NULL;
 #endif
 
     /* clear utf8 character classes */
@@ -1001,33 +1008,33 @@ perl_destruct(pTHXx)
     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;
-    PL_utf8_alpha      = Nullsv;
-    PL_utf8_space      = Nullsv;
-    PL_utf8_cntrl      = Nullsv;
-    PL_utf8_graph      = Nullsv;
-    PL_utf8_digit      = Nullsv;
-    PL_utf8_upper      = Nullsv;
-    PL_utf8_lower      = Nullsv;
-    PL_utf8_print      = Nullsv;
-    PL_utf8_punct      = Nullsv;
-    PL_utf8_xdigit     = Nullsv;
-    PL_utf8_mark       = Nullsv;
-    PL_utf8_toupper    = Nullsv;
-    PL_utf8_totitle    = Nullsv;
-    PL_utf8_tolower    = Nullsv;
-    PL_utf8_tofold     = Nullsv;
-    PL_utf8_idstart    = Nullsv;
-    PL_utf8_idcont     = Nullsv;
+    PL_utf8_alnum      = NULL;
+    PL_utf8_alnumc     = NULL;
+    PL_utf8_ascii      = NULL;
+    PL_utf8_alpha      = NULL;
+    PL_utf8_space      = NULL;
+    PL_utf8_cntrl      = NULL;
+    PL_utf8_graph      = NULL;
+    PL_utf8_digit      = NULL;
+    PL_utf8_upper      = NULL;
+    PL_utf8_lower      = NULL;
+    PL_utf8_print      = NULL;
+    PL_utf8_punct      = NULL;
+    PL_utf8_xdigit     = NULL;
+    PL_utf8_mark       = NULL;
+    PL_utf8_toupper    = NULL;
+    PL_utf8_totitle    = NULL;
+    PL_utf8_tolower    = NULL;
+    PL_utf8_tofold     = NULL;
+    PL_utf8_idstart    = NULL;
+    PL_utf8_idcont     = NULL;
 
     if (!specialWARN(PL_compiling.cop_warnings))
        SvREFCNT_dec(PL_compiling.cop_warnings);
-    PL_compiling.cop_warnings = Nullsv;
+    PL_compiling.cop_warnings = NULL;
     if (!specialCopIO(PL_compiling.cop_io))
        SvREFCNT_dec(PL_compiling.cop_io);
-    PL_compiling.cop_io = Nullsv;
+    PL_compiling.cop_io = NULL;
     CopFILE_free(&PL_compiling);
     CopSTASH_free(&PL_compiling);
 
@@ -1037,11 +1044,11 @@ perl_destruct(pTHXx)
     PL_defstash = 0;
     SvREFCNT_dec(hv);
     SvREFCNT_dec(PL_curstname);
-    PL_curstname = Nullsv;
+    PL_curstname = NULL;
 
     /* clear queued errors */
     SvREFCNT_dec(PL_errors);
-    PL_errors = Nullsv;
+    PL_errors = NULL;
 
     FREETMPS;
     if (destruct_level >= 2 && ckWARN_d(WARN_INTERNAL)) {
@@ -1206,7 +1213,7 @@ perl_destruct(pTHXx)
 #endif
 
     /* sv_undef needs to stay immortal until after PerlIO_cleanup
-       as currently layers use it rather than Nullsv as a marker
+       as currently layers use it rather than NULL as a marker
        for no arg - and will try and SvREFCNT_dec it.
      */
     SvREFCNT(&PL_sv_undef) = 0;
@@ -1229,7 +1236,7 @@ perl_destruct(pTHXx)
     PL_bitcount = NULL;
     Safefree(PL_psig_pend);
     PL_psig_pend = (int*)NULL;
-    PL_formfeed = Nullsv;
+    PL_formfeed = NULL;
     nuke_stacks();
     PL_tainting = FALSE;
     PL_taint_warn = FALSE;
@@ -1264,7 +1271,7 @@ perl_destruct(pTHXx)
        SvPV_free(PL_mess_sv);
        Safefree(SvANY(PL_mess_sv));
        Safefree(PL_mess_sv);
-       PL_mess_sv = Nullsv;
+       PL_mess_sv = NULL;
     }
     return STATUS_EXIT;
 }
@@ -1280,19 +1287,28 @@ Releases a Perl interpreter.  See L<perlembed>.
 void
 perl_free(pTHXx)
 {
+#ifdef PERL_TRACK_MEMPOOL
+    /* Emulate the PerlHost behaviour of free()ing all memory allocated in this
+       thread at thread exit.  */
+    while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header))
+       safesysfree(sTHX + (char *)(aTHXx->Imemory_debug_header.next));
+#endif
+
 #if defined(WIN32) || defined(NETWARE)
 #  if defined(PERL_IMPLICIT_SYS)
+    {
 #    ifdef NETWARE
-    void *host = nw_internal_host;
+       void *host = nw_internal_host;
 #    else
-    void *host = w32_internal_host;
+       void *host = w32_internal_host;
 #    endif
-    PerlMem_free(aTHXx);
+       PerlMem_free(aTHXx);
 #    ifdef NETWARE
-    nw_delete_internal_host(host);
+       nw_delete_internal_host(host);
 #    else
-    win32_delete_internal_host(host);
+       win32_delete_internal_host(host);
 #    endif
+    }
 #  else
     PerlMem_free(aTHXx);
 #  endif
@@ -1542,7 +1558,7 @@ setuid perl scripts securely.\n");
     }
     PL_main_start = Nullop;
     SvREFCNT_dec(PL_main_cv);
-    PL_main_cv = Nullcv;
+    PL_main_cv = NULL;
 
     time(&PL_basetime);
     oldscope = PL_scopestack_ix;
@@ -1594,8 +1610,6 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     bool minus_f = FALSE;
 #endif
 
-    PL_fdscript = -1;
-    PL_suidscript = -1;
     sv_setpvn(PL_linestr,"",0);
     sv = newSVpvs("");         /* first used for -I flags */
     SAVEFREESV(sv);
@@ -1673,7 +1687,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            if (argv[1] && !strcmp(argv[1], "Dev:Pseudo"))
                break;
 #endif
-           forbid_setid("-e");
+           forbid_setid('e', -1);
            if (!PL_e_script) {
                PL_e_script = newSVpvs("");
                filter_add(read_e_script, NULL);
@@ -1697,7 +1711,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            goto reswitch;
 
        case 'I':       /* -I handled both here and in moreswitches() */
-           forbid_setid("-I");
+           forbid_setid('I', -1);
            if (!*++s && (s=argv[1]) != NULL) {
                argc--,argv++;
            }
@@ -1714,12 +1728,12 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
                Perl_croak(aTHX_ "No directory specified for -I");
            break;
        case 'P':
-           forbid_setid("-P");
+           forbid_setid('P', -1);
            PL_preprocess = TRUE;
            s++;
            goto reswitch;
        case 'S':
-           forbid_setid("-S");
+           forbid_setid('S', -1);
            dosearch = TRUE;
            s++;
            goto reswitch;
@@ -2023,36 +2037,45 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     TAINT_NOT;
     init_perllib();
 
-    open_script(scriptname,dosearch,sv);
+    {
+       int suidscript;
+       const int fdscript
+           = open_script(scriptname, dosearch, sv, &suidscript);
 
-    validate_suid(validarg, scriptname);
+       validate_suid(validarg, scriptname, fdscript, suidscript);
 
 #ifndef PERL_MICRO
-#if defined(SIGCHLD) || defined(SIGCLD)
-    {
-#ifndef SIGCHLD
-#  define SIGCHLD SIGCLD
-#endif
-       Sighandler_t sigstate = rsignal_state(SIGCHLD);
-       if (sigstate == (Sighandler_t) SIG_IGN) {
-           if (ckWARN(WARN_SIGNAL))
-               Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
-                           "Can't ignore signal CHLD, forcing to default");
-           (void)rsignal(SIGCHLD, (Sighandler_t)SIG_DFL);
+#  if defined(SIGCHLD) || defined(SIGCLD)
+       {
+#  ifndef SIGCHLD
+#    define SIGCHLD SIGCLD
+#  endif
+           Sighandler_t sigstate = rsignal_state(SIGCHLD);
+           if (sigstate == (Sighandler_t) SIG_IGN) {
+               if (ckWARN(WARN_SIGNAL))
+                   Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
+                               "Can't ignore signal CHLD, forcing to default");
+               (void)rsignal(SIGCHLD, (Sighandler_t)SIG_DFL);
+           }
        }
-    }
-#endif
+#  endif
 #endif
 
+       if (PL_doextract
 #ifdef MACOS_TRADITIONAL
-    if (PL_doextract || gMacPerl_AlwaysExtract) {
-#else
-    if (PL_doextract) {
+           || gMacPerl_AlwaysExtract
 #endif
-       find_beginning();
-       if (cddir && PerlDir_chdir( (char *)cddir ) < 0)
-           Perl_croak(aTHX_ "Can't chdir to %s",cddir);
+           ) {
 
+           /* This will croak if suidscript is >= 0, as -x cannot be used with
+              setuid scripts.  */
+           forbid_setid('x', suidscript);
+           /* Hence you can't get here if suidscript >= 0  */
+
+           find_beginning();
+           if (cddir && PerlDir_chdir( (char *)cddir ) < 0)
+               Perl_croak(aTHX_ "Can't chdir to %s",cddir);
+       }
     }
 
     PL_main_cv = PL_compcv = (CV*)newSV(0);
@@ -2178,7 +2201,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     PL_preprocess = FALSE;
     if (PL_e_script) {
        SvREFCNT_dec(PL_e_script);
-       PL_e_script = Nullsv;
+       PL_e_script = NULL;
     }
 
     if (PL_do_undump)
@@ -2339,7 +2362,7 @@ Perl_get_sv(pTHX_ const char *name, I32 create)
     gv = gv_fetchpv(name, create, SVt_PV);
     if (gv)
        return GvSV(gv);
-    return Nullsv;
+    return NULL;
 }
 
 /*
@@ -2416,7 +2439,7 @@ Perl_get_cv(pTHX_ const char *name, I32 create)
                      Nullop);
     if (gv)
        return GvCVu(gv);
-    return Nullcv;
+    return NULL;
 }
 
 /* Be sure to refetch the stack pointer after calling these routines. */
@@ -3002,7 +3025,7 @@ Perl_moreswitches(pTHX_ char *s)
        s++;
        return s;
     case 'd':
-       forbid_setid("-d");
+       forbid_setid('d', -1);
        s++;
 
         /* -dt indicates to the debugger that threads will be used */
@@ -3036,7 +3059,7 @@ Perl_moreswitches(pTHX_ char *s)
     case 'D':
     {  
 #ifdef DEBUGGING
-       forbid_setid("-D");
+       forbid_setid('D', -1);
        s++;
        PL_debug = get_debug_opts( (const char **)&s, 1) | DEBUG_TOP_FLAG;
 #else /* !DEBUGGING */
@@ -3068,7 +3091,7 @@ Perl_moreswitches(pTHX_ char *s)
        }
        return s;
     case 'I':  /* -I handled both here and in parse_body() */
-       forbid_setid("-I");
+       forbid_setid('I', -1);
        ++s;
        while (*s && isSPACE(*s))
            ++s;
@@ -3097,7 +3120,7 @@ Perl_moreswitches(pTHX_ char *s)
        s++;
        if (PL_ors_sv) {
            SvREFCNT_dec(PL_ors_sv);
-           PL_ors_sv = Nullsv;
+           PL_ors_sv = NULL;
        }
        if (isDIGIT(*s)) {
             I32 flags = 0;
@@ -3117,7 +3140,7 @@ Perl_moreswitches(pTHX_ char *s)
        }
        return s;
     case 'A':
-       forbid_setid("-A");
+       forbid_setid('A', -1);
        if (!PL_preambleav)
            PL_preambleav = newAV();
        s++;
@@ -3140,10 +3163,10 @@ Perl_moreswitches(pTHX_ char *s)
            return s;
        }
     case 'M':
-       forbid_setid("-M");     /* XXX ? */
+       forbid_setid('M', -1);  /* XXX ? */
        /* FALL THROUGH */
     case 'm':
-       forbid_setid("-m");     /* XXX ? */
+       forbid_setid('m', -1);  /* XXX ? */
        if (*++s) {
            char *start;
            SV *sv;
@@ -3190,7 +3213,7 @@ Perl_moreswitches(pTHX_ char *s)
        s++;
        return s;
     case 's':
-       forbid_setid("-s");
+       forbid_setid('s', -1);
        PL_doswitches = TRUE;
        s++;
        return s;
@@ -3499,9 +3522,9 @@ S_init_main_stash(pTHX)
     sv_setpvn(get_sv("/", TRUE), "\n", 1);
 }
 
-/* PSz 18 Nov 03  fdscript now global but do not change prototype */
-STATIC void
-S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
+STATIC int
+S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv,
+             int *suidscript)
 {
 #ifndef IAMSUID
     const char *quote;
@@ -3509,10 +3532,10 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
     const char *cpp_discard_flag;
     const char *perl;
 #endif
+    int fdscript = -1;
     dVAR;
 
-    PL_fdscript = -1;
-    PL_suidscript = -1;
+    *suidscript = -1;
 
     if (PL_e_script) {
        PL_origfilename = savepvs("-e");
@@ -3523,7 +3546,7 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
 
        if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
             const char *s = scriptname + 8;
-           PL_fdscript = atoi(s);
+           fdscript = atoi(s);
            while (isDIGIT(*s))
                s++;
            if (*s) {
@@ -3536,7 +3559,7 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
                 * Is it a mistake to use a similar /dev/fd/ construct for
                 * suidperl?
                 */
-               PL_suidscript = 1;
+               *suidscript = 1;
                /* PSz 20 Feb 04  
                 * Be supersafe and do some sanity-checks.
                 * Still, can we be sure we got the right thing?
@@ -3558,8 +3581,8 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
     CopFILE_set(PL_curcop, PL_origfilename);
     if (*PL_origfilename == '-' && PL_origfilename[1] == '\0')
        scriptname = (char *)"";
-    if (PL_fdscript >= 0) {
-       PL_rsfp = PerlIO_fdopen(PL_fdscript,PERL_SCRIPT_MODE);
+    if (fdscript >= 0) {
+       PL_rsfp = PerlIO_fdopen(fdscript,PERL_SCRIPT_MODE);
 #       if defined(HAS_FCNTL) && defined(F_SETFD)
            if (PL_rsfp)
                 /* ensure close-on-exec */
@@ -3579,7 +3602,7 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
  * perl with that fd as it has always done.
  */
     }
-    if (PL_suidscript != 1) {
+    if (*suidscript != 1) {
        Perl_croak(aTHX_ "suidperl needs (suid) fd script\n");
     }
 #else /* IAMSUID */
@@ -3650,7 +3673,7 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
        SvREFCNT_dec(cpp);
     }
     else if (!*scriptname) {
-       forbid_setid("program input from stdin");
+       forbid_setid(0, *suidscript);
        PL_rsfp = PerlIO_stdin();
     }
     else {
@@ -3670,6 +3693,7 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv)
            Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n",
                    CopFILE(PL_curcop), Strerror(errno));
     }
+    return fdscript;
 }
 
 /* Mention
@@ -3807,7 +3831,8 @@ S_fd_on_nosuid_fs(pTHX_ int fd)
 #endif /* IAMSUID */
 
 STATIC void
-S_validate_suid(pTHX_ const char *validarg, const char *scriptname)
+S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
+               int fdscript, int suidscript)
 {
     dVAR;
 #ifdef IAMSUID
@@ -3852,7 +3877,7 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname)
        const char *s_end;
 
 #ifdef IAMSUID
-       if (PL_fdscript < 0 || PL_suidscript != 1)
+       if (fdscript < 0 || suidscript != 1)
            Perl_croak(aTHX_ "Need (suid) fdscript in suidperl\n");     /* We already checked this */
        /* PSz 11 Nov 03
         * Since the script is opened by perl, not suidperl, some of these
@@ -4002,7 +4027,7 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname)
            Perl_croak(aTHX_ "Args must match #! line");
 
 #ifndef IAMSUID
-       if (PL_fdscript < 0 &&
+       if (fdscript < 0 &&
            PL_euid != PL_uid && (PL_statbuf.st_mode & S_ISUID) &&
            PL_euid == PL_statbuf.st_uid)
            if (!PL_do_undump)
@@ -4010,7 +4035,7 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname)
 FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
 #endif /* IAMSUID */
 
-       if (PL_fdscript < 0 &&
+       if (fdscript < 0 &&
            PL_euid) {  /* oops, we're not the setuid root perl */
            /* PSz 18 Feb 04
             * When root runs a setuid script, we do not go through the same
@@ -4023,7 +4048,7 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
             * might run also non-setuid ones, and deserves what he gets.
             * 
             * Or, we might drop the PL_euid check above (and rely just on
-            * PL_fdscript to avoid loops), and do the execs
+            * fdscript to avoid loops), and do the execs
             * even for root.
             */
 #ifndef IAMSUID
@@ -4131,7 +4156,7 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
 #ifdef IAMSUID
     else if (PL_preprocess)    /* PSz 13 Nov 03  Caught elsewhere, useless(?!) here */
        Perl_croak(aTHX_ "-P not allowed for setuid/setgid script\n");
-    else if (PL_fdscript < 0 || PL_suidscript != 1)
+    else if (fdscript < 0 || suidscript != 1)
        /* PSz 13 Nov 03  Caught elsewhere, useless(?!) here */
        Perl_croak(aTHX_ "(suid) fdscript needed in suidperl\n");
     else {
@@ -4225,7 +4250,6 @@ S_find_beginning(pTHX)
 
     /* skip forward in input to the real script? */
 
-    forbid_setid("-x");
 #ifdef MACOS_TRADITIONAL
     /* Since the Mac OS does not honor #! arguments for us, we do it ourselves */
 
@@ -4346,15 +4370,27 @@ Perl_doing_taint(int argc, char *argv[], char *envp[])
     return 0;
 }
 
+/* Passing the flag as a single char rather than a string is a slight space
+   optimisation.  The only message that isn't /^-.$/ is
+   "program input from stdin", which is substituted in place of '\0', which
+   could never be a command line flag.  */
 STATIC void
-S_forbid_setid(pTHX_ const char *s)
+S_forbid_setid(pTHX_ const char flag, const int suidscript)
 {
     dVAR;
+    char string[3] = "-x";
+    const char *message = "program input from stdin";
+
+    if (flag) {
+       string[1] = flag;
+       message = string;
+    }
+
 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
     if (PL_euid != PL_uid)
-        Perl_croak(aTHX_ "No %s allowed while running setuid", s);
+        Perl_croak(aTHX_ "No %s allowed while running setuid", message);
     if (PL_egid != PL_gid)
-        Perl_croak(aTHX_ "No %s allowed while running setgid", s);
+        Perl_croak(aTHX_ "No %s allowed while running setgid", message);
 #endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
     /* PSz 29 Feb 04
      * Checks for UID/GID above "wrong": why disallow
@@ -4378,11 +4414,11 @@ S_forbid_setid(pTHX_ const char *s)
      * 
      * Also see comments about root running a setuid script, elsewhere.
      */
-    if (PL_suidscript >= 0)
-        Perl_croak(aTHX_ "No %s allowed with (suid) fdscript", s);
+    if (suidscript >= 0)
+        Perl_croak(aTHX_ "No %s allowed with (suid) fdscript", message);
 #ifdef IAMSUID
     /* PSz 11 Nov 03  Catch it in suidperl, always! */
-    Perl_croak(aTHX_ "No %s allowed in suidperl", s);
+    Perl_croak(aTHX_ "No %s allowed in suidperl", message);
 #endif /* IAMSUID */
 }
 
@@ -4597,7 +4633,7 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
        HV *hv;
        GvMULTI_on(PL_envgv);
        hv = GvHVn(PL_envgv);
-       hv_magic(hv, Nullgv, PERL_MAGIC_env);
+       hv_magic(hv, NULL, PERL_MAGIC_env);
 #ifndef PERL_MICRO
 #ifdef USE_ENVIRON_ARRAY
        /* Note that if the supplied env parameter is actually a copy
@@ -4823,7 +4859,7 @@ S_incpush(pTHX_ const char *dir, bool addsubdirs, bool addoldvers, bool usesep,
          bool canrelocate)
 {
     dVAR;
-    SV *subdir = Nullsv;
+    SV *subdir = NULL;
     const char *p = dir;
 
     if (!p || !*p)
@@ -5319,7 +5355,7 @@ S_my_exit_jump(pTHX)
 
     if (PL_e_script) {
        SvREFCNT_dec(PL_e_script);
-       PL_e_script = Nullsv;
+       PL_e_script = NULL;
     }
 
     POPSTACK_TO(PL_mainstack);