Jumbo Configure update.
[p5sagit/p5-mst-13.2.git] / perl.c
diff --git a/perl.c b/perl.c
index 388dd8b..8a4fedf 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -64,6 +64,9 @@ static void my_exit_jump _((void)) __attribute__((noreturn));
 static void nuke_stacks _((void));
 static void open_script _((char *, bool, SV *, int *fd));
 static void usage _((char *));
+#ifdef IAMSUID
+static int  fd_on_nosuid_fs _((int));
+#endif
 static void validate_suid _((char *, char*, int));
 static I32 read_e_script _((int idx, SV *buf_sv, int maxlen));
 #endif
@@ -354,6 +357,7 @@ perl_destruct(register PerlInterpreter *sv_interp)
     PL_main_start = Nullop;
     SvREFCNT_dec(PL_main_cv);
     PL_main_cv = Nullcv;
+    PL_dirty = TRUE;
 
     if (PL_sv_objcount) {
        /*
@@ -361,8 +365,6 @@ perl_destruct(register PerlInterpreter *sv_interp)
         * destructors and destructees still exist.  Some sv's might remain.
         * Non-referenced objects are on their own.
         */
-    
-       PL_dirty = TRUE;
        sv_clean_objs();
     }
 
@@ -548,6 +550,8 @@ perl_destruct(register PerlInterpreter *sv_interp)
     Safefree(PL_origfilename);
     Safefree(PL_archpat_auto);
     Safefree(PL_reg_start_tmp);
+    if (PL_reg_curpm)
+       Safefree(PL_reg_curpm);
     Safefree(HeKEY_hek(&PL_hv_fetch_ent_mh));
     Safefree(PL_op_mask);
     nuke_stacks();
@@ -829,7 +833,7 @@ setuid perl scripts securely.\n");
                    sv_catpv(PL_Sv,"\"  Locally applied patches:\\n\",");
                    for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
                        if (PL_localpatches[i])
-                           sv_catpvf(PL_Sv,"\"  \\t%s\\n\",",PL_localpatches[i]);
+                           sv_catpvf(PL_Sv,"q\"  \t%s\n\",",PL_localpatches[i]);
                    }
                }
 #endif
@@ -1020,7 +1024,7 @@ perl_run(void)
 perl_run(PerlInterpreter *sv_interp)
 #endif
 {
-    dSP;
+    dTHR;
     I32 oldscope;
     dJMPENV;
     int ret;
@@ -1144,6 +1148,7 @@ CV*
 perl_get_cv(char *name, I32 create)
 {
     GV* gv = gv_fetchpv(name, create, SVt_PVCV);
+    /* XXX unsafe for threads if eval_owner isn't held */
     if (create && !GvCVu(gv))
        return newSUB(start_subparse(FALSE, 0),
                      newSVOP(OP_CONST, 0, newSVpv(name,0)),
@@ -1446,8 +1451,10 @@ perl_eval_pv(char *p, I32 croak_on_error)
     sv = POPs;
     PUTBACK;
 
-    if (croak_on_error && SvTRUE(ERRSV))
-       croak(SvPVx(ERRSV, PL_na));
+    if (croak_on_error && SvTRUE(ERRSV)) {
+       STRLEN n_a;
+       croak(SvPVx(ERRSV, n_a));
+    }
 
     return sv;
 }
@@ -1752,6 +1759,9 @@ moreswitches(char *s)
 #ifdef POSIX_BC
        printf("BS2000 (POSIX) port by Start Amadeus GmbH, 1998\n");
 #endif
+#ifdef __MINT__
+       printf("MiNT port by Guido Flohr, 1997\n");
+#endif
 #ifdef BINARY_BUILD_NOTICE
        BINARY_BUILD_NOTICE;
 #endif
@@ -1850,6 +1860,7 @@ init_interp(void)
     PL_curcopdb                = NULL;         \
     PL_dbargs          = 0;            \
     PL_dlmax           = 128;          \
+    PL_dumpindent      = 4;            \
     PL_laststatval     = -1;           \
     PL_laststype       = OP_STAT;      \
     PL_maxscream       = -1;           \
@@ -1872,6 +1883,7 @@ init_interp(void)
     PL_profiledata     = NULL;         \
     PL_rsfp            = Nullfp;       \
     PL_rsfp_filters    = Nullav;       \
+    PL_dirty           = FALSE;        \
   } STMT_END
     I_REINIT;
 #else
@@ -1886,7 +1898,7 @@ init_interp(void)
 #    undef PERLVAR
 #    undef PERLVARI
 #    undef PERLVARIC
-#    else
+#  else
 #    define PERLVAR(var,type)
 #    define PERLVARI(var,type,init)    PL_##var = init;
 #    define PERLVARIC(var,type,init)   PL_##var = init;
@@ -2101,6 +2113,70 @@ sed %s -e \"/^[^#]/b\" \
     }
 }
 
