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