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