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