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