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