+#ifdef IAMSUID
+static int
+fd_on_nosuid_fs(int fd)
+{
+    int on_nosuid  = 0;
+    int check_okay = 0;
+/*
+ * Preferred order: fstatvfs(), fstatfs(), getmntent().
+ * fstatvfs() is UNIX98.
+ * fstatfs() is BSD.
+ * getmntent() is O(number-of-mounted-filesystems) and can hang.
+ */
+
+#   ifdef HAS_FSTATVFS
+    struct statvfs stfs;
+    check_okay = fstatvfs(fd, &stfs) == 0;
+    on_nosuid  = check_okay && (stfs.f_flag  & ST_NOSUID);
+#   else
+#       if defined(HAS_FSTATFS) && defined(HAS_STRUCT_STATFS_FLAGS)
+    struct statfs  stfs;
+    check_okay = fstatfs(fd, &stfs)  == 0;
+#           undef PERL_MOUNT_NOSUID
+#           if !defined(PERL_MOUNT_NOSUID) && defined(MNT_NOSUID)
+#              define PERL_MOUNT_NOSUID MNT_NOSUID
+#           endif
+#           if !defined(PERL_MOUNT_NOSUID) && defined(MS_NOSUID)
+#              define PERL_MOUNT_NOSUID MS_NOSUID
+#           endif
+#           if !defined(PERL_MOUNT_NOSUID) && defined(M_NOSUID)
+#              define PERL_MOUNT_NOSUID M_NOSUID
+#           endif
+#           ifdef PERL_MOUNT_NOSUID
+    on_nosuid  = check_okay && (stfs.f_flags & PERL_MOUNT_NOSUID);
+#           endif
+#       else
+#           if defined(HAS_GETMNENT) && defined(HAS_HASMNTOPT) && defined(MNTOPT_NOSUID)
+    FILE               *mtab = fopen("/etc/mtab", "r");
+    struct mntent      *entry;
+    struct stat                stb, fsb;
+
+    if (mtab && (fstat(fd, &stb) == 0)) {
+       while (entry = getmntent(mtab)) {
+           if (stat(entry->mnt_dir, &fsb) == 0
+               && fsb.st_dev == stb.st_dev)
+           {
+               /* found the filesystem */
+               check_okay = 1;
+               if (hasmntopt(entry, MNTOPT_NOSUID))
+                   on_nosuid = 1;
+               break;
+           } /* A single fs may well fail its stat(). */
+       }
+    }
+    if (mtab)
+       fclose(mtab);
+#           endif /* mntent */
+#       endif /* statfs */
+#   endif /* statvfs */
+    if (!check_okay) 
+       croak("Can't check filesystem of script \"%s\"", PL_origfilename);
+    return on_nosuid;
+}
+#endif /* IAMSUID */
+
 STATIC void
 validate_suid(char *validarg, char *scriptname, int fdscript)
 {
@@ -2134,6 +2210,7 @@ validate_suid(char *validarg, char *scriptname, int fdscript)
        croak("Can't stat script \"%s\"",PL_origfilename);
     if (fdscript < 0 && PL_statbuf.st_mode & (S_ISUID|S_ISGID)) {
        I32 len;
+       STRLEN n_a;
 
 #ifdef IAMSUID
 #ifndef HAS_SETREUID
@@ -2168,6 +2245,10 @@ validate_suid(char *validarg, char *scriptname, int fdscript)
                croak("Can't swap uid and euid");       /* really paranoid */
            if (PerlLIO_stat(SvPVX(GvSV(PL_curcop->cop_filegv)),&tmpstatbuf) < 0)
                croak("Permission denied");     /* testing full pathname here */
+#ifdef IAMSUID
+           if (fd_on_nosuid_fs(PerlIO_fileno(PL_rsfp)))
+               croak("Permission denied");
+#endif
            if (tmpstatbuf.st_dev != PL_statbuf.st_dev ||
                tmpstatbuf.st_ino != PL_statbuf.st_ino) {
                (void)PerlIO_close(PL_rsfp);
@@ -2206,12 +2287,12 @@ validate_suid(char *validarg, char *scriptname, int fdscript)
        PL_doswitches = FALSE;          /* -s is insecure in suid */
        PL_curcop->cop_line++;
        if (sv_gets(PL_linestr, PL_rsfp, 0) == Nullch ||
-         strnNE(SvPV(PL_linestr,PL_na),"#!",2) )       /* required even on Sys V */
+         strnNE(SvPV(PL_linestr,n_a),"#!",2) ) /* required even on Sys V */
            croak("No #! line");
-       s = SvPV(PL_linestr,PL_na)+2;
+       s = SvPV(PL_linestr,n_a)+2;
        if (*s == ' ') s++;
        while (!isSPACE(*s)) s++;
-       for (s2 = s;  (s2 > SvPV(PL_linestr,PL_na)+2 &&
+       for (s2 = s;  (s2 > SvPV(PL_linestr,n_a)+2 &&
                       (isDIGIT(s2[-1]) || strchr("._-", s2[-1])));  s2--) ;
        if (strnNE(s2-4,"perl",4) && strnNE(s-9,"perl",4))  /* sanity check */
            croak("Not a perl script");
@@ -2750,7 +2831,7 @@ incpush(char *p, int addsubdirs)
            char *unix;
            STRLEN len;
 
-           if ((unix = tounixspec_ts(SvPV(libdir,PL_na),Nullch)) != Nullch) {
+           if ((unix = tounixspec_ts(SvPV(libdir,len),Nullch)) != Nullch) {
                len = strlen(unix);
                while (unix[len-1] == '/') len--;  /* Cosmetic */
                sv_usepvn(libdir,unix,len);
@@ -2758,7 +2839,7 @@ incpush(char *p, int addsubdirs)
            else
                PerlIO_printf(PerlIO_stderr(),
                              "Failed to unixify @INC element \"%s\"\n",
-                             SvPV(libdir,PL_na));
+                             SvPV(libdir,len));
 #endif
            /* .../archname/version if -d .../archname/version/auto */
            sv_setsv(subdir, libdir);
@@ -2810,6 +2891,7 @@ init_main_thread()
     *SvEND(PL_thrsv) = '\0';   /* in the trailing_nul field */
     thr->oursv = PL_thrsv;
     PL_chopset = " \n-";
+    PL_dumpindent = 4;
 
     MUTEX_LOCK(&PL_threads_mutex);
     PL_nthreads++;
@@ -2978,7 +3060,7 @@ my_failure_exit(void)
 STATIC void
 my_exit_jump(void)
 {
-    dSP;
+    dTHR;
     register PERL_CONTEXT *cx;
     I32 gimme;
     SV **newsp;