2 * Copyright (c) 1991, 1992, 1993, 1994 Larry Wall
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Artistic License, as specified in the README file.
8 * Revision 4.1 92/08/07 18:25:50 lwall
10 * Revision 4.0.1.7 92/06/08 14:50:39 lwall
11 * patch20: PERLLIB now supports multiple directories
12 * patch20: running taintperl explicitly now does checks even if $< == $>
13 * patch20: -e 'cmd' no longer fails silently if /tmp runs out of space
14 * patch20: perl -P now uses location of sed determined by Configure
15 * patch20: form feed for formats is now specifiable via $^L
16 * patch20: paragraph mode now skips extra newlines automatically
17 * patch20: oldeval "1 #comment" didn't work
18 * patch20: couldn't require . files
19 * patch20: semantic compilation errors didn't abort execution
21 * Revision 4.0.1.6 91/11/11 16:38:45 lwall
22 * patch19: default arg for shift was wrong after first subroutine definition
23 * patch19: op/regexp.t failed from missing arg to bcmp()
25 * Revision 4.0.1.5 91/11/05 18:03:32 lwall
26 * patch11: random cleanup
27 * patch11: $0 was being truncated at times
28 * patch11: cppstdin now installed outside of source directory
29 * patch11: -P didn't allow use of #elif or #undef
30 * patch11: prepared for ctype implementations that don't define isascii()
31 * patch11: added oldeval {}
32 * patch11: oldeval confused by string containing null
34 * Revision 4.0.1.4 91/06/10 01:23:07 lwall
35 * patch10: perl -v printed incorrect copyright notice
37 * Revision 4.0.1.3 91/06/07 11:40:18 lwall
38 * patch4: changed old $^P to $^X
40 * Revision 4.0.1.2 91/06/07 11:26:16 lwall
41 * patch4: new copyright notice
42 * patch4: added $^P variable to control calling of perldb routines
43 * patch4: added $^F variable to specify maximum system fd, default 2
44 * patch4: debugger lost track of lines in oldeval
46 * Revision 4.0.1.1 91/04/11 17:49:05 lwall
47 * patch1: fixed undefined environ problem
49 * Revision 4.0 91/03/20 01:37:44 lwall
59 #include "patchlevel.h"
61 char rcsid[] = "$RCSfile: perl.c,v $$Revision: 5.0 $$Date: 92/08/07 18:25:50 $\nPatch level: ###\n";
69 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
75 static void incpush();
76 static void validate_suid();
77 static void find_beginning();
78 static void init_main_stash();
79 static void open_script();
80 static void init_debugger();
81 static void init_stack();
82 static void init_lexer();
83 static void init_context_stack();
84 static void init_predump_symbols();
85 static void init_postdump_symbols();
86 static void init_perllib();
91 PerlInterpreter *sv_interp;
95 Zero(&junk, 1, PerlInterpreter);
96 New(53, sv_interp, 1, PerlInterpreter);
101 perl_construct( sv_interp )
102 register PerlInterpreter *sv_interp;
104 if (!(curinterp = sv_interp))
107 Zero(sv_interp, 1, PerlInterpreter);
109 /* Init the real globals? */
111 linestr = NEWSV(65,80);
113 SvREADONLY_on(&sv_undef);
117 SvREADONLY_on(&sv_no);
119 sv_setpv(&sv_yes,Yes);
121 SvREADONLY_on(&sv_yes);
125 * There is no way we can refer to them from Perl so close them to save
126 * space. The other alternative would be to provide STDAUX and STDPRN
129 (void)fclose(stdaux);
130 (void)fclose(stdprn);
159 euid = (int)geteuid();
161 egid = (int)getegid();
162 tainting = (euid != uid || egid != gid);
163 sprintf(patchlevel,"%3.3s%2.2d", strchr(rcsid,'5'), PATCHLEVEL);
165 (void)sprintf(strchr(rcsid,'#'), "%d\n", PATCHLEVEL);
167 fdpid = newAV(); /* for remembering popen pids by fd */
168 pidstatus = newHV();/* for remembering status of dead pids */
172 perl_destruct(sv_interp)
173 register PerlInterpreter *sv_interp;
175 if (!(curinterp = sv_interp))
186 PerlInterpreter *sv_interp;
188 if (!(curinterp = sv_interp))
194 perl_parse(sv_interp, argc, argv, env)
195 PerlInterpreter *sv_interp;
197 register char **argv;
204 bool dosearch = FALSE;
207 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
210 croak("suidperl is no longer needed since the kernel can now execute\n\
211 setuid perl scripts securely.\n");
215 if (!(curinterp = sv_interp))
224 origenviron = environ;
226 switch (setjmp(top_env)) {
230 return(statusvalue); /* my_exit() was called */
232 fprintf(stderr, "panic: top_env\n");
237 origfilename = savestr(argv[0]);
239 cxstack_ix = -1; /* start label stack again */
242 sv_setpvn(linestr,"",0);
243 sv = newSVpv("",0); /* first used for -I flags */
245 for (argc--,argv++; argc > 0; argc--,argv++) {
246 if (argv[0][0] != '-' || !argv[0][1])
250 validarg = " PHOOEY ";
272 if (s = moreswitches(s))
277 if (euid != uid || egid != gid)
278 croak("No -e allowed in setuid scripts");
280 e_tmpname = savestr(TMPPATH);
281 (void)mktemp(e_tmpname);
283 croak("Can't mktemp()");
284 e_fp = fopen(e_tmpname,"w");
286 croak("Cannot open temporary file");
292 (void)putc('\n', e_fp);
300 (void)av_push(GvAVn(incgv),newSVpv(s,0));
303 (void)av_push(GvAVn(incgv),newSVpv(argv[1],0));
304 sv_catpv(sv,argv[1]);
331 croak("Unrecognized switch: -%s",s);
335 scriptname = argv[0];
337 if (fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
338 croak("Can't write to temp file for -e: %s", strerror(errno));
340 scriptname = e_tmpname;
342 else if (scriptname == Nullch) {
344 if ( isatty(fileno(stdin)) )
352 open_script(scriptname,dosearch,sv);
354 sv_free(sv); /* free -I directories */
357 validate_suid(validarg);
367 av_push(comppad, Nullsv);
368 curpad = AvARRAY(comppad);
370 comppadname = padname;
371 comppadnamefill = -1;
376 init_context_stack();
378 perl_init_ext(); /* in case linked C routines want magical variables */
380 init_predump_symbols();
384 /* now parse the script */
387 if (yyparse() || error_count) {
389 croak("%s had compilation errors.\n", origfilename);
391 croak("Execution of %s aborted due to compilation errors.\n",
395 curcop->cop_line = 0;
400 (void)UNLINK(e_tmpname);
403 /* now that script is parsed, we can modify record separator */
408 rspara = (nrslen == 2);
409 sv_setpvn(GvSV(gv_fetchpv("/", TRUE)), rs, rslen);
414 just_doit: /* come here if running an undumped a.out */
415 init_postdump_symbols(argc,argv,env);
421 PerlInterpreter *sv_interp;
423 if (!(curinterp = sv_interp))
427 switch (setjmp(top_env)) {
429 cxstack_ix = -1; /* start context stack again */
435 return(statusvalue); /* my_exit() was called */
438 fprintf(stderr, "panic: restartop\n");
441 if (stack != mainstack) {
443 SWITCHSTACK(stack, mainstack);
450 DEBUG(fprintf(stderr,"\nEXECUTING...\n\n"));
453 fprintf(stderr,"%s syntax OK\n", origfilename);
465 else if (main_start) {
477 statusvalue = (unsigned short)(status & 0xffff);
481 /* Be sure to refetch the stack pointer after calling these routines. */
484 perl_callback(subname, sp, gimme, hasargs, numargs)
486 I32 sp; /* stack pointer after args are pushed */
487 I32 gimme; /* called in array or scalar context */
488 I32 hasargs; /* whether to create a @_ array for routine */
489 I32 numargs; /* how many args are pushed on the stack */
491 BINOP myop; /* fake syntax tree node */
496 stack_base = AvARRAY(stack);
497 stack_sp = stack_base + sp - numargs - 1;
500 pp_pushmark(); /* doesn't look at op, actually, except to return */
501 *++stack_sp = (SV*)gv_fetchpv(subname, FALSE);
505 myop.op_flags = OPf_STACKED;
506 myop.op_last = (OP*)&myop;
508 myop.op_next = Nullop;
510 if (op = pp_entersubr())
514 return stack_sp - stack_base;
518 perl_callv(subname, sp, gimme, argv)
520 register I32 sp; /* current stack pointer */
521 I32 gimme; /* called in array or scalar context */
522 register char **argv; /* null terminated arg list, NULL for no arglist */
524 register I32 items = 0;
525 I32 hasargs = (argv != 0);
527 av_store(stack, ++sp, Nullsv); /* reserve spot for 1st return arg */
530 av_store(stack, ++sp, sv_2mortal(newSVpv(*argv,0)));
535 return perl_callback(subname, sp, gimme, hasargs, items);
539 magicname(sym,name,namlen)
546 if (gv = gv_fetchpv(sym,TRUE))
547 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
551 #define PERLLIB_SEP ';'
553 #define PERLLIB_SEP ':'
565 /* Break at all separators */
567 /* First, skip any consecutive separators */
568 while ( *p == PERLLIB_SEP ) {
569 /* Uncomment the next line for PATH semantics */
570 /* (void)av_push(GvAVn(incgv), newSVpv(".", 1)); */
573 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
574 (void)av_push(GvAVn(incgv), newSVpv(p, (I32)(s - p)));
577 (void)av_push(GvAVn(incgv), newSVpv(p, 0));
583 /* This routine handles any switches that can be given during run */
593 nrschar = scan_oct(s, 4, &numlen);
594 nrs = nsavestr("\n",1);
596 if (nrschar > 0377) {
600 else if (!nrschar && numlen >= 2) {
623 static char debopts[] = "psltocPmfrxuLHX";
626 for (s++; *s && (d = strchr(debopts,*s)); s++)
627 debug |= 1 << (d - debopts);
631 for (s++; isDIGIT(*s); s++) ;
635 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
636 for (s++; isDIGIT(*s); s++) ;
643 inplace = savestr(s+1);
645 for (s = inplace; *s && !isSPACE(*s); s++) ;
651 (void)av_push(GvAVn(incgv),newSVpv(s,0));
654 croak("No space allowed after -I");
662 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
666 ors = nsavestr(nrs,nrslen);
696 fputs("\nThis is perl, version 5.0, Alpha 4 (unsupported)\n\n",stdout);
698 fputs("\nCopyright (c) 1989, 1990, 1991, 1992, 1993, 1994 Larry Wall\n",stdout);
700 fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
703 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n",
708 fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout);
711 Perl may be copied only under the terms of either the Artistic License or the\n\
712 GNU General Public License, which may be found in the Perl 5.0 source kit.\n",stdout);
722 if (s[1] == '-') /* Additional switches on #! line. */
730 croak("Switch meaningless after -x: -%s",s);
735 /* compliments of Tom Christiansen */
737 /* unexec() can be found in the Gnu emacs distribution */
746 sprintf (buf, "%s.perldump", origfilename);
747 sprintf (tokenbuf, "%s/perl", BIN);
749 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
751 fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
754 ABORT(); /* for use with undump */
762 curstash = defstash = newHV();
763 curstname = newSVpv("main",4);
764 GvHV(gv = gv_fetchpv("_main",TRUE)) = defstash;
766 HvNAME(defstash) = "main";
767 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE)));
769 defgv = gv_fetchpv("_",TRUE);
773 open_script(scriptname,dosearch,sv)
778 char *xfound = Nullch;
779 char *xfailed = Nullch;
783 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
785 bufend = s + strlen(s);
788 s = cpytill(tokenbuf,s,bufend,':',&len);
791 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
792 tokenbuf[len] = '\0';
794 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
795 tokenbuf[len] = '\0';
801 if (len && tokenbuf[len-1] != '/')
804 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
806 if (len && tokenbuf[len-1] != '\\')
809 (void)strcat(tokenbuf+len,"/");
810 (void)strcat(tokenbuf+len,scriptname);
811 DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
812 if (stat(tokenbuf,&statbuf) < 0) /* not there? */
814 if (S_ISREG(statbuf.st_mode)
815 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
816 xfound = tokenbuf; /* bingo! */
820 xfailed = savestr(tokenbuf);
823 croak("Can't execute %s", xfailed ? xfailed : scriptname );
829 origfilename = savestr(scriptname);
830 curcop->cop_filegv = gv_fetchfile(origfilename);
831 if (strEQ(origfilename,"-"))
834 char *cpp = CPPSTDIN;
836 if (strEQ(cpp,"cppstdin"))
837 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
839 sprintf(tokenbuf, "%s", cpp);
841 sv_catpv(sv,PRIVLIB);
843 (void)sprintf(buf, "\
844 sed %s -e \"/^[^#]/b\" \
845 -e \"/^#[ ]*include[ ]/b\" \
846 -e \"/^#[ ]*define[ ]/b\" \
847 -e \"/^#[ ]*if[ ]/b\" \
848 -e \"/^#[ ]*ifdef[ ]/b\" \
849 -e \"/^#[ ]*ifndef[ ]/b\" \
850 -e \"/^#[ ]*else/b\" \
851 -e \"/^#[ ]*elif[ ]/b\" \
852 -e \"/^#[ ]*undef[ ]/b\" \
853 -e \"/^#[ ]*endif/b\" \
856 (doextract ? "-e \"1,/^#/d\n\"" : ""),
858 (void)sprintf(buf, "\
859 %s %s -e '/^[^#]/b' \
860 -e '/^#[ ]*include[ ]/b' \
861 -e '/^#[ ]*define[ ]/b' \
862 -e '/^#[ ]*if[ ]/b' \
863 -e '/^#[ ]*ifdef[ ]/b' \
864 -e '/^#[ ]*ifndef[ ]/b' \
866 -e '/^#[ ]*elif[ ]/b' \
867 -e '/^#[ ]*undef[ ]/b' \
868 -e '/^#[ ]*endif/b' \
876 (doextract ? "-e '1,/^#/d\n'" : ""),
878 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
879 DEBUG_P(fprintf(stderr, "%s\n", buf));
881 #ifdef IAMSUID /* actually, this is caught earlier */
882 if (euid != uid && !euid) { /* if running suidperl */
884 (void)seteuid(uid); /* musn't stay setuid root */
887 (void)setreuid(-1, uid);
892 if (geteuid() != uid)
893 croak("Can't do seteuid!\n");
896 rsfp = my_popen(buf,"r");
898 else if (!*scriptname) {
899 taint_not("program input from stdin");
903 rsfp = fopen(scriptname,"r");
904 if ((FILE*)rsfp == Nullfp) {
906 #ifndef IAMSUID /* in case script is not readable before setuid */
907 if (euid && stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
908 statbuf.st_mode & (S_ISUID|S_ISGID)) {
909 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
910 execv(buf, origargv); /* try again */
911 croak("Can't do setuid\n");
915 croak("Can't open perl script \"%s\": %s\n",
916 SvPVX(GvSV(curcop->cop_filegv)), strerror(errno));
921 validate_suid(validarg)
925 /* do we need to emulate setuid on scripts? */
927 /* This code is for those BSD systems that have setuid #! scripts disabled
928 * in the kernel because of a security problem. Merely defining DOSUID
929 * in perl will not fix that problem, but if you have disabled setuid
930 * scripts in the kernel, this will attempt to emulate setuid and setgid
931 * on scripts that have those now-otherwise-useless bits set. The setuid
932 * root version must be called suidperl or sperlN.NNN. If regular perl
933 * discovers that it has opened a setuid script, it calls suidperl with
934 * the same argv that it had. If suidperl finds that the script it has
935 * just opened is NOT setuid root, it sets the effective uid back to the
936 * uid. We don't just make perl setuid root because that loses the
937 * effective uid we had before invoking perl, if it was different from the
940 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
941 * be defined in suidperl only. suidperl must be setuid root. The
942 * Configure script will set this up for you if you want it.
946 if (fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
947 croak("Can't stat script \"%s\"",origfilename);
948 if (statbuf.st_mode & (S_ISUID|S_ISGID)) {
953 /* On this access check to make sure the directories are readable,
954 * there is actually a small window that the user could use to make
955 * filename point to an accessible directory. So there is a faint
956 * chance that someone could execute a setuid script down in a
957 * non-accessible directory. I don't know what to do about that.
958 * But I don't think it's too important. The manual lies when
959 * it says access() is useful in setuid programs.
961 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
962 croak("Permission denied");
964 /* If we can swap euid and uid, then we can determine access rights
965 * with a simple stat of the file, and then compare device and
966 * inode to make sure we did stat() on the same file we opened.
967 * Then we just have to make sure he or she can execute it.
970 struct stat tmpstatbuf;
972 if (setreuid(euid,uid) < 0 || getuid() != euid || geteuid() != uid)
973 croak("Can't swap uid and euid"); /* really paranoid */
974 if (stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
975 croak("Permission denied"); /* testing full pathname here */
976 if (tmpstatbuf.st_dev != statbuf.st_dev ||
977 tmpstatbuf.st_ino != statbuf.st_ino) {
979 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
981 "User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
982 (Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
983 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
984 statbuf.st_dev, statbuf.st_ino,
985 SvPVX(GvSV(curcop->cop_filegv)),
986 statbuf.st_uid, statbuf.st_gid);
987 (void)my_pclose(rsfp);
989 croak("Permission denied\n");
991 if (setreuid(uid,euid) < 0 || getuid() != uid || geteuid() != euid)
992 croak("Can't reswap uid and euid");
993 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
994 croak("Permission denied\n");
996 #endif /* HAS_SETREUID */
999 if (!S_ISREG(statbuf.st_mode))
1000 croak("Permission denied");
1001 if (statbuf.st_mode & S_IWOTH)
1002 croak("Setuid/gid script is writable by world");
1003 doswitches = FALSE; /* -s is insecure in suid */
1005 if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1006 strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */
1007 croak("No #! line");
1010 while (!isSPACE(*s)) s++;
1011 if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
1012 croak("Not a perl script");
1013 while (*s == ' ' || *s == '\t') s++;
1015 * #! arg must be what we saw above. They can invoke it by
1016 * mentioning suidperl explicitly, but they may not add any strange
1017 * arguments beyond what #! says if they do invoke suidperl that way.
1019 len = strlen(validarg);
1020 if (strEQ(validarg," PHOOEY ") ||
1021 strnNE(s,validarg,len) || !isSPACE(s[len]))
1022 croak("Args must match #! line");
1025 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1026 euid == statbuf.st_uid)
1028 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1029 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1030 #endif /* IAMSUID */
1032 if (euid) { /* oops, we're not the setuid root perl */
1035 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1036 execv(buf, origargv); /* try again */
1038 croak("Can't do setuid\n");
1041 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
1043 (void)setegid(statbuf.st_gid);
1046 (void)setregid((GIDTYPE)-1,statbuf.st_gid);
1048 setgid(statbuf.st_gid);
1051 if (getegid() != statbuf.st_gid)
1052 croak("Can't do setegid!\n");
1054 if (statbuf.st_mode & S_ISUID) {
1055 if (statbuf.st_uid != euid)
1057 (void)seteuid(statbuf.st_uid); /* all that for this */
1060 (void)setreuid((UIDTYPE)-1,statbuf.st_uid);
1062 setuid(statbuf.st_uid);
1065 if (geteuid() != statbuf.st_uid)
1066 croak("Can't do seteuid!\n");
1068 else if (uid) { /* oops, mustn't run as root */
1070 (void)seteuid((UIDTYPE)uid);
1073 (void)setreuid((UIDTYPE)-1,(UIDTYPE)uid);
1075 setuid((UIDTYPE)uid);
1078 if (geteuid() != uid)
1079 croak("Can't do seteuid!\n");
1081 uid = (int)getuid();
1082 euid = (int)geteuid();
1083 gid = (int)getgid();
1084 egid = (int)getegid();
1085 tainting |= (euid != uid || egid != gid);
1086 if (!cando(S_IXUSR,TRUE,&statbuf))
1087 croak("Permission denied\n"); /* they can't do this */
1090 else if (preprocess)
1091 croak("-P not allowed for setuid/setgid script\n");
1093 croak("Script is not setuid/setgid in suidperl\n");
1094 #endif /* IAMSUID */
1096 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1097 #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
1098 fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
1099 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1101 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1104 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1105 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1106 #endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1107 /* not set-id, must be wrapped */
1117 /* skip forward in input to the real script? */
1121 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
1122 croak("No Perl script found in input\n");
1123 if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1124 ungetc('\n',rsfp); /* to keep line count right */
1126 if (s = instr(s,"perl -")) {
1129 while (s = moreswitches(s)) ;
1131 if (cddir && chdir(cddir) < 0)
1132 croak("Can't chdir to %s",cddir);
1143 GvHV(gv_fetchpv("_DB",TRUE)) = debstash;
1144 curstash = debstash;
1145 dbargs = GvAV(gv_AVadd((tmpgv = gv_fetchpv("args",TRUE))));
1148 DBgv = gv_fetchpv("DB",TRUE);
1150 DBline = gv_fetchpv("dbline",TRUE);
1152 DBsub = gv_HVadd(tmpgv = gv_fetchpv("sub",TRUE));
1154 DBsingle = GvSV((tmpgv = gv_fetchpv("single",TRUE)));
1156 DBtrace = GvSV((tmpgv = gv_fetchpv("trace",TRUE)));
1158 DBsignal = GvSV((tmpgv = gv_fetchpv("signal",TRUE)));
1160 curstash = defstash;
1167 mainstack = stack; /* remember in case we switch stacks */
1168 AvREAL_off(stack); /* not a real array */
1169 av_fill(stack,127); av_fill(stack,-1); /* preextend stack */
1171 stack_base = AvARRAY(stack);
1172 stack_sp = stack_base;
1173 stack_max = stack_base + 128;
1175 New(54,markstack,64,int);
1176 markstack_ptr = markstack;
1177 markstack_max = markstack + 64;
1179 New(54,scopestack,32,int);
1181 scopestack_max = 32;
1183 New(54,savestack,128,ANY);
1185 savestack_max = 128;
1187 New(54,retstack,16,OP*);
1195 bufend = bufptr = SvPV(linestr, na);
1196 subname = newSVpv("main",4);
1197 lex_start(); /* we never leave */
1201 init_context_stack()
1203 New(50,cxstack,128,CONTEXT);
1205 New(51,debname,128,char);
1206 New(52,debdelim,128,char);
1211 init_predump_symbols()
1215 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE)), " ", 1);
1217 stdingv = gv_fetchpv("STDIN",TRUE);
1218 SvMULTI_on(stdingv);
1220 GvIO(stdingv) = newIO();
1221 GvIO(stdingv)->ifp = stdin;
1222 tmpgv = gv_fetchpv("stdin",TRUE);
1223 GvIO(tmpgv) = GvIO(stdingv);
1226 tmpgv = gv_fetchpv("STDOUT",TRUE);
1229 GvIO(tmpgv) = newIO();
1230 GvIO(tmpgv)->ofp = GvIO(tmpgv)->ifp = stdout;
1232 tmpgv = gv_fetchpv("stdout",TRUE);
1233 GvIO(tmpgv) = GvIO(defoutgv);
1236 curoutgv = gv_fetchpv("STDERR",TRUE);
1237 SvMULTI_on(curoutgv);
1238 if (!GvIO(curoutgv))
1239 GvIO(curoutgv) = newIO();
1240 GvIO(curoutgv)->ofp = GvIO(curoutgv)->ifp = stderr;
1241 tmpgv = gv_fetchpv("stderr",TRUE);
1242 GvIO(tmpgv) = GvIO(curoutgv);
1244 curoutgv = defoutgv; /* switch back to STDOUT */
1246 statname = NEWSV(66,0); /* last filename we did stat on */
1250 init_postdump_symbols(argc,argv,env)
1252 register char **argv;
1253 register char **env;
1259 argc--,argv++; /* skip name of script */
1261 for (; argc > 0 && **argv == '-'; argc--,argv++) {
1264 if (argv[0][1] == '-') {
1268 if (s = strchr(argv[0], '=')) {
1270 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE)),s);
1273 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE)),1);
1276 toptarget = NEWSV(0,0);
1277 sv_upgrade(toptarget, SVt_PVFM);
1278 sv_setpvn(toptarget, "", 0);
1279 bodytarget = NEWSV(0,0);
1280 sv_upgrade(bodytarget, SVt_PVFM);
1281 sv_setpvn(bodytarget, "", 0);
1282 formtarget = bodytarget;
1285 if (tmpgv = gv_fetchpv("0",TRUE)) {
1286 sv_setpv(GvSV(tmpgv),origfilename);
1287 magicname("0", "0", 1);
1289 if (tmpgv = gv_fetchpv("\024",TRUE))
1291 if (tmpgv = gv_fetchpv("\030",TRUE))
1292 sv_setpv(GvSV(tmpgv),origargv[0]);
1293 if (argvgv = gv_fetchpv("ARGV",TRUE)) {
1295 (void)gv_AVadd(argvgv);
1296 av_clear(GvAVn(argvgv));
1297 for (; argc > 0; argc--,argv++) {
1298 (void)av_push(GvAVn(argvgv),newSVpv(argv[0],0));
1301 if (envgv = gv_fetchpv("ENV",TRUE)) {
1307 environ[0] = Nullch;
1308 for (; *env; env++) {
1309 if (!(s = strchr(*env,'=')))
1312 sv = newSVpv(s--,0);
1313 (void)hv_store(hv, *env, s - *env, sv, 0);
1316 hv_magic(hv, envgv, 'E');
1319 if (tmpgv = gv_fetchpv("$",TRUE))
1320 sv_setiv(GvSV(tmpgv),(I32)getpid());
1330 incpush(getenv("PERLLIB"));
1333 #define PRIVLIB "/usr/local/lib/perl"
1336 (void)av_push(GvAVn(incgv),newSVpv(".",1));
1344 I32 fill = AvFILL(list);
1346 I32 sp = stack_sp - stack_base;
1348 av_store(stack, ++sp, Nullsv); /* reserve spot for 1st return arg */
1349 Copy(top_env, oldtop, 1, jmp_buf);
1351 for (i = 0; i <= fill; i++)
1353 GV *gv = (GV*)av_shift(list);
1354 SV* tmpsv = NEWSV(0,0);
1356 if (gv && GvCV(gv)) {
1357 gv_efullname(tmpsv, gv);
1358 if (setjmp(top_env)) {
1359 if (list == beginav)
1363 perl_callback(SvPVX(tmpsv), sp, G_SCALAR, 0, 0);
1370 Copy(oldtop, top_env, 1, jmp_buf);