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);
112 sv_upgrade(linestr,SVt_PVIV);
114 SvREADONLY_on(&sv_undef);
118 SvREADONLY_on(&sv_no);
120 sv_setpv(&sv_yes,Yes);
122 SvREADONLY_on(&sv_yes);
126 * There is no way we can refer to them from Perl so close them to save
127 * space. The other alternative would be to provide STDAUX and STDPRN
130 (void)fclose(stdaux);
131 (void)fclose(stdprn);
160 euid = (int)geteuid();
162 egid = (int)getegid();
163 tainting = (euid != uid || egid != gid);
164 sprintf(patchlevel,"%3.3s%2.2d", strchr(rcsid,'5'), PATCHLEVEL);
166 (void)sprintf(strchr(rcsid,'#'), "%d\n", PATCHLEVEL);
168 fdpid = newAV(); /* for remembering popen pids by fd */
169 pidstatus = newHV();/* for remembering status of dead pids */
173 perl_destruct(sv_interp)
174 register PerlInterpreter *sv_interp;
176 if (!(curinterp = sv_interp))
187 PerlInterpreter *sv_interp;
189 if (!(curinterp = sv_interp))
195 perl_parse(sv_interp, argc, argv, env)
196 PerlInterpreter *sv_interp;
198 register char **argv;
205 bool dosearch = FALSE;
208 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
211 croak("suidperl is no longer needed since the kernel can now execute\n\
212 setuid perl scripts securely.\n");
216 if (!(curinterp = sv_interp))
225 origenviron = environ;
227 switch (setjmp(top_env)) {
231 return(statusvalue); /* my_exit() was called */
233 fprintf(stderr, "panic: top_env\n");
238 origfilename = savestr(argv[0]);
240 cxstack_ix = -1; /* start label stack again */
243 sv_setpvn(linestr,"",0);
244 sv = newSVpv("",0); /* first used for -I flags */
246 for (argc--,argv++; argc > 0; argc--,argv++) {
247 if (argv[0][0] != '-' || !argv[0][1])
251 validarg = " PHOOEY ";
273 if (s = moreswitches(s))
278 if (euid != uid || egid != gid)
279 croak("No -e allowed in setuid scripts");
281 e_tmpname = savestr(TMPPATH);
282 (void)mktemp(e_tmpname);
284 croak("Can't mktemp()");
285 e_fp = fopen(e_tmpname,"w");
287 croak("Cannot open temporary file");
293 (void)putc('\n', e_fp);
301 (void)av_push(GvAVn(incgv),newSVpv(s,0));
304 (void)av_push(GvAVn(incgv),newSVpv(argv[1],0));
305 sv_catpv(sv,argv[1]);
332 croak("Unrecognized switch: -%s",s);
336 scriptname = argv[0];
338 if (fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
339 croak("Can't write to temp file for -e: %s", strerror(errno));
341 scriptname = e_tmpname;
343 else if (scriptname == Nullch) {
345 if ( isatty(fileno(stdin)) )
353 open_script(scriptname,dosearch,sv);
355 sv_free(sv); /* free -I directories */
358 validate_suid(validarg);
368 av_push(comppad, Nullsv);
369 curpad = AvARRAY(comppad);
371 comppadname = padname;
372 comppadnamefill = -1;
377 init_context_stack();
379 perl_init_ext(); /* in case linked C routines want magical variables */
381 init_predump_symbols();
385 /* now parse the script */
388 if (yyparse() || error_count) {
390 croak("%s had compilation errors.\n", origfilename);
392 croak("Execution of %s aborted due to compilation errors.\n",
396 curcop->cop_line = 0;
401 (void)UNLINK(e_tmpname);
404 /* now that script is parsed, we can modify record separator */
409 rspara = (nrslen == 2);
410 sv_setpvn(GvSV(gv_fetchpv("/", TRUE)), rs, rslen);
415 just_doit: /* come here if running an undumped a.out */
416 init_postdump_symbols(argc,argv,env);
422 PerlInterpreter *sv_interp;
424 if (!(curinterp = sv_interp))
428 switch (setjmp(top_env)) {
430 cxstack_ix = -1; /* start context stack again */
436 return(statusvalue); /* my_exit() was called */
439 fprintf(stderr, "panic: restartop\n");
442 if (stack != mainstack) {
444 SWITCHSTACK(stack, mainstack);
451 DEBUG(fprintf(stderr,"\nEXECUTING...\n\n"));
454 fprintf(stderr,"%s syntax OK\n", origfilename);
466 else if (main_start) {
478 statusvalue = (unsigned short)(status & 0xffff);
482 /* Be sure to refetch the stack pointer after calling these routines. */
485 perl_callback(subname, sp, gimme, hasargs, numargs)
487 I32 sp; /* stack pointer after args are pushed */
488 I32 gimme; /* called in array or scalar context */
489 I32 hasargs; /* whether to create a @_ array for routine */
490 I32 numargs; /* how many args are pushed on the stack */
492 BINOP myop; /* fake syntax tree node */
497 stack_base = AvARRAY(stack);
498 stack_sp = stack_base + sp - numargs - 1;
501 pp_pushmark(); /* doesn't look at op, actually, except to return */
502 *++stack_sp = (SV*)gv_fetchpv(subname, FALSE);
506 myop.op_flags = OPf_STACKED;
507 myop.op_last = (OP*)&myop;
509 myop.op_next = Nullop;
511 if (op = pp_entersubr())
515 return stack_sp - stack_base;
519 perl_callv(subname, sp, gimme, argv)
521 register I32 sp; /* current stack pointer */
522 I32 gimme; /* called in array or scalar context */
523 register char **argv; /* null terminated arg list, NULL for no arglist */
525 register I32 items = 0;
526 I32 hasargs = (argv != 0);
528 av_store(stack, ++sp, Nullsv); /* reserve spot for 1st return arg */
531 av_store(stack, ++sp, sv_2mortal(newSVpv(*argv,0)));
536 return perl_callback(subname, sp, gimme, hasargs, items);
540 magicname(sym,name,namlen)
547 if (gv = gv_fetchpv(sym,TRUE))
548 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
552 #define PERLLIB_SEP ';'
554 #define PERLLIB_SEP ':'
566 /* Break at all separators */
568 /* First, skip any consecutive separators */
569 while ( *p == PERLLIB_SEP ) {
570 /* Uncomment the next line for PATH semantics */
571 /* (void)av_push(GvAVn(incgv), newSVpv(".", 1)); */
574 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
575 (void)av_push(GvAVn(incgv), newSVpv(p, (I32)(s - p)));
578 (void)av_push(GvAVn(incgv), newSVpv(p, 0));
584 /* This routine handles any switches that can be given during run */
594 nrschar = scan_oct(s, 4, &numlen);
595 nrs = nsavestr("\n",1);
597 if (nrschar > 0377) {
601 else if (!nrschar && numlen >= 2) {
624 static char debopts[] = "psltocPmfrxuLHX";
627 for (s++; *s && (d = strchr(debopts,*s)); s++)
628 debug |= 1 << (d - debopts);
632 for (s++; isDIGIT(*s); s++) ;
636 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
637 for (s++; isDIGIT(*s); s++) ;
644 inplace = savestr(s+1);
646 for (s = inplace; *s && !isSPACE(*s); s++) ;
652 (void)av_push(GvAVn(incgv),newSVpv(s,0));
655 croak("No space allowed after -I");
663 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
667 ors = nsavestr(nrs,nrslen);
697 fputs("\nThis is perl, version 5.0, Alpha 5 (unsupported)\n\n",stdout);
699 fputs("\nCopyright (c) 1989, 1990, 1991, 1992, 1993, 1994 Larry Wall\n",stdout);
701 fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
704 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n",
709 fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout);
712 Perl may be copied only under the terms of either the Artistic License or the\n\
713 GNU General Public License, which may be found in the Perl 5.0 source kit.\n",stdout);
723 if (s[1] == '-') /* Additional switches on #! line. */
731 croak("Switch meaningless after -x: -%s",s);
736 /* compliments of Tom Christiansen */
738 /* unexec() can be found in the Gnu emacs distribution */
747 sprintf (buf, "%s.perldump", origfilename);
748 sprintf (tokenbuf, "%s/perl", BIN);
750 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
752 fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
755 ABORT(); /* for use with undump */
763 curstash = defstash = newHV();
764 curstname = newSVpv("main",4);
765 GvHV(gv = gv_fetchpv("_main",TRUE)) = defstash;
767 HvNAME(defstash) = "main";
768 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE)));
770 defgv = gv_fetchpv("_",TRUE);
774 open_script(scriptname,dosearch,sv)
779 char *xfound = Nullch;
780 char *xfailed = Nullch;
784 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
786 bufend = s + strlen(s);
789 s = cpytill(tokenbuf,s,bufend,':',&len);
792 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
793 tokenbuf[len] = '\0';
795 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
796 tokenbuf[len] = '\0';
802 if (len && tokenbuf[len-1] != '/')
805 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
807 if (len && tokenbuf[len-1] != '\\')
810 (void)strcat(tokenbuf+len,"/");
811 (void)strcat(tokenbuf+len,scriptname);
812 DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
813 if (stat(tokenbuf,&statbuf) < 0) /* not there? */
815 if (S_ISREG(statbuf.st_mode)
816 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
817 xfound = tokenbuf; /* bingo! */
821 xfailed = savestr(tokenbuf);
824 croak("Can't execute %s", xfailed ? xfailed : scriptname );
830 origfilename = savestr(scriptname);
831 curcop->cop_filegv = gv_fetchfile(origfilename);
832 if (strEQ(origfilename,"-"))
835 char *cpp = CPPSTDIN;
837 if (strEQ(cpp,"cppstdin"))
838 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
840 sprintf(tokenbuf, "%s", cpp);
842 sv_catpv(sv,PRIVLIB);
844 (void)sprintf(buf, "\
845 sed %s -e \"/^[^#]/b\" \
846 -e \"/^#[ ]*include[ ]/b\" \
847 -e \"/^#[ ]*define[ ]/b\" \
848 -e \"/^#[ ]*if[ ]/b\" \
849 -e \"/^#[ ]*ifdef[ ]/b\" \
850 -e \"/^#[ ]*ifndef[ ]/b\" \
851 -e \"/^#[ ]*else/b\" \
852 -e \"/^#[ ]*elif[ ]/b\" \
853 -e \"/^#[ ]*undef[ ]/b\" \
854 -e \"/^#[ ]*endif/b\" \
857 (doextract ? "-e \"1,/^#/d\n\"" : ""),
859 (void)sprintf(buf, "\
860 %s %s -e '/^[^#]/b' \
861 -e '/^#[ ]*include[ ]/b' \
862 -e '/^#[ ]*define[ ]/b' \
863 -e '/^#[ ]*if[ ]/b' \
864 -e '/^#[ ]*ifdef[ ]/b' \
865 -e '/^#[ ]*ifndef[ ]/b' \
867 -e '/^#[ ]*elif[ ]/b' \
868 -e '/^#[ ]*undef[ ]/b' \
869 -e '/^#[ ]*endif/b' \
877 (doextract ? "-e '1,/^#/d\n'" : ""),
879 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
880 DEBUG_P(fprintf(stderr, "%s\n", buf));
882 #ifdef IAMSUID /* actually, this is caught earlier */
883 if (euid != uid && !euid) { /* if running suidperl */
885 (void)seteuid(uid); /* musn't stay setuid root */
888 (void)setreuid(-1, uid);
893 if (geteuid() != uid)
894 croak("Can't do seteuid!\n");
897 rsfp = my_popen(buf,"r");
899 else if (!*scriptname) {
900 taint_not("program input from stdin");
904 rsfp = fopen(scriptname,"r");
905 if ((FILE*)rsfp == Nullfp) {
907 #ifndef IAMSUID /* in case script is not readable before setuid */
908 if (euid && stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
909 statbuf.st_mode & (S_ISUID|S_ISGID)) {
910 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
911 execv(buf, origargv); /* try again */
912 croak("Can't do setuid\n");
916 croak("Can't open perl script \"%s\": %s\n",
917 SvPVX(GvSV(curcop->cop_filegv)), strerror(errno));
922 validate_suid(validarg)
926 /* do we need to emulate setuid on scripts? */
928 /* This code is for those BSD systems that have setuid #! scripts disabled
929 * in the kernel because of a security problem. Merely defining DOSUID
930 * in perl will not fix that problem, but if you have disabled setuid
931 * scripts in the kernel, this will attempt to emulate setuid and setgid
932 * on scripts that have those now-otherwise-useless bits set. The setuid
933 * root version must be called suidperl or sperlN.NNN. If regular perl
934 * discovers that it has opened a setuid script, it calls suidperl with
935 * the same argv that it had. If suidperl finds that the script it has
936 * just opened is NOT setuid root, it sets the effective uid back to the
937 * uid. We don't just make perl setuid root because that loses the
938 * effective uid we had before invoking perl, if it was different from the
941 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
942 * be defined in suidperl only. suidperl must be setuid root. The
943 * Configure script will set this up for you if you want it.
947 if (fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
948 croak("Can't stat script \"%s\"",origfilename);
949 if (statbuf.st_mode & (S_ISUID|S_ISGID)) {
954 /* On this access check to make sure the directories are readable,
955 * there is actually a small window that the user could use to make
956 * filename point to an accessible directory. So there is a faint
957 * chance that someone could execute a setuid script down in a
958 * non-accessible directory. I don't know what to do about that.
959 * But I don't think it's too important. The manual lies when
960 * it says access() is useful in setuid programs.
962 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
963 croak("Permission denied");
965 /* If we can swap euid and uid, then we can determine access rights
966 * with a simple stat of the file, and then compare device and
967 * inode to make sure we did stat() on the same file we opened.
968 * Then we just have to make sure he or she can execute it.
971 struct stat tmpstatbuf;
973 if (setreuid(euid,uid) < 0 || getuid() != euid || geteuid() != uid)
974 croak("Can't swap uid and euid"); /* really paranoid */
975 if (stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
976 croak("Permission denied"); /* testing full pathname here */
977 if (tmpstatbuf.st_dev != statbuf.st_dev ||
978 tmpstatbuf.st_ino != statbuf.st_ino) {
980 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
982 "User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
983 (Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
984 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
985 statbuf.st_dev, statbuf.st_ino,
986 SvPVX(GvSV(curcop->cop_filegv)),
987 statbuf.st_uid, statbuf.st_gid);
988 (void)my_pclose(rsfp);
990 croak("Permission denied\n");
992 if (setreuid(uid,euid) < 0 || getuid() != uid || geteuid() != euid)
993 croak("Can't reswap uid and euid");
994 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
995 croak("Permission denied\n");
997 #endif /* HAS_SETREUID */
1000 if (!S_ISREG(statbuf.st_mode))
1001 croak("Permission denied");
1002 if (statbuf.st_mode & S_IWOTH)
1003 croak("Setuid/gid script is writable by world");
1004 doswitches = FALSE; /* -s is insecure in suid */
1006 if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1007 strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */
1008 croak("No #! line");
1011 while (!isSPACE(*s)) s++;
1012 if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
1013 croak("Not a perl script");
1014 while (*s == ' ' || *s == '\t') s++;
1016 * #! arg must be what we saw above. They can invoke it by
1017 * mentioning suidperl explicitly, but they may not add any strange
1018 * arguments beyond what #! says if they do invoke suidperl that way.
1020 len = strlen(validarg);
1021 if (strEQ(validarg," PHOOEY ") ||
1022 strnNE(s,validarg,len) || !isSPACE(s[len]))
1023 croak("Args must match #! line");
1026 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1027 euid == statbuf.st_uid)
1029 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1030 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1031 #endif /* IAMSUID */
1033 if (euid) { /* oops, we're not the setuid root perl */
1036 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1037 execv(buf, origargv); /* try again */
1039 croak("Can't do setuid\n");
1042 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
1044 (void)setegid(statbuf.st_gid);
1047 (void)setregid((GIDTYPE)-1,statbuf.st_gid);
1049 setgid(statbuf.st_gid);
1052 if (getegid() != statbuf.st_gid)
1053 croak("Can't do setegid!\n");
1055 if (statbuf.st_mode & S_ISUID) {
1056 if (statbuf.st_uid != euid)
1058 (void)seteuid(statbuf.st_uid); /* all that for this */
1061 (void)setreuid((UIDTYPE)-1,statbuf.st_uid);
1063 setuid(statbuf.st_uid);
1066 if (geteuid() != statbuf.st_uid)
1067 croak("Can't do seteuid!\n");
1069 else if (uid) { /* oops, mustn't run as root */
1071 (void)seteuid((UIDTYPE)uid);
1074 (void)setreuid((UIDTYPE)-1,(UIDTYPE)uid);
1076 setuid((UIDTYPE)uid);
1079 if (geteuid() != uid)
1080 croak("Can't do seteuid!\n");
1082 uid = (int)getuid();
1083 euid = (int)geteuid();
1084 gid = (int)getgid();
1085 egid = (int)getegid();
1086 tainting |= (euid != uid || egid != gid);
1087 if (!cando(S_IXUSR,TRUE,&statbuf))
1088 croak("Permission denied\n"); /* they can't do this */
1091 else if (preprocess)
1092 croak("-P not allowed for setuid/setgid script\n");
1094 croak("Script is not setuid/setgid in suidperl\n");
1095 #endif /* IAMSUID */
1097 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1098 #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
1099 fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
1100 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1102 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1105 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1106 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1107 #endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1108 /* not set-id, must be wrapped */
1118 /* skip forward in input to the real script? */
1122 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
1123 croak("No Perl script found in input\n");
1124 if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1125 ungetc('\n',rsfp); /* to keep line count right */
1127 if (s = instr(s,"perl -")) {
1130 while (s = moreswitches(s)) ;
1132 if (cddir && chdir(cddir) < 0)
1133 croak("Can't chdir to %s",cddir);
1144 GvHV(gv_fetchpv("_DB",TRUE)) = debstash;
1145 curstash = debstash;
1146 dbargs = GvAV(gv_AVadd((tmpgv = gv_fetchpv("args",TRUE))));
1149 DBgv = gv_fetchpv("DB",TRUE);
1151 DBline = gv_fetchpv("dbline",TRUE);
1153 DBsub = gv_HVadd(tmpgv = gv_fetchpv("sub",TRUE));
1155 DBsingle = GvSV((tmpgv = gv_fetchpv("single",TRUE)));
1157 DBtrace = GvSV((tmpgv = gv_fetchpv("trace",TRUE)));
1159 DBsignal = GvSV((tmpgv = gv_fetchpv("signal",TRUE)));
1161 curstash = defstash;
1168 mainstack = stack; /* remember in case we switch stacks */
1169 AvREAL_off(stack); /* not a real array */
1170 av_fill(stack,127); av_fill(stack,-1); /* preextend stack */
1172 stack_base = AvARRAY(stack);
1173 stack_sp = stack_base;
1174 stack_max = stack_base + 128;
1176 New(54,markstack,64,int);
1177 markstack_ptr = markstack;
1178 markstack_max = markstack + 64;
1180 New(54,scopestack,32,int);
1182 scopestack_max = 32;
1184 New(54,savestack,128,ANY);
1186 savestack_max = 128;
1188 New(54,retstack,16,OP*);
1196 bufend = bufptr = SvPV(linestr, na);
1197 subname = newSVpv("main",4);
1198 lex_start(); /* we never leave */
1202 init_context_stack()
1204 New(50,cxstack,128,CONTEXT);
1206 New(51,debname,128,char);
1207 New(52,debdelim,128,char);
1212 init_predump_symbols()
1216 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE)), " ", 1);
1218 stdingv = gv_fetchpv("STDIN",TRUE);
1219 SvMULTI_on(stdingv);
1221 GvIO(stdingv) = newIO();
1222 GvIO(stdingv)->ifp = stdin;
1223 tmpgv = gv_fetchpv("stdin",TRUE);
1224 GvIO(tmpgv) = GvIO(stdingv);
1227 tmpgv = gv_fetchpv("STDOUT",TRUE);
1230 GvIO(tmpgv) = newIO();
1231 GvIO(tmpgv)->ofp = GvIO(tmpgv)->ifp = stdout;
1233 tmpgv = gv_fetchpv("stdout",TRUE);
1234 GvIO(tmpgv) = GvIO(defoutgv);
1237 curoutgv = gv_fetchpv("STDERR",TRUE);
1238 SvMULTI_on(curoutgv);
1239 if (!GvIO(curoutgv))
1240 GvIO(curoutgv) = newIO();
1241 GvIO(curoutgv)->ofp = GvIO(curoutgv)->ifp = stderr;
1242 tmpgv = gv_fetchpv("stderr",TRUE);
1243 GvIO(tmpgv) = GvIO(curoutgv);
1245 curoutgv = defoutgv; /* switch back to STDOUT */
1247 statname = NEWSV(66,0); /* last filename we did stat on */
1251 init_postdump_symbols(argc,argv,env)
1253 register char **argv;
1254 register char **env;
1260 argc--,argv++; /* skip name of script */
1262 for (; argc > 0 && **argv == '-'; argc--,argv++) {
1265 if (argv[0][1] == '-') {
1269 if (s = strchr(argv[0], '=')) {
1271 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE)),s);
1274 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE)),1);
1277 toptarget = NEWSV(0,0);
1278 sv_upgrade(toptarget, SVt_PVFM);
1279 sv_setpvn(toptarget, "", 0);
1280 bodytarget = NEWSV(0,0);
1281 sv_upgrade(bodytarget, SVt_PVFM);
1282 sv_setpvn(bodytarget, "", 0);
1283 formtarget = bodytarget;
1286 if (tmpgv = gv_fetchpv("0",TRUE)) {
1287 sv_setpv(GvSV(tmpgv),origfilename);
1288 magicname("0", "0", 1);
1290 if (tmpgv = gv_fetchpv("\024",TRUE))
1292 if (tmpgv = gv_fetchpv("\030",TRUE))
1293 sv_setpv(GvSV(tmpgv),origargv[0]);
1294 if (argvgv = gv_fetchpv("ARGV",TRUE)) {
1296 (void)gv_AVadd(argvgv);
1297 av_clear(GvAVn(argvgv));
1298 for (; argc > 0; argc--,argv++) {
1299 (void)av_push(GvAVn(argvgv),newSVpv(argv[0],0));
1302 if (envgv = gv_fetchpv("ENV",TRUE)) {
1308 environ[0] = Nullch;
1309 for (; *env; env++) {
1310 if (!(s = strchr(*env,'=')))
1313 sv = newSVpv(s--,0);
1314 (void)hv_store(hv, *env, s - *env, sv, 0);
1317 hv_magic(hv, envgv, 'E');
1320 if (tmpgv = gv_fetchpv("$",TRUE))
1321 sv_setiv(GvSV(tmpgv),(I32)getpid());
1331 incpush(getenv("PERLLIB"));
1334 #define PRIVLIB "/usr/local/lib/perl"
1337 (void)av_push(GvAVn(incgv),newSVpv(".",1));
1345 I32 fill = AvFILL(list);
1347 I32 sp = stack_sp - stack_base;
1349 av_store(stack, ++sp, Nullsv); /* reserve spot for 1st return arg */
1350 Copy(top_env, oldtop, 1, jmp_buf);
1352 for (i = 0; i <= fill; i++)
1354 GV *gv = (GV*)av_shift(list);
1355 SV* tmpsv = NEWSV(0,0);
1357 if (gv && GvCV(gv)) {
1358 gv_efullname(tmpsv, gv);
1359 if (setjmp(top_env)) {
1360 if (list == beginav)
1364 perl_callback(SvPVX(tmpsv), sp, G_SCALAR, 0, 0);
1371 Copy(oldtop, top_env, 1, jmp_buf);