Re: OS/2 patch for _27
[p5sagit/p5-mst-13.2.git] / perl.c
CommitLineData
a0d0e21e 1/* perl.c
2 *
1a30305b 3 * Copyright (c) 1987-1996 Larry Wall
a687059c 4 *
352d5a3a 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.
a687059c 7 *
8d063cd8 8 */
9
a0d0e21e 10/*
11 * "A ship then new they built for him/of mithril and of elven glass" --Bilbo
12 */
45d8adaa 13
378cc40b 14#include "EXTERN.h"
15#include "perl.h"
a687059c 16#include "patchlevel.h"
378cc40b 17
df5cef82 18/* XXX If this causes problems, set i_unistd=undef in the hint file. */
a0d0e21e 19#ifdef I_UNISTD
20#include <unistd.h>
21#endif
a0d0e21e 22
71be2cbc 23dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n";
463ee0b2 24
a687059c 25#ifdef IAMSUID
26#ifndef DOSUID
27#define DOSUID
28#endif
29#endif
378cc40b 30
a687059c 31#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
32#ifdef DOSUID
33#undef DOSUID
34#endif
35#endif
8d063cd8 36
8ebc5c01 37#define I_REINIT \
38 STMT_START { \
39 chopset = " \n-"; \
40 copline = NOLINE; \
41 curcop = &compiling; \
42 curcopdb = NULL; \
43 cxstack_ix = -1; \
44 cxstack_max = 128; \
45 dbargs = 0; \
46 dlmax = 128; \
47 laststatval = -1; \
48 laststype = OP_STAT; \
49 maxscream = -1; \
50 maxsysfd = MAXSYSFD; \
51 statname = Nullsv; \
52 tmps_floor = -1; \
53 tmps_ix = -1; \
54 op_mask = NULL; \
55 dlmax = 128; \
56 laststatval = -1; \
57 laststype = OP_STAT; \
58 } STMT_END
59
a0d0e21e 60static void find_beginning _((void));
bbce6d69 61static void forbid_setid _((char *));
774d564b 62static void incpush _((char *, int));
748a9306 63static void init_ids _((void));
a0d0e21e 64static void init_debugger _((void));
65static void init_lexer _((void));
66static void init_main_stash _((void));
67static void init_perllib _((void));
68static void init_postdump_symbols _((int, char **, char **));
69static void init_predump_symbols _((void));
70static void init_stacks _((void));
f86702cc 71static void my_exit_jump _((void)) __attribute__((noreturn));
6e72f9df 72static void nuke_stacks _((void));
a0d0e21e 73static void open_script _((char *, bool, SV *));
ab821d7f 74static void usage _((char *));
96436eeb 75static void validate_suid _((char *, char*));
76
77static int fdscript = -1;
79072805 78
93a17b20 79PerlInterpreter *
79072805 80perl_alloc()
81{
93a17b20 82 PerlInterpreter *sv_interp;
79072805 83
8990e307 84 curinterp = 0;
93a17b20 85 New(53, sv_interp, 1, PerlInterpreter);
79072805 86 return sv_interp;
87}
88
89void
90perl_construct( sv_interp )
93a17b20 91register PerlInterpreter *sv_interp;
79072805 92{
93 if (!(curinterp = sv_interp))
94 return;
95
8990e307 96#ifdef MULTIPLICITY
93a17b20 97 Zero(sv_interp, 1, PerlInterpreter);
8990e307 98#endif
79072805 99
100 /* Init the real globals? */
101 if (!linestr) {
102 linestr = NEWSV(65,80);
ed6116ce 103 sv_upgrade(linestr,SVt_PVIV);
79072805 104
6e72f9df 105 if (!SvREADONLY(&sv_undef)) {
106 SvREADONLY_on(&sv_undef);
79072805 107
6e72f9df 108 sv_setpv(&sv_no,No);
109 SvNV(&sv_no);
110 SvREADONLY_on(&sv_no);
79072805 111
6e72f9df 112 sv_setpv(&sv_yes,Yes);
113 SvNV(&sv_yes);
114 SvREADONLY_on(&sv_yes);
115 }
79072805 116
c07a80fd 117 nrs = newSVpv("\n", 1);
118 rs = SvREFCNT_inc(nrs);
119
44a8e56a 120 pidstatus = newHV();
121
79072805 122#ifdef MSDOS
123 /*
124 * There is no way we can refer to them from Perl so close them to save
125 * space. The other alternative would be to provide STDAUX and STDPRN
126 * filehandles.
127 */
128 (void)fclose(stdaux);
129 (void)fclose(stdprn);
130#endif
131 }
132
8990e307 133#ifdef MULTIPLICITY
8ebc5c01 134 I_REINIT;
135 perl_destruct_level = 1;
136#else
137 if(perl_destruct_level > 0)
138 I_REINIT;
79072805 139#endif
140
748a9306 141 init_ids();
a5f75d66 142
f86702cc 143 STATUS_ALL_SUCCESS;
144
36477c24 145 SET_NUMERIC_STANDARD();
a5f75d66 146#if defined(SUBVERSION) && SUBVERSION > 0
e2666263 147 sprintf(patchlevel, "%7.5f", (double) 5
148 + ((double) PATCHLEVEL / (double) 1000)
149 + ((double) SUBVERSION / (double) 100000));
a5f75d66 150#else
e2666263 151 sprintf(patchlevel, "%5.3f", (double) 5 +
152 ((double) PATCHLEVEL / (double) 1000));
a5f75d66 153#endif
79072805 154
ab821d7f 155#if defined(LOCAL_PATCH_COUNT)
6e72f9df 156 localpatches = local_patches; /* For possible -v */
ab821d7f 157#endif
158
760ac839 159 PerlIO_init(); /* Hook to IO system */
160
79072805 161 fdpid = newAV(); /* for remembering popen pids by fd */
8990e307 162
163 init_stacks();
164 ENTER;
79072805 165}
166
167void
748a9306 168perl_destruct(sv_interp)
93a17b20 169register PerlInterpreter *sv_interp;
79072805 170{
748a9306 171 int destruct_level; /* 0=none, 1=full, 2=full with checks */
8990e307 172 I32 last_sv_count;
a0d0e21e 173 HV *hv;
8990e307 174
79072805 175 if (!(curinterp = sv_interp))
176 return;
748a9306 177
178 destruct_level = perl_destruct_level;
4633a7c4 179#ifdef DEBUGGING
180 {
181 char *s;
5f05dabc 182 if (s = getenv("PERL_DESTRUCT_LEVEL")) {
183 int i = atoi(s);
184 if (destruct_level < i)
185 destruct_level = i;
186 }
4633a7c4 187 }
188#endif
189
5f05dabc 190 /* unhook hooks which will soon be, or use, destroyed data */
191 SvREFCNT_dec(warnhook);
192 warnhook = Nullsv;
193 SvREFCNT_dec(diehook);
194 diehook = Nullsv;
195 SvREFCNT_dec(parsehook);
196 parsehook = Nullsv;
197
8990e307 198 LEAVE;
a0d0e21e 199 FREETMPS;
200
ff0cee69 201 /* We must account for everything. */
202
203 /* Destroy the main CV and syntax tree */
6e72f9df 204 if (main_root) {
205 curpad = AvARRAY(comppad);
206 op_free(main_root);
ff0cee69 207 main_root = Nullop;
a0d0e21e 208 }
ff0cee69 209 main_start = Nullop;
210 SvREFCNT_dec(main_cv);
211 main_cv = Nullcv;
212
a0d0e21e 213 if (sv_objcount) {
214 /*
215 * Try to destruct global references. We do this first so that the
216 * destructors and destructees still exist. Some sv's might remain.
217 * Non-referenced objects are on their own.
218 */
219
220 dirty = TRUE;
221 sv_clean_objs();
8990e307 222 }
223
a0d0e21e 224 if (destruct_level == 0){
8990e307 225
a0d0e21e 226 DEBUG_P(debprofdump());
227
228 /* The exit() function will do everything that needs doing. */
229 return;
230 }
5dd60ef7 231
5f05dabc 232 /* loosen bonds of global variables */
233
8ebc5c01 234 if(rsfp) {
235 (void)PerlIO_close(rsfp);
236 rsfp = Nullfp;
237 }
238
239 /* Filters for program text */
240 SvREFCNT_dec(rsfp_filters);
241 rsfp_filters = Nullav;
242
243 /* switches */
244 preprocess = FALSE;
245 minus_n = FALSE;
246 minus_p = FALSE;
247 minus_l = FALSE;
248 minus_a = FALSE;
249 minus_F = FALSE;
250 doswitches = FALSE;
251 dowarn = FALSE;
252 doextract = FALSE;
253 sawampersand = FALSE; /* must save all match strings */
254 sawstudy = FALSE; /* do fbm_instr on all strings */
255 sawvec = FALSE;
256 unsafe = FALSE;
257
258 Safefree(inplace);
259 inplace = Nullch;
260
261 Safefree(e_tmpname);
262 e_tmpname = Nullch;
263
264 if (e_fp) {
265 PerlIO_close(e_fp);
266 e_fp = Nullfp;
267 }
268
269 /* magical thingies */
270
271 Safefree(ofs); /* $, */
272 ofs = Nullch;
5f05dabc 273
8ebc5c01 274 Safefree(ors); /* $\ */
275 ors = Nullch;
276
277 SvREFCNT_dec(nrs); /* $\ helper */
5f05dabc 278 nrs = Nullsv;
279
8ebc5c01 280 multiline = 0; /* $* */
5f05dabc 281
8ebc5c01 282 SvREFCNT_dec(statname);
5f05dabc 283 statname = Nullsv;
284 statgv = Nullgv;
5f05dabc 285
8ebc5c01 286 /* defgv, aka *_ should be taken care of elsewhere */
287
288#if 0 /* just about all regexp stuff, seems to be ok */
289
290 /* shortcuts to regexp stuff */
291 leftgv = Nullgv;
292 ampergv = Nullgv;
293
294 SAVEFREEOP(curpm);
295 SAVEFREEOP(oldlastpm); /* for saving regexp context during debugger */
296
297 regprecomp = NULL; /* uncompiled string. */
298 regparse = NULL; /* Input-scan pointer. */
299 regxend = NULL; /* End of input for compile */
300 regnpar = 0; /* () count. */
301 regcode = NULL; /* Code-emit pointer; &regdummy = don't. */
302 regsize = 0; /* Code size. */
303 regnaughty = 0; /* How bad is this pattern? */
304 regsawback = 0; /* Did we see \1, ...? */
305
306 reginput = NULL; /* String-input pointer. */
307 regbol = NULL; /* Beginning of input, for ^ check. */
308 regeol = NULL; /* End of input, for $ check. */
309 regstartp = (char **)NULL; /* Pointer to startp array. */
310 regendp = (char **)NULL; /* Ditto for endp. */
311 reglastparen = 0; /* Similarly for lastparen. */
312 regtill = NULL; /* How far we are required to go. */
313 regflags = 0; /* are we folding, multilining? */
314 regprev = (char)NULL; /* char before regbol, \n if none */
315
316#endif /* if 0 */
317
318 /* clean up after study() */
319 SvREFCNT_dec(lastscream);
320 lastscream = Nullsv;
321 Safefree(screamfirst);
322 screamfirst = 0;
323 Safefree(screamnext);
324 screamnext = 0;
325
326 /* startup and shutdown function lists */
327 SvREFCNT_dec(beginav);
328 SvREFCNT_dec(endav);
5618dfe8 329 beginav = Nullav;
5618dfe8 330 endav = Nullav;
331
8ebc5c01 332 /* temp stack during pp_sort() */
333 SvREFCNT_dec(sortstack);
334 sortstack = Nullav;
335
336 /* shortcuts just get cleared */
337 envgv = Nullgv;
338 siggv = Nullgv;
339 incgv = Nullgv;
340 errgv = Nullgv;
341 argvgv = Nullgv;
342 argvoutgv = Nullgv;
343 stdingv = Nullgv;
344 last_in_gv = Nullgv;
345
346 /* reset so print() ends up where we expect */
347 setdefout(Nullgv);
348
a0d0e21e 349 /* Prepare to destruct main symbol table. */
5f05dabc 350
a0d0e21e 351 hv = defstash;
85e6fe83 352 defstash = 0;
a0d0e21e 353 SvREFCNT_dec(hv);
354
355 FREETMPS;
356 if (destruct_level >= 2) {
357 if (scopestack_ix != 0)
ff0cee69 358 warn("Unbalanced scopes: %ld more ENTERs than LEAVEs\n",
359 (long)scopestack_ix);
a0d0e21e 360 if (savestack_ix != 0)
ff0cee69 361 warn("Unbalanced saves: %ld more saves than restores\n",
362 (long)savestack_ix);
a0d0e21e 363 if (tmps_floor != -1)
ff0cee69 364 warn("Unbalanced tmps: %ld more allocs than frees\n",
365 (long)tmps_floor + 1);
a0d0e21e 366 if (cxstack_ix != -1)
ff0cee69 367 warn("Unbalanced context: %ld more PUSHes than POPs\n",
368 (long)cxstack_ix + 1);
a0d0e21e 369 }
8990e307 370
371 /* Now absolutely destruct everything, somehow or other, loops or no. */
8990e307 372 last_sv_count = 0;
6e72f9df 373 SvFLAGS(strtab) |= SVTYPEMASK; /* don't clean out strtab now */
8990e307 374 while (sv_count != 0 && sv_count != last_sv_count) {
375 last_sv_count = sv_count;
376 sv_clean_all();
377 }
6e72f9df 378 SvFLAGS(strtab) &= ~SVTYPEMASK;
379 SvFLAGS(strtab) |= SVt_PVHV;
380
381 /* Destruct the global string table. */
382 {
383 /* Yell and reset the HeVAL() slots that are still holding refcounts,
384 * so that sv_free() won't fail on them.
385 */
386 I32 riter;
387 I32 max;
388 HE *hent;
389 HE **array;
390
391 riter = 0;
392 max = HvMAX(strtab);
393 array = HvARRAY(strtab);
394 hent = array[0];
395 for (;;) {
396 if (hent) {
397 warn("Unbalanced string table refcount: (%d) for \"%s\"",
398 HeVAL(hent) - Nullsv, HeKEY(hent));
399 HeVAL(hent) = Nullsv;
400 hent = HeNEXT(hent);
401 }
402 if (!hent) {
403 if (++riter > max)
404 break;
405 hent = array[riter];
406 }
407 }
408 }
409 SvREFCNT_dec(strtab);
410
8990e307 411 if (sv_count != 0)
ff0cee69 412 warn("Scalars leaked: %ld\n", (long)sv_count);
6e72f9df 413
4633a7c4 414 sv_free_arenas();
44a8e56a 415
416 /* No SVs have survived, need to clean out */
417 linestr = NULL;
418 pidstatus = Nullhv;
6e72f9df 419 if (origfilename)
420 Safefree(origfilename);
421 nuke_stacks();
422 hints = 0; /* Reset hints. Should hints be per-interpreter ? */
423
a0d0e21e 424 DEBUG_P(debprofdump());
79072805 425}
426
427void
428perl_free(sv_interp)
93a17b20 429PerlInterpreter *sv_interp;
79072805 430{
431 if (!(curinterp = sv_interp))
432 return;
433 Safefree(sv_interp);
434}
ecfc5424 435#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
a0d0e21e 436char *getenv _((char *)); /* Usually in <stdlib.h> */
437#endif
79072805 438
439int
a0d0e21e 440perl_parse(sv_interp, xsinit, argc, argv, env)
93a17b20 441PerlInterpreter *sv_interp;
a0d0e21e 442void (*xsinit)_((void));
443int argc;
444char **argv;
79072805 445char **env;
8d063cd8 446{
79072805 447 register SV *sv;
8d063cd8 448 register char *s;
1a30305b 449 char *scriptname = NULL;
a0d0e21e 450 VOL bool dosearch = FALSE;
13281fa4 451 char *validarg = "";
748a9306 452 AV* comppadlist;
8d063cd8 453
a687059c 454#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
455#ifdef IAMSUID
456#undef IAMSUID
463ee0b2 457 croak("suidperl is no longer needed since the kernel can now execute\n\
a687059c 458setuid perl scripts securely.\n");
459#endif
460#endif
461
79072805 462 if (!(curinterp = sv_interp))
463 return 255;
464
6e72f9df 465#if defined(NeXT) && defined(__DYNAMIC__)
466 _dyld_lookup_and_bind
467 ("__environ", (unsigned long *) &environ_pointer, NULL);
468#endif /* environ */
469
ac58e20f 470 origargv = argv;
471 origargc = argc;
a0d0e21e 472#ifndef VMS /* VMS doesn't have environ array */
fe14fcc3 473 origenviron = environ;
a0d0e21e 474#endif
ab821d7f 475 e_tmpname = Nullch;
a0d0e21e 476
477 if (do_undump) {
478
479 /* Come here if running an undumped a.out. */
480
481 origfilename = savepv(argv[0]);
482 do_undump = FALSE;
483 cxstack_ix = -1; /* start label stack again */
748a9306 484 init_ids();
a0d0e21e 485 init_postdump_symbols(argc,argv,env);
486 return 0;
487 }
488
ff0cee69 489 if (main_root) {
490 curpad = AvARRAY(comppad);
a0d0e21e 491 op_free(main_root);
ff0cee69 492 main_root = Nullop;
493 }
494 main_start = Nullop;
495 SvREFCNT_dec(main_cv);
496 main_cv = Nullcv;
79072805 497
f86702cc 498 time(&basetime);
499
a5f75d66 500 switch (Sigsetjmp(top_env,1)) {
79072805 501 case 1:
f86702cc 502 STATUS_ALL_FAILURE;
503 /* FALL THROUGH */
79072805 504 case 2:
f86702cc 505 /* my_exit() was called */
8990e307 506 curstash = defstash;
507 if (endav)
508 calllist(endav);
f86702cc 509 return STATUS_NATIVE_EXPORT;
79072805 510 case 3:
760ac839 511 PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");
8990e307 512 return 1;
79072805 513 }
514
79072805 515 sv_setpvn(linestr,"",0);
516 sv = newSVpv("",0); /* first used for -I flags */
8990e307 517 SAVEFREESV(sv);
79072805 518 init_main_stash();
33b78306 519 for (argc--,argv++; argc > 0; argc--,argv++) {
8d063cd8 520 if (argv[0][0] != '-' || !argv[0][1])
521 break;
13281fa4 522#ifdef DOSUID
523 if (*validarg)
524 validarg = " PHOOEY ";
525 else
526 validarg = argv[0];
527#endif
528 s = argv[0]+1;
8d063cd8 529 reswitch:
13281fa4 530 switch (*s) {
27e2fb84 531 case '0':
2304df62 532 case 'F':
378cc40b 533 case 'a':
33b78306 534 case 'c':
a687059c 535 case 'd':
8d063cd8 536 case 'D':
4633a7c4 537 case 'h':
33b78306 538 case 'i':
fe14fcc3 539 case 'l':
1a30305b 540 case 'M':
541 case 'm':
33b78306 542 case 'n':
543 case 'p':
79072805 544 case 's':
33b78306 545 case 'u':
546 case 'U':
547 case 'v':
548 case 'w':
549 if (s = moreswitches(s))
550 goto reswitch;
8d063cd8 551 break;
33b78306 552
f86702cc 553 case 'T':
554 tainting = TRUE;
555 s++;
556 goto reswitch;
557
8d063cd8 558 case 'e':
a687059c 559 if (euid != uid || egid != gid)
463ee0b2 560 croak("No -e allowed in setuid scripts");
8d063cd8 561 if (!e_fp) {
a0d0e21e 562 e_tmpname = savepv(TMPPATH);
a687059c 563 (void)mktemp(e_tmpname);
83025b21 564 if (!*e_tmpname)
463ee0b2 565 croak("Can't mktemp()");
760ac839 566 e_fp = PerlIO_open(e_tmpname,"w");
33b78306 567 if (!e_fp)
463ee0b2 568 croak("Cannot open temporary file");
8d063cd8 569 }
552a7a9b 570 if (*++s)
571 PerlIO_puts(e_fp,s);
572 else if (argv[1]) {
760ac839 573 PerlIO_puts(e_fp,argv[1]);
33b78306 574 argc--,argv++;
575 }
552a7a9b 576 else
577 croak("No code specified for -e");
760ac839 578 (void)PerlIO_putc(e_fp,'\n');
8d063cd8 579 break;
580 case 'I':
bbce6d69 581 forbid_setid("-I");
79072805 582 sv_catpv(sv,"-");
583 sv_catpv(sv,s);
584 sv_catpv(sv," ");
a687059c 585 if (*++s) {
774d564b 586 incpush(s, TRUE);
378cc40b 587 }
33b78306 588 else if (argv[1]) {
774d564b 589 incpush(argv[1], TRUE);
79072805 590 sv_catpv(sv,argv[1]);
8d063cd8 591 argc--,argv++;
79072805 592 sv_catpv(sv," ");
8d063cd8 593 }
594 break;
8d063cd8 595 case 'P':
bbce6d69 596 forbid_setid("-P");
8d063cd8 597 preprocess = TRUE;
13281fa4 598 s++;
8d063cd8 599 goto reswitch;
378cc40b 600 case 'S':
bbce6d69 601 forbid_setid("-S");
378cc40b 602 dosearch = TRUE;
13281fa4 603 s++;
378cc40b 604 goto reswitch;
1a30305b 605 case 'V':
606 if (!preambleav)
607 preambleav = newAV();
608 av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
609 if (*++s != ':') {
6e72f9df 610 Sv = newSVpv("print myconfig();",0);
611#ifdef VMS
612 sv_catpv(Sv,"print \"\\nCharacteristics of this PERLSHR image: \\n\",");
613#else
614 sv_catpv(Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\",");
615#endif
616#if defined(DEBUGGING) || defined(NOEMBED) || defined(MULTIPLICITY)
617 strcpy(buf,"\" Compile-time options:");
618# ifdef DEBUGGING
619 strcat(buf," DEBUGGING");
620# endif
621# ifdef NOEMBED
622 strcat(buf," NOEMBED");
623# endif
624# ifdef MULTIPLICITY
625 strcat(buf," MULTIPLICITY");
626# endif
627 strcat(buf,"\\n\",");
628 sv_catpv(Sv,buf);
629#endif
630#if defined(LOCAL_PATCH_COUNT)
631 if (LOCAL_PATCH_COUNT > 0)
632 { int i;
633 sv_catpv(Sv,"print \" Locally applied patches:\\n\",");
634 for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
635 if (localpatches[i]) {
636 sprintf(buf,"\" \\t%s\\n\",",localpatches[i]);
637 sv_catpv(Sv,buf);
638 }
639 }
640 }
641#endif
642 sprintf(buf,"\" Built under %s\\n\",",OSNAME);
643 sv_catpv(Sv,buf);
644#ifdef __DATE__
645# ifdef __TIME__
646 sprintf(buf,"\" Compiled at %s %s\\n\"",__DATE__,__TIME__);
647# else
648 sprintf(buf,"\" Compiled on %s\\n\"",__DATE__);
649# endif
650 sv_catpv(Sv,buf);
651#endif
652 sv_catpv(Sv,"; $\"=\"\\n \"; print \" \\@INC:\\n @INC\\n\"");
1a30305b 653 }
654 else {
655 Sv = newSVpv("config_vars(qw(",0);
656 sv_catpv(Sv, ++s);
657 sv_catpv(Sv, "))");
658 s += strlen(s);
659 }
660 av_push(preambleav, Sv);
c07a80fd 661 scriptname = BIT_BUCKET; /* don't look for script or read stdin */
1a30305b 662 goto reswitch;
33b78306 663 case 'x':
664 doextract = TRUE;
13281fa4 665 s++;
33b78306 666 if (*s)
a0d0e21e 667 cddir = savepv(s);
33b78306 668 break;
8d063cd8 669 case '-':
670 argc--,argv++;
671 goto switch_end;
672 case 0:
673 break;
674 default:
463ee0b2 675 croak("Unrecognized switch: -%s",s);
8d063cd8 676 }
677 }
678 switch_end:
1a30305b 679 if (!scriptname)
680 scriptname = argv[0];
8d063cd8 681 if (e_fp) {
760ac839 682 if (PerlIO_flush(e_fp) || PerlIO_error(e_fp) || PerlIO_close(e_fp))
2304df62 683 croak("Can't write to temp file for -e: %s", Strerror(errno));
ab821d7f 684 e_fp = Nullfp;
8d063cd8 685 argc++,argv--;
45d8adaa 686 scriptname = e_tmpname;
8d063cd8 687 }
79072805 688 else if (scriptname == Nullch) {
689#ifdef MSDOS
760ac839 690 if ( isatty(PerlIO_fileno(PerlIO_stdin())) )
55497cff 691 moreswitches("h");
fe14fcc3 692#endif
79072805 693 scriptname = "-";
694 }
fe14fcc3 695
79072805 696 init_perllib();
8d063cd8 697
79072805 698 open_script(scriptname,dosearch,sv);
8d063cd8 699
96436eeb 700 validate_suid(validarg, scriptname);
378cc40b 701
79072805 702 if (doextract)
703 find_beginning();
704
4fdae800 705 main_cv = compcv = (CV*)NEWSV(1104,0);
748a9306 706 sv_upgrade((SV *)compcv, SVt_PVCV);
07055b4c 707 CvUNIQUE_on(compcv);
748a9306 708
6e72f9df 709 comppad = newAV();
79072805 710 av_push(comppad, Nullsv);
711 curpad = AvARRAY(comppad);
6e72f9df 712 comppad_name = newAV();
8990e307 713 comppad_name_fill = 0;
714 min_intro_pending = 0;
79072805 715 padix = 0;
716
748a9306 717 comppadlist = newAV();
718 AvREAL_off(comppadlist);
8e07c86e 719 av_store(comppadlist, 0, (SV*)comppad_name);
720 av_store(comppadlist, 1, (SV*)comppad);
748a9306 721 CvPADLIST(compcv) = comppadlist;
722
6e72f9df 723 boot_core_UNIVERSAL();
a0d0e21e 724 if (xsinit)
725 (*xsinit)(); /* in case linked C routines want magical variables */
748a9306 726#ifdef VMS
727 init_os_extras();
728#endif
93a17b20 729
93a17b20 730 init_predump_symbols();
8990e307 731 if (!do_undump)
732 init_postdump_symbols(argc,argv,env);
93a17b20 733
79072805 734 init_lexer();
735
736 /* now parse the script */
737
738 error_count = 0;
739 if (yyparse() || error_count) {
740 if (minus_c)
463ee0b2 741 croak("%s had compilation errors.\n", origfilename);
79072805 742 else {
463ee0b2 743 croak("Execution of %s aborted due to compilation errors.\n",
79072805 744 origfilename);
378cc40b 745 }
79072805 746 }
747 curcop->cop_line = 0;
748 curstash = defstash;
749 preprocess = FALSE;
ab821d7f 750 if (e_tmpname) {
79072805 751 (void)UNLINK(e_tmpname);
ab821d7f 752 Safefree(e_tmpname);
753 e_tmpname = Nullch;
378cc40b 754 }
a687059c 755
93a17b20 756 /* now that script is parsed, we can modify record separator */
c07a80fd 757 SvREFCNT_dec(rs);
758 rs = SvREFCNT_inc(nrs);
759 sv_setsv(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs);
45d8adaa 760
79072805 761 if (do_undump)
762 my_unexec();
763
8990e307 764 if (dowarn)
765 gv_check(defstash);
766
a0d0e21e 767 LEAVE;
768 FREETMPS;
c07a80fd 769
770#ifdef DEBUGGING_MSTATS
771 if ((s=getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
772 dump_mstats("after compilation:");
773#endif
774
a0d0e21e 775 ENTER;
776 restartop = 0;
79072805 777 return 0;
778}
779
780int
781perl_run(sv_interp)
93a17b20 782PerlInterpreter *sv_interp;
79072805 783{
784 if (!(curinterp = sv_interp))
785 return 255;
a5f75d66 786 switch (Sigsetjmp(top_env,1)) {
79072805 787 case 1:
788 cxstack_ix = -1; /* start context stack again */
789 break;
790 case 2:
f86702cc 791 /* my_exit() was called */
79072805 792 curstash = defstash;
93a17b20 793 if (endav)
794 calllist(endav);
a0d0e21e 795 FREETMPS;
c07a80fd 796#ifdef DEBUGGING_MSTATS
797 if (getenv("PERL_DEBUG_MSTATS"))
798 dump_mstats("after execution: ");
799#endif
f86702cc 800 return STATUS_NATIVE_EXPORT;
79072805 801 case 3:
802 if (!restartop) {
760ac839 803 PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
a0d0e21e 804 FREETMPS;
8990e307 805 return 1;
83025b21 806 }
6e72f9df 807 if (curstack != mainstack) {
79072805 808 dSP;
6e72f9df 809 SWITCHSTACK(curstack, mainstack);
79072805 810 }
811 break;
8d063cd8 812 }
79072805 813
760ac839 814 DEBUG_r(PerlIO_printf(PerlIO_stderr(), "%s $` $& $' support.\n",
6e72f9df 815 sawampersand ? "Enabling" : "Omitting"));
816
79072805 817 if (!restartop) {
818 DEBUG_x(dump_all());
760ac839 819 DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n"));
79072805 820
821 if (minus_c) {
760ac839 822 PerlIO_printf(PerlIO_stderr(), "%s syntax OK\n", origfilename);
79072805 823 my_exit(0);
824 }
a0d0e21e 825 if (perldb && DBsingle)
826 sv_setiv(DBsingle, 1);
45d8adaa 827 }
79072805 828
829 /* do it */
830
831 if (restartop) {
832 op = restartop;
833 restartop = 0;
ab821d7f 834 runops();
79072805 835 }
836 else if (main_start) {
4fdae800 837 CvDEPTH(main_cv) = 1;
79072805 838 op = main_start;
ab821d7f 839 runops();
79072805 840 }
79072805 841
842 my_exit(0);
a0d0e21e 843 return 0;
79072805 844}
845
a0d0e21e 846SV*
847perl_get_sv(name, create)
848char* name;
849I32 create;
850{
851 GV* gv = gv_fetchpv(name, create, SVt_PV);
852 if (gv)
853 return GvSV(gv);
854 return Nullsv;
855}
856
857AV*
858perl_get_av(name, create)
859char* name;
860I32 create;
861{
862 GV* gv = gv_fetchpv(name, create, SVt_PVAV);
863 if (create)
864 return GvAVn(gv);
865 if (gv)
866 return GvAV(gv);
867 return Nullav;
868}
869
870HV*
871perl_get_hv(name, create)
872char* name;
873I32 create;
874{
875 GV* gv = gv_fetchpv(name, create, SVt_PVHV);
876 if (create)
877 return GvHVn(gv);
878 if (gv)
879 return GvHV(gv);
880 return Nullhv;
881}
882
883CV*
884perl_get_cv(name, create)
885char* name;
886I32 create;
887{
888 GV* gv = gv_fetchpv(name, create, SVt_PVCV);
8ebc5c01 889 if (create && !GvCVu(gv))
774d564b 890 return newSUB(start_subparse(FALSE, 0),
a0d0e21e 891 newSVOP(OP_CONST, 0, newSVpv(name,0)),
4633a7c4 892 Nullop,
a0d0e21e 893 Nullop);
894 if (gv)
8ebc5c01 895 return GvCVu(gv);
a0d0e21e 896 return Nullcv;
897}
898
79072805 899/* Be sure to refetch the stack pointer after calling these routines. */
900
a0d0e21e 901I32
902perl_call_argv(subname, flags, argv)
8990e307 903char *subname;
a0d0e21e 904I32 flags; /* See G_* flags in cop.h */
905register char **argv; /* null terminated arg list */
8990e307 906{
a0d0e21e 907 dSP;
8990e307 908
a0d0e21e 909 PUSHMARK(sp);
910 if (argv) {
8990e307 911 while (*argv) {
a0d0e21e 912 XPUSHs(sv_2mortal(newSVpv(*argv,0)));
8990e307 913 argv++;
914 }
a0d0e21e 915 PUTBACK;
8990e307 916 }
a0d0e21e 917 return perl_call_pv(subname, flags);
8990e307 918}
919
a0d0e21e 920I32
921perl_call_pv(subname, flags)
922char *subname; /* name of the subroutine */
923I32 flags; /* See G_* flags in cop.h */
924{
925 return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags);
926}
927
928I32
929perl_call_method(methname, flags)
930char *methname; /* name of the subroutine */
931I32 flags; /* See G_* flags in cop.h */
932{
933 dSP;
934 OP myop;
935 if (!op)
936 op = &myop;
937 XPUSHs(sv_2mortal(newSVpv(methname,0)));
938 PUTBACK;
939 pp_method();
940 return perl_call_sv(*stack_sp--, flags);
941}
942
943/* May be called with any of a CV, a GV, or an SV containing the name. */
944I32
945perl_call_sv(sv, flags)
946SV* sv;
947I32 flags; /* See G_* flags in cop.h */
948{
949 LOGOP myop; /* fake syntax tree node */
950 SV** sp = stack_sp;
951 I32 oldmark = TOPMARK;
952 I32 retval;
a5f75d66 953 Sigjmp_buf oldtop;
a0d0e21e 954 I32 oldscope;
6e72f9df 955 static CV *DBcv;
a0d0e21e 956
957 if (flags & G_DISCARD) {
958 ENTER;
959 SAVETMPS;
960 }
961
962 SAVESPTR(op);
963 op = (OP*)&myop;
964 Zero(op, 1, LOGOP);
965 EXTEND(stack_sp, 1);
966 *++stack_sp = sv;
967 oldscope = scopestack_ix;
968
969 if (!(flags & G_NOARGS))
970 myop.op_flags = OPf_STACKED;
971 myop.op_next = Nullop;
972 myop.op_flags |= OPf_KNOW;
973 if (flags & G_ARRAY)
974 myop.op_flags |= OPf_LIST;
975
36477c24 976 if (perldb && curstash != debstash
977 /* Handle first BEGIN of -d. */
978 && (DBcv || (DBcv = GvCV(DBsub)))
979 /* Try harder, since this may have been a sighandler, thus
980 * curstash may be meaningless. */
981 && (SvTYPE(sv) != SVt_PVCV || CvSTASH((CV*)sv) != debstash))
6e72f9df 982 op->op_private |= OPpENTERSUB_DB;
983
a0d0e21e 984 if (flags & G_EVAL) {
a5f75d66 985 Copy(top_env, oldtop, 1, Sigjmp_buf);
a0d0e21e 986
987 cLOGOP->op_other = op;
988 markstack_ptr--;
4633a7c4 989 /* we're trying to emulate pp_entertry() here */
990 {
991 register CONTEXT *cx;
992 I32 gimme = GIMME;
993
994 ENTER;
995 SAVETMPS;
996
997 push_return(op->op_next);
998 PUSHBLOCK(cx, CXt_EVAL, stack_sp);
999 PUSHEVAL(cx, 0, 0);
1000 eval_root = op; /* Only needed so that goto works right. */
1001
1002 in_eval = 1;
1003 if (flags & G_KEEPERR)
1004 in_eval |= 4;
1005 else
1006 sv_setpv(GvSV(errgv),"");
1007 }
a0d0e21e 1008 markstack_ptr++;
1009
1010 restart:
a5f75d66 1011 switch (Sigsetjmp(top_env,1)) {
a0d0e21e 1012 case 0:
1013 break;
1014 case 1:
f86702cc 1015 STATUS_ALL_FAILURE;
a0d0e21e 1016 /* FALL THROUGH */
1017 case 2:
1018 /* my_exit() was called */
1019 curstash = defstash;
1020 FREETMPS;
a5f75d66 1021 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 1022 if (statusvalue)
1023 croak("Callback called exit");
f86702cc 1024 my_exit_jump();
a0d0e21e 1025 /* NOTREACHED */
1026 case 3:
1027 if (restartop) {
1028 op = restartop;
1029 restartop = 0;
1030 goto restart;
1031 }
1032 stack_sp = stack_base + oldmark;
1033 if (flags & G_ARRAY)
1034 retval = 0;
1035 else {
1036 retval = 1;
1037 *++stack_sp = &sv_undef;
1038 }
1039 goto cleanup;
1040 }
1041 }
1042
1043 if (op == (OP*)&myop)
1044 op = pp_entersub();
1045 if (op)
ab821d7f 1046 runops();
a0d0e21e 1047 retval = stack_sp - (stack_base + oldmark);
4633a7c4 1048 if ((flags & G_EVAL) && !(flags & G_KEEPERR))
1049 sv_setpv(GvSV(errgv),"");
a0d0e21e 1050
1051 cleanup:
1052 if (flags & G_EVAL) {
1053 if (scopestack_ix > oldscope) {
a0a2876f 1054 SV **newsp;
1055 PMOP *newpm;
1056 I32 gimme;
1057 register CONTEXT *cx;
1058 I32 optype;
1059
1060 POPBLOCK(cx,newpm);
1061 POPEVAL(cx);
1062 pop_return();
1063 curpm = newpm;
1064 LEAVE;
a0d0e21e 1065 }
a5f75d66 1066 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 1067 }
1068 if (flags & G_DISCARD) {
1069 stack_sp = stack_base + oldmark;
1070 retval = 0;
1071 FREETMPS;
1072 LEAVE;
1073 }
1074 return retval;
1075}
1076
6e72f9df 1077/* Eval a string. The G_EVAL flag is always assumed. */
8990e307 1078
a0d0e21e 1079I32
4633a7c4 1080perl_eval_sv(sv, flags)
8990e307 1081SV* sv;
4633a7c4 1082I32 flags; /* See G_* flags in cop.h */
a0d0e21e 1083{
1084 UNOP myop; /* fake syntax tree node */
4633a7c4 1085 SV** sp = stack_sp;
1086 I32 oldmark = sp - stack_base;
1087 I32 retval;
a5f75d66 1088 Sigjmp_buf oldtop;
4633a7c4 1089 I32 oldscope;
79072805 1090
4633a7c4 1091 if (flags & G_DISCARD) {
1092 ENTER;
1093 SAVETMPS;
1094 }
1095
79072805 1096 SAVESPTR(op);
79072805 1097 op = (OP*)&myop;
a0d0e21e 1098 Zero(op, 1, UNOP);
4633a7c4 1099 EXTEND(stack_sp, 1);
1100 *++stack_sp = sv;
1101 oldscope = scopestack_ix;
79072805 1102
4633a7c4 1103 if (!(flags & G_NOARGS))
1104 myop.op_flags = OPf_STACKED;
79072805 1105 myop.op_next = Nullop;
6e72f9df 1106 myop.op_type = OP_ENTEREVAL;
4633a7c4 1107 myop.op_flags |= OPf_KNOW;
6e72f9df 1108 if (flags & G_KEEPERR)
1109 myop.op_flags |= OPf_SPECIAL;
4633a7c4 1110 if (flags & G_ARRAY)
6e72f9df 1111 myop.op_flags |= OPf_LIST;
79072805 1112
a5f75d66 1113 Copy(top_env, oldtop, 1, Sigjmp_buf);
4633a7c4 1114
1115restart:
a5f75d66 1116 switch (Sigsetjmp(top_env,1)) {
4633a7c4 1117 case 0:
1118 break;
1119 case 1:
f86702cc 1120 STATUS_ALL_FAILURE;
4633a7c4 1121 /* FALL THROUGH */
1122 case 2:
1123 /* my_exit() was called */
1124 curstash = defstash;
1125 FREETMPS;
a5f75d66 1126 Copy(oldtop, top_env, 1, Sigjmp_buf);
4633a7c4 1127 if (statusvalue)
1128 croak("Callback called exit");
f86702cc 1129 my_exit_jump();
4633a7c4 1130 /* NOTREACHED */
1131 case 3:
1132 if (restartop) {
1133 op = restartop;
1134 restartop = 0;
1135 goto restart;
1136 }
1137 stack_sp = stack_base + oldmark;
1138 if (flags & G_ARRAY)
1139 retval = 0;
1140 else {
1141 retval = 1;
1142 *++stack_sp = &sv_undef;
1143 }
1144 goto cleanup;
1145 }
1146
1147 if (op == (OP*)&myop)
1148 op = pp_entereval();
1149 if (op)
ab821d7f 1150 runops();
4633a7c4 1151 retval = stack_sp - (stack_base + oldmark);
6e72f9df 1152 if (!(flags & G_KEEPERR))
4633a7c4 1153 sv_setpv(GvSV(errgv),"");
1154
1155 cleanup:
a5f75d66 1156 Copy(oldtop, top_env, 1, Sigjmp_buf);
4633a7c4 1157 if (flags & G_DISCARD) {
1158 stack_sp = stack_base + oldmark;
1159 retval = 0;
1160 FREETMPS;
1161 LEAVE;
1162 }
1163 return retval;
1164}
1165
1166/* Require a module. */
1167
1168void
1169perl_require_pv(pv)
1170char* pv;
1171{
1172 SV* sv = sv_newmortal();
1173 sv_setpv(sv, "require '");
1174 sv_catpv(sv, pv);
1175 sv_catpv(sv, "'");
1176 perl_eval_sv(sv, G_DISCARD);
79072805 1177}
1178
79072805 1179void
79072805 1180magicname(sym,name,namlen)
1181char *sym;
1182char *name;
1183I32 namlen;
1184{
1185 register GV *gv;
1186
85e6fe83 1187 if (gv = gv_fetchpv(sym,TRUE, SVt_PV))
79072805 1188 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
1189}
1190
ab821d7f 1191static void
1a30305b 1192usage(name) /* XXX move this out into a module ? */
4633a7c4 1193char *name;
1194{
ab821d7f 1195 /* This message really ought to be max 23 lines.
1196 * Removed -h because the user already knows that opton. Others? */
1197 printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name);
4633a7c4 1198 printf("\n -0[octal] specify record separator (\\0, if no argument)");
ab821d7f 1199 printf("\n -a autosplit mode with -n or -p (splits $_ into @F)");
4633a7c4 1200 printf("\n -c check syntax only (runs BEGIN and END blocks)");
1a30305b 1201 printf("\n -d[:debugger] run scripts under debugger");
4633a7c4 1202 printf("\n -D[number/list] set debugging flags (argument is a bit mask or flags)");
ab821d7f 1203 printf("\n -e 'command' one line of script. Several -e's allowed. Omit [programfile].");
1204 printf("\n -F/pattern/ split() pattern for autosplit (-a). The //'s are optional.");
4633a7c4 1205 printf("\n -i[extension] edit <> files in place (make backup if extension supplied)");
ab821d7f 1206 printf("\n -Idirectory specify @INC/#include directory (may be used more then once)");
4633a7c4 1207 printf("\n -l[octal] enable line ending processing, specifies line teminator");
ab821d7f 1208 printf("\n -[mM][-]module.. executes `use/no module...' before executing your script.");
4633a7c4 1209 printf("\n -n assume 'while (<>) { ... }' loop arround your script");
1210 printf("\n -p assume loop like -n but print line also like sed");
1211 printf("\n -P run script through C preprocessor before compilation");
4633a7c4 1212 printf("\n -s enable some switch parsing for switches after script name");
1213 printf("\n -S look for the script using PATH environment variable");
1214 printf("\n -T turn on tainting checks");
1215 printf("\n -u dump core after parsing script");
1216 printf("\n -U allow unsafe operations");
1217 printf("\n -v print version number and patchlevel of perl");
1a30305b 1218 printf("\n -V[:variable] print perl configuration information");
ab821d7f 1219 printf("\n -w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT.");
4633a7c4 1220 printf("\n -x[directory] strip off text before #!perl line and perhaps cd to directory\n");
1221}
1222
79072805 1223/* This routine handles any switches that can be given during run */
1224
1225char *
1226moreswitches(s)
1227char *s;
1228{
1229 I32 numlen;
c07a80fd 1230 U32 rschar;
79072805 1231
1232 switch (*s) {
1233 case '0':
c07a80fd 1234 rschar = scan_oct(s, 4, &numlen);
1235 SvREFCNT_dec(nrs);
1236 if (rschar & ~((U8)~0))
1237 nrs = &sv_undef;
1238 else if (!rschar && numlen >= 2)
1239 nrs = newSVpv("", 0);
1240 else {
1241 char ch = rschar;
1242 nrs = newSVpv(&ch, 1);
79072805 1243 }
1244 return s + numlen;
2304df62 1245 case 'F':
1246 minus_F = TRUE;
a0d0e21e 1247 splitstr = savepv(s + 1);
2304df62 1248 s += strlen(s);
1249 return s;
79072805 1250 case 'a':
1251 minus_a = TRUE;
1252 s++;
1253 return s;
1254 case 'c':
1255 minus_c = TRUE;
1256 s++;
1257 return s;
1258 case 'd':
bbce6d69 1259 forbid_setid("-d");
4633a7c4 1260 s++;
c07a80fd 1261 if (*s == ':' || *s == '=') {
4633a7c4 1262 sprintf(buf, "use Devel::%s;", ++s);
1263 s += strlen(s);
1264 my_setenv("PERL5DB",buf);
1265 }
a0d0e21e 1266 if (!perldb) {
1267 perldb = TRUE;
1268 init_debugger();
1269 }
79072805 1270 return s;
1271 case 'D':
1272#ifdef DEBUGGING
bbce6d69 1273 forbid_setid("-D");
79072805 1274 if (isALPHA(s[1])) {
8990e307 1275 static char debopts[] = "psltocPmfrxuLHXD";
79072805 1276 char *d;
1277
93a17b20 1278 for (s++; *s && (d = strchr(debopts,*s)); s++)
79072805 1279 debug |= 1 << (d - debopts);
1280 }
1281 else {
1282 debug = atoi(s+1);
1283 for (s++; isDIGIT(*s); s++) ;
1284 }
8990e307 1285 debug |= 0x80000000;
79072805 1286#else
1287 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
a0d0e21e 1288 for (s++; isALNUM(*s); s++) ;
79072805 1289#endif
1290 /*SUPPRESS 530*/
1291 return s;
4633a7c4 1292 case 'h':
1293 usage(origargv[0]);
1294 exit(0);
79072805 1295 case 'i':
1296 if (inplace)
1297 Safefree(inplace);
a0d0e21e 1298 inplace = savepv(s+1);
79072805 1299 /*SUPPRESS 530*/
1300 for (s = inplace; *s && !isSPACE(*s); s++) ;
1301 *s = '\0';
1302 break;
1303 case 'I':
bbce6d69 1304 forbid_setid("-I");
79072805 1305 if (*++s) {
774d564b 1306 char *e, *p;
748a9306 1307 for (e = s; *e && !isSPACE(*e); e++) ;
774d564b 1308 p = savepvn(s, e-s);
1309 incpush(p, TRUE);
1310 Safefree(p);
748a9306 1311 if (*e)
1312 return e;
79072805 1313 }
1314 else
463ee0b2 1315 croak("No space allowed after -I");
79072805 1316 break;
1317 case 'l':
1318 minus_l = TRUE;
1319 s++;
a0d0e21e 1320 if (ors)
1321 Safefree(ors);
79072805 1322 if (isDIGIT(*s)) {
a0d0e21e 1323 ors = savepv("\n");
79072805 1324 orslen = 1;
1325 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
1326 s += numlen;
1327 }
1328 else {
c07a80fd 1329 if (RsPARA(nrs)) {
6e72f9df 1330 ors = "\n\n";
c07a80fd 1331 orslen = 2;
1332 }
1333 else
1334 ors = SvPV(nrs, orslen);
6e72f9df 1335 ors = savepvn(ors, orslen);
79072805 1336 }
1337 return s;
1a30305b 1338 case 'M':
bbce6d69 1339 forbid_setid("-M"); /* XXX ? */
1a30305b 1340 /* FALL THROUGH */
1341 case 'm':
bbce6d69 1342 forbid_setid("-m"); /* XXX ? */
1a30305b 1343 if (*++s) {
a5f75d66 1344 char *start;
1345 char *use = "use ";
1346 /* -M-foo == 'no foo' */
1347 if (*s == '-') { use = "no "; ++s; }
1348 Sv = newSVpv(use,0);
1349 start = s;
1a30305b 1350 /* We allow -M'Module qw(Foo Bar)' */
c07a80fd 1351 while(isALNUM(*s) || *s==':') ++s;
1352 if (*s != '=') {
1353 sv_catpv(Sv, start);
1354 if (*(start-1) == 'm') {
1355 if (*s != '\0')
1356 croak("Can't use '%c' after -mname", *s);
1357 sv_catpv( Sv, " ()");
1358 }
1359 } else {
1360 sv_catpvn(Sv, start, s-start);
a5f75d66 1361 sv_catpv(Sv, " split(/,/,q{");
c07a80fd 1362 sv_catpv(Sv, ++s);
a5f75d66 1363 sv_catpv(Sv, "})");
c07a80fd 1364 }
1a30305b 1365 s += strlen(s);
c07a80fd 1366 if (preambleav == NULL)
1367 preambleav = newAV();
1368 av_push(preambleav, Sv);
1a30305b 1369 }
1370 else
1371 croak("No space allowed after -%c", *(s-1));
1372 return s;
79072805 1373 case 'n':
1374 minus_n = TRUE;
1375 s++;
1376 return s;
1377 case 'p':
1378 minus_p = TRUE;
1379 s++;
1380 return s;
1381 case 's':
bbce6d69 1382 forbid_setid("-s");
79072805 1383 doswitches = TRUE;
1384 s++;
1385 return s;
463ee0b2 1386 case 'T':
f86702cc 1387 if (!tainting)
1388 croak("Too late for \"-T\" option (try putting it first)");
463ee0b2 1389 s++;
1390 return s;
79072805 1391 case 'u':
1392 do_undump = TRUE;
1393 s++;
1394 return s;
1395 case 'U':
1396 unsafe = TRUE;
1397 s++;
1398 return s;
1399 case 'v':
a5f75d66 1400#if defined(SUBVERSION) && SUBVERSION > 0
1401 printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION);
1402#else
1403 printf("\nThis is perl, version %s",patchlevel);
1404#endif
1a30305b 1405
44a8e56a 1406 printf("\n\nCopyright 1987-1997, Larry Wall\n");
79072805 1407#ifdef MSDOS
55497cff 1408 printf("\n\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
1409#endif
1410#ifdef DJGPP
1411 printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n");
4633a7c4 1412#endif
79072805 1413#ifdef OS2
5dd60ef7 1414 printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
760ac839 1415 "Version 5 port Copyright (c) 1994-1996, Andreas Kaiser, Ilya Zakharevich\n");
79072805 1416#endif
79072805 1417#ifdef atarist
760ac839 1418 printf("atariST series port, ++jrb bammi@cadence.com\n");
79072805 1419#endif
760ac839 1420 printf("\n\
79072805 1421Perl may be copied only under the terms of either the Artistic License or the\n\
760ac839 1422GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n");
79072805 1423 exit(0);
1424 case 'w':
1425 dowarn = TRUE;
1426 s++;
1427 return s;
a0d0e21e 1428 case '*':
79072805 1429 case ' ':
1430 if (s[1] == '-') /* Additional switches on #! line. */
1431 return s+2;
1432 break;
a0d0e21e 1433 case '-':
79072805 1434 case 0:
1435 case '\n':
1436 case '\t':
1437 break;
a0d0e21e 1438 case 'P':
1439 if (preprocess)
1440 return s+1;
833d3f25 1441#ifdef ALTERNATE_SHEBANG
1442 case 'S': /* OS/2 needs -S on "extproc" line. */
1443 break;
1444#endif
a0d0e21e 1445 /* FALL THROUGH */
79072805 1446 default:
a0d0e21e 1447 croak("Can't emulate -%.1s on #! line",s);
79072805 1448 }
1449 return Nullch;
1450}
1451
1452/* compliments of Tom Christiansen */
1453
1454/* unexec() can be found in the Gnu emacs distribution */
1455
1456void
1457my_unexec()
1458{
1459#ifdef UNEXEC
1460 int status;
1461 extern int etext;
1462
1463 sprintf (buf, "%s.perldump", origfilename);
1464 sprintf (tokenbuf, "%s/perl", BIN);
1465
1466 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
1467 if (status)
760ac839 1468 PerlIO_printf(PerlIO_stderr(), "unexec of %s into %s failed!\n", tokenbuf, buf);
a0d0e21e 1469 exit(status);
79072805 1470#else
a5f75d66 1471# ifdef VMS
1472# include <lib$routines.h>
1473 lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */
1474#else
79072805 1475 ABORT(); /* for use with undump */
1476#endif
a5f75d66 1477#endif
79072805 1478}
1479
1480static void
1481init_main_stash()
1482{
463ee0b2 1483 GV *gv;
6e72f9df 1484
1485 /* Note that strtab is a rather special HV. Assumptions are made
1486 about not iterating on it, and not adding tie magic to it.
1487 It is properly deallocated in perl_destruct() */
1488 strtab = newHV();
1489 HvSHAREKEYS_off(strtab); /* mandatory */
1490 Newz(506,((XPVHV*)SvANY(strtab))->xhv_array,
1491 sizeof(HE*) * (((XPVHV*)SvANY(strtab))->xhv_max + 1), char);
1492
463ee0b2 1493 curstash = defstash = newHV();
79072805 1494 curstname = newSVpv("main",4);
adbc6bb1 1495 gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1496 SvREFCNT_dec(GvHV(gv));
1497 GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
463ee0b2 1498 SvREADONLY_on(gv);
a0d0e21e 1499 HvNAME(defstash) = savepv("main");
85e6fe83 1500 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
a5f75d66 1501 GvMULTI_on(incgv);
a0d0e21e 1502 defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
4633a7c4 1503 errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
a5f75d66 1504 GvMULTI_on(errgv);
552a7a9b 1505 sv_setpvn(GvSV(errgv), "", 0);
8990e307 1506 curstash = defstash;
1507 compiling.cop_stash = defstash;
adbc6bb1 1508 debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
4633a7c4 1509 /* We must init $/ before switches are processed. */
1510 sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1);
79072805 1511}
1512
a0d0e21e 1513#ifdef CAN_PROTOTYPE
1514static void
1515open_script(char *scriptname, bool dosearch, SV *sv)
1516#else
79072805 1517static void
1518open_script(scriptname,dosearch,sv)
1519char *scriptname;
1520bool dosearch;
1521SV *sv;
a0d0e21e 1522#endif
79072805 1523{
1524 char *xfound = Nullch;
1525 char *xfailed = Nullch;
1526 register char *s;
1527 I32 len;
a38d6535 1528 int retval;
1529#if defined(DOSISH) && !defined(OS2) && !defined(atarist)
1530#define SEARCH_EXTS ".bat", ".cmd", NULL
1531#endif
ab821d7f 1532#ifdef VMS
1533# define SEARCH_EXTS ".pl", ".com", NULL
1534#endif
a38d6535 1535 /* additional extensions to try in each dir if scriptname not found */
1536#ifdef SEARCH_EXTS
1537 char *ext[] = { SEARCH_EXTS };
1538 int extidx = (strchr(scriptname,'.')) ? -1 : 0; /* has ext already */
1539#endif
79072805 1540
c07a80fd 1541#ifdef VMS
6e72f9df 1542 if (dosearch) {
1543 int hasdir, idx = 0, deftypes = 1;
1544
1545 hasdir = (strpbrk(scriptname,":[</") != Nullch) ;
1546 /* The first time through, just add SEARCH_EXTS to whatever we
1547 * already have, so we can check for default file types. */
1548 while (deftypes || (!hasdir && my_trnlnm("DCL$PATH",tokenbuf,idx++)) ) {
1549 if (deftypes) { deftypes = 0; *tokenbuf = '\0'; }
c07a80fd 1550 strcat(tokenbuf,scriptname);
1551#else /* !VMS */
93a17b20 1552 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
79072805 1553
1554 bufend = s + strlen(s);
1555 while (*s) {
1556#ifndef DOSISH
1557 s = cpytill(tokenbuf,s,bufend,':',&len);
1558#else
1559#ifdef atarist
1560 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
1561 tokenbuf[len] = '\0';
1562#else
1563 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
1564 tokenbuf[len] = '\0';
1565#endif
1566#endif
1567 if (*s)
1568 s++;
1569#ifndef DOSISH
1570 if (len && tokenbuf[len-1] != '/')
1571#else
1572#ifdef atarist
1573 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
1574#else
1575 if (len && tokenbuf[len-1] != '\\')
1576#endif
1577#endif
1578 (void)strcat(tokenbuf+len,"/");
1579 (void)strcat(tokenbuf+len,scriptname);
c07a80fd 1580#endif /* !VMS */
a38d6535 1581
1582#ifdef SEARCH_EXTS
1583 len = strlen(tokenbuf);
1584 if (extidx > 0) /* reset after previous loop */
1585 extidx = 0;
1586 do {
1587#endif
760ac839 1588 DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tokenbuf));
a38d6535 1589 retval = Stat(tokenbuf,&statbuf);
1590#ifdef SEARCH_EXTS
1591 } while ( retval < 0 /* not there */
1592 && extidx>=0 && ext[extidx] /* try an extension? */
1593 && strcpy(tokenbuf+len, ext[extidx++])
1594 );
1595#endif
1596 if (retval < 0)
79072805 1597 continue;
1598 if (S_ISREG(statbuf.st_mode)
1599 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
1600 xfound = tokenbuf; /* bingo! */
1601 break;
1602 }
1603 if (!xfailed)
a0d0e21e 1604 xfailed = savepv(tokenbuf);
79072805 1605 }
1606 if (!xfound)
463ee0b2 1607 croak("Can't execute %s", xfailed ? xfailed : scriptname );
79072805 1608 if (xfailed)
1609 Safefree(xfailed);
1610 scriptname = xfound;
1611 }
1612
96436eeb 1613 if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
1614 char *s = scriptname + 8;
1615 fdscript = atoi(s);
1616 while (isDIGIT(*s))
1617 s++;
1618 if (*s)
1619 scriptname = s + 1;
1620 }
1621 else
1622 fdscript = -1;
ab821d7f 1623 origfilename = savepv(e_tmpname ? "-e" : scriptname);
79072805 1624 curcop->cop_filegv = gv_fetchfile(origfilename);
1625 if (strEQ(origfilename,"-"))
1626 scriptname = "";
96436eeb 1627 if (fdscript >= 0) {
760ac839 1628 rsfp = PerlIO_fdopen(fdscript,"r");
96436eeb 1629#if defined(HAS_FCNTL) && defined(F_SETFD)
7aa04957 1630 if (rsfp)
1631 fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
96436eeb 1632#endif
1633 }
1634 else if (preprocess) {
79072805 1635 char *cpp = CPPSTDIN;
1636
1637 if (strEQ(cpp,"cppstdin"))
1638 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
1639 else
1640 sprintf(tokenbuf, "%s", cpp);
1641 sv_catpv(sv,"-I");
fed7345c 1642 sv_catpv(sv,PRIVLIB_EXP);
79072805 1643#ifdef MSDOS
1644 (void)sprintf(buf, "\
1645sed %s -e \"/^[^#]/b\" \
1646 -e \"/^#[ ]*include[ ]/b\" \
1647 -e \"/^#[ ]*define[ ]/b\" \
1648 -e \"/^#[ ]*if[ ]/b\" \
1649 -e \"/^#[ ]*ifdef[ ]/b\" \
1650 -e \"/^#[ ]*ifndef[ ]/b\" \
1651 -e \"/^#[ ]*else/b\" \
1652 -e \"/^#[ ]*elif[ ]/b\" \
1653 -e \"/^#[ ]*undef[ ]/b\" \
1654 -e \"/^#[ ]*endif/b\" \
1655 -e \"s/^#.*//\" \
1656 %s | %s -C %s %s",
1657 (doextract ? "-e \"1,/^#/d\n\"" : ""),
1658#else
1659 (void)sprintf(buf, "\
1660%s %s -e '/^[^#]/b' \
1661 -e '/^#[ ]*include[ ]/b' \
1662 -e '/^#[ ]*define[ ]/b' \
1663 -e '/^#[ ]*if[ ]/b' \
1664 -e '/^#[ ]*ifdef[ ]/b' \
1665 -e '/^#[ ]*ifndef[ ]/b' \
1666 -e '/^#[ ]*else/b' \
1667 -e '/^#[ ]*elif[ ]/b' \
1668 -e '/^#[ ]*undef[ ]/b' \
1669 -e '/^#[ ]*endif/b' \
1670 -e 's/^[ ]*#.*//' \
1671 %s | %s -C %s %s",
1672#ifdef LOC_SED
1673 LOC_SED,
1674#else
1675 "sed",
1676#endif
1677 (doextract ? "-e '1,/^#/d\n'" : ""),
1678#endif
463ee0b2 1679 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
79072805 1680 doextract = FALSE;
1681#ifdef IAMSUID /* actually, this is caught earlier */
1682 if (euid != uid && !euid) { /* if running suidperl */
1683#ifdef HAS_SETEUID
1684 (void)seteuid(uid); /* musn't stay setuid root */
1685#else
1686#ifdef HAS_SETREUID
85e6fe83 1687 (void)setreuid((Uid_t)-1, uid);
1688#else
1689#ifdef HAS_SETRESUID
1690 (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
79072805 1691#else
1692 setuid(uid);
1693#endif
1694#endif
85e6fe83 1695#endif
79072805 1696 if (geteuid() != uid)
463ee0b2 1697 croak("Can't do seteuid!\n");
79072805 1698 }
1699#endif /* IAMSUID */
1700 rsfp = my_popen(buf,"r");
1701 }
1702 else if (!*scriptname) {
bbce6d69 1703 forbid_setid("program input from stdin");
760ac839 1704 rsfp = PerlIO_stdin();
79072805 1705 }
96436eeb 1706 else {
760ac839 1707 rsfp = PerlIO_open(scriptname,"r");
96436eeb 1708#if defined(HAS_FCNTL) && defined(F_SETFD)
7aa04957 1709 if (rsfp)
1710 fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
96436eeb 1711#endif
1712 }
5dd60ef7 1713 if (e_tmpname) {
1714 e_fp = rsfp;
1715 }
7aa04957 1716 if (!rsfp) {
13281fa4 1717#ifdef DOSUID
a687059c 1718#ifndef IAMSUID /* in case script is not readable before setuid */
a0d0e21e 1719 if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
13281fa4 1720 statbuf.st_mode & (S_ISUID|S_ISGID)) {
27e2fb84 1721 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1722 execv(buf, origargv); /* try again */
463ee0b2 1723 croak("Can't do setuid\n");
13281fa4 1724 }
1725#endif
1726#endif
463ee0b2 1727 croak("Can't open perl script \"%s\": %s\n",
2304df62 1728 SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
13281fa4 1729 }
79072805 1730}
8d063cd8 1731
79072805 1732static void
96436eeb 1733validate_suid(validarg, scriptname)
79072805 1734char *validarg;
96436eeb 1735char *scriptname;
79072805 1736{
96436eeb 1737 int which;
1738
13281fa4 1739 /* do we need to emulate setuid on scripts? */
1740
1741 /* This code is for those BSD systems that have setuid #! scripts disabled
1742 * in the kernel because of a security problem. Merely defining DOSUID
1743 * in perl will not fix that problem, but if you have disabled setuid
1744 * scripts in the kernel, this will attempt to emulate setuid and setgid
1745 * on scripts that have those now-otherwise-useless bits set. The setuid
27e2fb84 1746 * root version must be called suidperl or sperlN.NNN. If regular perl
1747 * discovers that it has opened a setuid script, it calls suidperl with
1748 * the same argv that it had. If suidperl finds that the script it has
1749 * just opened is NOT setuid root, it sets the effective uid back to the
1750 * uid. We don't just make perl setuid root because that loses the
1751 * effective uid we had before invoking perl, if it was different from the
1752 * uid.
13281fa4 1753 *
1754 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
1755 * be defined in suidperl only. suidperl must be setuid root. The
1756 * Configure script will set this up for you if you want it.
1757 */
a687059c 1758
13281fa4 1759#ifdef DOSUID
6e72f9df 1760 char *s, *s2;
a0d0e21e 1761
760ac839 1762 if (Fstat(PerlIO_fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
463ee0b2 1763 croak("Can't stat script \"%s\"",origfilename);
96436eeb 1764 if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) {
79072805 1765 I32 len;
13281fa4 1766
a687059c 1767#ifdef IAMSUID
fe14fcc3 1768#ifndef HAS_SETREUID
a687059c 1769 /* On this access check to make sure the directories are readable,
1770 * there is actually a small window that the user could use to make
1771 * filename point to an accessible directory. So there is a faint
1772 * chance that someone could execute a setuid script down in a
1773 * non-accessible directory. I don't know what to do about that.
1774 * But I don't think it's too important. The manual lies when
1775 * it says access() is useful in setuid programs.
1776 */
463ee0b2 1777 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
1778 croak("Permission denied");
a687059c 1779#else
1780 /* If we can swap euid and uid, then we can determine access rights
1781 * with a simple stat of the file, and then compare device and
1782 * inode to make sure we did stat() on the same file we opened.
1783 * Then we just have to make sure he or she can execute it.
1784 */
1785 {
1786 struct stat tmpstatbuf;
1787
85e6fe83 1788 if (
1789#ifdef HAS_SETREUID
1790 setreuid(euid,uid) < 0
a0d0e21e 1791#else
1792# if HAS_SETRESUID
85e6fe83 1793 setresuid(euid,uid,(Uid_t)-1) < 0
a0d0e21e 1794# endif
85e6fe83 1795#endif
1796 || getuid() != euid || geteuid() != uid)
463ee0b2 1797 croak("Can't swap uid and euid"); /* really paranoid */
a0d0e21e 1798 if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
463ee0b2 1799 croak("Permission denied"); /* testing full pathname here */
a687059c 1800 if (tmpstatbuf.st_dev != statbuf.st_dev ||
1801 tmpstatbuf.st_ino != statbuf.st_ino) {
760ac839 1802 (void)PerlIO_close(rsfp);
79072805 1803 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
760ac839 1804 PerlIO_printf(rsfp,
ff0cee69 1805"User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\
1806(Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n",
1807 (long)uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino,
1808 (long)statbuf.st_dev, (long)statbuf.st_ino,
463ee0b2 1809 SvPVX(GvSV(curcop->cop_filegv)),
ff0cee69 1810 (long)statbuf.st_uid, (long)statbuf.st_gid);
79072805 1811 (void)my_pclose(rsfp);
a687059c 1812 }
463ee0b2 1813 croak("Permission denied\n");
a687059c 1814 }
85e6fe83 1815 if (
1816#ifdef HAS_SETREUID
1817 setreuid(uid,euid) < 0
a0d0e21e 1818#else
1819# if defined(HAS_SETRESUID)
85e6fe83 1820 setresuid(uid,euid,(Uid_t)-1) < 0
a0d0e21e 1821# endif
85e6fe83 1822#endif
1823 || getuid() != uid || geteuid() != euid)
463ee0b2 1824 croak("Can't reswap uid and euid");
27e2fb84 1825 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
463ee0b2 1826 croak("Permission denied\n");
a687059c 1827 }
fe14fcc3 1828#endif /* HAS_SETREUID */
a687059c 1829#endif /* IAMSUID */
1830
27e2fb84 1831 if (!S_ISREG(statbuf.st_mode))
463ee0b2 1832 croak("Permission denied");
27e2fb84 1833 if (statbuf.st_mode & S_IWOTH)
463ee0b2 1834 croak("Setuid/gid script is writable by world");
13281fa4 1835 doswitches = FALSE; /* -s is insecure in suid */
79072805 1836 curcop->cop_line++;
760ac839 1837 if (sv_gets(linestr, rsfp, 0) == Nullch ||
1838 strnNE(SvPV(linestr,na),"#!",2) ) /* required even on Sys V */
463ee0b2 1839 croak("No #! line");
760ac839 1840 s = SvPV(linestr,na)+2;
663a0e37 1841 if (*s == ' ') s++;
45d8adaa 1842 while (!isSPACE(*s)) s++;
760ac839 1843 for (s2 = s; (s2 > SvPV(linestr,na)+2 &&
6e72f9df 1844 (isDIGIT(s2[-1]) || strchr("._-", s2[-1]))); s2--) ;
1845 if (strnNE(s2-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
463ee0b2 1846 croak("Not a perl script");
a687059c 1847 while (*s == ' ' || *s == '\t') s++;
13281fa4 1848 /*
1849 * #! arg must be what we saw above. They can invoke it by
1850 * mentioning suidperl explicitly, but they may not add any strange
1851 * arguments beyond what #! says if they do invoke suidperl that way.
1852 */
1853 len = strlen(validarg);
1854 if (strEQ(validarg," PHOOEY ") ||
45d8adaa 1855 strnNE(s,validarg,len) || !isSPACE(s[len]))
463ee0b2 1856 croak("Args must match #! line");
a687059c 1857
1858#ifndef IAMSUID
1859 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1860 euid == statbuf.st_uid)
1861 if (!do_undump)
463ee0b2 1862 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c 1863FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1864#endif /* IAMSUID */
13281fa4 1865
1866 if (euid) { /* oops, we're not the setuid root perl */
760ac839 1867 (void)PerlIO_close(rsfp);
13281fa4 1868#ifndef IAMSUID
27e2fb84 1869 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1870 execv(buf, origargv); /* try again */
13281fa4 1871#endif
463ee0b2 1872 croak("Can't do setuid\n");
13281fa4 1873 }
1874
83025b21 1875 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
fe14fcc3 1876#ifdef HAS_SETEGID
a687059c 1877 (void)setegid(statbuf.st_gid);
1878#else
fe14fcc3 1879#ifdef HAS_SETREGID
85e6fe83 1880 (void)setregid((Gid_t)-1,statbuf.st_gid);
1881#else
1882#ifdef HAS_SETRESGID
1883 (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
a687059c 1884#else
1885 setgid(statbuf.st_gid);
1886#endif
1887#endif
85e6fe83 1888#endif
83025b21 1889 if (getegid() != statbuf.st_gid)
463ee0b2 1890 croak("Can't do setegid!\n");
83025b21 1891 }
a687059c 1892 if (statbuf.st_mode & S_ISUID) {
1893 if (statbuf.st_uid != euid)
fe14fcc3 1894#ifdef HAS_SETEUID
a687059c 1895 (void)seteuid(statbuf.st_uid); /* all that for this */
1896#else
fe14fcc3 1897#ifdef HAS_SETREUID
85e6fe83 1898 (void)setreuid((Uid_t)-1,statbuf.st_uid);
1899#else
1900#ifdef HAS_SETRESUID
1901 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
a687059c 1902#else
1903 setuid(statbuf.st_uid);
1904#endif
1905#endif
85e6fe83 1906#endif
83025b21 1907 if (geteuid() != statbuf.st_uid)
463ee0b2 1908 croak("Can't do seteuid!\n");
a687059c 1909 }
83025b21 1910 else if (uid) { /* oops, mustn't run as root */
fe14fcc3 1911#ifdef HAS_SETEUID
85e6fe83 1912 (void)seteuid((Uid_t)uid);
a687059c 1913#else
fe14fcc3 1914#ifdef HAS_SETREUID
85e6fe83 1915 (void)setreuid((Uid_t)-1,(Uid_t)uid);
a687059c 1916#else
85e6fe83 1917#ifdef HAS_SETRESUID
1918 (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
1919#else
1920 setuid((Uid_t)uid);
1921#endif
a687059c 1922#endif
1923#endif
83025b21 1924 if (geteuid() != uid)
463ee0b2 1925 croak("Can't do seteuid!\n");
83025b21 1926 }
748a9306 1927 init_ids();
27e2fb84 1928 if (!cando(S_IXUSR,TRUE,&statbuf))
463ee0b2 1929 croak("Permission denied\n"); /* they can't do this */
13281fa4 1930 }
1931#ifdef IAMSUID
1932 else if (preprocess)
463ee0b2 1933 croak("-P not allowed for setuid/setgid script\n");
96436eeb 1934 else if (fdscript >= 0)
1935 croak("fd script not allowed in suidperl\n");
13281fa4 1936 else
463ee0b2 1937 croak("Script is not setuid/setgid in suidperl\n");
96436eeb 1938
1939 /* We absolutely must clear out any saved ids here, so we */
1940 /* exec the real perl, substituting fd script for scriptname. */
1941 /* (We pass script name as "subdir" of fd, which perl will grok.) */
760ac839 1942 PerlIO_rewind(rsfp);
1943 lseek(PerlIO_fileno(rsfp),(Off_t)0,0); /* just in case rewind didn't */
96436eeb 1944 for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ;
1945 if (!origargv[which])
1946 croak("Permission denied");
760ac839 1947 (void)sprintf(buf, "/dev/fd/%d/%.127s", PerlIO_fileno(rsfp), origargv[which]);
96436eeb 1948 origargv[which] = buf;
1949
1950#if defined(HAS_FCNTL) && defined(F_SETFD)
760ac839 1951 fcntl(PerlIO_fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */
96436eeb 1952#endif
1953
1954 (void)sprintf(tokenbuf, "%s/perl%s", BIN, patchlevel);
1955 execv(tokenbuf, origargv); /* try again */
1956 croak("Can't do setuid\n");
13281fa4 1957#endif /* IAMSUID */
a687059c 1958#else /* !DOSUID */
a687059c 1959 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1960#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
760ac839 1961 Fstat(PerlIO_fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
a687059c 1962 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1963 ||
1964 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1965 )
1966 if (!do_undump)
463ee0b2 1967 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c 1968FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1969#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1970 /* not set-id, must be wrapped */
a687059c 1971 }
13281fa4 1972#endif /* DOSUID */
79072805 1973}
13281fa4 1974
79072805 1975static void
1976find_beginning()
1977{
6e72f9df 1978 register char *s, *s2;
33b78306 1979
1980 /* skip forward in input to the real script? */
1981
bbce6d69 1982 forbid_setid("-x");
33b78306 1983 while (doextract) {
79072805 1984 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
463ee0b2 1985 croak("No Perl script found in input\n");
6e72f9df 1986 if (*s == '#' && s[1] == '!' && (s = instr(s,"perl"))) {
760ac839 1987 PerlIO_ungetc(rsfp, '\n'); /* to keep line count right */
33b78306 1988 doextract = FALSE;
6e72f9df 1989 while (*s && !(isSPACE (*s) || *s == '#')) s++;
1990 s2 = s;
1991 while (*s == ' ' || *s == '\t') s++;
1992 if (*s++ == '-') {
1993 while (isDIGIT(s2[-1]) || strchr("-._", s2[-1])) s2--;
1994 if (strnEQ(s2-4,"perl",4))
1995 /*SUPPRESS 530*/
1996 while (s = moreswitches(s)) ;
33b78306 1997 }
79072805 1998 if (cddir && chdir(cddir) < 0)
463ee0b2 1999 croak("Can't chdir to %s",cddir);
83025b21 2000 }
2001 }
2002}
2003
79072805 2004static void
748a9306 2005init_ids()
352d5a3a 2006{
748a9306 2007 uid = (int)getuid();
2008 euid = (int)geteuid();
2009 gid = (int)getgid();
2010 egid = (int)getegid();
2011#ifdef VMS
2012 uid |= gid << 16;
2013 euid |= egid << 16;
2014#endif
4633a7c4 2015 tainting |= (uid && (euid != uid || egid != gid));
748a9306 2016}
79072805 2017
748a9306 2018static void
bbce6d69 2019forbid_setid(s)
2020char *s;
2021{
2022 if (euid != uid)
2023 croak("No %s allowed while running setuid", s);
2024 if (egid != gid)
2025 croak("No %s allowed while running setgid", s);
2026}
2027
2028static void
748a9306 2029init_debugger()
2030{
79072805 2031 curstash = debstash;
748a9306 2032 dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
79072805 2033 AvREAL_off(dbargs);
a0d0e21e 2034 DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
2035 DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
748a9306 2036 DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
2037 DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
c07a80fd 2038 sv_setiv(DBsingle, 0);
748a9306 2039 DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
c07a80fd 2040 sv_setiv(DBtrace, 0);
748a9306 2041 DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
c07a80fd 2042 sv_setiv(DBsignal, 0);
79072805 2043 curstash = defstash;
352d5a3a 2044}
2045
79072805 2046static void
8990e307 2047init_stacks()
79072805 2048{
6e72f9df 2049 curstack = newAV();
5f05dabc 2050 mainstack = curstack; /* remember in case we switch stacks */
2051 AvREAL_off(curstack); /* not a real array */
6e72f9df 2052 av_extend(curstack,127);
79072805 2053
6e72f9df 2054 stack_base = AvARRAY(curstack);
79072805 2055 stack_sp = stack_base;
8990e307 2056 stack_max = stack_base + 127;
79072805 2057
5f05dabc 2058 cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */
2059 New(50,cxstack,cxstack_max + 1,CONTEXT);
2060 cxstack_ix = -1;
2061
2062 New(50,tmps_stack,128,SV*);
2063 tmps_ix = -1;
2064 tmps_max = 128;
2065
2066 DEBUG( {
2067 New(51,debname,128,char);
2068 New(52,debdelim,128,char);
2069 } )
2070
2071 /*
2072 * The following stacks almost certainly should be per-interpreter,
2073 * but for now they're not. XXX
2074 */
2075
6e72f9df 2076 if (markstack) {
2077 markstack_ptr = markstack;
2078 } else {
2079 New(54,markstack,64,I32);
2080 markstack_ptr = markstack;
2081 markstack_max = markstack + 64;
2082 }
79072805 2083
6e72f9df 2084 if (scopestack) {
2085 scopestack_ix = 0;
2086 } else {
2087 New(54,scopestack,32,I32);
2088 scopestack_ix = 0;
2089 scopestack_max = 32;
2090 }
79072805 2091
6e72f9df 2092 if (savestack) {
2093 savestack_ix = 0;
2094 } else {
2095 New(54,savestack,128,ANY);
2096 savestack_ix = 0;
2097 savestack_max = 128;
2098 }
79072805 2099
6e72f9df 2100 if (retstack) {
2101 retstack_ix = 0;
2102 } else {
2103 New(54,retstack,16,OP*);
2104 retstack_ix = 0;
2105 retstack_max = 16;
5f05dabc 2106 }
378cc40b 2107}
33b78306 2108
6e72f9df 2109static void
2110nuke_stacks()
2111{
2112 Safefree(cxstack);
2113 Safefree(tmps_stack);
5f05dabc 2114 DEBUG( {
2115 Safefree(debname);
2116 Safefree(debdelim);
2117 } )
6e72f9df 2118}
2119
760ac839 2120static PerlIO *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
7aa04957 2121
79072805 2122static void
8990e307 2123init_lexer()
2124{
a0d0e21e 2125 tmpfp = rsfp;
8990e307 2126 lex_start(linestr);
2127 rsfp = tmpfp;
2128 subname = newSVpv("main",4);
2129}
2130
2131static void
79072805 2132init_predump_symbols()
45d8adaa 2133{
93a17b20 2134 GV *tmpgv;
a0d0e21e 2135 GV *othergv;
79072805 2136
85e6fe83 2137 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
79072805 2138
85e6fe83 2139 stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
a5f75d66 2140 GvMULTI_on(stdingv);
760ac839 2141 IoIFP(GvIOp(stdingv)) = PerlIO_stdin();
adbc6bb1 2142 tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
a5f75d66 2143 GvMULTI_on(tmpgv);
a0d0e21e 2144 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
79072805 2145
85e6fe83 2146 tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
a5f75d66 2147 GvMULTI_on(tmpgv);
760ac839 2148 IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = PerlIO_stdout();
4633a7c4 2149 setdefout(tmpgv);
adbc6bb1 2150 tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
a5f75d66 2151 GvMULTI_on(tmpgv);
a0d0e21e 2152 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
79072805 2153
a0d0e21e 2154 othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
a5f75d66 2155 GvMULTI_on(othergv);
760ac839 2156 IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = PerlIO_stderr();
adbc6bb1 2157 tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
a5f75d66 2158 GvMULTI_on(tmpgv);
a0d0e21e 2159 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
79072805 2160
2161 statname = NEWSV(66,0); /* last filename we did stat on */
ab821d7f 2162
6e72f9df 2163 if (!osname)
2164 osname = savepv(OSNAME);
79072805 2165}
33b78306 2166
79072805 2167static void
2168init_postdump_symbols(argc,argv,env)
2169register int argc;
2170register char **argv;
2171register char **env;
33b78306 2172{
79072805 2173 char *s;
2174 SV *sv;
2175 GV* tmpgv;
fe14fcc3 2176
79072805 2177 argc--,argv++; /* skip name of script */
2178 if (doswitches) {
2179 for (; argc > 0 && **argv == '-'; argc--,argv++) {
2180 if (!argv[0][1])
2181 break;
2182 if (argv[0][1] == '-') {
2183 argc--,argv++;
2184 break;
2185 }
93a17b20 2186 if (s = strchr(argv[0], '=')) {
79072805 2187 *s++ = '\0';
85e6fe83 2188 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
79072805 2189 }
2190 else
85e6fe83 2191 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
fe14fcc3 2192 }
79072805 2193 }
2194 toptarget = NEWSV(0,0);
2195 sv_upgrade(toptarget, SVt_PVFM);
2196 sv_setpvn(toptarget, "", 0);
748a9306 2197 bodytarget = NEWSV(0,0);
79072805 2198 sv_upgrade(bodytarget, SVt_PVFM);
2199 sv_setpvn(bodytarget, "", 0);
2200 formtarget = bodytarget;
2201
bbce6d69 2202 TAINT;
85e6fe83 2203 if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
79072805 2204 sv_setpv(GvSV(tmpgv),origfilename);
2205 magicname("0", "0", 1);
2206 }
85e6fe83 2207 if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
79072805 2208 sv_setpv(GvSV(tmpgv),origargv[0]);
85e6fe83 2209 if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
a5f75d66 2210 GvMULTI_on(argvgv);
79072805 2211 (void)gv_AVadd(argvgv);
2212 av_clear(GvAVn(argvgv));
2213 for (; argc > 0; argc--,argv++) {
a0d0e21e 2214 av_push(GvAVn(argvgv),newSVpv(argv[0],0));
79072805 2215 }
2216 }
85e6fe83 2217 if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
79072805 2218 HV *hv;
a5f75d66 2219 GvMULTI_on(envgv);
79072805 2220 hv = GvHVn(envgv);
463ee0b2 2221 hv_clear(hv);
a0d0e21e 2222#ifndef VMS /* VMS doesn't have environ array */
4633a7c4 2223 /* Note that if the supplied env parameter is actually a copy
2224 of the global environ then it may now point to free'd memory
2225 if the environment has been modified since. To avoid this
2226 problem we treat env==NULL as meaning 'use the default'
2227 */
2228 if (!env)
2229 env = environ;
8990e307 2230 if (env != environ) {
79072805 2231 environ[0] = Nullch;
8990e307 2232 hv_magic(hv, envgv, 'E');
2233 }
79072805 2234 for (; *env; env++) {
93a17b20 2235 if (!(s = strchr(*env,'=')))
79072805 2236 continue;
2237 *s++ = '\0';
2238 sv = newSVpv(s--,0);
85e6fe83 2239 sv_magic(sv, sv, 'e', *env, s - *env);
79072805 2240 (void)hv_store(hv, *env, s - *env, sv, 0);
2241 *s = '=';
fe14fcc3 2242 }
4550b24a 2243#endif
2244#ifdef DYNAMIC_ENV_FETCH
2245 HvNAME(hv) = savepv(ENV_HV_NAME);
2246#endif
f511e57f 2247 hv_magic(hv, envgv, 'E');
79072805 2248 }
bbce6d69 2249 TAINT_NOT;
85e6fe83 2250 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
79072805 2251 sv_setiv(GvSV(tmpgv),(I32)getpid());
33b78306 2252}
34de22dd 2253
79072805 2254static void
2255init_perllib()
34de22dd 2256{
85e6fe83 2257 char *s;
2258 if (!tainting) {
552a7a9b 2259#ifndef VMS
85e6fe83 2260 s = getenv("PERL5LIB");
2261 if (s)
774d564b 2262 incpush(s, TRUE);
85e6fe83 2263 else
774d564b 2264 incpush(getenv("PERLLIB"), FALSE);
552a7a9b 2265#else /* VMS */
2266 /* Treat PERL5?LIB as a possible search list logical name -- the
2267 * "natural" VMS idiom for a Unix path string. We allow each
2268 * element to be a set of |-separated directories for compatibility.
2269 */
2270 char buf[256];
2271 int idx = 0;
2272 if (my_trnlnm("PERL5LIB",buf,0))
774d564b 2273 do { incpush(buf,TRUE); } while (my_trnlnm("PERL5LIB",buf,++idx));
552a7a9b 2274 else
774d564b 2275 while (my_trnlnm("PERLLIB",buf,idx++)) incpush(buf,FALSE);
552a7a9b 2276#endif /* VMS */
85e6fe83 2277 }
34de22dd 2278
df5cef82 2279/* Use the ~-expanded versions of APPLIB (undocumented),
2280 ARCHLIB PRIVLIB SITEARCH SITELIB and OLDARCHLIB
2281*/
4633a7c4 2282#ifdef APPLLIB_EXP
774d564b 2283 incpush(APPLLIB_EXP, FALSE);
16d20bd9 2284#endif
4633a7c4 2285
fed7345c 2286#ifdef ARCHLIB_EXP
774d564b 2287 incpush(ARCHLIB_EXP, FALSE);
a0d0e21e 2288#endif
fed7345c 2289#ifndef PRIVLIB_EXP
2290#define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
34de22dd 2291#endif
774d564b 2292 incpush(PRIVLIB_EXP, FALSE);
4633a7c4 2293
2294#ifdef SITEARCH_EXP
774d564b 2295 incpush(SITEARCH_EXP, FALSE);
4633a7c4 2296#endif
2297#ifdef SITELIB_EXP
774d564b 2298 incpush(SITELIB_EXP, FALSE);
4633a7c4 2299#endif
2300#ifdef OLDARCHLIB_EXP /* 5.00[01] compatibility */
774d564b 2301 incpush(OLDARCHLIB_EXP, FALSE);
4633a7c4 2302#endif
a0d0e21e 2303
4633a7c4 2304 if (!tainting)
774d564b 2305 incpush(".", FALSE);
2306}
2307
2308#if defined(DOSISH)
2309# define PERLLIB_SEP ';'
2310#else
2311# if defined(VMS)
2312# define PERLLIB_SEP '|'
2313# else
2314# define PERLLIB_SEP ':'
2315# endif
2316#endif
2317#ifndef PERLLIB_MANGLE
2318# define PERLLIB_MANGLE(s,n) (s)
2319#endif
2320
2321static void
2322incpush(p, addsubdirs)
2323char *p;
2324int addsubdirs;
2325{
2326 SV *subdir = Nullsv;
2327 static char *archpat_auto;
2328
2329 if (!p)
2330 return;
2331
2332 if (addsubdirs) {
2333 subdir = newSV(0);
2334 if (!archpat_auto) {
2335 STRLEN len = (sizeof(ARCHNAME) + strlen(patchlevel)
2336 + sizeof("//auto"));
2337 New(55, archpat_auto, len, char);
2338 sprintf(archpat_auto, "/%s/%s/auto", ARCHNAME, patchlevel);
2339 }
2340 }
2341
2342 /* Break at all separators */
2343 while (p && *p) {
2344 SV *libdir = newSV(0);
2345 char *s;
2346
2347 /* skip any consecutive separators */
2348 while ( *p == PERLLIB_SEP ) {
2349 /* Uncomment the next line for PATH semantics */
2350 /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
2351 p++;
2352 }
2353
2354 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
2355 sv_setpvn(libdir, PERLLIB_MANGLE(p, (STRLEN)(s - p)),
2356 (STRLEN)(s - p));
2357 p = s + 1;
2358 }
2359 else {
2360 sv_setpv(libdir, PERLLIB_MANGLE(p, 0));
2361 p = Nullch; /* break out */
2362 }
2363
2364 /*
2365 * BEFORE pushing libdir onto @INC we may first push version- and
2366 * archname-specific sub-directories.
2367 */
2368 if (addsubdirs) {
2369 struct stat tmpstatbuf;
2370
4fdae800 2371 /* .../archname/version if -d .../archname/version/auto */
774d564b 2372 sv_setsv(subdir, libdir);
2373 sv_catpv(subdir, archpat_auto);
2374 if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
2375 S_ISDIR(tmpstatbuf.st_mode))
2376 av_push(GvAVn(incgv),
2377 newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto"));
2378
4fdae800 2379 /* .../archname if -d .../archname/auto */
774d564b 2380 sv_insert(subdir, SvCUR(libdir) + sizeof(ARCHNAME),
2381 strlen(patchlevel) + 1, "", 0);
2382 if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
2383 S_ISDIR(tmpstatbuf.st_mode))
2384 av_push(GvAVn(incgv),
2385 newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto"));
2386 }
2387
2388 /* finally push this lib directory on the end of @INC */
2389 av_push(GvAVn(incgv), libdir);
2390 }
2391
2392 SvREFCNT_dec(subdir);
34de22dd 2393}
93a17b20 2394
2395void
2396calllist(list)
2397AV* list;
2398{
a5f75d66 2399 Sigjmp_buf oldtop;
a0d0e21e 2400 STRLEN len;
2401 line_t oldline = curcop->cop_line;
93a17b20 2402
a5f75d66 2403 Copy(top_env, oldtop, 1, Sigjmp_buf);
93a17b20 2404
8990e307 2405 while (AvFILL(list) >= 0) {
2406 CV *cv = (CV*)av_shift(list);
93a17b20 2407
8990e307 2408 SAVEFREESV(cv);
a0d0e21e 2409
a5f75d66 2410 switch (Sigsetjmp(top_env,1)) {
748a9306 2411 case 0: {
4633a7c4 2412 SV* atsv = GvSV(errgv);
748a9306 2413 PUSHMARK(stack_sp);
2414 perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
2415 (void)SvPV(atsv, len);
2416 if (len) {
a5f75d66 2417 Copy(oldtop, top_env, 1, Sigjmp_buf);
748a9306 2418 curcop = &compiling;
2419 curcop->cop_line = oldline;
2420 if (list == beginav)
2421 sv_catpv(atsv, "BEGIN failed--compilation aborted");
2422 else
2423 sv_catpv(atsv, "END failed--cleanup aborted");
2424 croak("%s", SvPVX(atsv));
2425 }
a0d0e21e 2426 }
85e6fe83 2427 break;
2428 case 1:
f86702cc 2429 STATUS_ALL_FAILURE;
85e6fe83 2430 /* FALL THROUGH */
2431 case 2:
2432 /* my_exit() was called */
2433 curstash = defstash;
2434 if (endav)
2435 calllist(endav);
a0d0e21e 2436 FREETMPS;
a5f75d66 2437 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 2438 curcop = &compiling;
2439 curcop->cop_line = oldline;
85e6fe83 2440 if (statusvalue) {
2441 if (list == beginav)
a0d0e21e 2442 croak("BEGIN failed--compilation aborted");
85e6fe83 2443 else
a0d0e21e 2444 croak("END failed--cleanup aborted");
85e6fe83 2445 }
f86702cc 2446 my_exit_jump();
85e6fe83 2447 /* NOTREACHED */
85e6fe83 2448 case 3:
2449 if (!restartop) {
760ac839 2450 PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
a0d0e21e 2451 FREETMPS;
85e6fe83 2452 break;
2453 }
a5f75d66 2454 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 2455 curcop = &compiling;
2456 curcop->cop_line = oldline;
a5f75d66 2457 Siglongjmp(top_env, 3);
8990e307 2458 }
93a17b20 2459 }
2460
a5f75d66 2461 Copy(oldtop, top_env, 1, Sigjmp_buf);
93a17b20 2462}
2463
f86702cc 2464void
2465my_exit(status)
2466U32 status;
2467{
2468 switch (status) {
2469 case 0:
2470 STATUS_ALL_SUCCESS;
2471 break;
2472 case 1:
2473 STATUS_ALL_FAILURE;
2474 break;
2475 default:
2476 STATUS_NATIVE_SET(status);
2477 break;
2478 }
2479 my_exit_jump();
2480}
2481
2482void
2483my_failure_exit()
2484{
2485#ifdef VMS
2486 if (vaxc$errno & 1) {
4fdae800 2487 if (STATUS_NATIVE & 1) /* fortuitiously includes "-1" */
2488 STATUS_NATIVE_SET(44);
f86702cc 2489 }
2490 else {
ff0cee69 2491 if (!vaxc$errno && errno) /* unlikely */
4fdae800 2492 STATUS_NATIVE_SET(44);
f86702cc 2493 else
4fdae800 2494 STATUS_NATIVE_SET(vaxc$errno);
f86702cc 2495 }
2496#else
2497 if (errno & 255)
2498 STATUS_POSIX_SET(errno);
2499 else if (STATUS_POSIX == 0)
2500 STATUS_POSIX_SET(255);
2501#endif
2502 my_exit_jump();
2503}
2504
2505static void
2506my_exit_jump()
2507{
2508 register CONTEXT *cx;
2509 I32 gimme;
2510 SV **newsp;
2511
2512 if (e_tmpname) {
2513 if (e_fp) {
2514 PerlIO_close(e_fp);
2515 e_fp = Nullfp;
2516 }
2517 (void)UNLINK(e_tmpname);
2518 Safefree(e_tmpname);
2519 e_tmpname = Nullch;
2520 }
2521
2522 if (cxstack_ix >= 0) {
2523 if (cxstack_ix > 0)
2524 dounwind(0);
2525 POPBLOCK(cx,curpm);
2526 LEAVE;
2527 }
ff0cee69 2528
f86702cc 2529 Siglongjmp(top_env, 2);
2530}