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