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