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