#include "perl.h"
#include "patchlevel.h"
-/* Omit -- it causes too much grief on mixed systems.
+/* XXX If this causes problems, set i_unistd=undef in the hint file. */
#ifdef I_UNISTD
#include <unistd.h>
#endif
-*/
dEXT char rcsid[] = "perl.c\nPatch level: ###\n";
#endif
#endif
-#ifndef OSNAME
-#define OSNAME "unknown"
-#endif
-
static void find_beginning _((void));
+static void forbid_setid _((char *));
static void incpush _((char *));
static void init_ids _((void));
static void init_debugger _((void));
rsfp = Nullfp;
statname = Nullsv;
tmps_floor = -1;
+ perl_destruct_level = 1;
#endif
init_ids();
+ SET_NUMERIC_STANDARD();
#if defined(SUBVERSION) && SUBVERSION > 0
- sprintf(patchlevel, "%7.5f", 5.0 + (PATCHLEVEL / 1000.0)
- + (SUBVERSION / 100000.0));
+ sprintf(patchlevel, "%7.5f", (double) 5
+ + ((double) PATCHLEVEL / (double) 1000)
+ + ((double) SUBVERSION / (double) 100000));
#else
- sprintf(patchlevel, "%5.3f", 5.0 + (PATCHLEVEL / 1000.0));
+ sprintf(patchlevel, "%5.3f", (double) 5 +
+ ((double) PATCHLEVEL / (double) 1000));
#endif
#if defined(LOCAL_PATCH_COUNT)
#ifdef DEBUGGING
{
char *s;
- if (s = getenv("PERL_DESTRUCT_LEVEL"))
- destruct_level = atoi(s);
+ if (s = getenv("PERL_DESTRUCT_LEVEL")) {
+ int i = atoi(s);
+ if (destruct_level < i)
+ destruct_level = i;
+ }
}
#endif
+ /* unhook hooks which will soon be, or use, destroyed data */
+ SvREFCNT_dec(warnhook);
+ warnhook = Nullsv;
+ SvREFCNT_dec(diehook);
+ diehook = Nullsv;
+ SvREFCNT_dec(parsehook);
+ parsehook = Nullsv;
+
LEAVE;
FREETMPS;
/* The exit() function will do everything that needs doing. */
return;
}
-
+
+ /* loosen bonds of global variables */
+
+ setdefout(Nullgv);
+
+ sv_free(nrs);
+ nrs = Nullsv;
+
+ sv_free(lastscream);
+ lastscream = Nullsv;
+
+ sv_free(statname);
+ statname = Nullsv;
+ statgv = Nullgv;
+ laststatval = -1;
+
/* Prepare to destruct main symbol table. */
+
hv = defstash;
defstash = 0;
SvREFCNT_dec(hv);
if (!e_fp)
croak("Cannot open temporary file");
}
- if (argv[1]) {
+ if (*++s)
+ PerlIO_puts(e_fp,s);
+ else if (argv[1]) {
PerlIO_puts(e_fp,argv[1]);
argc--,argv++;
}
+ else
+ croak("No code specified for -e");
(void)PerlIO_putc(e_fp,'\n');
break;
case 'I':
- taint_not("-I");
+ forbid_setid("-I");
sv_catpv(sv,"-");
sv_catpv(sv,s);
sv_catpv(sv," ");
}
break;
case 'P':
- taint_not("-P");
+ forbid_setid("-P");
preprocess = TRUE;
s++;
goto reswitch;
case 'S':
- taint_not("-S");
+ forbid_setid("-S");
dosearch = TRUE;
s++;
goto reswitch;
else if (scriptname == Nullch) {
#ifdef MSDOS
if ( isatty(PerlIO_fileno(PerlIO_stdin())) )
- moreswitches("v");
+ moreswitches("h");
#endif
scriptname = "-";
}
if (flags & G_ARRAY)
myop.op_flags |= OPf_LIST;
- if (perldb && curstash != debstash
- && (DBcv || (DBcv = GvCV(DBsub)))) /* to handle first BEGIN of -d */
+ if (perldb && curstash != debstash
+ /* Handle first BEGIN of -d. */
+ && (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))
op->op_private |= OPpENTERSUB_DB;
if (flags & G_EVAL) {
s++;
return s;
case 'd':
- taint_not("-d");
+ forbid_setid("-d");
s++;
if (*s == ':' || *s == '=') {
sprintf(buf, "use Devel::%s;", ++s);
return s;
case 'D':
#ifdef DEBUGGING
- taint_not("-D");
+ forbid_setid("-D");
if (isALPHA(s[1])) {
static char debopts[] = "psltocPmfrxuLHXD";
char *d;
*s = '\0';
break;
case 'I':
- taint_not("-I");
+ forbid_setid("-I");
if (*++s) {
char *e;
for (e = s; *e && !isSPACE(*e); e++) ;
}
return s;
case 'M':
- taint_not("-M"); /* XXX ? */
+ forbid_setid("-M"); /* XXX ? */
/* FALL THROUGH */
case 'm':
- taint_not("-m"); /* XXX ? */
+ forbid_setid("-m"); /* XXX ? */
if (*++s) {
char *start;
char *use = "use ";
s++;
return s;
case 's':
- taint_not("-s");
+ forbid_setid("-s");
doswitches = TRUE;
s++;
return s;
printf("\n\nCopyright 1987-1996, Larry Wall\n");
printf("\n\t+ suidperl security patch");
#ifdef MSDOS
- printf("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
+ printf("\n\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
+#endif
+#ifdef DJGPP
+ printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n");
#endif
#ifdef OS2
- printf("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
+ printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
"Version 5 port Copyright (c) 1994-1996, Andreas Kaiser, Ilya Zakharevich\n");
#endif
#ifdef atarist
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");
-#ifdef MSDOS
- usage(origargv[0]);
-#endif
exit(0);
case 'w':
dowarn = TRUE;
defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
GvMULTI_on(errgv);
+ sv_setpvn(GvSV(errgv), "", 0);
curstash = defstash;
compiling.cop_stash = defstash;
debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
if (fdscript >= 0) {
rsfp = PerlIO_fdopen(fdscript,"r");
#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
+ if (rsfp)
+ fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
#endif
}
else if (preprocess) {
rsfp = my_popen(buf,"r");
}
else if (!*scriptname) {
- taint_not("program input from stdin");
+ forbid_setid("program input from stdin");
rsfp = PerlIO_stdin();
}
else {
rsfp = PerlIO_open(scriptname,"r");
#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
+ if (rsfp)
+ fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
#endif
}
- if ((PerlIO*)rsfp == Nullfp) {
+ if (e_tmpname) {
+ e_fp = rsfp;
+ }
+ if (!rsfp) {
#ifdef DOSUID
#ifndef IAMSUID /* in case script is not readable before setuid */
if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
/* skip forward in input to the real script? */
- taint_not("-x");
+ forbid_setid("-x");
while (doextract) {
if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
croak("No Perl script found in input\n");
}
static void
+forbid_setid(s)
+char *s;
+{
+ if (euid != uid)
+ croak("No %s allowed while running setuid", s);
+ if (egid != gid)
+ croak("No %s allowed while running setgid", s);
+}
+
+static void
init_debugger()
{
curstash = debstash;
init_stacks()
{
curstack = newAV();
- mainstack = curstack; /* remember in case we switch stacks */
- AvREAL_off(curstack); /* not a real array */
+ 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;
- /* Shouldn't these stacks be per-interpreter? */
+ cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */
+ New(50,cxstack,cxstack_max + 1,CONTEXT);
+ cxstack_ix = -1;
+
+ New(50,tmps_stack,128,SV*);
+ tmps_ix = -1;
+ tmps_max = 128;
+
+ DEBUG( {
+ New(51,debname,128,char);
+ New(52,debdelim,128,char);
+ } )
+
+ /*
+ * The following stacks almost certainly should be per-interpreter,
+ * but for now they're not. XXX
+ */
+
if (markstack) {
markstack_ptr = markstack;
} else {
New(54,retstack,16,OP*);
retstack_ix = 0;
retstack_max = 16;
- }
-
- cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */
- New(50,cxstack,cxstack_max + 1,CONTEXT);
- cxstack_ix = -1;
-
- New(50,tmps_stack,128,SV*);
- tmps_ix = -1;
- tmps_max = 128;
-
- DEBUG( {
- New(51,debname,128,char);
- New(52,debdelim,128,char);
- } )
+ }
}
static void
{
Safefree(cxstack);
Safefree(tmps_stack);
+ DEBUG( {
+ Safefree(debname);
+ Safefree(debdelim);
+ } )
}
static PerlIO *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
+
static void
init_lexer()
{
tmpfp = rsfp;
-
lex_start(linestr);
rsfp = tmpfp;
subname = newSVpv("main",4);
sv_setpvn(bodytarget, "", 0);
formtarget = bodytarget;
- tainted = 1;
+ TAINT;
if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
sv_setpv(GvSV(tmpgv),origfilename);
magicname("0", "0", 1);
#endif
hv_magic(hv, envgv, 'E');
}
- tainted = 0;
+ TAINT_NOT;
if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
sv_setiv(GvSV(tmpgv),(I32)getpid());
-
}
static void
{
char *s;
if (!tainting) {
+#ifndef VMS
s = getenv("PERL5LIB");
if (s)
incpush(s);
else
incpush(getenv("PERLLIB"));
+#else /* VMS */
+ /* Treat PERL5?LIB as a possible search list logical name -- the
+ * "natural" VMS idiom for a Unix path string. We allow each
+ * element to be a set of |-separated directories for compatibility.
+ */
+ char buf[256];
+ int idx = 0;
+ if (my_trnlnm("PERL5LIB",buf,0))
+ do { incpush(buf); } while (my_trnlnm("PERL5LIB",buf,++idx));
+ else
+ while (my_trnlnm("PERLLIB",buf,idx++)) incpush(buf);
+#endif /* VMS */
}
+/* Use the ~-expanded versions of APPLIB (undocumented),
+ ARCHLIB PRIVLIB SITEARCH SITELIB and OLDARCHLIB
+*/
#ifdef APPLLIB_EXP
incpush(APPLLIB_EXP);
#endif