This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.0 alpha 5
[perl5.git] / perl.c
CommitLineData
8d063cd8 1/*
463ee0b2 2 * Copyright (c) 1991, 1992, 1993, 1994 Larry Wall
a687059c 3 *
352d5a3a
LW
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Artistic License, as specified in the README file.
a687059c 6 *
fe14fcc3 7 * $Log: perl.c,v $
79072805
LW
8 * Revision 4.1 92/08/07 18:25:50 lwall
9 *
83025b21
LW
10 * Revision 4.0.1.7 92/06/08 14:50:39 lwall
11 * patch20: PERLLIB now supports multiple directories
12 * patch20: running taintperl explicitly now does checks even if $< == $>
13 * patch20: -e 'cmd' no longer fails silently if /tmp runs out of space
14 * patch20: perl -P now uses location of sed determined by Configure
15 * patch20: form feed for formats is now specifiable via $^L
16 * patch20: paragraph mode now skips extra newlines automatically
79072805 17 * patch20: oldeval "1 #comment" didn't work
83025b21
LW
18 * patch20: couldn't require . files
19 * patch20: semantic compilation errors didn't abort execution
20 *
988174c1
LW
21 * Revision 4.0.1.6 91/11/11 16:38:45 lwall
22 * patch19: default arg for shift was wrong after first subroutine definition
23 * patch19: op/regexp.t failed from missing arg to bcmp()
24 *
45d8adaa
LW
25 * Revision 4.0.1.5 91/11/05 18:03:32 lwall
26 * patch11: random cleanup
27 * patch11: $0 was being truncated at times
28 * patch11: cppstdin now installed outside of source directory
29 * patch11: -P didn't allow use of #elif or #undef
30 * patch11: prepared for ctype implementations that don't define isascii()
79072805
LW
31 * patch11: added oldeval {}
32 * patch11: oldeval confused by string containing null
45d8adaa 33 *
1462b684
LW
34 * Revision 4.0.1.4 91/06/10 01:23:07 lwall
35 * patch10: perl -v printed incorrect copyright notice
36 *
352d5a3a
LW
37 * Revision 4.0.1.3 91/06/07 11:40:18 lwall
38 * patch4: changed old $^P to $^X
39 *
40 * Revision 4.0.1.2 91/06/07 11:26:16 lwall
41 * patch4: new copyright notice
42 * patch4: added $^P variable to control calling of perldb routines
43 * patch4: added $^F variable to specify maximum system fd, default 2
79072805 44 * patch4: debugger lost track of lines in oldeval
352d5a3a 45 *
35c8bce7
LW
46 * Revision 4.0.1.1 91/04/11 17:49:05 lwall
47 * patch1: fixed undefined environ problem
48 *
fe14fcc3
LW
49 * Revision 4.0 91/03/20 01:37:44 lwall
50 * 4.0 baseline.
8d063cd8
LW
51 *
52 */
53
45d8adaa
LW
54/*SUPPRESS 560*/
55
378cc40b
LW
56#include "EXTERN.h"
57#include "perl.h"
58#include "perly.h"
a687059c 59#include "patchlevel.h"
378cc40b 60
463ee0b2
LW
61char rcsid[] = "$RCSfile: perl.c,v $$Revision: 5.0 $$Date: 92/08/07 18:25:50 $\nPatch level: ###\n";
62
a687059c
LW
63#ifdef IAMSUID
64#ifndef DOSUID
65#define DOSUID
66#endif
67#endif
378cc40b 68
a687059c
LW
69#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
70#ifdef DOSUID
71#undef DOSUID
72#endif
73#endif
8d063cd8 74
83025b21 75static void incpush();
79072805
LW
76static void validate_suid();
77static void find_beginning();
78static void init_main_stash();
79static void open_script();
80static void init_debugger();
81static void init_stack();
82static void init_lexer();
83static void init_context_stack();
84static void init_predump_symbols();
85static void init_postdump_symbols();
86static void init_perllib();
87
93a17b20 88PerlInterpreter *
79072805
LW
89perl_alloc()
90{
93a17b20
LW
91 PerlInterpreter *sv_interp;
92 PerlInterpreter junk;
79072805
LW
93
94 curinterp = &junk;
93a17b20
LW
95 Zero(&junk, 1, PerlInterpreter);
96 New(53, sv_interp, 1, PerlInterpreter);
79072805
LW
97 return sv_interp;
98}
99
100void
101perl_construct( sv_interp )
93a17b20 102register PerlInterpreter *sv_interp;
79072805
LW
103{
104 if (!(curinterp = sv_interp))
105 return;
106
93a17b20 107 Zero(sv_interp, 1, PerlInterpreter);
79072805
LW
108
109 /* Init the real globals? */
110 if (!linestr) {
111 linestr = NEWSV(65,80);
ed6116ce 112 sv_upgrade(linestr,SVt_PVIV);
79072805
LW
113
114 SvREADONLY_on(&sv_undef);
115
116 sv_setpv(&sv_no,No);
463ee0b2 117 SvNV(&sv_no);
79072805
LW
118 SvREADONLY_on(&sv_no);
119
120 sv_setpv(&sv_yes,Yes);
463ee0b2 121 SvNV(&sv_yes);
79072805
LW
122 SvREADONLY_on(&sv_yes);
123
124#ifdef MSDOS
125 /*
126 * There is no way we can refer to them from Perl so close them to save
127 * space. The other alternative would be to provide STDAUX and STDPRN
128 * filehandles.
129 */
130 (void)fclose(stdaux);
131 (void)fclose(stdprn);
132#endif
133 }
134
135#ifdef EMBEDDED
136 chopset = " \n-";
463ee0b2 137 copline = NOLINE;
79072805
LW
138 curcop = &compiling;
139 cxstack_ix = -1;
140 cxstack_max = 128;
141 dlmax = 128;
142 laststatval = -1;
143 laststype = OP_STAT;
144 maxscream = -1;
145 maxsysfd = MAXSYSFD;
146 nrs = "\n";
147 nrschar = '\n';
148 nrslen = 1;
149 rs = "\n";
150 rschar = '\n';
151 rsfp = Nullfp;
152 rslen = 1;
463ee0b2 153 statname = Nullsv;
79072805
LW
154 tmps_floor = -1;
155 tmps_ix = -1;
156 tmps_max = -1;
157#endif
158
159 uid = (int)getuid();
160 euid = (int)geteuid();
161 gid = (int)getgid();
162 egid = (int)getegid();
463ee0b2
LW
163 tainting = (euid != uid || egid != gid);
164 sprintf(patchlevel,"%3.3s%2.2d", strchr(rcsid,'5'), PATCHLEVEL);
79072805 165
93a17b20 166 (void)sprintf(strchr(rcsid,'#'), "%d\n", PATCHLEVEL);
79072805
LW
167
168 fdpid = newAV(); /* for remembering popen pids by fd */
463ee0b2 169 pidstatus = newHV();/* for remembering status of dead pids */
79072805
LW
170}
171
172void
173perl_destruct(sv_interp)
93a17b20 174register PerlInterpreter *sv_interp;
79072805
LW
175{
176 if (!(curinterp = sv_interp))
177 return;
178#ifdef EMBEDDED
179 if (main_root)
180 op_free(main_root);
181 main_root = 0;
79072805
LW
182#endif
183}
184
185void
186perl_free(sv_interp)
93a17b20 187PerlInterpreter *sv_interp;
79072805
LW
188{
189 if (!(curinterp = sv_interp))
190 return;
191 Safefree(sv_interp);
192}
193
194int
195perl_parse(sv_interp, argc, argv, env)
93a17b20 196PerlInterpreter *sv_interp;
8d063cd8
LW
197register int argc;
198register char **argv;
79072805 199char **env;
8d063cd8 200{
79072805 201 register SV *sv;
8d063cd8 202 register char *s;
45d8adaa 203 char *scriptname;
352d5a3a 204 char *getenv();
378cc40b 205 bool dosearch = FALSE;
13281fa4 206 char *validarg = "";
8d063cd8 207
a687059c
LW
208#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
209#ifdef IAMSUID
210#undef IAMSUID
463ee0b2 211 croak("suidperl is no longer needed since the kernel can now execute\n\
a687059c
LW
212setuid perl scripts securely.\n");
213#endif
214#endif
215
79072805
LW
216 if (!(curinterp = sv_interp))
217 return 255;
218
219 if (main_root)
220 op_free(main_root);
221 main_root = 0;
79072805 222
ac58e20f
LW
223 origargv = argv;
224 origargc = argc;
fe14fcc3 225 origenviron = environ;
79072805
LW
226
227 switch (setjmp(top_env)) {
228 case 1:
229 statusvalue = 255;
230 case 2:
231 return(statusvalue); /* my_exit() was called */
232 case 3:
233 fprintf(stderr, "panic: top_env\n");
234 exit(1);
235 }
236
a687059c 237 if (do_undump) {
33b78306 238 origfilename = savestr(argv[0]);
79072805
LW
239 do_undump = FALSE;
240 cxstack_ix = -1; /* start label stack again */
a687059c
LW
241 goto just_doit;
242 }
79072805
LW
243 sv_setpvn(linestr,"",0);
244 sv = newSVpv("",0); /* first used for -I flags */
245 init_main_stash();
33b78306 246 for (argc--,argv++; argc > 0; argc--,argv++) {
8d063cd8
LW
247 if (argv[0][0] != '-' || !argv[0][1])
248 break;
13281fa4
LW
249#ifdef DOSUID
250 if (*validarg)
251 validarg = " PHOOEY ";
252 else
253 validarg = argv[0];
254#endif
255 s = argv[0]+1;
8d063cd8 256 reswitch:
13281fa4 257 switch (*s) {
27e2fb84 258 case '0':
378cc40b 259 case 'a':
33b78306 260 case 'c':
a687059c 261 case 'd':
8d063cd8 262 case 'D':
33b78306 263 case 'i':
fe14fcc3 264 case 'l':
33b78306
LW
265 case 'n':
266 case 'p':
79072805 267 case 's':
463ee0b2 268 case 'T':
33b78306
LW
269 case 'u':
270 case 'U':
271 case 'v':
272 case 'w':
273 if (s = moreswitches(s))
274 goto reswitch;
8d063cd8 275 break;
33b78306 276
8d063cd8 277 case 'e':
a687059c 278 if (euid != uid || egid != gid)
463ee0b2 279 croak("No -e allowed in setuid scripts");
8d063cd8 280 if (!e_fp) {
a687059c
LW
281 e_tmpname = savestr(TMPPATH);
282 (void)mktemp(e_tmpname);
83025b21 283 if (!*e_tmpname)
463ee0b2 284 croak("Can't mktemp()");
8d063cd8 285 e_fp = fopen(e_tmpname,"w");
33b78306 286 if (!e_fp)
463ee0b2 287 croak("Cannot open temporary file");
8d063cd8 288 }
33b78306 289 if (argv[1]) {
8d063cd8 290 fputs(argv[1],e_fp);
33b78306
LW
291 argc--,argv++;
292 }
a687059c 293 (void)putc('\n', e_fp);
8d063cd8
LW
294 break;
295 case 'I':
463ee0b2 296 taint_not("-I");
79072805
LW
297 sv_catpv(sv,"-");
298 sv_catpv(sv,s);
299 sv_catpv(sv," ");
a687059c 300 if (*++s) {
79072805 301 (void)av_push(GvAVn(incgv),newSVpv(s,0));
378cc40b 302 }
33b78306 303 else if (argv[1]) {
79072805
LW
304 (void)av_push(GvAVn(incgv),newSVpv(argv[1],0));
305 sv_catpv(sv,argv[1]);
8d063cd8 306 argc--,argv++;
79072805 307 sv_catpv(sv," ");
8d063cd8
LW
308 }
309 break;
8d063cd8 310 case 'P':
463ee0b2 311 taint_not("-P");
8d063cd8 312 preprocess = TRUE;
13281fa4 313 s++;
8d063cd8 314 goto reswitch;
378cc40b 315 case 'S':
463ee0b2 316 taint_not("-S");
378cc40b 317 dosearch = TRUE;
13281fa4 318 s++;
378cc40b 319 goto reswitch;
33b78306
LW
320 case 'x':
321 doextract = TRUE;
13281fa4 322 s++;
33b78306
LW
323 if (*s)
324 cddir = savestr(s);
325 break;
8d063cd8
LW
326 case '-':
327 argc--,argv++;
328 goto switch_end;
329 case 0:
330 break;
331 default:
463ee0b2 332 croak("Unrecognized switch: -%s",s);
8d063cd8
LW
333 }
334 }
335 switch_end:
45d8adaa 336 scriptname = argv[0];
8d063cd8 337 if (e_fp) {
83025b21 338 if (fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
463ee0b2 339 croak("Can't write to temp file for -e: %s", strerror(errno));
8d063cd8 340 argc++,argv--;
45d8adaa 341 scriptname = e_tmpname;
8d063cd8 342 }
79072805
LW
343 else if (scriptname == Nullch) {
344#ifdef MSDOS
345 if ( isatty(fileno(stdin)) )
346 moreswitches("v");
fe14fcc3 347#endif
79072805
LW
348 scriptname = "-";
349 }
fe14fcc3 350
79072805 351 init_perllib();
8d063cd8 352
79072805 353 open_script(scriptname,dosearch,sv);
8d063cd8 354
79072805
LW
355 sv_free(sv); /* free -I directories */
356 sv = Nullsv;
8d063cd8 357
79072805 358 validate_suid(validarg);
378cc40b 359
79072805
LW
360 if (doextract)
361 find_beginning();
362
363 if (perldb)
364 init_debugger();
365
366 pad = newAV();
367 comppad = pad;
368 av_push(comppad, Nullsv);
369 curpad = AvARRAY(comppad);
93a17b20
LW
370 padname = newAV();
371 comppadname = padname;
372 comppadnamefill = -1;
79072805
LW
373 padix = 0;
374
375 init_stack();
376
93a17b20
LW
377 init_context_stack();
378
463ee0b2 379 perl_init_ext(); /* in case linked C routines want magical variables */
93a17b20 380
93a17b20
LW
381 init_predump_symbols();
382
79072805
LW
383 init_lexer();
384
385 /* now parse the script */
386
387 error_count = 0;
388 if (yyparse() || error_count) {
389 if (minus_c)
463ee0b2 390 croak("%s had compilation errors.\n", origfilename);
79072805 391 else {
463ee0b2 392 croak("Execution of %s aborted due to compilation errors.\n",
79072805 393 origfilename);
378cc40b 394 }
79072805
LW
395 }
396 curcop->cop_line = 0;
397 curstash = defstash;
398 preprocess = FALSE;
399 if (e_fp) {
400 e_fp = Nullfp;
401 (void)UNLINK(e_tmpname);
378cc40b 402 }
a687059c 403
93a17b20 404 /* now that script is parsed, we can modify record separator */
a687059c 405
93a17b20
LW
406 rs = nrs;
407 rslen = nrslen;
408 rschar = nrschar;
409 rspara = (nrslen == 2);
410 sv_setpvn(GvSV(gv_fetchpv("/", TRUE)), rs, rslen);
45d8adaa 411
79072805
LW
412 if (do_undump)
413 my_unexec();
414
415 just_doit: /* come here if running an undumped a.out */
416 init_postdump_symbols(argc,argv,env);
417 return 0;
418}
419
420int
421perl_run(sv_interp)
93a17b20 422PerlInterpreter *sv_interp;
79072805
LW
423{
424 if (!(curinterp = sv_interp))
425 return 255;
93a17b20
LW
426 if (beginav)
427 calllist(beginav);
79072805
LW
428 switch (setjmp(top_env)) {
429 case 1:
430 cxstack_ix = -1; /* start context stack again */
431 break;
432 case 2:
433 curstash = defstash;
93a17b20
LW
434 if (endav)
435 calllist(endav);
436 return(statusvalue); /* my_exit() was called */
79072805
LW
437 case 3:
438 if (!restartop) {
439 fprintf(stderr, "panic: restartop\n");
440 exit(1);
83025b21 441 }
79072805
LW
442 if (stack != mainstack) {
443 dSP;
444 SWITCHSTACK(stack, mainstack);
445 }
446 break;
8d063cd8 447 }
79072805
LW
448
449 if (!restartop) {
450 DEBUG_x(dump_all());
451 DEBUG(fprintf(stderr,"\nEXECUTING...\n\n"));
452
453 if (minus_c) {
454 fprintf(stderr,"%s syntax OK\n", origfilename);
455 my_exit(0);
456 }
45d8adaa 457 }
79072805
LW
458
459 /* do it */
460
461 if (restartop) {
462 op = restartop;
463 restartop = 0;
464 run();
465 }
466 else if (main_start) {
467 op = main_start;
468 run();
469 }
79072805
LW
470
471 my_exit(0);
472}
473
474void
475my_exit(status)
476int status;
477{
478 statusvalue = (unsigned short)(status & 0xffff);
479 longjmp(top_env, 2);
480}
481
482/* Be sure to refetch the stack pointer after calling these routines. */
483
484int
485perl_callback(subname, sp, gimme, hasargs, numargs)
486char *subname;
487I32 sp; /* stack pointer after args are pushed */
488I32 gimme; /* called in array or scalar context */
489I32 hasargs; /* whether to create a @_ array for routine */
490I32 numargs; /* how many args are pushed on the stack */
491{
492 BINOP myop; /* fake syntax tree node */
493
494 ENTER;
463ee0b2 495 SAVETMPS;
79072805
LW
496 SAVESPTR(op);
497 stack_base = AvARRAY(stack);
93a17b20 498 stack_sp = stack_base + sp - numargs - 1;
79072805 499 op = (OP*)&myop;
463ee0b2 500 Zero(op, 1, BINOP);
79072805 501 pp_pushmark(); /* doesn't look at op, actually, except to return */
93a17b20 502 *++stack_sp = (SV*)gv_fetchpv(subname, FALSE);
79072805
LW
503 stack_sp += numargs;
504
463ee0b2
LW
505 if (hasargs) {
506 myop.op_flags = OPf_STACKED;
507 myop.op_last = (OP*)&myop;
508 }
79072805
LW
509 myop.op_next = Nullop;
510
463ee0b2
LW
511 if (op = pp_entersubr())
512 run();
513 free_tmps();
79072805
LW
514 LEAVE;
515 return stack_sp - stack_base;
516}
517
518int
519perl_callv(subname, sp, gimme, argv)
520char *subname;
521register I32 sp; /* current stack pointer */
522I32 gimme; /* called in array or scalar context */
523register char **argv; /* null terminated arg list, NULL for no arglist */
524{
525 register I32 items = 0;
526 I32 hasargs = (argv != 0);
527
528 av_store(stack, ++sp, Nullsv); /* reserve spot for 1st return arg */
529 if (hasargs) {
530 while (*argv) {
531 av_store(stack, ++sp, sv_2mortal(newSVpv(*argv,0)));
532 items++;
533 argv++;
534 }
535 }
536 return perl_callback(subname, sp, gimme, hasargs, items);
537}
538
539void
79072805
LW
540magicname(sym,name,namlen)
541char *sym;
542char *name;
543I32 namlen;
544{
545 register GV *gv;
546
463ee0b2 547 if (gv = gv_fetchpv(sym,TRUE))
79072805
LW
548 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
549}
550
551#ifdef DOSISH
552#define PERLLIB_SEP ';'
553#else
554#define PERLLIB_SEP ':'
555#endif
556
557static void
558incpush(p)
559char *p;
560{
561 char *s;
562
563 if (!p)
564 return;
565
566 /* Break at all separators */
567 while (*p) {
568 /* First, skip any consecutive separators */
569 while ( *p == PERLLIB_SEP ) {
570 /* Uncomment the next line for PATH semantics */
571 /* (void)av_push(GvAVn(incgv), newSVpv(".", 1)); */
572 p++;
573 }
93a17b20 574 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
79072805
LW
575 (void)av_push(GvAVn(incgv), newSVpv(p, (I32)(s - p)));
576 p = s + 1;
577 } else {
578 (void)av_push(GvAVn(incgv), newSVpv(p, 0));
579 break;
580 }
581 }
582}
583
584/* This routine handles any switches that can be given during run */
585
586char *
587moreswitches(s)
588char *s;
589{
590 I32 numlen;
591
592 switch (*s) {
593 case '0':
594 nrschar = scan_oct(s, 4, &numlen);
595 nrs = nsavestr("\n",1);
596 *nrs = nrschar;
597 if (nrschar > 0377) {
598 nrslen = 0;
599 nrs = "";
600 }
601 else if (!nrschar && numlen >= 2) {
602 nrslen = 2;
603 nrs = "\n\n";
604 nrschar = '\n';
605 }
606 return s + numlen;
607 case 'a':
608 minus_a = TRUE;
609 s++;
610 return s;
611 case 'c':
612 minus_c = TRUE;
613 s++;
614 return s;
615 case 'd':
463ee0b2 616 taint_not("-d");
79072805
LW
617 perldb = TRUE;
618 s++;
619 return s;
620 case 'D':
621#ifdef DEBUGGING
463ee0b2 622 taint_not("-D");
79072805
LW
623 if (isALPHA(s[1])) {
624 static char debopts[] = "psltocPmfrxuLHX";
625 char *d;
626
93a17b20 627 for (s++; *s && (d = strchr(debopts,*s)); s++)
79072805
LW
628 debug |= 1 << (d - debopts);
629 }
630 else {
631 debug = atoi(s+1);
632 for (s++; isDIGIT(*s); s++) ;
633 }
634 debug |= 32768;
635#else
636 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
637 for (s++; isDIGIT(*s); s++) ;
638#endif
639 /*SUPPRESS 530*/
640 return s;
641 case 'i':
642 if (inplace)
643 Safefree(inplace);
644 inplace = savestr(s+1);
645 /*SUPPRESS 530*/
646 for (s = inplace; *s && !isSPACE(*s); s++) ;
647 *s = '\0';
648 break;
649 case 'I':
463ee0b2 650 taint_not("-I");
79072805
LW
651 if (*++s) {
652 (void)av_push(GvAVn(incgv),newSVpv(s,0));
653 }
654 else
463ee0b2 655 croak("No space allowed after -I");
79072805
LW
656 break;
657 case 'l':
658 minus_l = TRUE;
659 s++;
660 if (isDIGIT(*s)) {
661 ors = savestr("\n");
662 orslen = 1;
663 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
664 s += numlen;
665 }
666 else {
667 ors = nsavestr(nrs,nrslen);
668 orslen = nrslen;
669 }
670 return s;
671 case 'n':
672 minus_n = TRUE;
673 s++;
674 return s;
675 case 'p':
676 minus_p = TRUE;
677 s++;
678 return s;
679 case 's':
463ee0b2 680 taint_not("-s");
79072805
LW
681 doswitches = TRUE;
682 s++;
683 return s;
463ee0b2
LW
684 case 'T':
685 tainting = TRUE;
686 s++;
687 return s;
79072805
LW
688 case 'u':
689 do_undump = TRUE;
690 s++;
691 return s;
692 case 'U':
693 unsafe = TRUE;
694 s++;
695 return s;
696 case 'v':
ed6116ce 697 fputs("\nThis is perl, version 5.0, Alpha 5 (unsupported)\n\n",stdout);
79072805 698 fputs(rcsid,stdout);
463ee0b2 699 fputs("\nCopyright (c) 1989, 1990, 1991, 1992, 1993, 1994 Larry Wall\n",stdout);
79072805
LW
700#ifdef MSDOS
701 fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
702 stdout);
703#ifdef OS2
704 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n",
705 stdout);
706#endif
707#endif
708#ifdef atarist
709 fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout);
710#endif
711 fputs("\n\
712Perl may be copied only under the terms of either the Artistic License or the\n\
713GNU General Public License, which may be found in the Perl 5.0 source kit.\n",stdout);
714#ifdef MSDOS
715 usage(origargv[0]);
716#endif
717 exit(0);
718 case 'w':
719 dowarn = TRUE;
720 s++;
721 return s;
722 case ' ':
723 if (s[1] == '-') /* Additional switches on #! line. */
724 return s+2;
725 break;
726 case 0:
727 case '\n':
728 case '\t':
729 break;
730 default:
463ee0b2 731 croak("Switch meaningless after -x: -%s",s);
79072805
LW
732 }
733 return Nullch;
734}
735
736/* compliments of Tom Christiansen */
737
738/* unexec() can be found in the Gnu emacs distribution */
739
740void
741my_unexec()
742{
743#ifdef UNEXEC
744 int status;
745 extern int etext;
746
747 sprintf (buf, "%s.perldump", origfilename);
748 sprintf (tokenbuf, "%s/perl", BIN);
749
750 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
751 if (status)
752 fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
753 my_exit(status);
754#else
755 ABORT(); /* for use with undump */
756#endif
757}
758
759static void
760init_main_stash()
761{
463ee0b2
LW
762 GV *gv;
763 curstash = defstash = newHV();
79072805 764 curstname = newSVpv("main",4);
463ee0b2
LW
765 GvHV(gv = gv_fetchpv("_main",TRUE)) = defstash;
766 SvREADONLY_on(gv);
79072805
LW
767 HvNAME(defstash) = "main";
768 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE)));
769 SvMULTI_on(incgv);
770 defgv = gv_fetchpv("_",TRUE);
771}
772
773static void
774open_script(scriptname,dosearch,sv)
775char *scriptname;
776bool dosearch;
777SV *sv;
778{
779 char *xfound = Nullch;
780 char *xfailed = Nullch;
781 register char *s;
782 I32 len;
783
93a17b20 784 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
79072805
LW
785
786 bufend = s + strlen(s);
787 while (*s) {
788#ifndef DOSISH
789 s = cpytill(tokenbuf,s,bufend,':',&len);
790#else
791#ifdef atarist
792 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
793 tokenbuf[len] = '\0';
794#else
795 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
796 tokenbuf[len] = '\0';
797#endif
798#endif
799 if (*s)
800 s++;
801#ifndef DOSISH
802 if (len && tokenbuf[len-1] != '/')
803#else
804#ifdef atarist
805 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
806#else
807 if (len && tokenbuf[len-1] != '\\')
808#endif
809#endif
810 (void)strcat(tokenbuf+len,"/");
811 (void)strcat(tokenbuf+len,scriptname);
812 DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
813 if (stat(tokenbuf,&statbuf) < 0) /* not there? */
814 continue;
815 if (S_ISREG(statbuf.st_mode)
816 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
817 xfound = tokenbuf; /* bingo! */
818 break;
819 }
820 if (!xfailed)
821 xfailed = savestr(tokenbuf);
822 }
823 if (!xfound)
463ee0b2 824 croak("Can't execute %s", xfailed ? xfailed : scriptname );
79072805
LW
825 if (xfailed)
826 Safefree(xfailed);
827 scriptname = xfound;
828 }
829
830 origfilename = savestr(scriptname);
831 curcop->cop_filegv = gv_fetchfile(origfilename);
832 if (strEQ(origfilename,"-"))
833 scriptname = "";
834 if (preprocess) {
835 char *cpp = CPPSTDIN;
836
837 if (strEQ(cpp,"cppstdin"))
838 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
839 else
840 sprintf(tokenbuf, "%s", cpp);
841 sv_catpv(sv,"-I");
842 sv_catpv(sv,PRIVLIB);
843#ifdef MSDOS
844 (void)sprintf(buf, "\
845sed %s -e \"/^[^#]/b\" \
846 -e \"/^#[ ]*include[ ]/b\" \
847 -e \"/^#[ ]*define[ ]/b\" \
848 -e \"/^#[ ]*if[ ]/b\" \
849 -e \"/^#[ ]*ifdef[ ]/b\" \
850 -e \"/^#[ ]*ifndef[ ]/b\" \
851 -e \"/^#[ ]*else/b\" \
852 -e \"/^#[ ]*elif[ ]/b\" \
853 -e \"/^#[ ]*undef[ ]/b\" \
854 -e \"/^#[ ]*endif/b\" \
855 -e \"s/^#.*//\" \
856 %s | %s -C %s %s",
857 (doextract ? "-e \"1,/^#/d\n\"" : ""),
858#else
859 (void)sprintf(buf, "\
860%s %s -e '/^[^#]/b' \
861 -e '/^#[ ]*include[ ]/b' \
862 -e '/^#[ ]*define[ ]/b' \
863 -e '/^#[ ]*if[ ]/b' \
864 -e '/^#[ ]*ifdef[ ]/b' \
865 -e '/^#[ ]*ifndef[ ]/b' \
866 -e '/^#[ ]*else/b' \
867 -e '/^#[ ]*elif[ ]/b' \
868 -e '/^#[ ]*undef[ ]/b' \
869 -e '/^#[ ]*endif/b' \
870 -e 's/^[ ]*#.*//' \
871 %s | %s -C %s %s",
872#ifdef LOC_SED
873 LOC_SED,
874#else
875 "sed",
876#endif
877 (doextract ? "-e '1,/^#/d\n'" : ""),
878#endif
463ee0b2 879 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
79072805
LW
880 DEBUG_P(fprintf(stderr, "%s\n", buf));
881 doextract = FALSE;
882#ifdef IAMSUID /* actually, this is caught earlier */
883 if (euid != uid && !euid) { /* if running suidperl */
884#ifdef HAS_SETEUID
885 (void)seteuid(uid); /* musn't stay setuid root */
886#else
887#ifdef HAS_SETREUID
888 (void)setreuid(-1, uid);
889#else
890 setuid(uid);
891#endif
892#endif
893 if (geteuid() != uid)
463ee0b2 894 croak("Can't do seteuid!\n");
79072805
LW
895 }
896#endif /* IAMSUID */
897 rsfp = my_popen(buf,"r");
898 }
899 else if (!*scriptname) {
463ee0b2 900 taint_not("program input from stdin");
79072805
LW
901 rsfp = stdin;
902 }
903 else
904 rsfp = fopen(scriptname,"r");
45d8adaa 905 if ((FILE*)rsfp == Nullfp) {
13281fa4 906#ifdef DOSUID
a687059c 907#ifndef IAMSUID /* in case script is not readable before setuid */
463ee0b2 908 if (euid && stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
13281fa4 909 statbuf.st_mode & (S_ISUID|S_ISGID)) {
27e2fb84 910 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 911 execv(buf, origargv); /* try again */
463ee0b2 912 croak("Can't do setuid\n");
13281fa4
LW
913 }
914#endif
915#endif
463ee0b2
LW
916 croak("Can't open perl script \"%s\": %s\n",
917 SvPVX(GvSV(curcop->cop_filegv)), strerror(errno));
13281fa4 918 }
79072805 919}
8d063cd8 920
79072805
LW
921static void
922validate_suid(validarg)
923char *validarg;
924{
93a17b20 925 char *s;
13281fa4
LW
926 /* do we need to emulate setuid on scripts? */
927
928 /* This code is for those BSD systems that have setuid #! scripts disabled
929 * in the kernel because of a security problem. Merely defining DOSUID
930 * in perl will not fix that problem, but if you have disabled setuid
931 * scripts in the kernel, this will attempt to emulate setuid and setgid
932 * on scripts that have those now-otherwise-useless bits set. The setuid
27e2fb84
LW
933 * root version must be called suidperl or sperlN.NNN. If regular perl
934 * discovers that it has opened a setuid script, it calls suidperl with
935 * the same argv that it had. If suidperl finds that the script it has
936 * just opened is NOT setuid root, it sets the effective uid back to the
937 * uid. We don't just make perl setuid root because that loses the
938 * effective uid we had before invoking perl, if it was different from the
939 * uid.
13281fa4
LW
940 *
941 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
942 * be defined in suidperl only. suidperl must be setuid root. The
943 * Configure script will set this up for you if you want it.
944 */
a687059c 945
13281fa4
LW
946#ifdef DOSUID
947 if (fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
463ee0b2 948 croak("Can't stat script \"%s\"",origfilename);
13281fa4 949 if (statbuf.st_mode & (S_ISUID|S_ISGID)) {
79072805 950 I32 len;
13281fa4 951
a687059c 952#ifdef IAMSUID
fe14fcc3 953#ifndef HAS_SETREUID
a687059c
LW
954 /* On this access check to make sure the directories are readable,
955 * there is actually a small window that the user could use to make
956 * filename point to an accessible directory. So there is a faint
957 * chance that someone could execute a setuid script down in a
958 * non-accessible directory. I don't know what to do about that.
959 * But I don't think it's too important. The manual lies when
960 * it says access() is useful in setuid programs.
961 */
463ee0b2
LW
962 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
963 croak("Permission denied");
a687059c
LW
964#else
965 /* If we can swap euid and uid, then we can determine access rights
966 * with a simple stat of the file, and then compare device and
967 * inode to make sure we did stat() on the same file we opened.
968 * Then we just have to make sure he or she can execute it.
969 */
970 {
971 struct stat tmpstatbuf;
972
973 if (setreuid(euid,uid) < 0 || getuid() != euid || geteuid() != uid)
463ee0b2
LW
974 croak("Can't swap uid and euid"); /* really paranoid */
975 if (stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
976 croak("Permission denied"); /* testing full pathname here */
a687059c
LW
977 if (tmpstatbuf.st_dev != statbuf.st_dev ||
978 tmpstatbuf.st_ino != statbuf.st_ino) {
979 (void)fclose(rsfp);
79072805 980 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
a687059c
LW
981 fprintf(rsfp,
982"User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
983(Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
984 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
985 statbuf.st_dev, statbuf.st_ino,
463ee0b2 986 SvPVX(GvSV(curcop->cop_filegv)),
20188a90 987 statbuf.st_uid, statbuf.st_gid);
79072805 988 (void)my_pclose(rsfp);
a687059c 989 }
463ee0b2 990 croak("Permission denied\n");
a687059c
LW
991 }
992 if (setreuid(uid,euid) < 0 || getuid() != uid || geteuid() != euid)
463ee0b2 993 croak("Can't reswap uid and euid");
27e2fb84 994 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
463ee0b2 995 croak("Permission denied\n");
a687059c 996 }
fe14fcc3 997#endif /* HAS_SETREUID */
a687059c
LW
998#endif /* IAMSUID */
999
27e2fb84 1000 if (!S_ISREG(statbuf.st_mode))
463ee0b2 1001 croak("Permission denied");
27e2fb84 1002 if (statbuf.st_mode & S_IWOTH)
463ee0b2 1003 croak("Setuid/gid script is writable by world");
13281fa4 1004 doswitches = FALSE; /* -s is insecure in suid */
79072805 1005 curcop->cop_line++;
13281fa4
LW
1006 if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1007 strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */
463ee0b2 1008 croak("No #! line");
663a0e37
LW
1009 s = tokenbuf+2;
1010 if (*s == ' ') s++;
45d8adaa 1011 while (!isSPACE(*s)) s++;
27e2fb84 1012 if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
463ee0b2 1013 croak("Not a perl script");
a687059c 1014 while (*s == ' ' || *s == '\t') s++;
13281fa4
LW
1015 /*
1016 * #! arg must be what we saw above. They can invoke it by
1017 * mentioning suidperl explicitly, but they may not add any strange
1018 * arguments beyond what #! says if they do invoke suidperl that way.
1019 */
1020 len = strlen(validarg);
1021 if (strEQ(validarg," PHOOEY ") ||
45d8adaa 1022 strnNE(s,validarg,len) || !isSPACE(s[len]))
463ee0b2 1023 croak("Args must match #! line");
a687059c
LW
1024
1025#ifndef IAMSUID
1026 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1027 euid == statbuf.st_uid)
1028 if (!do_undump)
463ee0b2 1029 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
1030FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1031#endif /* IAMSUID */
13281fa4
LW
1032
1033 if (euid) { /* oops, we're not the setuid root perl */
a687059c 1034 (void)fclose(rsfp);
13281fa4 1035#ifndef IAMSUID
27e2fb84 1036 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1037 execv(buf, origargv); /* try again */
13281fa4 1038#endif
463ee0b2 1039 croak("Can't do setuid\n");
13281fa4
LW
1040 }
1041
83025b21 1042 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
fe14fcc3 1043#ifdef HAS_SETEGID
a687059c
LW
1044 (void)setegid(statbuf.st_gid);
1045#else
fe14fcc3 1046#ifdef HAS_SETREGID
a687059c
LW
1047 (void)setregid((GIDTYPE)-1,statbuf.st_gid);
1048#else
1049 setgid(statbuf.st_gid);
1050#endif
1051#endif
83025b21 1052 if (getegid() != statbuf.st_gid)
463ee0b2 1053 croak("Can't do setegid!\n");
83025b21 1054 }
a687059c
LW
1055 if (statbuf.st_mode & S_ISUID) {
1056 if (statbuf.st_uid != euid)
fe14fcc3 1057#ifdef HAS_SETEUID
a687059c
LW
1058 (void)seteuid(statbuf.st_uid); /* all that for this */
1059#else
fe14fcc3 1060#ifdef HAS_SETREUID
a687059c
LW
1061 (void)setreuid((UIDTYPE)-1,statbuf.st_uid);
1062#else
1063 setuid(statbuf.st_uid);
1064#endif
1065#endif
83025b21 1066 if (geteuid() != statbuf.st_uid)
463ee0b2 1067 croak("Can't do seteuid!\n");
a687059c 1068 }
83025b21 1069 else if (uid) { /* oops, mustn't run as root */
fe14fcc3 1070#ifdef HAS_SETEUID
a687059c
LW
1071 (void)seteuid((UIDTYPE)uid);
1072#else
fe14fcc3 1073#ifdef HAS_SETREUID
a687059c
LW
1074 (void)setreuid((UIDTYPE)-1,(UIDTYPE)uid);
1075#else
1076 setuid((UIDTYPE)uid);
1077#endif
1078#endif
83025b21 1079 if (geteuid() != uid)
463ee0b2 1080 croak("Can't do seteuid!\n");
83025b21 1081 }
ffed7fef 1082 uid = (int)getuid();
13281fa4 1083 euid = (int)geteuid();
ffed7fef
LW
1084 gid = (int)getgid();
1085 egid = (int)getegid();
463ee0b2 1086 tainting |= (euid != uid || egid != gid);
27e2fb84 1087 if (!cando(S_IXUSR,TRUE,&statbuf))
463ee0b2 1088 croak("Permission denied\n"); /* they can't do this */
13281fa4
LW
1089 }
1090#ifdef IAMSUID
1091 else if (preprocess)
463ee0b2 1092 croak("-P not allowed for setuid/setgid script\n");
13281fa4 1093 else
463ee0b2 1094 croak("Script is not setuid/setgid in suidperl\n");
13281fa4 1095#endif /* IAMSUID */
a687059c 1096#else /* !DOSUID */
a687059c
LW
1097 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1098#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
1099 fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
1100 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1101 ||
1102 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1103 )
1104 if (!do_undump)
463ee0b2 1105 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
1106FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1107#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1108 /* not set-id, must be wrapped */
a687059c 1109 }
13281fa4 1110#endif /* DOSUID */
79072805 1111}
13281fa4 1112
79072805
LW
1113static void
1114find_beginning()
1115{
79072805 1116 register char *s;
33b78306
LW
1117
1118 /* skip forward in input to the real script? */
1119
463ee0b2 1120 taint_not("-x");
33b78306 1121 while (doextract) {
79072805 1122 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
463ee0b2 1123 croak("No Perl script found in input\n");
33b78306
LW
1124 if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1125 ungetc('\n',rsfp); /* to keep line count right */
1126 doextract = FALSE;
1127 if (s = instr(s,"perl -")) {
1128 s += 6;
45d8adaa 1129 /*SUPPRESS 530*/
33b78306
LW
1130 while (s = moreswitches(s)) ;
1131 }
79072805 1132 if (cddir && chdir(cddir) < 0)
463ee0b2 1133 croak("Can't chdir to %s",cddir);
83025b21
LW
1134 }
1135 }
1136}
1137
79072805
LW
1138static void
1139init_debugger()
352d5a3a 1140{
79072805
LW
1141 GV* tmpgv;
1142
463ee0b2 1143 debstash = newHV();
79072805
LW
1144 GvHV(gv_fetchpv("_DB",TRUE)) = debstash;
1145 curstash = debstash;
1146 dbargs = GvAV(gv_AVadd((tmpgv = gv_fetchpv("args",TRUE))));
1147 SvMULTI_on(tmpgv);
1148 AvREAL_off(dbargs);
1149 DBgv = gv_fetchpv("DB",TRUE);
1150 SvMULTI_on(DBgv);
1151 DBline = gv_fetchpv("dbline",TRUE);
1152 SvMULTI_on(DBline);
1153 DBsub = gv_HVadd(tmpgv = gv_fetchpv("sub",TRUE));
1154 SvMULTI_on(tmpgv);
1155 DBsingle = GvSV((tmpgv = gv_fetchpv("single",TRUE)));
1156 SvMULTI_on(tmpgv);
1157 DBtrace = GvSV((tmpgv = gv_fetchpv("trace",TRUE)));
1158 SvMULTI_on(tmpgv);
1159 DBsignal = GvSV((tmpgv = gv_fetchpv("signal",TRUE)));
1160 SvMULTI_on(tmpgv);
1161 curstash = defstash;
352d5a3a
LW
1162}
1163
79072805
LW
1164static void
1165init_stack()
1166{
1167 stack = newAV();
1168 mainstack = stack; /* remember in case we switch stacks */
1169 AvREAL_off(stack); /* not a real array */
1170 av_fill(stack,127); av_fill(stack,-1); /* preextend stack */
1171
1172 stack_base = AvARRAY(stack);
1173 stack_sp = stack_base;
1174 stack_max = stack_base + 128;
1175
1176 New(54,markstack,64,int);
1177 markstack_ptr = markstack;
1178 markstack_max = markstack + 64;
1179
1180 New(54,scopestack,32,int);
1181 scopestack_ix = 0;
1182 scopestack_max = 32;
1183
1184 New(54,savestack,128,ANY);
1185 savestack_ix = 0;
1186 savestack_max = 128;
1187
1188 New(54,retstack,16,OP*);
1189 retstack_ix = 0;
1190 retstack_max = 16;
1191}
8d063cd8 1192
79072805
LW
1193static void
1194init_lexer()
8d063cd8 1195{
463ee0b2 1196 bufend = bufptr = SvPV(linestr, na);
79072805 1197 subname = newSVpv("main",4);
463ee0b2 1198 lex_start(); /* we never leave */
79072805 1199}
20188a90 1200
79072805
LW
1201static void
1202init_context_stack()
1203{
1204 New(50,cxstack,128,CONTEXT);
1205 DEBUG( {
1206 New(51,debname,128,char);
1207 New(52,debdelim,128,char);
1208 } )
378cc40b 1209}
33b78306 1210
79072805
LW
1211static void
1212init_predump_symbols()
45d8adaa 1213{
93a17b20 1214 GV *tmpgv;
79072805 1215
79072805
LW
1216 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE)), " ", 1);
1217
1218 stdingv = gv_fetchpv("STDIN",TRUE);
1219 SvMULTI_on(stdingv);
1220 if (!GvIO(stdingv))
1221 GvIO(stdingv) = newIO();
1222 GvIO(stdingv)->ifp = stdin;
1223 tmpgv = gv_fetchpv("stdin",TRUE);
1224 GvIO(tmpgv) = GvIO(stdingv);
1225 SvMULTI_on(tmpgv);
1226
1227 tmpgv = gv_fetchpv("STDOUT",TRUE);
1228 SvMULTI_on(tmpgv);
1229 if (!GvIO(tmpgv))
1230 GvIO(tmpgv) = newIO();
1231 GvIO(tmpgv)->ofp = GvIO(tmpgv)->ifp = stdout;
1232 defoutgv = tmpgv;
1233 tmpgv = gv_fetchpv("stdout",TRUE);
1234 GvIO(tmpgv) = GvIO(defoutgv);
1235 SvMULTI_on(tmpgv);
1236
1237 curoutgv = gv_fetchpv("STDERR",TRUE);
1238 SvMULTI_on(curoutgv);
1239 if (!GvIO(curoutgv))
1240 GvIO(curoutgv) = newIO();
1241 GvIO(curoutgv)->ofp = GvIO(curoutgv)->ifp = stderr;
1242 tmpgv = gv_fetchpv("stderr",TRUE);
1243 GvIO(tmpgv) = GvIO(curoutgv);
1244 SvMULTI_on(tmpgv);
1245 curoutgv = defoutgv; /* switch back to STDOUT */
1246
1247 statname = NEWSV(66,0); /* last filename we did stat on */
79072805 1248}
33b78306 1249
79072805
LW
1250static void
1251init_postdump_symbols(argc,argv,env)
1252register int argc;
1253register char **argv;
1254register char **env;
33b78306 1255{
79072805
LW
1256 char *s;
1257 SV *sv;
1258 GV* tmpgv;
fe14fcc3 1259
79072805
LW
1260 argc--,argv++; /* skip name of script */
1261 if (doswitches) {
1262 for (; argc > 0 && **argv == '-'; argc--,argv++) {
1263 if (!argv[0][1])
1264 break;
1265 if (argv[0][1] == '-') {
1266 argc--,argv++;
1267 break;
1268 }
93a17b20 1269 if (s = strchr(argv[0], '=')) {
79072805
LW
1270 *s++ = '\0';
1271 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE)),s);
1272 }
1273 else
1274 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE)),1);
fe14fcc3 1275 }
79072805
LW
1276 }
1277 toptarget = NEWSV(0,0);
1278 sv_upgrade(toptarget, SVt_PVFM);
1279 sv_setpvn(toptarget, "", 0);
1280 bodytarget = NEWSV(0,0);
1281 sv_upgrade(bodytarget, SVt_PVFM);
1282 sv_setpvn(bodytarget, "", 0);
1283 formtarget = bodytarget;
1284
79072805 1285 tainted = 1;
463ee0b2 1286 if (tmpgv = gv_fetchpv("0",TRUE)) {
79072805
LW
1287 sv_setpv(GvSV(tmpgv),origfilename);
1288 magicname("0", "0", 1);
1289 }
463ee0b2 1290 if (tmpgv = gv_fetchpv("\024",TRUE))
79072805 1291 time(&basetime);
463ee0b2 1292 if (tmpgv = gv_fetchpv("\030",TRUE))
79072805 1293 sv_setpv(GvSV(tmpgv),origargv[0]);
463ee0b2 1294 if (argvgv = gv_fetchpv("ARGV",TRUE)) {
79072805
LW
1295 SvMULTI_on(argvgv);
1296 (void)gv_AVadd(argvgv);
1297 av_clear(GvAVn(argvgv));
1298 for (; argc > 0; argc--,argv++) {
1299 (void)av_push(GvAVn(argvgv),newSVpv(argv[0],0));
1300 }
1301 }
463ee0b2 1302 if (envgv = gv_fetchpv("ENV",TRUE)) {
79072805
LW
1303 HV *hv;
1304 SvMULTI_on(envgv);
1305 hv = GvHVn(envgv);
463ee0b2 1306 hv_clear(hv);
79072805
LW
1307 if (env != environ)
1308 environ[0] = Nullch;
1309 for (; *env; env++) {
93a17b20 1310 if (!(s = strchr(*env,'=')))
79072805
LW
1311 continue;
1312 *s++ = '\0';
1313 sv = newSVpv(s--,0);
1314 (void)hv_store(hv, *env, s - *env, sv, 0);
1315 *s = '=';
fe14fcc3 1316 }
f511e57f 1317 hv_magic(hv, envgv, 'E');
79072805 1318 }
79072805 1319 tainted = 0;
463ee0b2 1320 if (tmpgv = gv_fetchpv("$",TRUE))
79072805
LW
1321 sv_setiv(GvSV(tmpgv),(I32)getpid());
1322
463ee0b2
LW
1323 if (dowarn)
1324 gv_check(defstash);
33b78306 1325}
34de22dd 1326
79072805
LW
1327static void
1328init_perllib()
34de22dd 1329{
463ee0b2
LW
1330 if (!tainting)
1331 incpush(getenv("PERLLIB"));
34de22dd 1332
79072805
LW
1333#ifndef PRIVLIB
1334#define PRIVLIB "/usr/local/lib/perl"
34de22dd 1335#endif
79072805
LW
1336 incpush(PRIVLIB);
1337 (void)av_push(GvAVn(incgv),newSVpv(".",1));
34de22dd 1338}
93a17b20
LW
1339
1340void
1341calllist(list)
1342AV* list;
1343{
1344 I32 i;
1345 I32 fill = AvFILL(list);
1346 jmp_buf oldtop;
1347 I32 sp = stack_sp - stack_base;
1348
1349 av_store(stack, ++sp, Nullsv); /* reserve spot for 1st return arg */
1350 Copy(top_env, oldtop, 1, jmp_buf);
1351
1352 for (i = 0; i <= fill; i++)
1353 {
1354 GV *gv = (GV*)av_shift(list);
1355 SV* tmpsv = NEWSV(0,0);
1356
1357 if (gv && GvCV(gv)) {
1358 gv_efullname(tmpsv, gv);
1359 if (setjmp(top_env)) {
1360 if (list == beginav)
1361 exit(1);
1362 }
1363 else {
463ee0b2 1364 perl_callback(SvPVX(tmpsv), sp, G_SCALAR, 0, 0);
93a17b20
LW
1365 }
1366 }
1367 sv_free(tmpsv);
1368 sv_free(gv);
1369 }
1370
1371 Copy(oldtop, top_env, 1, jmp_buf);
1372}
1373