xref: /openbsd-src/gnu/usr.bin/perl/perl.c (revision a4afd6dad3fba28f80e70208181c06c482259988)
1 /*    perl.c
2  *
3  *    Copyright (c) 1987-1996 Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9 
10 /*
11  * "A ship then new they built for him/of mithril and of elven glass" --Bilbo
12  */
13 
14 #include "EXTERN.h"
15 #include "perl.h"
16 #include "patchlevel.h"
17 
18 /* Omit -- it causes too much grief on mixed systems.
19 #ifdef I_UNISTD
20 #include <unistd.h>
21 #endif
22 */
23 
24 dEXT char rcsid[] = "perl.c\nPatch level: ###\n";
25 
26 #ifdef IAMSUID
27 #ifndef DOSUID
28 #define DOSUID
29 #endif
30 #endif
31 
32 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
33 #ifdef DOSUID
34 #undef DOSUID
35 #endif
36 #endif
37 
38 static void find_beginning _((void));
39 static void incpush _((char *));
40 static void init_ids _((void));
41 static void init_debugger _((void));
42 static void init_lexer _((void));
43 static void init_main_stash _((void));
44 static void init_perllib _((void));
45 static void init_postdump_symbols _((int, char **, char **));
46 static void init_predump_symbols _((void));
47 static void init_stacks _((void));
48 static void open_script _((char *, bool, SV *));
49 static void usage _((char *));
50 static void validate_suid _((char *, char*));
51 
52 static int fdscript = -1;
53 
54 PerlInterpreter *
55 perl_alloc()
56 {
57     PerlInterpreter *sv_interp;
58 
59     curinterp = 0;
60     New(53, sv_interp, 1, PerlInterpreter);
61     return sv_interp;
62 }
63 
64 void
65 perl_construct( sv_interp )
66 register PerlInterpreter *sv_interp;
67 {
68     if (!(curinterp = sv_interp))
69 	return;
70 
71 #ifdef MULTIPLICITY
72     Zero(sv_interp, 1, PerlInterpreter);
73 #endif
74 
75     /* Init the real globals? */
76     if (!linestr) {
77 	linestr = NEWSV(65,80);
78 	sv_upgrade(linestr,SVt_PVIV);
79 
80 	SvREADONLY_on(&sv_undef);
81 
82 	sv_setpv(&sv_no,No);
83 	SvNV(&sv_no);
84 	SvREADONLY_on(&sv_no);
85 
86 	sv_setpv(&sv_yes,Yes);
87 	SvNV(&sv_yes);
88 	SvREADONLY_on(&sv_yes);
89 
90 	nrs = newSVpv("\n", 1);
91 	rs = SvREFCNT_inc(nrs);
92 
93 #ifdef MSDOS
94 	/*
95 	 * There is no way we can refer to them from Perl so close them to save
96 	 * space.  The other alternative would be to provide STDAUX and STDPRN
97 	 * filehandles.
98 	 */
99 	(void)fclose(stdaux);
100 	(void)fclose(stdprn);
101 #endif
102     }
103 
104 #ifdef MULTIPLICITY
105     chopset	= " \n-";
106     copline	= NOLINE;
107     curcop	= &compiling;
108     dbargs	= 0;
109     dlmax	= 128;
110     laststatval	= -1;
111     laststype	= OP_STAT;
112     maxscream	= -1;
113     maxsysfd	= MAXSYSFD;
114     rsfp	= Nullfp;
115     statname	= Nullsv;
116     tmps_floor	= -1;
117 #endif
118 
119     init_ids();
120 
121 #if defined(SUBVERSION) && SUBVERSION > 0
122     sprintf(patchlevel, "%7.5f", 5.0 + (PATCHLEVEL / 1000.0)
123 				     + (SUBVERSION / 100000.0));
124 #else
125     sprintf(patchlevel, "%5.3f", 5.0 + (PATCHLEVEL / 1000.0));
126 #endif
127 
128 #if defined(LOCAL_PATCH_COUNT)
129     Ilocalpatches = local_patches;	/* For possible -v */
130 #endif
131 
132     fdpid = newAV();	/* for remembering popen pids by fd */
133     pidstatus = newHV();/* for remembering status of dead pids */
134 
135     init_stacks();
136     ENTER;
137 }
138 
139 void
140 perl_destruct(sv_interp)
141 register PerlInterpreter *sv_interp;
142 {
143     int destruct_level;  /* 0=none, 1=full, 2=full with checks */
144     I32 last_sv_count;
145     HV *hv;
146 
147     if (!(curinterp = sv_interp))
148 	return;
149 
150     destruct_level = perl_destruct_level;
151 #ifdef DEBUGGING
152     {
153 	char *s;
154 	if (s = getenv("PERL_DESTRUCT_LEVEL"))
155 	    destruct_level = atoi(s);
156     }
157 #endif
158 
159     LEAVE;
160     FREETMPS;
161 
162     if (sv_objcount) {
163 	/* We must account for everything.  First the syntax tree. */
164 	if (main_root) {
165 	    curpad = AvARRAY(comppad);
166 	    op_free(main_root);
167 	    main_root = 0;
168 	}
169     }
170     if (sv_objcount) {
171 	/*
172 	 * Try to destruct global references.  We do this first so that the
173 	 * destructors and destructees still exist.  Some sv's might remain.
174 	 * Non-referenced objects are on their own.
175 	 */
176 
177 	dirty = TRUE;
178 	sv_clean_objs();
179     }
180 
181     if (destruct_level == 0){
182 
183 	DEBUG_P(debprofdump());
184 
185 	/* The exit() function will do everything that needs doing. */
186 	return;
187     }
188 
189     /* Prepare to destruct main symbol table.  */
190     hv = defstash;
191     defstash = 0;
192     SvREFCNT_dec(hv);
193 
194     FREETMPS;
195     if (destruct_level >= 2) {
196 	if (scopestack_ix != 0)
197 	    warn("Unbalanced scopes: %d more ENTERs than LEAVEs\n", scopestack_ix);
198 	if (savestack_ix != 0)
199 	    warn("Unbalanced saves: %d more saves than restores\n", savestack_ix);
200 	if (tmps_floor != -1)
201 	    warn("Unbalanced tmps: %d more allocs than frees\n", tmps_floor + 1);
202 	if (cxstack_ix != -1)
203 	    warn("Unbalanced context: %d more PUSHes than POPs\n", cxstack_ix + 1);
204     }
205 
206     /* Now absolutely destruct everything, somehow or other, loops or no. */
207     last_sv_count = 0;
208     while (sv_count != 0 && sv_count != last_sv_count) {
209 	last_sv_count = sv_count;
210 	sv_clean_all();
211     }
212     if (sv_count != 0)
213 	warn("Scalars leaked: %d\n", sv_count);
214     sv_free_arenas();
215 
216     DEBUG_P(debprofdump());
217 }
218 
219 void
220 perl_free(sv_interp)
221 PerlInterpreter *sv_interp;
222 {
223     if (!(curinterp = sv_interp))
224 	return;
225     Safefree(sv_interp);
226 }
227 #if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
228 char *getenv _((char *)); /* Usually in <stdlib.h> */
229 #endif
230 
231 int
232 perl_parse(sv_interp, xsinit, argc, argv, env)
233 PerlInterpreter *sv_interp;
234 void (*xsinit)_((void));
235 int argc;
236 char **argv;
237 char **env;
238 {
239     register SV *sv;
240     register char *s;
241     char *scriptname = NULL;
242     VOL bool dosearch = FALSE;
243     char *validarg = "";
244     AV* comppadlist;
245 
246 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
247 #ifdef IAMSUID
248 #undef IAMSUID
249     croak("suidperl is no longer needed since the kernel can now execute\n\
250 setuid perl scripts securely.\n");
251 #endif
252 #endif
253 
254     if (!(curinterp = sv_interp))
255 	return 255;
256 
257     origargv = argv;
258     origargc = argc;
259 #ifndef VMS  /* VMS doesn't have environ array */
260     origenviron = environ;
261 #endif
262     e_tmpname = Nullch;
263 
264     if (do_undump) {
265 
266 	/* Come here if running an undumped a.out. */
267 
268 	origfilename = savepv(argv[0]);
269 	do_undump = FALSE;
270 	cxstack_ix = -1;		/* start label stack again */
271 	init_ids();
272 	init_postdump_symbols(argc,argv,env);
273 	return 0;
274     }
275 
276     if (main_root)
277 	op_free(main_root);
278     main_root = 0;
279 
280     switch (Sigsetjmp(top_env,1)) {
281     case 1:
282 #ifdef VMS
283 	statusvalue = 255;
284 #else
285 	statusvalue = 1;
286 #endif
287     case 2:
288 	curstash = defstash;
289 	if (endav)
290 	    calllist(endav);
291 	return(statusvalue);	/* my_exit() was called */
292     case 3:
293 	fprintf(stderr, "panic: top_env\n");
294 	return 1;
295     }
296 
297     sv_setpvn(linestr,"",0);
298     sv = newSVpv("",0);		/* first used for -I flags */
299     SAVEFREESV(sv);
300     init_main_stash();
301     for (argc--,argv++; argc > 0; argc--,argv++) {
302 	if (argv[0][0] != '-' || !argv[0][1])
303 	    break;
304 #ifdef DOSUID
305     if (*validarg)
306 	validarg = " PHOOEY ";
307     else
308 	validarg = argv[0];
309 #endif
310 	s = argv[0]+1;
311       reswitch:
312 	switch (*s) {
313 	case '0':
314 	case 'F':
315 	case 'a':
316 	case 'c':
317 	case 'd':
318 	case 'D':
319 	case 'h':
320 	case 'i':
321 	case 'l':
322 	case 'M':
323 	case 'm':
324 	case 'n':
325 	case 'p':
326 	case 's':
327 	case 'T':
328 	case 'u':
329 	case 'U':
330 	case 'v':
331 	case 'w':
332 	    if (s = moreswitches(s))
333 		goto reswitch;
334 	    break;
335 
336 	case 'e':
337 	    if (euid != uid || egid != gid)
338 		croak("No -e allowed in setuid scripts");
339 	    if (!e_fp) {
340 	        e_tmpname = savepv(TMPPATH);
341 		(void)mktemp(e_tmpname);
342 		if (!*e_tmpname)
343 		    croak("Can't mktemp()");
344 		e_fp = fopen(e_tmpname,"w");
345 		if (!e_fp)
346 		    croak("Cannot open temporary file");
347 	    }
348 	    if (argv[1]) {
349 		fputs(argv[1],e_fp);
350 		argc--,argv++;
351 	    }
352 	    (void)putc('\n', e_fp);
353 	    break;
354 	case 'I':
355 	    taint_not("-I");
356 	    sv_catpv(sv,"-");
357 	    sv_catpv(sv,s);
358 	    sv_catpv(sv," ");
359 	    if (*++s) {
360 		av_push(GvAVn(incgv),newSVpv(s,0));
361 	    }
362 	    else if (argv[1]) {
363 		av_push(GvAVn(incgv),newSVpv(argv[1],0));
364 		sv_catpv(sv,argv[1]);
365 		argc--,argv++;
366 		sv_catpv(sv," ");
367 	    }
368 	    break;
369 	case 'P':
370 	    taint_not("-P");
371 	    preprocess = TRUE;
372 	    s++;
373 	    goto reswitch;
374 	case 'S':
375 	    taint_not("-S");
376 	    dosearch = TRUE;
377 	    s++;
378 	    goto reswitch;
379 	case 'V':
380 	    if (!preambleav)
381 		preambleav = newAV();
382 	    av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
383 	    if (*++s != ':')  {
384 		Sv = newSVpv("print myconfig(),'@INC: '.\"@INC\\n\"",0);
385 	    }
386 	    else {
387 		Sv = newSVpv("config_vars(qw(",0);
388 		sv_catpv(Sv, ++s);
389 		sv_catpv(Sv, "))");
390 		s += strlen(s);
391 	    }
392 	    av_push(preambleav, Sv);
393 	    scriptname = BIT_BUCKET;	/* don't look for script or read stdin */
394 	    goto reswitch;
395 	case 'x':
396 	    doextract = TRUE;
397 	    s++;
398 	    if (*s)
399 		cddir = savepv(s);
400 	    break;
401 	case '-':
402 	    argc--,argv++;
403 	    goto switch_end;
404 	case 0:
405 	    break;
406 	default:
407 	    croak("Unrecognized switch: -%s",s);
408 	}
409     }
410   switch_end:
411     if (!scriptname)
412 	scriptname = argv[0];
413     if (e_fp) {
414 	if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
415 	    croak("Can't write to temp file for -e: %s", Strerror(errno));
416 	e_fp = Nullfp;
417 	argc++,argv--;
418 	scriptname = e_tmpname;
419     }
420     else if (scriptname == Nullch) {
421 #ifdef MSDOS
422 	if ( isatty(fileno(stdin)) )
423 	    moreswitches("v");
424 #endif
425 	scriptname = "-";
426     }
427 
428     init_perllib();
429 
430     open_script(scriptname,dosearch,sv);
431 
432     validate_suid(validarg, scriptname);
433 
434     if (doextract)
435 	find_beginning();
436 
437     compcv = (CV*)NEWSV(1104,0);
438     sv_upgrade((SV *)compcv, SVt_PVCV);
439 
440     pad = newAV();
441     comppad = pad;
442     av_push(comppad, Nullsv);
443     curpad = AvARRAY(comppad);
444     padname = newAV();
445     comppad_name = padname;
446     comppad_name_fill = 0;
447     min_intro_pending = 0;
448     padix = 0;
449 
450     comppadlist = newAV();
451     AvREAL_off(comppadlist);
452     av_store(comppadlist, 0, (SV*)comppad_name);
453     av_store(comppadlist, 1, (SV*)comppad);
454     CvPADLIST(compcv) = comppadlist;
455 
456     if (xsinit)
457 	(*xsinit)();	/* in case linked C routines want magical variables */
458 #ifdef VMS
459     init_os_extras();
460 #endif
461 
462     init_predump_symbols();
463     if (!do_undump)
464 	init_postdump_symbols(argc,argv,env);
465 
466     init_lexer();
467 
468     /* now parse the script */
469 
470     error_count = 0;
471     if (yyparse() || error_count) {
472 	if (minus_c)
473 	    croak("%s had compilation errors.\n", origfilename);
474 	else {
475 	    croak("Execution of %s aborted due to compilation errors.\n",
476 		origfilename);
477 	}
478     }
479     curcop->cop_line = 0;
480     curstash = defstash;
481     preprocess = FALSE;
482     if (e_tmpname) {
483 	(void)UNLINK(e_tmpname);
484 	Safefree(e_tmpname);
485 	e_tmpname = Nullch;
486     }
487 
488     /* now that script is parsed, we can modify record separator */
489     SvREFCNT_dec(rs);
490     rs = SvREFCNT_inc(nrs);
491     sv_setsv(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs);
492 
493     if (do_undump)
494 	my_unexec();
495 
496     if (dowarn)
497 	gv_check(defstash);
498 
499     LEAVE;
500     FREETMPS;
501 
502 #ifdef DEBUGGING_MSTATS
503     if ((s=getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
504 	dump_mstats("after compilation:");
505 #endif
506 
507     ENTER;
508     restartop = 0;
509     return 0;
510 }
511 
512 int
513 perl_run(sv_interp)
514 PerlInterpreter *sv_interp;
515 {
516     if (!(curinterp = sv_interp))
517 	return 255;
518     switch (Sigsetjmp(top_env,1)) {
519     case 1:
520 	cxstack_ix = -1;		/* start context stack again */
521 	break;
522     case 2:
523 	curstash = defstash;
524 	if (endav)
525 	    calllist(endav);
526 	FREETMPS;
527 #ifdef DEBUGGING_MSTATS
528 	if (getenv("PERL_DEBUG_MSTATS"))
529 	    dump_mstats("after execution:  ");
530 #endif
531 	return(statusvalue);		/* my_exit() was called */
532     case 3:
533 	if (!restartop) {
534 	    fprintf(stderr, "panic: restartop\n");
535 	    FREETMPS;
536 	    return 1;
537 	}
538 	if (stack != mainstack) {
539 	    dSP;
540 	    SWITCHSTACK(stack, mainstack);
541 	}
542 	break;
543     }
544 
545     if (!restartop) {
546 	DEBUG_x(dump_all());
547 	DEBUG(fprintf(stderr,"\nEXECUTING...\n\n"));
548 
549 	if (minus_c) {
550 	    fprintf(stderr,"%s syntax OK\n", origfilename);
551 	    my_exit(0);
552 	}
553 	if (perldb && DBsingle)
554 	   sv_setiv(DBsingle, 1);
555     }
556 
557     /* do it */
558 
559     if (restartop) {
560 	op = restartop;
561 	restartop = 0;
562 	runops();
563     }
564     else if (main_start) {
565 	op = main_start;
566 	runops();
567     }
568 
569     my_exit(0);
570     return 0;
571 }
572 
573 void
574 my_exit(status)
575 U32 status;
576 {
577     register CONTEXT *cx;
578     I32 gimme;
579     SV **newsp;
580 
581     statusvalue = FIXSTATUS(status);
582     if (cxstack_ix >= 0) {
583 	if (cxstack_ix > 0)
584 	    dounwind(0);
585 	POPBLOCK(cx,curpm);
586 	LEAVE;
587     }
588     Siglongjmp(top_env, 2);
589 }
590 
591 SV*
592 perl_get_sv(name, create)
593 char* name;
594 I32 create;
595 {
596     GV* gv = gv_fetchpv(name, create, SVt_PV);
597     if (gv)
598 	return GvSV(gv);
599     return Nullsv;
600 }
601 
602 AV*
603 perl_get_av(name, create)
604 char* name;
605 I32 create;
606 {
607     GV* gv = gv_fetchpv(name, create, SVt_PVAV);
608     if (create)
609     	return GvAVn(gv);
610     if (gv)
611 	return GvAV(gv);
612     return Nullav;
613 }
614 
615 HV*
616 perl_get_hv(name, create)
617 char* name;
618 I32 create;
619 {
620     GV* gv = gv_fetchpv(name, create, SVt_PVHV);
621     if (create)
622     	return GvHVn(gv);
623     if (gv)
624 	return GvHV(gv);
625     return Nullhv;
626 }
627 
628 CV*
629 perl_get_cv(name, create)
630 char* name;
631 I32 create;
632 {
633     GV* gv = gv_fetchpv(name, create, SVt_PVCV);
634     if (create && !GvCV(gv))
635     	return newSUB(start_subparse(),
636 		      newSVOP(OP_CONST, 0, newSVpv(name,0)),
637 		      Nullop,
638 		      Nullop);
639     if (gv)
640 	return GvCV(gv);
641     return Nullcv;
642 }
643 
644 /* Be sure to refetch the stack pointer after calling these routines. */
645 
646 I32
647 perl_call_argv(subname, flags, argv)
648 char *subname;
649 I32 flags;		/* See G_* flags in cop.h */
650 register char **argv;	/* null terminated arg list */
651 {
652     dSP;
653 
654     PUSHMARK(sp);
655     if (argv) {
656 	while (*argv) {
657 	    XPUSHs(sv_2mortal(newSVpv(*argv,0)));
658 	    argv++;
659 	}
660 	PUTBACK;
661     }
662     return perl_call_pv(subname, flags);
663 }
664 
665 I32
666 perl_call_pv(subname, flags)
667 char *subname;		/* name of the subroutine */
668 I32 flags;		/* See G_* flags in cop.h */
669 {
670     return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags);
671 }
672 
673 I32
674 perl_call_method(methname, flags)
675 char *methname;		/* name of the subroutine */
676 I32 flags;		/* See G_* flags in cop.h */
677 {
678     dSP;
679     OP myop;
680     if (!op)
681 	op = &myop;
682     XPUSHs(sv_2mortal(newSVpv(methname,0)));
683     PUTBACK;
684     pp_method();
685     return perl_call_sv(*stack_sp--, flags);
686 }
687 
688 /* May be called with any of a CV, a GV, or an SV containing the name. */
689 I32
690 perl_call_sv(sv, flags)
691 SV* sv;
692 I32 flags;		/* See G_* flags in cop.h */
693 {
694     LOGOP myop;		/* fake syntax tree node */
695     SV** sp = stack_sp;
696     I32 oldmark = TOPMARK;
697     I32 retval;
698     Sigjmp_buf oldtop;
699     I32 oldscope;
700 
701     if (flags & G_DISCARD) {
702 	ENTER;
703 	SAVETMPS;
704     }
705 
706     SAVESPTR(op);
707     op = (OP*)&myop;
708     Zero(op, 1, LOGOP);
709     EXTEND(stack_sp, 1);
710     *++stack_sp = sv;
711     oldscope = scopestack_ix;
712 
713     if (!(flags & G_NOARGS))
714 	myop.op_flags = OPf_STACKED;
715     myop.op_next = Nullop;
716     myop.op_flags |= OPf_KNOW;
717     if (flags & G_ARRAY)
718       myop.op_flags |= OPf_LIST;
719 
720     if (flags & G_EVAL) {
721 	Copy(top_env, oldtop, 1, Sigjmp_buf);
722 
723 	cLOGOP->op_other = op;
724 	markstack_ptr--;
725 	/* we're trying to emulate pp_entertry() here */
726 	{
727 	    register CONTEXT *cx;
728 	    I32 gimme = GIMME;
729 
730 	    ENTER;
731 	    SAVETMPS;
732 
733 	    push_return(op->op_next);
734 	    PUSHBLOCK(cx, CXt_EVAL, stack_sp);
735 	    PUSHEVAL(cx, 0, 0);
736 	    eval_root = op;             /* Only needed so that goto works right. */
737 
738 	    in_eval = 1;
739 	    if (flags & G_KEEPERR)
740 		in_eval |= 4;
741 	    else
742 		sv_setpv(GvSV(errgv),"");
743 	}
744 	markstack_ptr++;
745 
746     restart:
747 	switch (Sigsetjmp(top_env,1)) {
748 	case 0:
749 	    break;
750 	case 1:
751 #ifdef VMS
752 	    statusvalue = 255;	/* XXX I don't think we use 1 anymore. */
753 #else
754 	statusvalue = 1;
755 #endif
756 	    /* FALL THROUGH */
757 	case 2:
758 	    /* my_exit() was called */
759 	    curstash = defstash;
760 	    FREETMPS;
761 	    Copy(oldtop, top_env, 1, Sigjmp_buf);
762 	    if (statusvalue)
763 		croak("Callback called exit");
764 	    my_exit(statusvalue);
765 	    /* NOTREACHED */
766 	case 3:
767 	    if (restartop) {
768 		op = restartop;
769 		restartop = 0;
770 		goto restart;
771 	    }
772 	    stack_sp = stack_base + oldmark;
773 	    if (flags & G_ARRAY)
774 		retval = 0;
775 	    else {
776 		retval = 1;
777 		*++stack_sp = &sv_undef;
778 	    }
779 	    goto cleanup;
780 	}
781     }
782 
783     if (op == (OP*)&myop)
784 	op = pp_entersub();
785     if (op)
786 	runops();
787     retval = stack_sp - (stack_base + oldmark);
788     if ((flags & G_EVAL) && !(flags & G_KEEPERR))
789 	sv_setpv(GvSV(errgv),"");
790 
791   cleanup:
792     if (flags & G_EVAL) {
793 	if (scopestack_ix > oldscope) {
794 	    SV **newsp;
795 	    PMOP *newpm;
796 	    I32 gimme;
797 	    register CONTEXT *cx;
798 	    I32 optype;
799 
800 	    POPBLOCK(cx,newpm);
801 	    POPEVAL(cx);
802 	    pop_return();
803 	    curpm = newpm;
804 	    LEAVE;
805 	}
806 	Copy(oldtop, top_env, 1, Sigjmp_buf);
807     }
808     if (flags & G_DISCARD) {
809 	stack_sp = stack_base + oldmark;
810 	retval = 0;
811 	FREETMPS;
812 	LEAVE;
813     }
814     return retval;
815 }
816 
817 /* Eval a string. */
818 
819 I32
820 perl_eval_sv(sv, flags)
821 SV* sv;
822 I32 flags;		/* See G_* flags in cop.h */
823 {
824     UNOP myop;		/* fake syntax tree node */
825     SV** sp = stack_sp;
826     I32 oldmark = sp - stack_base;
827     I32 retval;
828     Sigjmp_buf oldtop;
829     I32 oldscope;
830 
831     if (flags & G_DISCARD) {
832 	ENTER;
833 	SAVETMPS;
834     }
835 
836     SAVESPTR(op);
837     op = (OP*)&myop;
838     Zero(op, 1, UNOP);
839     EXTEND(stack_sp, 1);
840     *++stack_sp = sv;
841     oldscope = scopestack_ix;
842 
843     if (!(flags & G_NOARGS))
844 	myop.op_flags = OPf_STACKED;
845     myop.op_next = Nullop;
846     myop.op_flags |= OPf_KNOW;
847     if (flags & G_ARRAY)
848       myop.op_flags |= OPf_LIST;
849 
850     Copy(top_env, oldtop, 1, Sigjmp_buf);
851 
852 restart:
853     switch (Sigsetjmp(top_env,1)) {
854     case 0:
855 	break;
856     case 1:
857 #ifdef VMS
858 	statusvalue = 255;	/* XXX I don't think we use 1 anymore. */
859 #else
860     statusvalue = 1;
861 #endif
862 	/* FALL THROUGH */
863     case 2:
864 	/* my_exit() was called */
865 	curstash = defstash;
866 	FREETMPS;
867 	Copy(oldtop, top_env, 1, Sigjmp_buf);
868 	if (statusvalue)
869 	    croak("Callback called exit");
870 	my_exit(statusvalue);
871 	/* NOTREACHED */
872     case 3:
873 	if (restartop) {
874 	    op = restartop;
875 	    restartop = 0;
876 	    goto restart;
877 	}
878 	stack_sp = stack_base + oldmark;
879 	if (flags & G_ARRAY)
880 	    retval = 0;
881 	else {
882 	    retval = 1;
883 	    *++stack_sp = &sv_undef;
884 	}
885 	goto cleanup;
886     }
887 
888     if (op == (OP*)&myop)
889 	op = pp_entereval();
890     if (op)
891 	runops();
892     retval = stack_sp - (stack_base + oldmark);
893     if ((flags & G_EVAL) && !(flags & G_KEEPERR))
894 	sv_setpv(GvSV(errgv),"");
895 
896   cleanup:
897     Copy(oldtop, top_env, 1, Sigjmp_buf);
898     if (flags & G_DISCARD) {
899 	stack_sp = stack_base + oldmark;
900 	retval = 0;
901 	FREETMPS;
902 	LEAVE;
903     }
904     return retval;
905 }
906 
907 /* Require a module. */
908 
909 void
910 perl_require_pv(pv)
911 char* pv;
912 {
913     SV* sv = sv_newmortal();
914     sv_setpv(sv, "require '");
915     sv_catpv(sv, pv);
916     sv_catpv(sv, "'");
917     perl_eval_sv(sv, G_DISCARD);
918 }
919 
920 void
921 magicname(sym,name,namlen)
922 char *sym;
923 char *name;
924 I32 namlen;
925 {
926     register GV *gv;
927 
928     if (gv = gv_fetchpv(sym,TRUE, SVt_PV))
929 	sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
930 }
931 
932 #if defined(DOSISH)
933 #    define PERLLIB_SEP ';'
934 #else
935 #  if defined(VMS)
936 #    define PERLLIB_SEP '|'
937 #  else
938 #    define PERLLIB_SEP ':'
939 #  endif
940 #endif
941 
942 static void
943 incpush(p)
944 char *p;
945 {
946     char *s;
947 
948     if (!p)
949 	return;
950 
951     /* Break at all separators */
952     while (*p) {
953 	/* First, skip any consecutive separators */
954 	while ( *p == PERLLIB_SEP ) {
955 	    /* Uncomment the next line for PATH semantics */
956 	    /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
957 	    p++;
958 	}
959 	if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
960 	    av_push(GvAVn(incgv), newSVpv(p, (STRLEN)(s - p)));
961 	    p = s + 1;
962 	} else {
963 	    av_push(GvAVn(incgv), newSVpv(p, 0));
964 	    break;
965 	}
966     }
967 }
968 
969 static void
970 usage(name)		/* XXX move this out into a module ? */
971 char *name;
972 {
973     /* This message really ought to be max 23 lines.
974      * Removed -h because the user already knows that opton. Others? */
975     printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name);
976     printf("\n  -0[octal]       specify record separator (\\0, if no argument)");
977     printf("\n  -a              autosplit mode with -n or -p (splits $_ into @F)");
978     printf("\n  -c              check syntax only (runs BEGIN and END blocks)");
979     printf("\n  -d[:debugger]   run scripts under debugger");
980     printf("\n  -D[number/list] set debugging flags (argument is a bit mask or flags)");
981     printf("\n  -e 'command'    one line of script. Several -e's allowed. Omit [programfile].");
982     printf("\n  -F/pattern/     split() pattern for autosplit (-a). The //'s are optional.");
983     printf("\n  -i[extension]   edit <> files in place (make backup if extension supplied)");
984     printf("\n  -Idirectory     specify @INC/#include directory (may be used more then once)");
985     printf("\n  -l[octal]       enable line ending processing, specifies line teminator");
986     printf("\n  -[mM][-]module.. executes `use/no module...' before executing your script.");
987     printf("\n  -n              assume 'while (<>) { ... }' loop arround your script");
988     printf("\n  -p              assume loop like -n but print line also like sed");
989     printf("\n  -P              run script through C preprocessor before compilation");
990 #ifdef OS2
991     printf("\n  -R              enable REXX variable pool");
992 #endif
993     printf("\n  -s              enable some switch parsing for switches after script name");
994     printf("\n  -S              look for the script using PATH environment variable");
995     printf("\n  -T              turn on tainting checks");
996     printf("\n  -u              dump core after parsing script");
997     printf("\n  -U              allow unsafe operations");
998     printf("\n  -v              print version number and patchlevel of perl");
999     printf("\n  -V[:variable]   print perl configuration information");
1000     printf("\n  -w              TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT.");
1001     printf("\n  -x[directory]   strip off text before #!perl line and perhaps cd to directory\n");
1002 }
1003 
1004 /* This routine handles any switches that can be given during run */
1005 
1006 char *
1007 moreswitches(s)
1008 char *s;
1009 {
1010     I32 numlen;
1011     U32 rschar;
1012 
1013     switch (*s) {
1014     case '0':
1015 	rschar = scan_oct(s, 4, &numlen);
1016 	SvREFCNT_dec(nrs);
1017 	if (rschar & ~((U8)~0))
1018 	    nrs = &sv_undef;
1019 	else if (!rschar && numlen >= 2)
1020 	    nrs = newSVpv("", 0);
1021 	else {
1022 	    char ch = rschar;
1023 	    nrs = newSVpv(&ch, 1);
1024 	}
1025 	return s + numlen;
1026     case 'F':
1027 	minus_F = TRUE;
1028 	splitstr = savepv(s + 1);
1029 	s += strlen(s);
1030 	return s;
1031     case 'a':
1032 	minus_a = TRUE;
1033 	s++;
1034 	return s;
1035     case 'c':
1036 	minus_c = TRUE;
1037 	s++;
1038 	return s;
1039     case 'd':
1040 	taint_not("-d");
1041 	s++;
1042 	if (*s == ':' || *s == '=')  {
1043 	    sprintf(buf, "use Devel::%s;", ++s);
1044 	    s += strlen(s);
1045 	    my_setenv("PERL5DB",buf);
1046 	}
1047 	if (!perldb) {
1048 	    perldb = TRUE;
1049 	    init_debugger();
1050 	}
1051 	return s;
1052     case 'D':
1053 #ifdef DEBUGGING
1054 	taint_not("-D");
1055 	if (isALPHA(s[1])) {
1056 	    static char debopts[] = "psltocPmfrxuLHXD";
1057 	    char *d;
1058 
1059 	    for (s++; *s && (d = strchr(debopts,*s)); s++)
1060 		debug |= 1 << (d - debopts);
1061 	}
1062 	else {
1063 	    debug = atoi(s+1);
1064 	    for (s++; isDIGIT(*s); s++) ;
1065 	}
1066 	debug |= 0x80000000;
1067 #else
1068 	warn("Recompile perl with -DDEBUGGING to use -D switch\n");
1069 	for (s++; isALNUM(*s); s++) ;
1070 #endif
1071 	/*SUPPRESS 530*/
1072 	return s;
1073     case 'h':
1074 	usage(origargv[0]);
1075 	exit(0);
1076     case 'i':
1077 	if (inplace)
1078 	    Safefree(inplace);
1079 	inplace = savepv(s+1);
1080 	/*SUPPRESS 530*/
1081 	for (s = inplace; *s && !isSPACE(*s); s++) ;
1082 	*s = '\0';
1083 	break;
1084     case 'I':
1085 	taint_not("-I");
1086 	if (*++s) {
1087 	    char *e;
1088 	    for (e = s; *e && !isSPACE(*e); e++) ;
1089 	    av_push(GvAVn(incgv),newSVpv(s,e-s));
1090 	    if (*e)
1091 		return e;
1092 	}
1093 	else
1094 	    croak("No space allowed after -I");
1095 	break;
1096     case 'l':
1097 	minus_l = TRUE;
1098 	s++;
1099 	if (ors)
1100 	    Safefree(ors);
1101 	if (isDIGIT(*s)) {
1102 	    ors = savepv("\n");
1103 	    orslen = 1;
1104 	    *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
1105 	    s += numlen;
1106 	}
1107 	else {
1108 	    if (RsPARA(nrs)) {
1109 		ors = savepvn("\n\n", 2);
1110 		orslen = 2;
1111 	    }
1112 	    else
1113 		ors = SvPV(nrs, orslen);
1114 	}
1115 	return s;
1116     case 'M':
1117 	taint_not("-M");	/* XXX ? */
1118 	/* FALL THROUGH */
1119     case 'm':
1120 	taint_not("-m");	/* XXX ? */
1121 	if (*++s) {
1122 	    char *start;
1123 	    char *use = "use ";
1124 	    /* -M-foo == 'no foo'	*/
1125 	    if (*s == '-') { use = "no "; ++s; }
1126 	    Sv = newSVpv(use,0);
1127 	    start = s;
1128 	    /* We allow -M'Module qw(Foo Bar)'	*/
1129 	    while(isALNUM(*s) || *s==':') ++s;
1130 	    if (*s != '=') {
1131 		sv_catpv(Sv, start);
1132 		if (*(start-1) == 'm') {
1133 		    if (*s != '\0')
1134 			croak("Can't use '%c' after -mname", *s);
1135 		    sv_catpv( Sv, " ()");
1136 		}
1137 	    } else {
1138 		sv_catpvn(Sv, start, s-start);
1139 		sv_catpv(Sv, " split(/,/,q{");
1140 		sv_catpv(Sv, ++s);
1141 		sv_catpv(Sv,    "})");
1142 	    }
1143 	    s += strlen(s);
1144 	    if (preambleav == NULL)
1145 		preambleav = newAV();
1146 	    av_push(preambleav, Sv);
1147 	}
1148 	else
1149 	    croak("No space allowed after -%c", *(s-1));
1150 	return s;
1151     case 'n':
1152 	minus_n = TRUE;
1153 	s++;
1154 	return s;
1155     case 'p':
1156 	minus_p = TRUE;
1157 	s++;
1158 	return s;
1159     case 's':
1160 	taint_not("-s");
1161 	doswitches = TRUE;
1162 	s++;
1163 	return s;
1164     case 'T':
1165 	tainting = TRUE;
1166 	s++;
1167 	return s;
1168     case 'u':
1169 	do_undump = TRUE;
1170 	s++;
1171 	return s;
1172     case 'U':
1173 	unsafe = TRUE;
1174 	s++;
1175 	return s;
1176     case 'v':
1177 #if defined(SUBVERSION) && SUBVERSION > 0
1178 	printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION);
1179 #else
1180 	printf("\nThis is perl, version %s",patchlevel);
1181 #endif
1182 
1183 #if defined(DEBUGGING) || defined(EMBED) || defined(MULTIPLICITY)
1184 	fputs(" with", stdout);
1185 #ifdef DEBUGGING
1186 	fputs(" DEBUGGING", stdout);
1187 #endif
1188 #ifdef EMBED
1189 	fputs(" EMBED", stdout);
1190 #endif
1191 #ifdef MULTIPLICITY
1192 	fputs(" MULTIPLICITY", stdout);
1193 #endif
1194 #endif
1195 
1196 #if defined(LOCAL_PATCH_COUNT)
1197     if (LOCAL_PATCH_COUNT > 0)
1198     {	int i;
1199 	fputs("\n\tLocally applied patches:\n", stdout);
1200 	for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
1201 		if (Ilocalpatches[i])
1202 			fprintf(stdout, "\t  %s\n", Ilocalpatches[i]);
1203 	}
1204     }
1205 #endif
1206     printf("\n\tbuilt under %s",OSNAME);
1207 #ifdef __DATE__
1208 #  ifdef __TIME__
1209 	printf(" at %s %s",__DATE__,__TIME__);
1210 #  else
1211 	printf(" on %s",__DATE__);
1212 #  endif
1213 #endif
1214 	fputs("\n\t+ suidperl security patch", stdout);
1215 	fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout);
1216 #ifdef MSDOS
1217 	fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
1218 	stdout);
1219 #endif
1220 #ifdef OS2
1221 	fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
1222 	    "Version 5 port Copyright (c) 1994-1995, Andreas Kaiser\n", stdout);
1223 #endif
1224 #ifdef atarist
1225 	fputs("atariST series port, ++jrb  bammi@cadence.com\n", stdout);
1226 #endif
1227 	fputs("\n\
1228 Perl may be copied only under the terms of either the Artistic License or the\n\
1229 GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n",stdout);
1230 #ifdef MSDOS
1231         usage(origargv[0]);
1232 #endif
1233 	exit(0);
1234     case 'w':
1235 	dowarn = TRUE;
1236 	s++;
1237 	return s;
1238     case '*':
1239     case ' ':
1240 	if (s[1] == '-')	/* Additional switches on #! line. */
1241 	    return s+2;
1242 	break;
1243     case '-':
1244     case 0:
1245     case '\n':
1246     case '\t':
1247 	break;
1248     case 'P':
1249 	if (preprocess)
1250 	    return s+1;
1251 	/* FALL THROUGH */
1252     default:
1253 	croak("Can't emulate -%.1s on #! line",s);
1254     }
1255     return Nullch;
1256 }
1257 
1258 /* compliments of Tom Christiansen */
1259 
1260 /* unexec() can be found in the Gnu emacs distribution */
1261 
1262 void
1263 my_unexec()
1264 {
1265 #ifdef UNEXEC
1266     int    status;
1267     extern int etext;
1268 
1269     sprintf (buf, "%s.perldump", origfilename);
1270     sprintf (tokenbuf, "%s/perl", BIN);
1271 
1272     status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
1273     if (status)
1274 	fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
1275     exit(status);
1276 #else
1277 #  ifdef VMS
1278 #    include <lib$routines.h>
1279      lib$signal(SS$_DEBUG);  /* ssdef.h #included from vmsish.h */
1280 #else
1281     ABORT();		/* for use with undump */
1282 #endif
1283 #endif
1284 }
1285 
1286 static void
1287 init_main_stash()
1288 {
1289     GV *gv;
1290     curstash = defstash = newHV();
1291     curstname = newSVpv("main",4);
1292     gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1293     SvREFCNT_dec(GvHV(gv));
1294     GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
1295     SvREADONLY_on(gv);
1296     HvNAME(defstash) = savepv("main");
1297     incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
1298     GvMULTI_on(incgv);
1299     defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
1300     errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
1301     GvMULTI_on(errgv);
1302     curstash = defstash;
1303     compiling.cop_stash = defstash;
1304     debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
1305     /* We must init $/ before switches are processed. */
1306     sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1);
1307 }
1308 
1309 #ifdef CAN_PROTOTYPE
1310 static void
1311 open_script(char *scriptname, bool dosearch, SV *sv)
1312 #else
1313 static void
1314 open_script(scriptname,dosearch,sv)
1315 char *scriptname;
1316 bool dosearch;
1317 SV *sv;
1318 #endif
1319 {
1320     char *xfound = Nullch;
1321     char *xfailed = Nullch;
1322     register char *s;
1323     I32 len;
1324     int retval;
1325 #if defined(DOSISH) && !defined(OS2) && !defined(atarist)
1326 #define SEARCH_EXTS ".bat", ".cmd", NULL
1327 #endif
1328 #ifdef VMS
1329 #  define SEARCH_EXTS ".pl", ".com", NULL
1330 #endif
1331     /* additional extensions to try in each dir if scriptname not found */
1332 #ifdef SEARCH_EXTS
1333     char *ext[] = { SEARCH_EXTS };
1334     int extidx = (strchr(scriptname,'.')) ? -1 : 0; /* has ext already */
1335 #endif
1336 
1337 #ifdef VMS
1338     if (dosearch && !strpbrk(scriptname,":[</") && (my_getenv("DCL$PATH"))) {
1339 	int idx = 0;
1340 
1341 	while (my_trnlnm("DCL$PATH",tokenbuf,idx++)) {
1342 	    strcat(tokenbuf,scriptname);
1343 #else  /* !VMS */
1344     if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
1345 
1346 	bufend = s + strlen(s);
1347 	while (*s) {
1348 #ifndef DOSISH
1349 	    s = cpytill(tokenbuf,s,bufend,':',&len);
1350 #else
1351 #ifdef atarist
1352 	    for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
1353 	    tokenbuf[len] = '\0';
1354 #else
1355 	    for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
1356 	    tokenbuf[len] = '\0';
1357 #endif
1358 #endif
1359 	    if (*s)
1360 		s++;
1361 #ifndef DOSISH
1362 	    if (len && tokenbuf[len-1] != '/')
1363 #else
1364 #ifdef atarist
1365 	    if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
1366 #else
1367 	    if (len && tokenbuf[len-1] != '\\')
1368 #endif
1369 #endif
1370 		(void)strcat(tokenbuf+len,"/");
1371 	    (void)strcat(tokenbuf+len,scriptname);
1372 #endif  /* !VMS */
1373 
1374 #ifdef SEARCH_EXTS
1375 	    len = strlen(tokenbuf);
1376 	    if (extidx > 0)	/* reset after previous loop */
1377 		extidx = 0;
1378 	    do {
1379 #endif
1380 		DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
1381 		retval = Stat(tokenbuf,&statbuf);
1382 #ifdef SEARCH_EXTS
1383 	    } while (  retval < 0		/* not there */
1384 		    && extidx>=0 && ext[extidx]	/* try an extension? */
1385 		    && strcpy(tokenbuf+len, ext[extidx++])
1386 		);
1387 #endif
1388 	    if (retval < 0)
1389 		continue;
1390 	    if (S_ISREG(statbuf.st_mode)
1391 	     && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
1392 		xfound = tokenbuf;              /* bingo! */
1393 		break;
1394 	    }
1395 	    if (!xfailed)
1396 		xfailed = savepv(tokenbuf);
1397 	}
1398 	if (!xfound)
1399 	    croak("Can't execute %s", xfailed ? xfailed : scriptname );
1400 	if (xfailed)
1401 	    Safefree(xfailed);
1402 	scriptname = xfound;
1403     }
1404 
1405     if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
1406 	char *s = scriptname + 8;
1407 	fdscript = atoi(s);
1408 	while (isDIGIT(*s))
1409 	    s++;
1410 	if (*s)
1411 	    scriptname = s + 1;
1412     }
1413     else
1414 	fdscript = -1;
1415     origfilename = savepv(e_tmpname ? "-e" : scriptname);
1416     curcop->cop_filegv = gv_fetchfile(origfilename);
1417     if (strEQ(origfilename,"-"))
1418 	scriptname = "";
1419     if (fdscript >= 0) {
1420 	rsfp = fdopen(fdscript,"r");
1421 #if defined(HAS_FCNTL) && defined(F_SETFD)
1422 	fcntl(fileno(rsfp),F_SETFD,1);	/* ensure close-on-exec */
1423 #endif
1424     }
1425     else if (preprocess) {
1426 	char *cpp = CPPSTDIN;
1427 
1428 	if (strEQ(cpp,"cppstdin"))
1429 	    sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
1430 	else
1431 	    sprintf(tokenbuf, "%s", cpp);
1432 	sv_catpv(sv,"-I");
1433 	sv_catpv(sv,PRIVLIB_EXP);
1434 #ifdef MSDOS
1435 	(void)sprintf(buf, "\
1436 sed %s -e \"/^[^#]/b\" \
1437  -e \"/^#[ 	]*include[ 	]/b\" \
1438  -e \"/^#[ 	]*define[ 	]/b\" \
1439  -e \"/^#[ 	]*if[ 	]/b\" \
1440  -e \"/^#[ 	]*ifdef[ 	]/b\" \
1441  -e \"/^#[ 	]*ifndef[ 	]/b\" \
1442  -e \"/^#[ 	]*else/b\" \
1443  -e \"/^#[ 	]*elif[ 	]/b\" \
1444  -e \"/^#[ 	]*undef[ 	]/b\" \
1445  -e \"/^#[ 	]*endif/b\" \
1446  -e \"s/^#.*//\" \
1447  %s | %s -C %s %s",
1448 	  (doextract ? "-e \"1,/^#/d\n\"" : ""),
1449 #else
1450 	(void)sprintf(buf, "\
1451 %s %s -e '/^[^#]/b' \
1452  -e '/^#[ 	]*include[ 	]/b' \
1453  -e '/^#[ 	]*define[ 	]/b' \
1454  -e '/^#[ 	]*if[ 	]/b' \
1455  -e '/^#[ 	]*ifdef[ 	]/b' \
1456  -e '/^#[ 	]*ifndef[ 	]/b' \
1457  -e '/^#[ 	]*else/b' \
1458  -e '/^#[ 	]*elif[ 	]/b' \
1459  -e '/^#[ 	]*undef[ 	]/b' \
1460  -e '/^#[ 	]*endif/b' \
1461  -e 's/^[ 	]*#.*//' \
1462  %s | %s -C %s %s",
1463 #ifdef LOC_SED
1464 	  LOC_SED,
1465 #else
1466 	  "sed",
1467 #endif
1468 	  (doextract ? "-e '1,/^#/d\n'" : ""),
1469 #endif
1470 	  scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
1471 	doextract = FALSE;
1472 #ifdef IAMSUID				/* actually, this is caught earlier */
1473 	if (euid != uid && !euid) {	/* if running suidperl */
1474 #ifdef HAS_SETEUID
1475 	    (void)seteuid(uid);		/* musn't stay setuid root */
1476 #else
1477 #ifdef HAS_SETREUID
1478 	    (void)setreuid((Uid_t)-1, uid);
1479 #else
1480 #ifdef HAS_SETRESUID
1481 	    (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
1482 #else
1483 	    setuid(uid);
1484 #endif
1485 #endif
1486 #endif
1487 	    if (geteuid() != uid)
1488 		croak("Can't do seteuid!\n");
1489 	}
1490 #endif /* IAMSUID */
1491 	rsfp = my_popen(buf,"r");
1492     }
1493     else if (!*scriptname) {
1494 	taint_not("program input from stdin");
1495 	rsfp = stdin;
1496     }
1497     else {
1498 	rsfp = fopen(scriptname,"r");
1499 #if defined(HAS_FCNTL) && defined(F_SETFD)
1500 	fcntl(fileno(rsfp),F_SETFD,1);	/* ensure close-on-exec */
1501 #endif
1502     }
1503     if ((FILE*)rsfp == Nullfp) {
1504 #ifdef DOSUID
1505 #ifndef IAMSUID		/* in case script is not readable before setuid */
1506 	if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
1507 	  statbuf.st_mode & (S_ISUID|S_ISGID)) {
1508 	    (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1509 	    execv(buf, origargv);	/* try again */
1510 	    croak("Can't do setuid\n");
1511 	}
1512 #endif
1513 #endif
1514 	croak("Can't open perl script \"%s\": %s\n",
1515 	  SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
1516     }
1517 }
1518 
1519 static void
1520 validate_suid(validarg, scriptname)
1521 char *validarg;
1522 char *scriptname;
1523 {
1524     int which;
1525 
1526     /* do we need to emulate setuid on scripts? */
1527 
1528     /* This code is for those BSD systems that have setuid #! scripts disabled
1529      * in the kernel because of a security problem.  Merely defining DOSUID
1530      * in perl will not fix that problem, but if you have disabled setuid
1531      * scripts in the kernel, this will attempt to emulate setuid and setgid
1532      * on scripts that have those now-otherwise-useless bits set.  The setuid
1533      * root version must be called suidperl or sperlN.NNN.  If regular perl
1534      * discovers that it has opened a setuid script, it calls suidperl with
1535      * the same argv that it had.  If suidperl finds that the script it has
1536      * just opened is NOT setuid root, it sets the effective uid back to the
1537      * uid.  We don't just make perl setuid root because that loses the
1538      * effective uid we had before invoking perl, if it was different from the
1539      * uid.
1540      *
1541      * DOSUID must be defined in both perl and suidperl, and IAMSUID must
1542      * be defined in suidperl only.  suidperl must be setuid root.  The
1543      * Configure script will set this up for you if you want it.
1544      */
1545 
1546 #ifdef DOSUID
1547     char *s;
1548 
1549     if (Fstat(fileno(rsfp),&statbuf) < 0)	/* normal stat is insecure */
1550 	croak("Can't stat script \"%s\"",origfilename);
1551     if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) {
1552 	I32 len;
1553 
1554 #ifdef IAMSUID
1555 #ifndef HAS_SETREUID
1556 	/* On this access check to make sure the directories are readable,
1557 	 * there is actually a small window that the user could use to make
1558 	 * filename point to an accessible directory.  So there is a faint
1559 	 * chance that someone could execute a setuid script down in a
1560 	 * non-accessible directory.  I don't know what to do about that.
1561 	 * But I don't think it's too important.  The manual lies when
1562 	 * it says access() is useful in setuid programs.
1563 	 */
1564 	if (access(SvPVX(GvSV(curcop->cop_filegv)),1))	/*double check*/
1565 	    croak("Permission denied");
1566 #else
1567 	/* If we can swap euid and uid, then we can determine access rights
1568 	 * with a simple stat of the file, and then compare device and
1569 	 * inode to make sure we did stat() on the same file we opened.
1570 	 * Then we just have to make sure he or she can execute it.
1571 	 */
1572 	{
1573 	    struct stat tmpstatbuf;
1574 
1575 	    if (
1576 #ifdef HAS_SETREUID
1577 		setreuid(euid,uid) < 0
1578 #else
1579 # if HAS_SETRESUID
1580 		setresuid(euid,uid,(Uid_t)-1) < 0
1581 # endif
1582 #endif
1583 		|| getuid() != euid || geteuid() != uid)
1584 		croak("Can't swap uid and euid");	/* really paranoid */
1585 	    if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
1586 		croak("Permission denied");	/* testing full pathname here */
1587 	    if (tmpstatbuf.st_dev != statbuf.st_dev ||
1588 		tmpstatbuf.st_ino != statbuf.st_ino) {
1589 		(void)fclose(rsfp);
1590 		if (rsfp = my_popen("/bin/mail root","w")) {	/* heh, heh */
1591 		    fprintf(rsfp,
1592 "User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
1593 (Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
1594 			uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
1595 			statbuf.st_dev, statbuf.st_ino,
1596 			SvPVX(GvSV(curcop->cop_filegv)),
1597 			statbuf.st_uid, statbuf.st_gid);
1598 		    (void)my_pclose(rsfp);
1599 		}
1600 		croak("Permission denied\n");
1601 	    }
1602 	    if (
1603 #ifdef HAS_SETREUID
1604               setreuid(uid,euid) < 0
1605 #else
1606 # if defined(HAS_SETRESUID)
1607               setresuid(uid,euid,(Uid_t)-1) < 0
1608 # endif
1609 #endif
1610               || getuid() != uid || geteuid() != euid)
1611 		croak("Can't reswap uid and euid");
1612 	    if (!cando(S_IXUSR,FALSE,&statbuf))		/* can real uid exec? */
1613 		croak("Permission denied\n");
1614 	}
1615 #endif /* HAS_SETREUID */
1616 #endif /* IAMSUID */
1617 
1618 	if (!S_ISREG(statbuf.st_mode))
1619 	    croak("Permission denied");
1620 	if (statbuf.st_mode & S_IWOTH)
1621 	    croak("Setuid/gid script is writable by world");
1622 	doswitches = FALSE;		/* -s is insecure in suid */
1623 	curcop->cop_line++;
1624 	if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1625 	  strnNE(tokenbuf,"#!",2) )	/* required even on Sys V */
1626 	    croak("No #! line");
1627 	s = tokenbuf+2;
1628 	if (*s == ' ') s++;
1629 	while (!isSPACE(*s)) s++;
1630 	if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4))  /* sanity check */
1631 	    croak("Not a perl script");
1632 	while (*s == ' ' || *s == '\t') s++;
1633 	/*
1634 	 * #! arg must be what we saw above.  They can invoke it by
1635 	 * mentioning suidperl explicitly, but they may not add any strange
1636 	 * arguments beyond what #! says if they do invoke suidperl that way.
1637 	 */
1638 	len = strlen(validarg);
1639 	if (strEQ(validarg," PHOOEY ") ||
1640 	    strnNE(s,validarg,len) || !isSPACE(s[len]))
1641 	    croak("Args must match #! line");
1642 
1643 #ifndef IAMSUID
1644 	if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1645 	    euid == statbuf.st_uid)
1646 	    if (!do_undump)
1647 		croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1648 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1649 #endif /* IAMSUID */
1650 
1651 	if (euid) {	/* oops, we're not the setuid root perl */
1652 	    (void)fclose(rsfp);
1653 #ifndef IAMSUID
1654 	    (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1655 	    execv(buf, origargv);	/* try again */
1656 #endif
1657 	    croak("Can't do setuid\n");
1658 	}
1659 
1660 	if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
1661 #ifdef HAS_SETEGID
1662 	    (void)setegid(statbuf.st_gid);
1663 #else
1664 #ifdef HAS_SETREGID
1665            (void)setregid((Gid_t)-1,statbuf.st_gid);
1666 #else
1667 #ifdef HAS_SETRESGID
1668            (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
1669 #else
1670 	    setgid(statbuf.st_gid);
1671 #endif
1672 #endif
1673 #endif
1674 	    if (getegid() != statbuf.st_gid)
1675 		croak("Can't do setegid!\n");
1676 	}
1677 	if (statbuf.st_mode & S_ISUID) {
1678 	    if (statbuf.st_uid != euid)
1679 #ifdef HAS_SETEUID
1680 		(void)seteuid(statbuf.st_uid);	/* all that for this */
1681 #else
1682 #ifdef HAS_SETREUID
1683                 (void)setreuid((Uid_t)-1,statbuf.st_uid);
1684 #else
1685 #ifdef HAS_SETRESUID
1686                 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
1687 #else
1688 		setuid(statbuf.st_uid);
1689 #endif
1690 #endif
1691 #endif
1692 	    if (geteuid() != statbuf.st_uid)
1693 		croak("Can't do seteuid!\n");
1694 	}
1695 	else if (uid) {			/* oops, mustn't run as root */
1696 #ifdef HAS_SETEUID
1697           (void)seteuid((Uid_t)uid);
1698 #else
1699 #ifdef HAS_SETREUID
1700           (void)setreuid((Uid_t)-1,(Uid_t)uid);
1701 #else
1702 #ifdef HAS_SETRESUID
1703           (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
1704 #else
1705           setuid((Uid_t)uid);
1706 #endif
1707 #endif
1708 #endif
1709 	    if (geteuid() != uid)
1710 		croak("Can't do seteuid!\n");
1711 	}
1712 	init_ids();
1713 	if (!cando(S_IXUSR,TRUE,&statbuf))
1714 	    croak("Permission denied\n");	/* they can't do this */
1715     }
1716 #ifdef IAMSUID
1717     else if (preprocess)
1718 	croak("-P not allowed for setuid/setgid script\n");
1719     else if (fdscript >= 0)
1720 	croak("fd script not allowed in suidperl\n");
1721     else
1722 	croak("Script is not setuid/setgid in suidperl\n");
1723 
1724     /* We absolutely must clear out any saved ids here, so we */
1725     /* exec the real perl, substituting fd script for scriptname. */
1726     /* (We pass script name as "subdir" of fd, which perl will grok.) */
1727     rewind(rsfp);
1728     for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ;
1729     if (!origargv[which])
1730 	croak("Permission denied");
1731     (void)sprintf(buf, "/dev/fd/%d/%.127s", fileno(rsfp), origargv[which]);
1732     origargv[which] = buf;
1733 
1734 #if defined(HAS_FCNTL) && defined(F_SETFD)
1735     fcntl(fileno(rsfp),F_SETFD,0);	/* ensure no close-on-exec */
1736 #endif
1737 
1738     (void)sprintf(tokenbuf, "%s/perl%s", BIN, patchlevel);
1739     execv(tokenbuf, origargv);	/* try again */
1740     croak("Can't do setuid\n");
1741 #endif /* IAMSUID */
1742 #else /* !DOSUID */
1743     if (euid != uid || egid != gid) {	/* (suidperl doesn't exist, in fact) */
1744 #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
1745 	Fstat(fileno(rsfp),&statbuf);	/* may be either wrapped or real suid */
1746 	if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1747 	    ||
1748 	    (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1749 	   )
1750 	    if (!do_undump)
1751 		croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1752 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1753 #endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1754 	/* not set-id, must be wrapped */
1755     }
1756 #endif /* DOSUID */
1757 }
1758 
1759 static void
1760 find_beginning()
1761 {
1762     register char *s;
1763 
1764     /* skip forward in input to the real script? */
1765 
1766     taint_not("-x");
1767     while (doextract) {
1768 	if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
1769 	    croak("No Perl script found in input\n");
1770 	if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1771 	    ungetc('\n',rsfp);		/* to keep line count right */
1772 	    doextract = FALSE;
1773 	    if (s = instr(s,"perl -")) {
1774 		s += 6;
1775 		/*SUPPRESS 530*/
1776 		while (s = moreswitches(s)) ;
1777 	    }
1778 	    if (cddir && chdir(cddir) < 0)
1779 		croak("Can't chdir to %s",cddir);
1780 	}
1781     }
1782 }
1783 
1784 static void
1785 init_ids()
1786 {
1787     uid = (int)getuid();
1788     euid = (int)geteuid();
1789     gid = (int)getgid();
1790     egid = (int)getegid();
1791 #ifdef VMS
1792     uid |= gid << 16;
1793     euid |= egid << 16;
1794 #endif
1795     tainting |= (uid && (euid != uid || egid != gid));
1796 }
1797 
1798 static void
1799 init_debugger()
1800 {
1801     curstash = debstash;
1802     dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
1803     AvREAL_off(dbargs);
1804     DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
1805     DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
1806     DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
1807     DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
1808     sv_setiv(DBsingle, 0);
1809     DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
1810     sv_setiv(DBtrace, 0);
1811     DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
1812     sv_setiv(DBsignal, 0);
1813     curstash = defstash;
1814 }
1815 
1816 static void
1817 init_stacks()
1818 {
1819     stack = newAV();
1820     mainstack = stack;			/* remember in case we switch stacks */
1821     AvREAL_off(stack);			/* not a real array */
1822     av_extend(stack,127);
1823 
1824     stack_base = AvARRAY(stack);
1825     stack_sp = stack_base;
1826     stack_max = stack_base + 127;
1827 
1828     New(54,markstack,64,I32);
1829     markstack_ptr = markstack;
1830     markstack_max = markstack + 64;
1831 
1832     New(54,scopestack,32,I32);
1833     scopestack_ix = 0;
1834     scopestack_max = 32;
1835 
1836     New(54,savestack,128,ANY);
1837     savestack_ix = 0;
1838     savestack_max = 128;
1839 
1840     New(54,retstack,16,OP*);
1841     retstack_ix = 0;
1842     retstack_max = 16;
1843 
1844     cxstack_max = 8192 / sizeof(CONTEXT) - 2;	/* Use most of 8K. */
1845     New(50,cxstack,cxstack_max + 1,CONTEXT);
1846     cxstack_ix	= -1;
1847 
1848     New(50,tmps_stack,128,SV*);
1849     tmps_ix = -1;
1850     tmps_max = 128;
1851 
1852     DEBUG( {
1853 	New(51,debname,128,char);
1854 	New(52,debdelim,128,char);
1855     } )
1856 }
1857 
1858 static FILE *tmpfp;  /* moved outside init_lexer() because of UNICOS bug */
1859 static void
1860 init_lexer()
1861 {
1862     tmpfp = rsfp;
1863 
1864     lex_start(linestr);
1865     rsfp = tmpfp;
1866     subname = newSVpv("main",4);
1867 }
1868 
1869 static void
1870 init_predump_symbols()
1871 {
1872     GV *tmpgv;
1873     GV *othergv;
1874 
1875     sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
1876 
1877     stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
1878     GvMULTI_on(stdingv);
1879     IoIFP(GvIOp(stdingv)) = stdin;
1880     tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
1881     GvMULTI_on(tmpgv);
1882     GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
1883 
1884     tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
1885     GvMULTI_on(tmpgv);
1886     IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = stdout;
1887     setdefout(tmpgv);
1888     tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
1889     GvMULTI_on(tmpgv);
1890     GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
1891 
1892     othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
1893     GvMULTI_on(othergv);
1894     IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = stderr;
1895     tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
1896     GvMULTI_on(tmpgv);
1897     GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
1898 
1899     statname = NEWSV(66,0);		/* last filename we did stat on */
1900 
1901     osname = savepv(OSNAME);
1902 }
1903 
1904 static void
1905 init_postdump_symbols(argc,argv,env)
1906 register int argc;
1907 register char **argv;
1908 register char **env;
1909 {
1910     char *s;
1911     SV *sv;
1912     GV* tmpgv;
1913 
1914     argc--,argv++;	/* skip name of script */
1915     if (doswitches) {
1916 	for (; argc > 0 && **argv == '-'; argc--,argv++) {
1917 	    if (!argv[0][1])
1918 		break;
1919 	    if (argv[0][1] == '-') {
1920 		argc--,argv++;
1921 		break;
1922 	    }
1923 	    if (s = strchr(argv[0], '=')) {
1924 		*s++ = '\0';
1925 		sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
1926 	    }
1927 	    else
1928 		sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
1929 	}
1930     }
1931     toptarget = NEWSV(0,0);
1932     sv_upgrade(toptarget, SVt_PVFM);
1933     sv_setpvn(toptarget, "", 0);
1934     bodytarget = NEWSV(0,0);
1935     sv_upgrade(bodytarget, SVt_PVFM);
1936     sv_setpvn(bodytarget, "", 0);
1937     formtarget = bodytarget;
1938 
1939     tainted = 1;
1940     if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
1941 	sv_setpv(GvSV(tmpgv),origfilename);
1942 	magicname("0", "0", 1);
1943     }
1944     if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV))
1945 	time(&basetime);
1946     if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
1947 	sv_setpv(GvSV(tmpgv),origargv[0]);
1948     if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
1949 	GvMULTI_on(argvgv);
1950 	(void)gv_AVadd(argvgv);
1951 	av_clear(GvAVn(argvgv));
1952 	for (; argc > 0; argc--,argv++) {
1953 	    av_push(GvAVn(argvgv),newSVpv(argv[0],0));
1954 	}
1955     }
1956     if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
1957 	HV *hv;
1958 	GvMULTI_on(envgv);
1959 	hv = GvHVn(envgv);
1960 	hv_clear(hv);
1961 #ifndef VMS  /* VMS doesn't have environ array */
1962 	/* Note that if the supplied env parameter is actually a copy
1963 	   of the global environ then it may now point to free'd memory
1964 	   if the environment has been modified since. To avoid this
1965 	   problem we treat env==NULL as meaning 'use the default'
1966 	*/
1967 	if (!env)
1968 	    env = environ;
1969 	if (env != environ) {
1970 	    environ[0] = Nullch;
1971 	    hv_magic(hv, envgv, 'E');
1972 	}
1973 	for (; *env; env++) {
1974 	    if (!(s = strchr(*env,'=')))
1975 		continue;
1976 	    *s++ = '\0';
1977 	    sv = newSVpv(s--,0);
1978 	    sv_magic(sv, sv, 'e', *env, s - *env);
1979 	    (void)hv_store(hv, *env, s - *env, sv, 0);
1980 	    *s = '=';
1981 	}
1982 #endif
1983 #ifdef DYNAMIC_ENV_FETCH
1984 	HvNAME(hv) = savepv(ENV_HV_NAME);
1985 #endif
1986 	hv_magic(hv, envgv, 'E');
1987     }
1988     tainted = 0;
1989     if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
1990 	sv_setiv(GvSV(tmpgv),(I32)getpid());
1991 
1992 }
1993 
1994 static void
1995 init_perllib()
1996 {
1997     char *s;
1998     if (!tainting) {
1999 	s = getenv("PERL5LIB");
2000 	if (s)
2001 	    incpush(s);
2002 	else
2003 	    incpush(getenv("PERLLIB"));
2004     }
2005 
2006 #ifdef APPLLIB_EXP
2007     incpush(APPLLIB_EXP);
2008 #endif
2009 
2010 #ifdef ARCHLIB_EXP
2011     incpush(ARCHLIB_EXP);
2012 #endif
2013 #ifndef PRIVLIB_EXP
2014 #define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
2015 #endif
2016     incpush(PRIVLIB_EXP);
2017 
2018 #ifdef SITEARCH_EXP
2019     incpush(SITEARCH_EXP);
2020 #endif
2021 #ifdef SITELIB_EXP
2022     incpush(SITELIB_EXP);
2023 #endif
2024 #ifdef OLDARCHLIB_EXP  /* 5.00[01] compatibility */
2025     incpush(OLDARCHLIB_EXP);
2026 #endif
2027 
2028     if (!tainting)
2029 	incpush(".");
2030 }
2031 
2032 void
2033 calllist(list)
2034 AV* list;
2035 {
2036     Sigjmp_buf oldtop;
2037     STRLEN len;
2038     line_t oldline = curcop->cop_line;
2039 
2040     Copy(top_env, oldtop, 1, Sigjmp_buf);
2041 
2042     while (AvFILL(list) >= 0) {
2043 	CV *cv = (CV*)av_shift(list);
2044 
2045 	SAVEFREESV(cv);
2046 
2047 	switch (Sigsetjmp(top_env,1)) {
2048 	case 0: {
2049 		SV* atsv = GvSV(errgv);
2050 		PUSHMARK(stack_sp);
2051 		perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
2052 		(void)SvPV(atsv, len);
2053 		if (len) {
2054 		    Copy(oldtop, top_env, 1, Sigjmp_buf);
2055 		    curcop = &compiling;
2056 		    curcop->cop_line = oldline;
2057 		    if (list == beginav)
2058 			sv_catpv(atsv, "BEGIN failed--compilation aborted");
2059 		    else
2060 			sv_catpv(atsv, "END failed--cleanup aborted");
2061 		    croak("%s", SvPVX(atsv));
2062 		}
2063 	    }
2064 	    break;
2065 	case 1:
2066 #ifdef VMS
2067 	    statusvalue = 255;	/* XXX I don't think we use 1 anymore. */
2068 #else
2069 	statusvalue = 1;
2070 #endif
2071 	    /* FALL THROUGH */
2072 	case 2:
2073 	    /* my_exit() was called */
2074 	    curstash = defstash;
2075 	    if (endav)
2076 		calllist(endav);
2077 	    FREETMPS;
2078 	    Copy(oldtop, top_env, 1, Sigjmp_buf);
2079 	    curcop = &compiling;
2080 	    curcop->cop_line = oldline;
2081 	    if (statusvalue) {
2082 		if (list == beginav)
2083 		    croak("BEGIN failed--compilation aborted");
2084 		else
2085 		    croak("END failed--cleanup aborted");
2086 	    }
2087 	    my_exit(statusvalue);
2088 	    /* NOTREACHED */
2089 	    return;
2090 	case 3:
2091 	    if (!restartop) {
2092 		fprintf(stderr, "panic: restartop\n");
2093 		FREETMPS;
2094 		break;
2095 	    }
2096 	    Copy(oldtop, top_env, 1, Sigjmp_buf);
2097 	    curcop = &compiling;
2098 	    curcop->cop_line = oldline;
2099 	    Siglongjmp(top_env, 3);
2100 	}
2101     }
2102 
2103     Copy(oldtop, top_env, 1, Sigjmp_buf);
2104 }
2105 
2106