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