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