This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Rewrite thread destruction system using linked list of threads.
[perl5.git] / perl.c
CommitLineData
a0d0e21e
LW
1/* perl.c
2 *
9607fc9c 3 * Copyright (c) 1987-1997 Larry Wall
a687059c 4 *
352d5a3a
LW
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
a687059c 7 *
8d063cd8
LW
8 */
9
a0d0e21e
LW
10/*
11 * "A ship then new they built for him/of mithril and of elven glass" --Bilbo
12 */
45d8adaa 13
378cc40b
LW
14#include "EXTERN.h"
15#include "perl.h"
a687059c 16#include "patchlevel.h"
378cc40b 17
df5cef82 18/* XXX If this causes problems, set i_unistd=undef in the hint file. */
a0d0e21e
LW
19#ifdef I_UNISTD
20#include <unistd.h>
21#endif
a0d0e21e 22
54310121 23#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
24char *getenv _((char *)); /* Usually in <stdlib.h> */
25#endif
26
71be2cbc 27dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n";
463ee0b2 28
a687059c
LW
29#ifdef IAMSUID
30#ifndef DOSUID
31#define DOSUID
32#endif
33#endif
378cc40b 34
a687059c
LW
35#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
36#ifdef DOSUID
37#undef DOSUID
38#endif
39#endif
8d063cd8 40
8ebc5c01 41#define I_REINIT \
42 STMT_START { \
43 chopset = " \n-"; \
44 copline = NOLINE; \
45 curcop = &compiling; \
46 curcopdb = NULL; \
47 cxstack_ix = -1; \
48 cxstack_max = 128; \
49 dbargs = 0; \
50 dlmax = 128; \
51 laststatval = -1; \
52 laststype = OP_STAT; \
53 maxscream = -1; \
54 maxsysfd = MAXSYSFD; \
55 statname = Nullsv; \
56 tmps_floor = -1; \
57 tmps_ix = -1; \
58 op_mask = NULL; \
59 dlmax = 128; \
60 laststatval = -1; \
61 laststype = OP_STAT; \
46fc3d4c 62 mess_sv = Nullsv; \
8ebc5c01 63 } STMT_END
64
a0d0e21e 65static void find_beginning _((void));
bbce6d69 66static void forbid_setid _((char *));
774d564b 67static void incpush _((char *, int));
748a9306 68static void init_ids _((void));
a0d0e21e
LW
69static void init_debugger _((void));
70static void init_lexer _((void));
71static void init_main_stash _((void));
72static void init_perllib _((void));
73static void init_postdump_symbols _((int, char **, char **));
74static void init_predump_symbols _((void));
f86702cc 75static void my_exit_jump _((void)) __attribute__((noreturn));
6e72f9df 76static void nuke_stacks _((void));
a0d0e21e 77static void open_script _((char *, bool, SV *));
ab821d7f 78static void usage _((char *));
96436eeb 79static void validate_suid _((char *, char*));
80
81static int fdscript = -1;
79072805 82
77a005ab
MB
83#if defined(DEBUGGING) && defined(USE_THREADS) && defined(__linux__)
84#include <asm/sigcontext.h>
85static void
86catch_sigsegv(int signo, struct sigcontext_struct sc)
87{
88 signal(SIGSEGV, SIG_DFL);
89 fprintf(stderr, "Segmentation fault dereferencing 0x%lx\n"
90 "return_address = 0x%lx, eip = 0x%lx\n",
91 sc.cr2, __builtin_return_address(0), sc.eip);
92 fprintf(stderr, "thread = 0x%lx\n", (unsigned long)THR);
93}
94#endif
95
93a17b20 96PerlInterpreter *
79072805
LW
97perl_alloc()
98{
93a17b20 99 PerlInterpreter *sv_interp;
79072805 100
8990e307 101 curinterp = 0;
93a17b20 102 New(53, sv_interp, 1, PerlInterpreter);
79072805
LW
103 return sv_interp;
104}
105
106void
107perl_construct( sv_interp )
93a17b20 108register PerlInterpreter *sv_interp;
79072805 109{
0f15f207 110#if defined(USE_THREADS) && !defined(FAKE_THREADS)
11343788 111 struct thread *thr;
0f15f207 112#endif
11343788 113
79072805
LW
114 if (!(curinterp = sv_interp))
115 return;
116
8990e307 117#ifdef MULTIPLICITY
93a17b20 118 Zero(sv_interp, 1, PerlInterpreter);
8990e307 119#endif
79072805 120
33f46ff6 121 /* Init the real globals (and main thread)? */
c116a00c 122 if (!linestr) {
11343788 123#ifdef USE_THREADS
33f46ff6 124 INIT_THREADS;
c116a00c
MB
125 New(53, thr, 1, struct thread);
126 MUTEX_INIT(&malloc_mutex);
127 MUTEX_INIT(&sv_mutex);
128 MUTEX_INIT(&eval_mutex);
129 COND_INIT(&eval_cond);
33f46ff6 130 MUTEX_INIT(&threads_mutex);
c116a00c
MB
131 COND_INIT(&nthreads_cond);
132 nthreads = 1;
133 cvcache = newHV();
c116a00c 134 curcop = &compiling;
33f46ff6
MB
135 thr->flags = THRf_NORMAL;
136 thr->next = thr;
137 thr->prev = thr;
0f15f207 138#ifdef FAKE_THREADS
c116a00c 139 self = thr;
33f46ff6 140 thr->next_run = thr->prev_run = thr;
c116a00c
MB
141 thr->wait_queue = 0;
142 thr->private = 0;
33f46ff6 143 thr->tid = 0;
0f15f207 144#else
c116a00c 145 self = pthread_self();
33f46ff6 146 if (pthread_key_create(&thr_key, 0))
c116a00c
MB
147 croak("panic: pthread_key_create");
148 if (pthread_setspecific(thr_key, (void *) thr))
149 croak("panic: pthread_setspecific");
150#endif /* FAKE_THREADS */
11343788
MB
151#endif /* USE_THREADS */
152
79072805 153 linestr = NEWSV(65,80);
ed6116ce 154 sv_upgrade(linestr,SVt_PVIV);
79072805 155
6e72f9df 156 if (!SvREADONLY(&sv_undef)) {
157 SvREADONLY_on(&sv_undef);
79072805 158
6e72f9df 159 sv_setpv(&sv_no,No);
160 SvNV(&sv_no);
161 SvREADONLY_on(&sv_no);
79072805 162
6e72f9df 163 sv_setpv(&sv_yes,Yes);
164 SvNV(&sv_yes);
165 SvREADONLY_on(&sv_yes);
166 }
79072805 167
c07a80fd 168 nrs = newSVpv("\n", 1);
169 rs = SvREFCNT_inc(nrs);
170
c23142e2 171 sighandlerp = sighandler;
44a8e56a 172 pidstatus = newHV();
173
79072805
LW
174#ifdef MSDOS
175 /*
176 * There is no way we can refer to them from Perl so close them to save
177 * space. The other alternative would be to provide STDAUX and STDPRN
178 * filehandles.
179 */
180 (void)fclose(stdaux);
181 (void)fclose(stdprn);
182#endif
183 }
184
8990e307 185#ifdef MULTIPLICITY
8ebc5c01 186 I_REINIT;
187 perl_destruct_level = 1;
188#else
189 if(perl_destruct_level > 0)
190 I_REINIT;
79072805
LW
191#endif
192
748a9306 193 init_ids();
a5f75d66 194
54310121 195 start_env.je_prev = NULL;
196 start_env.je_ret = -1;
197 start_env.je_mustcatch = TRUE;
198 top_env = &start_env;
f86702cc 199 STATUS_ALL_SUCCESS;
200
36477c24 201 SET_NUMERIC_STANDARD();
a5f75d66 202#if defined(SUBVERSION) && SUBVERSION > 0
e2666263 203 sprintf(patchlevel, "%7.5f", (double) 5
204 + ((double) PATCHLEVEL / (double) 1000)
205 + ((double) SUBVERSION / (double) 100000));
a5f75d66 206#else
e2666263 207 sprintf(patchlevel, "%5.3f", (double) 5 +
208 ((double) PATCHLEVEL / (double) 1000));
a5f75d66 209#endif
79072805 210
ab821d7f 211#if defined(LOCAL_PATCH_COUNT)
6e72f9df 212 localpatches = local_patches; /* For possible -v */
ab821d7f 213#endif
214
760ac839
LW
215 PerlIO_init(); /* Hook to IO system */
216
79072805 217 fdpid = newAV(); /* for remembering popen pids by fd */
8990e307 218
11343788
MB
219 init_stacks(ARGS);
220 DEBUG( {
221 New(51,debname,128,char);
222 New(52,debdelim,128,char);
223 } )
224
8990e307 225 ENTER;
79072805
LW
226}
227
228void
748a9306 229perl_destruct(sv_interp)
93a17b20 230register PerlInterpreter *sv_interp;
79072805 231{
11343788 232 dTHR;
748a9306 233 int destruct_level; /* 0=none, 1=full, 2=full with checks */
8990e307 234 I32 last_sv_count;
a0d0e21e 235 HV *hv;
33f46ff6 236 Thread t;
8990e307 237
79072805
LW
238 if (!(curinterp = sv_interp))
239 return;
748a9306 240
11343788 241#ifdef USE_THREADS
0f15f207 242#ifndef FAKE_THREADS
33f46ff6
MB
243 /* Detach any remaining joinable threads apart from ourself */
244 MUTEX_LOCK(&threads_mutex);
245 DEBUG_L(PerlIO_printf(PerlIO_stderr(),
246 "perl_destruct: detaching remaining %d threads\n",
247 nthreads - 1));
248 for (t = thr->next; t != thr; t = t->next) {
249 if (ThrSTATE(t) == THRf_NORMAL) {
250 DETACH(t);
251 ThrSETSTATE(t, THRf_DETACHED);
252 DEBUG_L(PerlIO_printf(PerlIO_stderr(), "...detached %p\n", t));
253 }
254 }
255 /* Now wait for the thread count nthreads to drop to one */
11343788
MB
256 while (nthreads > 1)
257 {
33f46ff6
MB
258 DEBUG_L(PerlIO_printf(PerlIO_stderr(),
259 "perl_destruct: waiting for %d threads\n",
260 nthreads - 1));
261 COND_WAIT(&nthreads_cond, &threads_mutex);
11343788
MB
262 }
263 /* At this point, we're the last thread */
33f46ff6 264 MUTEX_UNLOCK(&threads_mutex);
d9f997d7 265 DEBUG_L(PerlIO_printf(PerlIO_stderr(), "perl_destruct: armageddon has arrived\n"));
33f46ff6 266 MUTEX_DESTROY(&threads_mutex);
11343788 267 COND_DESTROY(&nthreads_cond);
0f15f207 268#endif /* !defined(FAKE_THREADS) */
11343788
MB
269#endif /* USE_THREADS */
270
748a9306 271 destruct_level = perl_destruct_level;
4633a7c4
LW
272#ifdef DEBUGGING
273 {
274 char *s;
5f05dabc 275 if (s = getenv("PERL_DESTRUCT_LEVEL")) {
276 int i = atoi(s);
277 if (destruct_level < i)
278 destruct_level = i;
279 }
4633a7c4
LW
280 }
281#endif
282
8990e307 283 LEAVE;
a0d0e21e
LW
284 FREETMPS;
285
ff0cee69 286 /* We must account for everything. */
287
288 /* Destroy the main CV and syntax tree */
6e72f9df 289 if (main_root) {
290 curpad = AvARRAY(comppad);
291 op_free(main_root);
ff0cee69 292 main_root = Nullop;
a0d0e21e 293 }
ff0cee69 294 main_start = Nullop;
295 SvREFCNT_dec(main_cv);
296 main_cv = Nullcv;
297
a0d0e21e
LW
298 if (sv_objcount) {
299 /*
300 * Try to destruct global references. We do this first so that the
301 * destructors and destructees still exist. Some sv's might remain.
302 * Non-referenced objects are on their own.
303 */
304
305 dirty = TRUE;
306 sv_clean_objs();
8990e307
LW
307 }
308
5cd24f17 309 /* unhook hooks which will soon be, or use, destroyed data */
310 SvREFCNT_dec(warnhook);
311 warnhook = Nullsv;
312 SvREFCNT_dec(diehook);
313 diehook = Nullsv;
314 SvREFCNT_dec(parsehook);
315 parsehook = Nullsv;
316
a0d0e21e 317 if (destruct_level == 0){
8990e307 318
a0d0e21e
LW
319 DEBUG_P(debprofdump());
320
321 /* The exit() function will do everything that needs doing. */
322 return;
323 }
5dd60ef7 324
5f05dabc 325 /* loosen bonds of global variables */
326
8ebc5c01 327 if(rsfp) {
328 (void)PerlIO_close(rsfp);
329 rsfp = Nullfp;
330 }
331
332 /* Filters for program text */
333 SvREFCNT_dec(rsfp_filters);
334 rsfp_filters = Nullav;
335
336 /* switches */
337 preprocess = FALSE;
338 minus_n = FALSE;
339 minus_p = FALSE;
340 minus_l = FALSE;
341 minus_a = FALSE;
342 minus_F = FALSE;
343 doswitches = FALSE;
344 dowarn = FALSE;
345 doextract = FALSE;
346 sawampersand = FALSE; /* must save all match strings */
347 sawstudy = FALSE; /* do fbm_instr on all strings */
348 sawvec = FALSE;
349 unsafe = FALSE;
350
351 Safefree(inplace);
352 inplace = Nullch;
353
354 Safefree(e_tmpname);
355 e_tmpname = Nullch;
356
357 if (e_fp) {
358 PerlIO_close(e_fp);
359 e_fp = Nullfp;
360 }
361
362 /* magical thingies */
363
364 Safefree(ofs); /* $, */
365 ofs = Nullch;
5f05dabc 366
8ebc5c01 367 Safefree(ors); /* $\ */
368 ors = Nullch;
369
370 SvREFCNT_dec(nrs); /* $\ helper */
5f05dabc 371 nrs = Nullsv;
372
8ebc5c01 373 multiline = 0; /* $* */
5f05dabc 374
8ebc5c01 375 SvREFCNT_dec(statname);
5f05dabc 376 statname = Nullsv;
377 statgv = Nullgv;
5f05dabc 378
8ebc5c01 379 /* defgv, aka *_ should be taken care of elsewhere */
380
381#if 0 /* just about all regexp stuff, seems to be ok */
382
383 /* shortcuts to regexp stuff */
384 leftgv = Nullgv;
385 ampergv = Nullgv;
386
387 SAVEFREEOP(curpm);
388 SAVEFREEOP(oldlastpm); /* for saving regexp context during debugger */
389
390 regprecomp = NULL; /* uncompiled string. */
391 regparse = NULL; /* Input-scan pointer. */
392 regxend = NULL; /* End of input for compile */
393 regnpar = 0; /* () count. */
394 regcode = NULL; /* Code-emit pointer; &regdummy = don't. */
395 regsize = 0; /* Code size. */
396 regnaughty = 0; /* How bad is this pattern? */
397 regsawback = 0; /* Did we see \1, ...? */
398
399 reginput = NULL; /* String-input pointer. */
400 regbol = NULL; /* Beginning of input, for ^ check. */
401 regeol = NULL; /* End of input, for $ check. */
402 regstartp = (char **)NULL; /* Pointer to startp array. */
403 regendp = (char **)NULL; /* Ditto for endp. */
404 reglastparen = 0; /* Similarly for lastparen. */
405 regtill = NULL; /* How far we are required to go. */
406 regflags = 0; /* are we folding, multilining? */
407 regprev = (char)NULL; /* char before regbol, \n if none */
408
409#endif /* if 0 */
410
411 /* clean up after study() */
412 SvREFCNT_dec(lastscream);
413 lastscream = Nullsv;
414 Safefree(screamfirst);
415 screamfirst = 0;
416 Safefree(screamnext);
417 screamnext = 0;
418
419 /* startup and shutdown function lists */
420 SvREFCNT_dec(beginav);
421 SvREFCNT_dec(endav);
77a005ab 422 SvREFCNT_dec(initav);
5618dfe8 423 beginav = Nullav;
5618dfe8 424 endav = Nullav;
77a005ab 425 initav = Nullav;
5618dfe8 426
8ebc5c01 427 /* temp stack during pp_sort() */
428 SvREFCNT_dec(sortstack);
429 sortstack = Nullav;
430
431 /* shortcuts just get cleared */
432 envgv = Nullgv;
433 siggv = Nullgv;
434 incgv = Nullgv;
435 errgv = Nullgv;
436 argvgv = Nullgv;
437 argvoutgv = Nullgv;
438 stdingv = Nullgv;
439 last_in_gv = Nullgv;
440
441 /* reset so print() ends up where we expect */
442 setdefout(Nullgv);
443
a0d0e21e 444 /* Prepare to destruct main symbol table. */
5f05dabc 445
a0d0e21e 446 hv = defstash;
85e6fe83 447 defstash = 0;
a0d0e21e
LW
448 SvREFCNT_dec(hv);
449
450 FREETMPS;
451 if (destruct_level >= 2) {
452 if (scopestack_ix != 0)
ff0cee69 453 warn("Unbalanced scopes: %ld more ENTERs than LEAVEs\n",
454 (long)scopestack_ix);
a0d0e21e 455 if (savestack_ix != 0)
ff0cee69 456 warn("Unbalanced saves: %ld more saves than restores\n",
457 (long)savestack_ix);
a0d0e21e 458 if (tmps_floor != -1)
ff0cee69 459 warn("Unbalanced tmps: %ld more allocs than frees\n",
460 (long)tmps_floor + 1);
a0d0e21e 461 if (cxstack_ix != -1)
ff0cee69 462 warn("Unbalanced context: %ld more PUSHes than POPs\n",
463 (long)cxstack_ix + 1);
a0d0e21e 464 }
8990e307
LW
465
466 /* Now absolutely destruct everything, somehow or other, loops or no. */
8990e307 467 last_sv_count = 0;
6e72f9df 468 SvFLAGS(strtab) |= SVTYPEMASK; /* don't clean out strtab now */
8990e307
LW
469 while (sv_count != 0 && sv_count != last_sv_count) {
470 last_sv_count = sv_count;
471 sv_clean_all();
472 }
6e72f9df 473 SvFLAGS(strtab) &= ~SVTYPEMASK;
474 SvFLAGS(strtab) |= SVt_PVHV;
475
476 /* Destruct the global string table. */
477 {
478 /* Yell and reset the HeVAL() slots that are still holding refcounts,
479 * so that sv_free() won't fail on them.
480 */
481 I32 riter;
482 I32 max;
483 HE *hent;
484 HE **array;
485
486 riter = 0;
487 max = HvMAX(strtab);
488 array = HvARRAY(strtab);
489 hent = array[0];
490 for (;;) {
491 if (hent) {
492 warn("Unbalanced string table refcount: (%d) for \"%s\"",
493 HeVAL(hent) - Nullsv, HeKEY(hent));
494 HeVAL(hent) = Nullsv;
495 hent = HeNEXT(hent);
496 }
497 if (!hent) {
498 if (++riter > max)
499 break;
500 hent = array[riter];
501 }
502 }
503 }
504 SvREFCNT_dec(strtab);
505
8990e307 506 if (sv_count != 0)
ff0cee69 507 warn("Scalars leaked: %ld\n", (long)sv_count);
6e72f9df 508
4633a7c4 509 sv_free_arenas();
44a8e56a 510
511 /* No SVs have survived, need to clean out */
512 linestr = NULL;
513 pidstatus = Nullhv;
6e72f9df 514 if (origfilename)
515 Safefree(origfilename);
516 nuke_stacks();
fc36a67e 517 hints = 0; /* Reset hints. Should hints be per-interpreter ? */
a0d0e21e
LW
518
519 DEBUG_P(debprofdump());
11343788
MB
520#ifdef USE_THREADS
521 MUTEX_DESTROY(&sv_mutex);
522 MUTEX_DESTROY(&malloc_mutex);
523 MUTEX_DESTROY(&eval_mutex);
c116a00c 524 COND_DESTROY(&eval_cond);
11343788 525#endif /* USE_THREADS */
fc36a67e 526
527 /* As the absolutely last thing, free the non-arena SV for mess() */
528
529 if (mess_sv) {
530 /* we know that type >= SVt_PV */
531 SvOOK_off(mess_sv);
532 Safefree(SvPVX(mess_sv));
533 Safefree(SvANY(mess_sv));
534 Safefree(mess_sv);
535 mess_sv = Nullsv;
536 }
79072805
LW
537}
538
539void
540perl_free(sv_interp)
93a17b20 541PerlInterpreter *sv_interp;
79072805
LW
542{
543 if (!(curinterp = sv_interp))
544 return;
545 Safefree(sv_interp);
546}
547
548int
a0d0e21e 549perl_parse(sv_interp, xsinit, argc, argv, env)
93a17b20 550PerlInterpreter *sv_interp;
a0d0e21e
LW
551void (*xsinit)_((void));
552int argc;
553char **argv;
79072805 554char **env;
8d063cd8 555{
11343788 556 dTHR;
79072805 557 register SV *sv;
8d063cd8 558 register char *s;
1a30305b 559 char *scriptname = NULL;
a0d0e21e 560 VOL bool dosearch = FALSE;
13281fa4 561 char *validarg = "";
2ae324a7 562 I32 oldscope;
748a9306 563 AV* comppadlist;
54310121 564 dJMPENV;
22921e25 565 int ret;
8d063cd8 566
a687059c
LW
567#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
568#ifdef IAMSUID
569#undef IAMSUID
463ee0b2 570 croak("suidperl is no longer needed since the kernel can now execute\n\
a687059c
LW
571setuid perl scripts securely.\n");
572#endif
573#endif
574
79072805
LW
575 if (!(curinterp = sv_interp))
576 return 255;
577
6e72f9df 578#if defined(NeXT) && defined(__DYNAMIC__)
579 _dyld_lookup_and_bind
580 ("__environ", (unsigned long *) &environ_pointer, NULL);
581#endif /* environ */
582
ac58e20f
LW
583 origargv = argv;
584 origargc = argc;
a0d0e21e 585#ifndef VMS /* VMS doesn't have environ array */
fe14fcc3 586 origenviron = environ;
a0d0e21e 587#endif
ab821d7f 588 e_tmpname = Nullch;
a0d0e21e
LW
589
590 if (do_undump) {
591
592 /* Come here if running an undumped a.out. */
593
594 origfilename = savepv(argv[0]);
595 do_undump = FALSE;
596 cxstack_ix = -1; /* start label stack again */
748a9306 597 init_ids();
a0d0e21e
LW
598 init_postdump_symbols(argc,argv,env);
599 return 0;
600 }
601
ff0cee69 602 if (main_root) {
603 curpad = AvARRAY(comppad);
a0d0e21e 604 op_free(main_root);
ff0cee69 605 main_root = Nullop;
606 }
607 main_start = Nullop;
608 SvREFCNT_dec(main_cv);
609 main_cv = Nullcv;
79072805 610
f86702cc 611 time(&basetime);
2ae324a7 612 oldscope = scopestack_ix;
f86702cc 613
22921e25
CS
614 JMPENV_PUSH(ret);
615 switch (ret) {
79072805 616 case 1:
f86702cc 617 STATUS_ALL_FAILURE;
618 /* FALL THROUGH */
79072805 619 case 2:
f86702cc 620 /* my_exit() was called */
2ae324a7 621 while (scopestack_ix > oldscope)
622 LEAVE;
84902520 623 FREETMPS;
8990e307
LW
624 curstash = defstash;
625 if (endav)
68dc0745 626 call_list(oldscope, endav);
54310121 627 JMPENV_POP;
f86702cc 628 return STATUS_NATIVE_EXPORT;
79072805 629 case 3:
54310121 630 JMPENV_POP;
760ac839 631 PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");
8990e307 632 return 1;
79072805
LW
633 }
634
79072805
LW
635 sv_setpvn(linestr,"",0);
636 sv = newSVpv("",0); /* first used for -I flags */
8990e307 637 SAVEFREESV(sv);
79072805 638 init_main_stash();
54310121 639
33b78306 640 for (argc--,argv++; argc > 0; argc--,argv++) {
8d063cd8
LW
641 if (argv[0][0] != '-' || !argv[0][1])
642 break;
13281fa4
LW
643#ifdef DOSUID
644 if (*validarg)
645 validarg = " PHOOEY ";
646 else
647 validarg = argv[0];
648#endif
649 s = argv[0]+1;
8d063cd8 650 reswitch:
13281fa4 651 switch (*s) {
27e2fb84 652 case '0':
2304df62 653 case 'F':
378cc40b 654 case 'a':
33b78306 655 case 'c':
a687059c 656 case 'd':
8d063cd8 657 case 'D':
4633a7c4 658 case 'h':
33b78306 659 case 'i':
fe14fcc3 660 case 'l':
1a30305b 661 case 'M':
662 case 'm':
33b78306
LW
663 case 'n':
664 case 'p':
79072805 665 case 's':
33b78306
LW
666 case 'u':
667 case 'U':
668 case 'v':
669 case 'w':
670 if (s = moreswitches(s))
671 goto reswitch;
8d063cd8 672 break;
33b78306 673
f86702cc 674 case 'T':
675 tainting = TRUE;
676 s++;
677 goto reswitch;
678
8d063cd8 679 case 'e':
a687059c 680 if (euid != uid || egid != gid)
463ee0b2 681 croak("No -e allowed in setuid scripts");
8d063cd8 682 if (!e_fp) {
a0d0e21e 683 e_tmpname = savepv(TMPPATH);
a687059c 684 (void)mktemp(e_tmpname);
83025b21 685 if (!*e_tmpname)
463ee0b2 686 croak("Can't mktemp()");
760ac839 687 e_fp = PerlIO_open(e_tmpname,"w");
33b78306 688 if (!e_fp)
463ee0b2 689 croak("Cannot open temporary file");
8d063cd8 690 }
552a7a9b 691 if (*++s)
692 PerlIO_puts(e_fp,s);
693 else if (argv[1]) {
760ac839 694 PerlIO_puts(e_fp,argv[1]);
33b78306
LW
695 argc--,argv++;
696 }
552a7a9b 697 else
698 croak("No code specified for -e");
760ac839 699 (void)PerlIO_putc(e_fp,'\n');
8d063cd8
LW
700 break;
701 case 'I':
bbce6d69 702 forbid_setid("-I");
79072805
LW
703 sv_catpv(sv,"-");
704 sv_catpv(sv,s);
705 sv_catpv(sv," ");
a687059c 706 if (*++s) {
774d564b 707 incpush(s, TRUE);
378cc40b 708 }
33b78306 709 else if (argv[1]) {
774d564b 710 incpush(argv[1], TRUE);
79072805 711 sv_catpv(sv,argv[1]);
8d063cd8 712 argc--,argv++;
79072805 713 sv_catpv(sv," ");
8d063cd8
LW
714 }
715 break;
8d063cd8 716 case 'P':
bbce6d69 717 forbid_setid("-P");
8d063cd8 718 preprocess = TRUE;
13281fa4 719 s++;
8d063cd8 720 goto reswitch;
378cc40b 721 case 'S':
bbce6d69 722 forbid_setid("-S");
378cc40b 723 dosearch = TRUE;
13281fa4 724 s++;
378cc40b 725 goto reswitch;
1a30305b 726 case 'V':
727 if (!preambleav)
728 preambleav = newAV();
729 av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
730 if (*++s != ':') {
6e72f9df 731 Sv = newSVpv("print myconfig();",0);
732#ifdef VMS
733 sv_catpv(Sv,"print \"\\nCharacteristics of this PERLSHR image: \\n\",");
734#else
735 sv_catpv(Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\",");
736#endif
54310121 737#if defined(DEBUGGING) || defined(NO_EMBED) || defined(MULTIPLICITY)
46fc3d4c 738 sv_catpv(Sv,"\" Compile-time options:");
6e72f9df 739# ifdef DEBUGGING
46fc3d4c 740 sv_catpv(Sv," DEBUGGING");
6e72f9df 741# endif
54310121 742# ifdef NO_EMBED
46fc3d4c 743 sv_catpv(Sv," NO_EMBED");
6e72f9df 744# endif
745# ifdef MULTIPLICITY
46fc3d4c 746 sv_catpv(Sv," MULTIPLICITY");
6e72f9df 747# endif
46fc3d4c 748 sv_catpv(Sv,"\\n\",");
6e72f9df 749#endif
750#if defined(LOCAL_PATCH_COUNT)
54310121 751 if (LOCAL_PATCH_COUNT > 0) {
752 int i;
5cd24f17 753 sv_catpv(Sv,"\" Locally applied patches:\\n\",");
6e72f9df 754 for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
46fc3d4c 755 if (localpatches[i])
756 sv_catpvf(Sv,"\" \\t%s\\n\",",localpatches[i]);
6e72f9df 757 }
758 }
759#endif
46fc3d4c 760 sv_catpvf(Sv,"\" Built under %s\\n\"",OSNAME);
6e72f9df 761#ifdef __DATE__
762# ifdef __TIME__
46fc3d4c 763 sv_catpvf(Sv,",\" Compiled at %s %s\\n\"",__DATE__,__TIME__);
6e72f9df 764# else
46fc3d4c 765 sv_catpvf(Sv,",\" Compiled on %s\\n\"",__DATE__);
6e72f9df 766# endif
6e72f9df 767#endif
54310121 768 sv_catpv(Sv, "; \
769$\"=\"\\n \"; \
770@env = map { \"$_=\\\"$ENV{$_}\\\"\" } sort grep {/^PERL/} keys %ENV; \
771print \" \\%ENV:\\n @env\\n\" if @env; \
772print \" \\@INC:\\n @INC\\n\";");
1a30305b 773 }
774 else {
775 Sv = newSVpv("config_vars(qw(",0);
776 sv_catpv(Sv, ++s);
777 sv_catpv(Sv, "))");
778 s += strlen(s);
779 }
780 av_push(preambleav, Sv);
c07a80fd 781 scriptname = BIT_BUCKET; /* don't look for script or read stdin */
1a30305b 782 goto reswitch;
33b78306
LW
783 case 'x':
784 doextract = TRUE;
13281fa4 785 s++;
33b78306 786 if (*s)
a0d0e21e 787 cddir = savepv(s);
33b78306 788 break;
8d063cd8 789 case '-':
90248788
TB
790 if (*++s) { /* catch use of gnu style long options */
791 if (strEQ(s, "version")) {
792 s = "v";
793 goto reswitch;
794 }
795 if (strEQ(s, "help")) {
796 s = "h";
797 goto reswitch;
798 }
799 croak("Unrecognized switch: --%s (-h will show valid options)",s);
800 }
8d063cd8
LW
801 argc--,argv++;
802 goto switch_end;
803 case 0:
804 break;
805 default:
90248788 806 croak("Unrecognized switch: -%s (-h will show valid options)",s);
8d063cd8
LW
807 }
808 }
809 switch_end:
54310121 810
811 if (!tainting && (s = getenv("PERL5OPT"))) {
812 for (;;) {
813 while (isSPACE(*s))
814 s++;
815 if (*s == '-') {
816 s++;
817 if (isSPACE(*s))
818 continue;
819 }
820 if (!*s)
821 break;
822 if (!strchr("DIMUdmw", *s))
823 croak("Illegal switch in PERL5OPT: -%c", *s);
824 s = moreswitches(s);
825 }
826 }
827
1a30305b 828 if (!scriptname)
829 scriptname = argv[0];
8d063cd8 830 if (e_fp) {
68dc0745 831 if (PerlIO_flush(e_fp) || PerlIO_error(e_fp) || PerlIO_close(e_fp)) {
832#ifndef MULTIPLICITY
833 warn("Did you forget to compile with -DMULTIPLICITY?");
834#endif
2304df62 835 croak("Can't write to temp file for -e: %s", Strerror(errno));
68dc0745 836 }
ab821d7f 837 e_fp = Nullfp;
8d063cd8 838 argc++,argv--;
45d8adaa 839 scriptname = e_tmpname;
8d063cd8 840 }
79072805
LW
841 else if (scriptname == Nullch) {
842#ifdef MSDOS
760ac839 843 if ( isatty(PerlIO_fileno(PerlIO_stdin())) )
55497cff 844 moreswitches("h");
fe14fcc3 845#endif
79072805
LW
846 scriptname = "-";
847 }
fe14fcc3 848
79072805 849 init_perllib();
8d063cd8 850
79072805 851 open_script(scriptname,dosearch,sv);
8d063cd8 852
96436eeb 853 validate_suid(validarg, scriptname);
378cc40b 854
79072805
LW
855 if (doextract)
856 find_beginning();
857
4fdae800 858 main_cv = compcv = (CV*)NEWSV(1104,0);
748a9306 859 sv_upgrade((SV *)compcv, SVt_PVCV);
07055b4c 860 CvUNIQUE_on(compcv);
748a9306 861
6e72f9df 862 comppad = newAV();
79072805
LW
863 av_push(comppad, Nullsv);
864 curpad = AvARRAY(comppad);
6e72f9df 865 comppad_name = newAV();
8990e307 866 comppad_name_fill = 0;
e858de61
MB
867 min_intro_pending = 0;
868 padix = 0;
11343788
MB
869#ifdef USE_THREADS
870 av_store(comppad_name, 0, newSVpv("@_", 2));
e858de61 871 curpad[0] = (SV*)newAV();
6d4ff0d2 872 SvPADMY_on(curpad[0]); /* XXX Needed? */
e858de61 873 CvOWNER(compcv) = 0;
12ca11f6 874 New(666, CvMUTEXP(compcv), 1, perl_mutex);
e858de61 875 MUTEX_INIT(CvMUTEXP(compcv));
11343788 876#endif /* USE_THREADS */
79072805 877
748a9306
LW
878 comppadlist = newAV();
879 AvREAL_off(comppadlist);
8e07c86e
AD
880 av_store(comppadlist, 0, (SV*)comppad_name);
881 av_store(comppadlist, 1, (SV*)comppad);
748a9306
LW
882 CvPADLIST(compcv) = comppadlist;
883
6e72f9df 884 boot_core_UNIVERSAL();
a0d0e21e
LW
885 if (xsinit)
886 (*xsinit)(); /* in case linked C routines want magical variables */
ad2e33dc 887#if defined(VMS) || defined(WIN32)
748a9306
LW
888 init_os_extras();
889#endif
93a17b20 890
77a005ab
MB
891#if defined(DEBUGGING) && defined(USE_THREADS) && defined(__linux__)
892 DEBUG_L(signal(SIGSEGV, (void(*)(int))catch_sigsegv););
893#endif
894
93a17b20 895 init_predump_symbols();
8990e307
LW
896 if (!do_undump)
897 init_postdump_symbols(argc,argv,env);
93a17b20 898
79072805
LW
899 init_lexer();
900
901 /* now parse the script */
902
903 error_count = 0;
904 if (yyparse() || error_count) {
905 if (minus_c)
463ee0b2 906 croak("%s had compilation errors.\n", origfilename);
79072805 907 else {
463ee0b2 908 croak("Execution of %s aborted due to compilation errors.\n",
79072805 909 origfilename);
378cc40b 910 }
79072805
LW
911 }
912 curcop->cop_line = 0;
913 curstash = defstash;
914 preprocess = FALSE;
ab821d7f 915 if (e_tmpname) {
79072805 916 (void)UNLINK(e_tmpname);
ab821d7f 917 Safefree(e_tmpname);
918 e_tmpname = Nullch;
378cc40b 919 }
a687059c 920
93a17b20 921 /* now that script is parsed, we can modify record separator */
c07a80fd 922 SvREFCNT_dec(rs);
923 rs = SvREFCNT_inc(nrs);
924 sv_setsv(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs);
45d8adaa 925
79072805
LW
926 if (do_undump)
927 my_unexec();
928
8990e307
LW
929 if (dowarn)
930 gv_check(defstash);
931
a0d0e21e
LW
932 LEAVE;
933 FREETMPS;
c07a80fd 934
3562ef9b 935#ifdef MYMALLOC
c07a80fd 936 if ((s=getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
937 dump_mstats("after compilation:");
938#endif
939
a0d0e21e
LW
940 ENTER;
941 restartop = 0;
54310121 942 JMPENV_POP;
79072805
LW
943 return 0;
944}
945
946int
947perl_run(sv_interp)
93a17b20 948PerlInterpreter *sv_interp;
79072805 949{
11343788 950 dTHR;
2ae324a7 951 I32 oldscope;
22921e25
CS
952 dJMPENV;
953 int ret;
2ae324a7 954
79072805
LW
955 if (!(curinterp = sv_interp))
956 return 255;
2ae324a7 957
958 oldscope = scopestack_ix;
959
22921e25
CS
960 JMPENV_PUSH(ret);
961 switch (ret) {
79072805
LW
962 case 1:
963 cxstack_ix = -1; /* start context stack again */
964 break;
965 case 2:
f86702cc 966 /* my_exit() was called */
2ae324a7 967 while (scopestack_ix > oldscope)
968 LEAVE;
84902520 969 FREETMPS;
79072805 970 curstash = defstash;
93a17b20 971 if (endav)
68dc0745 972 call_list(oldscope, endav);
3562ef9b 973#ifdef MYMALLOC
c07a80fd 974 if (getenv("PERL_DEBUG_MSTATS"))
975 dump_mstats("after execution: ");
976#endif
54310121 977 JMPENV_POP;
f86702cc 978 return STATUS_NATIVE_EXPORT;
79072805
LW
979 case 3:
980 if (!restartop) {
760ac839 981 PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
a0d0e21e 982 FREETMPS;
54310121 983 JMPENV_POP;
8990e307 984 return 1;
83025b21 985 }
6e72f9df 986 if (curstack != mainstack) {
79072805 987 dSP;
6e72f9df 988 SWITCHSTACK(curstack, mainstack);
79072805
LW
989 }
990 break;
8d063cd8 991 }
79072805 992
760ac839 993 DEBUG_r(PerlIO_printf(PerlIO_stderr(), "%s $` $& $' support.\n",
6e72f9df 994 sawampersand ? "Enabling" : "Omitting"));
995
79072805
LW
996 if (!restartop) {
997 DEBUG_x(dump_all());
760ac839 998 DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n"));
11343788 999#ifdef USE_THREADS
5dc0d613
MB
1000 DEBUG_L(PerlIO_printf(Perl_debug_log, "main thread is 0x%lx\n",
1001 (unsigned long) thr));
11343788 1002#endif /* USE_THREADS */
79072805
LW
1003
1004 if (minus_c) {
760ac839 1005 PerlIO_printf(PerlIO_stderr(), "%s syntax OK\n", origfilename);
79072805
LW
1006 my_exit(0);
1007 }
84902520 1008 if (PERLDB_SINGLE && DBsingle)
a0d0e21e 1009 sv_setiv(DBsingle, 1);
7d07dbc2
MB
1010 if (initav)
1011 call_list(oldscope, initav);
45d8adaa 1012 }
79072805
LW
1013
1014 /* do it */
1015
1016 if (restartop) {
1017 op = restartop;
1018 restartop = 0;
ab821d7f 1019 runops();
79072805
LW
1020 }
1021 else if (main_start) {
4fdae800 1022 CvDEPTH(main_cv) = 1;
79072805 1023 op = main_start;
ab821d7f 1024 runops();
79072805 1025 }
79072805
LW
1026
1027 my_exit(0);
54310121 1028 /* NOTREACHED */
a0d0e21e 1029 return 0;
79072805
LW
1030}
1031
a0d0e21e
LW
1032SV*
1033perl_get_sv(name, create)
1034char* name;
1035I32 create;
1036{
1037 GV* gv = gv_fetchpv(name, create, SVt_PV);
1038 if (gv)
1039 return GvSV(gv);
1040 return Nullsv;
1041}
1042
1043AV*
1044perl_get_av(name, create)
1045char* name;
1046I32 create;
1047{
1048 GV* gv = gv_fetchpv(name, create, SVt_PVAV);
1049 if (create)
1050 return GvAVn(gv);
1051 if (gv)
1052 return GvAV(gv);
1053 return Nullav;
1054}
1055
1056HV*
1057perl_get_hv(name, create)
1058char* name;
1059I32 create;
1060{
1061 GV* gv = gv_fetchpv(name, create, SVt_PVHV);
1062 if (create)
1063 return GvHVn(gv);
1064 if (gv)
1065 return GvHV(gv);
1066 return Nullhv;
1067}
1068
1069CV*
1070perl_get_cv(name, create)
1071char* name;
1072I32 create;
1073{
1074 GV* gv = gv_fetchpv(name, create, SVt_PVCV);
8ebc5c01 1075 if (create && !GvCVu(gv))
774d564b 1076 return newSUB(start_subparse(FALSE, 0),
a0d0e21e 1077 newSVOP(OP_CONST, 0, newSVpv(name,0)),
4633a7c4 1078 Nullop,
a0d0e21e
LW
1079 Nullop);
1080 if (gv)
8ebc5c01 1081 return GvCVu(gv);
a0d0e21e
LW
1082 return Nullcv;
1083}
1084
79072805
LW
1085/* Be sure to refetch the stack pointer after calling these routines. */
1086
a0d0e21e
LW
1087I32
1088perl_call_argv(subname, flags, argv)
8990e307 1089char *subname;
a0d0e21e
LW
1090I32 flags; /* See G_* flags in cop.h */
1091register char **argv; /* null terminated arg list */
8990e307 1092{
11343788 1093 dTHR;
a0d0e21e 1094 dSP;
8990e307 1095
a0d0e21e
LW
1096 PUSHMARK(sp);
1097 if (argv) {
8990e307 1098 while (*argv) {
a0d0e21e 1099 XPUSHs(sv_2mortal(newSVpv(*argv,0)));
8990e307
LW
1100 argv++;
1101 }
a0d0e21e 1102 PUTBACK;
8990e307 1103 }
a0d0e21e 1104 return perl_call_pv(subname, flags);
8990e307
LW
1105}
1106
a0d0e21e
LW
1107I32
1108perl_call_pv(subname, flags)
1109char *subname; /* name of the subroutine */
1110I32 flags; /* See G_* flags in cop.h */
1111{
1112 return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags);
1113}
1114
1115I32
1116perl_call_method(methname, flags)
1117char *methname; /* name of the subroutine */
1118I32 flags; /* See G_* flags in cop.h */
1119{
11343788 1120 dTHR;
a0d0e21e
LW
1121 dSP;
1122 OP myop;
1123 if (!op)
1124 op = &myop;
1125 XPUSHs(sv_2mortal(newSVpv(methname,0)));
1126 PUTBACK;
11343788 1127 pp_method(ARGS);
a0d0e21e
LW
1128 return perl_call_sv(*stack_sp--, flags);
1129}
1130
1131/* May be called with any of a CV, a GV, or an SV containing the name. */
1132I32
1133perl_call_sv(sv, flags)
1134SV* sv;
1135I32 flags; /* See G_* flags in cop.h */
1136{
11343788 1137 dTHR;
a0d0e21e
LW
1138 LOGOP myop; /* fake syntax tree node */
1139 SV** sp = stack_sp;
aa689395 1140 I32 oldmark;
a0d0e21e 1141 I32 retval;
a0d0e21e 1142 I32 oldscope;
6e72f9df 1143 static CV *DBcv;
54310121 1144 bool oldcatch = CATCH_GET;
1145 dJMPENV;
22921e25 1146 int ret;
d6602a8c 1147 OP* oldop = op;
1e422769 1148
a0d0e21e
LW
1149 if (flags & G_DISCARD) {
1150 ENTER;
1151 SAVETMPS;
1152 }
1153
aa689395 1154 Zero(&myop, 1, LOGOP);
54310121 1155 myop.op_next = Nullop;
f51d4af5 1156 if (!(flags & G_NOARGS))
aa689395 1157 myop.op_flags |= OPf_STACKED;
54310121 1158 myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
1159 (flags & G_ARRAY) ? OPf_WANT_LIST :
1160 OPf_WANT_SCALAR);
462e5cf6 1161 SAVEOP();
a0d0e21e 1162 op = (OP*)&myop;
aa689395 1163
a0d0e21e
LW
1164 EXTEND(stack_sp, 1);
1165 *++stack_sp = sv;
aa689395 1166 oldmark = TOPMARK;
a0d0e21e
LW
1167 oldscope = scopestack_ix;
1168
84902520 1169 if (PERLDB_SUB && curstash != debstash
36477c24 1170 /* Handle first BEGIN of -d. */
1171 && (DBcv || (DBcv = GvCV(DBsub)))
1172 /* Try harder, since this may have been a sighandler, thus
1173 * curstash may be meaningless. */
1174 && (SvTYPE(sv) != SVt_PVCV || CvSTASH((CV*)sv) != debstash))
6e72f9df 1175 op->op_private |= OPpENTERSUB_DB;
a0d0e21e
LW
1176
1177 if (flags & G_EVAL) {
a0d0e21e
LW
1178 cLOGOP->op_other = op;
1179 markstack_ptr--;
4633a7c4
LW
1180 /* we're trying to emulate pp_entertry() here */
1181 {
1182 register CONTEXT *cx;
54310121 1183 I32 gimme = GIMME_V;
4633a7c4
LW
1184
1185 ENTER;
1186 SAVETMPS;
1187
1188 push_return(op->op_next);
1189 PUSHBLOCK(cx, CXt_EVAL, stack_sp);
1190 PUSHEVAL(cx, 0, 0);
1191 eval_root = op; /* Only needed so that goto works right. */
1192
1193 in_eval = 1;
1194 if (flags & G_KEEPERR)
1195 in_eval |= 4;
1196 else
1197 sv_setpv(GvSV(errgv),"");
1198 }
a0d0e21e
LW
1199 markstack_ptr++;
1200
22921e25
CS
1201 JMPENV_PUSH(ret);
1202 switch (ret) {
a0d0e21e
LW
1203 case 0:
1204 break;
1205 case 1:
f86702cc 1206 STATUS_ALL_FAILURE;
a0d0e21e
LW
1207 /* FALL THROUGH */
1208 case 2:
1209 /* my_exit() was called */
1210 curstash = defstash;
1211 FREETMPS;
54310121 1212 JMPENV_POP;
a0d0e21e
LW
1213 if (statusvalue)
1214 croak("Callback called exit");
f86702cc 1215 my_exit_jump();
a0d0e21e
LW
1216 /* NOTREACHED */
1217 case 3:
1218 if (restartop) {
1219 op = restartop;
1220 restartop = 0;
54310121 1221 break;
a0d0e21e
LW
1222 }
1223 stack_sp = stack_base + oldmark;
1224 if (flags & G_ARRAY)
1225 retval = 0;
1226 else {
1227 retval = 1;
1228 *++stack_sp = &sv_undef;
1229 }
1230 goto cleanup;
1231 }
1232 }
1e422769 1233 else
54310121 1234 CATCH_SET(TRUE);
a0d0e21e
LW
1235
1236 if (op == (OP*)&myop)
11343788 1237 op = pp_entersub(ARGS);
a0d0e21e 1238 if (op)
ab821d7f 1239 runops();
a0d0e21e 1240 retval = stack_sp - (stack_base + oldmark);
4633a7c4
LW
1241 if ((flags & G_EVAL) && !(flags & G_KEEPERR))
1242 sv_setpv(GvSV(errgv),"");
a0d0e21e
LW
1243
1244 cleanup:
1245 if (flags & G_EVAL) {
1246 if (scopestack_ix > oldscope) {
a0a2876f
LW
1247 SV **newsp;
1248 PMOP *newpm;
1249 I32 gimme;
1250 register CONTEXT *cx;
1251 I32 optype;
1252
1253 POPBLOCK(cx,newpm);
1254 POPEVAL(cx);
1255 pop_return();
1256 curpm = newpm;
1257 LEAVE;
a0d0e21e 1258 }
54310121 1259 JMPENV_POP;
a0d0e21e 1260 }
1e422769 1261 else
54310121 1262 CATCH_SET(oldcatch);
1e422769 1263
a0d0e21e
LW
1264 if (flags & G_DISCARD) {
1265 stack_sp = stack_base + oldmark;
1266 retval = 0;
1267 FREETMPS;
1268 LEAVE;
1269 }
d6602a8c 1270 op = oldop;
a0d0e21e
LW
1271 return retval;
1272}
1273
6e72f9df 1274/* Eval a string. The G_EVAL flag is always assumed. */
8990e307 1275
a0d0e21e 1276I32
4633a7c4 1277perl_eval_sv(sv, flags)
8990e307 1278SV* sv;
4633a7c4 1279I32 flags; /* See G_* flags in cop.h */
a0d0e21e 1280{
11343788 1281 dTHR;
a0d0e21e 1282 UNOP myop; /* fake syntax tree node */
4633a7c4
LW
1283 SV** sp = stack_sp;
1284 I32 oldmark = sp - stack_base;
1285 I32 retval;
4633a7c4 1286 I32 oldscope;
54310121 1287 dJMPENV;
22921e25 1288 int ret;
84902520
TB
1289 OP* oldop = op;
1290
4633a7c4
LW
1291 if (flags & G_DISCARD) {
1292 ENTER;
1293 SAVETMPS;
1294 }
1295
462e5cf6 1296 SAVEOP();
79072805 1297 op = (OP*)&myop;
a0d0e21e 1298 Zero(op, 1, UNOP);
4633a7c4
LW
1299 EXTEND(stack_sp, 1);
1300 *++stack_sp = sv;
1301 oldscope = scopestack_ix;
79072805 1302
4633a7c4
LW
1303 if (!(flags & G_NOARGS))
1304 myop.op_flags = OPf_STACKED;
79072805 1305 myop.op_next = Nullop;
6e72f9df 1306 myop.op_type = OP_ENTEREVAL;
54310121 1307 myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
1308 (flags & G_ARRAY) ? OPf_WANT_LIST :
1309 OPf_WANT_SCALAR);
6e72f9df 1310 if (flags & G_KEEPERR)
1311 myop.op_flags |= OPf_SPECIAL;
4633a7c4 1312
22921e25
CS
1313 JMPENV_PUSH(ret);
1314 switch (ret) {
4633a7c4
LW
1315 case 0:
1316 break;
1317 case 1:
f86702cc 1318 STATUS_ALL_FAILURE;
4633a7c4
LW
1319 /* FALL THROUGH */
1320 case 2:
1321 /* my_exit() was called */
1322 curstash = defstash;
1323 FREETMPS;
54310121 1324 JMPENV_POP;
4633a7c4
LW
1325 if (statusvalue)
1326 croak("Callback called exit");
f86702cc 1327 my_exit_jump();
4633a7c4
LW
1328 /* NOTREACHED */
1329 case 3:
1330 if (restartop) {
1331 op = restartop;
1332 restartop = 0;
54310121 1333 break;
4633a7c4
LW
1334 }
1335 stack_sp = stack_base + oldmark;
1336 if (flags & G_ARRAY)
1337 retval = 0;
1338 else {
1339 retval = 1;
1340 *++stack_sp = &sv_undef;
1341 }
1342 goto cleanup;
1343 }
1344
1345 if (op == (OP*)&myop)
11343788 1346 op = pp_entereval(ARGS);
4633a7c4 1347 if (op)
ab821d7f 1348 runops();
4633a7c4 1349 retval = stack_sp - (stack_base + oldmark);
6e72f9df 1350 if (!(flags & G_KEEPERR))
4633a7c4
LW
1351 sv_setpv(GvSV(errgv),"");
1352
1353 cleanup:
54310121 1354 JMPENV_POP;
4633a7c4
LW
1355 if (flags & G_DISCARD) {
1356 stack_sp = stack_base + oldmark;
1357 retval = 0;
1358 FREETMPS;
1359 LEAVE;
1360 }
84902520 1361 op = oldop;
4633a7c4
LW
1362 return retval;
1363}
1364
137443ea 1365SV*
1366perl_eval_pv(p, croak_on_error)
1367char* p;
1368I32 croak_on_error;
1369{
e858de61 1370 dTHR;
137443ea 1371 dSP;
1372 SV* sv = newSVpv(p, 0);
1373
1374 PUSHMARK(sp);
1375 perl_eval_sv(sv, G_SCALAR);
1376 SvREFCNT_dec(sv);
1377
1378 SPAGAIN;
1379 sv = POPs;
1380 PUTBACK;
1381
1382 if (croak_on_error && SvTRUE(GvSV(errgv)))
1383 croak(SvPVx(GvSV(errgv), na));
1384
1385 return sv;
1386}
1387
4633a7c4
LW
1388/* Require a module. */
1389
1390void
1391perl_require_pv(pv)
1392char* pv;
1393{
1394 SV* sv = sv_newmortal();
1395 sv_setpv(sv, "require '");
1396 sv_catpv(sv, pv);
1397 sv_catpv(sv, "'");
1398 perl_eval_sv(sv, G_DISCARD);
79072805
LW
1399}
1400
79072805 1401void
79072805
LW
1402magicname(sym,name,namlen)
1403char *sym;
1404char *name;
1405I32 namlen;
1406{
1407 register GV *gv;
1408
85e6fe83 1409 if (gv = gv_fetchpv(sym,TRUE, SVt_PV))
79072805
LW
1410 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
1411}
1412
ab821d7f 1413static void
1a30305b 1414usage(name) /* XXX move this out into a module ? */
4633a7c4
LW
1415char *name;
1416{
ab821d7f 1417 /* This message really ought to be max 23 lines.
1418 * Removed -h because the user already knows that opton. Others? */
1419 printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name);
4633a7c4 1420 printf("\n -0[octal] specify record separator (\\0, if no argument)");
ab821d7f 1421 printf("\n -a autosplit mode with -n or -p (splits $_ into @F)");
4633a7c4 1422 printf("\n -c check syntax only (runs BEGIN and END blocks)");
1a30305b 1423 printf("\n -d[:debugger] run scripts under debugger");
4633a7c4 1424 printf("\n -D[number/list] set debugging flags (argument is a bit mask or flags)");
ab821d7f 1425 printf("\n -e 'command' one line of script. Several -e's allowed. Omit [programfile].");
1426 printf("\n -F/pattern/ split() pattern for autosplit (-a). The //'s are optional.");
4633a7c4 1427 printf("\n -i[extension] edit <> files in place (make backup if extension supplied)");
50492d44
RW
1428 printf("\n -Idirectory specify @INC/#include directory (may be used more than once)");
1429 printf("\n -l[octal] enable line ending processing, specifies line terminator");
ab821d7f 1430 printf("\n -[mM][-]module.. executes `use/no module...' before executing your script.");
50492d44 1431 printf("\n -n assume 'while (<>) { ... }' loop around your script");
4633a7c4
LW
1432 printf("\n -p assume loop like -n but print line also like sed");
1433 printf("\n -P run script through C preprocessor before compilation");
4633a7c4
LW
1434 printf("\n -s enable some switch parsing for switches after script name");
1435 printf("\n -S look for the script using PATH environment variable");
1436 printf("\n -T turn on tainting checks");
1437 printf("\n -u dump core after parsing script");
1438 printf("\n -U allow unsafe operations");
1439 printf("\n -v print version number and patchlevel of perl");
1a30305b 1440 printf("\n -V[:variable] print perl configuration information");
90248788 1441 printf("\n -w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT. Recommended.");
4633a7c4
LW
1442 printf("\n -x[directory] strip off text before #!perl line and perhaps cd to directory\n");
1443}
1444
79072805
LW
1445/* This routine handles any switches that can be given during run */
1446
1447char *
1448moreswitches(s)
1449char *s;
1450{
1451 I32 numlen;
c07a80fd 1452 U32 rschar;
79072805
LW
1453
1454 switch (*s) {
1455 case '0':
c07a80fd 1456 rschar = scan_oct(s, 4, &numlen);
1457 SvREFCNT_dec(nrs);
1458 if (rschar & ~((U8)~0))
1459 nrs = &sv_undef;
1460 else if (!rschar && numlen >= 2)
1461 nrs = newSVpv("", 0);
1462 else {
1463 char ch = rschar;
1464 nrs = newSVpv(&ch, 1);
79072805
LW
1465 }
1466 return s + numlen;
2304df62
AD
1467 case 'F':
1468 minus_F = TRUE;
a0d0e21e 1469 splitstr = savepv(s + 1);
2304df62
AD
1470 s += strlen(s);
1471 return s;
79072805
LW
1472 case 'a':
1473 minus_a = TRUE;
1474 s++;
1475 return s;
1476 case 'c':
1477 minus_c = TRUE;
1478 s++;
1479 return s;
1480 case 'd':
bbce6d69 1481 forbid_setid("-d");
4633a7c4 1482 s++;
c07a80fd 1483 if (*s == ':' || *s == '=') {
46fc3d4c 1484 my_setenv("PERL5DB", form("use Devel::%s;", ++s));
4633a7c4 1485 s += strlen(s);
4633a7c4 1486 }
a0d0e21e 1487 if (!perldb) {
84902520 1488 perldb = PERLDB_ALL;
a0d0e21e
LW
1489 init_debugger();
1490 }
79072805
LW
1491 return s;
1492 case 'D':
1493#ifdef DEBUGGING
bbce6d69 1494 forbid_setid("-D");
79072805 1495 if (isALPHA(s[1])) {
8990e307 1496 static char debopts[] = "psltocPmfrxuLHXD";
79072805
LW
1497 char *d;
1498
93a17b20 1499 for (s++; *s && (d = strchr(debopts,*s)); s++)
79072805
LW
1500 debug |= 1 << (d - debopts);
1501 }
1502 else {
1503 debug = atoi(s+1);
1504 for (s++; isDIGIT(*s); s++) ;
1505 }
8990e307 1506 debug |= 0x80000000;
79072805
LW
1507#else
1508 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
a0d0e21e 1509 for (s++; isALNUM(*s); s++) ;
79072805
LW
1510#endif
1511 /*SUPPRESS 530*/
1512 return s;
4633a7c4
LW
1513 case 'h':
1514 usage(origargv[0]);
1515 exit(0);
79072805
LW
1516 case 'i':
1517 if (inplace)
1518 Safefree(inplace);
a0d0e21e 1519 inplace = savepv(s+1);
79072805
LW
1520 /*SUPPRESS 530*/
1521 for (s = inplace; *s && !isSPACE(*s); s++) ;
1522 *s = '\0';
1523 break;
1524 case 'I':
bbce6d69 1525 forbid_setid("-I");
79072805 1526 if (*++s) {
774d564b 1527 char *e, *p;
748a9306 1528 for (e = s; *e && !isSPACE(*e); e++) ;
774d564b 1529 p = savepvn(s, e-s);
1530 incpush(p, TRUE);
1531 Safefree(p);
748a9306
LW
1532 if (*e)
1533 return e;
79072805
LW
1534 }
1535 else
463ee0b2 1536 croak("No space allowed after -I");
79072805
LW
1537 break;
1538 case 'l':
1539 minus_l = TRUE;
1540 s++;
a0d0e21e
LW
1541 if (ors)
1542 Safefree(ors);
79072805 1543 if (isDIGIT(*s)) {
a0d0e21e 1544 ors = savepv("\n");
79072805
LW
1545 orslen = 1;
1546 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
1547 s += numlen;
1548 }
1549 else {
c07a80fd 1550 if (RsPARA(nrs)) {
6e72f9df 1551 ors = "\n\n";
c07a80fd 1552 orslen = 2;
1553 }
1554 else
1555 ors = SvPV(nrs, orslen);
6e72f9df 1556 ors = savepvn(ors, orslen);
79072805
LW
1557 }
1558 return s;
1a30305b 1559 case 'M':
bbce6d69 1560 forbid_setid("-M"); /* XXX ? */
1a30305b 1561 /* FALL THROUGH */
1562 case 'm':
bbce6d69 1563 forbid_setid("-m"); /* XXX ? */
1a30305b 1564 if (*++s) {
a5f75d66 1565 char *start;
11343788 1566 SV *sv;
a5f75d66
AD
1567 char *use = "use ";
1568 /* -M-foo == 'no foo' */
1569 if (*s == '-') { use = "no "; ++s; }
11343788 1570 sv = newSVpv(use,0);
a5f75d66 1571 start = s;
1a30305b 1572 /* We allow -M'Module qw(Foo Bar)' */
c07a80fd 1573 while(isALNUM(*s) || *s==':') ++s;
1574 if (*s != '=') {
11343788 1575 sv_catpv(sv, start);
c07a80fd 1576 if (*(start-1) == 'm') {
1577 if (*s != '\0')
1578 croak("Can't use '%c' after -mname", *s);
11343788 1579 sv_catpv( sv, " ()");
c07a80fd 1580 }
1581 } else {
11343788
MB
1582 sv_catpvn(sv, start, s-start);
1583 sv_catpv(sv, " split(/,/,q{");
1584 sv_catpv(sv, ++s);
1585 sv_catpv(sv, "})");
c07a80fd 1586 }
1a30305b 1587 s += strlen(s);
c07a80fd 1588 if (preambleav == NULL)
1589 preambleav = newAV();
11343788 1590 av_push(preambleav, sv);
1a30305b 1591 }
1592 else
1593 croak("No space allowed after -%c", *(s-1));
1594 return s;
79072805
LW
1595 case 'n':
1596 minus_n = TRUE;
1597 s++;
1598 return s;
1599 case 'p':
1600 minus_p = TRUE;
1601 s++;
1602 return s;
1603 case 's':
bbce6d69 1604 forbid_setid("-s");
79072805
LW
1605 doswitches = TRUE;
1606 s++;
1607 return s;
463ee0b2 1608 case 'T':
f86702cc 1609 if (!tainting)
9607fc9c 1610 croak("Too late for \"-T\" option");
463ee0b2
LW
1611 s++;
1612 return s;
79072805
LW
1613 case 'u':
1614 do_undump = TRUE;
1615 s++;
1616 return s;
1617 case 'U':
1618 unsafe = TRUE;
1619 s++;
1620 return s;
1621 case 'v':
a5f75d66
AD
1622#if defined(SUBVERSION) && SUBVERSION > 0
1623 printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION);
1624#else
1625 printf("\nThis is perl, version %s",patchlevel);
1626#endif
1a30305b 1627
44a8e56a 1628 printf("\n\nCopyright 1987-1997, Larry Wall\n");
79072805 1629#ifdef MSDOS
55497cff 1630 printf("\n\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
1631#endif
1632#ifdef DJGPP
1633 printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n");
4633a7c4 1634#endif
79072805 1635#ifdef OS2
5dd60ef7 1636 printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
9607fc9c 1637 "Version 5 port Copyright (c) 1994-1997, Andreas Kaiser, Ilya Zakharevich\n");
79072805 1638#endif
79072805 1639#ifdef atarist
760ac839 1640 printf("atariST series port, ++jrb bammi@cadence.com\n");
79072805 1641#endif
760ac839 1642 printf("\n\
79072805 1643Perl may be copied only under the terms of either the Artistic License or the\n\
760ac839 1644GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n");
79072805
LW
1645 exit(0);
1646 case 'w':
1647 dowarn = TRUE;
1648 s++;
1649 return s;
a0d0e21e 1650 case '*':
79072805
LW
1651 case ' ':
1652 if (s[1] == '-') /* Additional switches on #! line. */
1653 return s+2;
1654 break;
a0d0e21e 1655 case '-':
79072805
LW
1656 case 0:
1657 case '\n':
1658 case '\t':
1659 break;
aa689395 1660#ifdef ALTERNATE_SHEBANG
1661 case 'S': /* OS/2 needs -S on "extproc" line. */
1662 break;
1663#endif
a0d0e21e
LW
1664 case 'P':
1665 if (preprocess)
1666 return s+1;
1667 /* FALL THROUGH */
79072805 1668 default:
a0d0e21e 1669 croak("Can't emulate -%.1s on #! line",s);
79072805
LW
1670 }
1671 return Nullch;
1672}
1673
1674/* compliments of Tom Christiansen */
1675
1676/* unexec() can be found in the Gnu emacs distribution */
1677
1678void
1679my_unexec()
1680{
1681#ifdef UNEXEC
46fc3d4c 1682 SV* prog;
1683 SV* file;
79072805
LW
1684 int status;
1685 extern int etext;
1686
46fc3d4c 1687 prog = newSVpv(BIN_EXP);
1688 sv_catpv(prog, "/perl");
1689 file = newSVpv(origfilename);
1690 sv_catpv(file, ".perldump");
79072805 1691
46fc3d4c 1692 status = unexec(SvPVX(file), SvPVX(prog), &etext, sbrk(0), 0);
79072805 1693 if (status)
46fc3d4c 1694 PerlIO_printf(PerlIO_stderr(), "unexec of %s into %s failed!\n",
1695 SvPVX(prog), SvPVX(file));
a0d0e21e 1696 exit(status);
79072805 1697#else
a5f75d66
AD
1698# ifdef VMS
1699# include <lib$routines.h>
1700 lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */
aa689395 1701# else
79072805 1702 ABORT(); /* for use with undump */
aa689395 1703# endif
a5f75d66 1704#endif
79072805
LW
1705}
1706
1707static void
1708init_main_stash()
1709{
11343788 1710 dTHR;
463ee0b2 1711 GV *gv;
6e72f9df 1712
1713 /* Note that strtab is a rather special HV. Assumptions are made
1714 about not iterating on it, and not adding tie magic to it.
1715 It is properly deallocated in perl_destruct() */
1716 strtab = newHV();
1717 HvSHAREKEYS_off(strtab); /* mandatory */
1718 Newz(506,((XPVHV*)SvANY(strtab))->xhv_array,
1719 sizeof(HE*) * (((XPVHV*)SvANY(strtab))->xhv_max + 1), char);
1720
463ee0b2 1721 curstash = defstash = newHV();
79072805 1722 curstname = newSVpv("main",4);
adbc6bb1
LW
1723 gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1724 SvREFCNT_dec(GvHV(gv));
1725 GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
463ee0b2 1726 SvREADONLY_on(gv);
a0d0e21e 1727 HvNAME(defstash) = savepv("main");
85e6fe83 1728 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
a5f75d66 1729 GvMULTI_on(incgv);
a0d0e21e 1730 defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
4633a7c4 1731 errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
a5f75d66 1732 GvMULTI_on(errgv);
84902520
TB
1733 (void)form("%240s",""); /* Preallocate temp - for immediate signals. */
1734 sv_grow(GvSV(errgv), 240); /* Preallocate - for immediate signals. */
552a7a9b 1735 sv_setpvn(GvSV(errgv), "", 0);
8990e307
LW
1736 curstash = defstash;
1737 compiling.cop_stash = defstash;
adbc6bb1 1738 debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
4633a7c4
LW
1739 /* We must init $/ before switches are processed. */
1740 sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1);
79072805
LW
1741}
1742
a0d0e21e
LW
1743#ifdef CAN_PROTOTYPE
1744static void
1745open_script(char *scriptname, bool dosearch, SV *sv)
1746#else
79072805
LW
1747static void
1748open_script(scriptname,dosearch,sv)
1749char *scriptname;
1750bool dosearch;
1751SV *sv;
a0d0e21e 1752#endif
79072805 1753{
0f15f207 1754 dTHR;
79072805
LW
1755 char *xfound = Nullch;
1756 char *xfailed = Nullch;
1757 register char *s;
1758 I32 len;
a38d6535
LW
1759 int retval;
1760#if defined(DOSISH) && !defined(OS2) && !defined(atarist)
fc36a67e 1761# define SEARCH_EXTS ".bat", ".cmd", NULL
1762# define MAX_EXT_LEN 4
a38d6535 1763#endif
d8c2d278
IZ
1764#ifdef OS2
1765# define SEARCH_EXTS ".cmd", ".btm", ".bat", ".pl", NULL
1766# define MAX_EXT_LEN 4
1767#endif
ab821d7f 1768#ifdef VMS
1769# define SEARCH_EXTS ".pl", ".com", NULL
fc36a67e 1770# define MAX_EXT_LEN 4
ab821d7f 1771#endif
a38d6535
LW
1772 /* additional extensions to try in each dir if scriptname not found */
1773#ifdef SEARCH_EXTS
1774 char *ext[] = { SEARCH_EXTS };
2a92aaa0
GS
1775 int extidx = 0, i = 0;
1776 char *curext = Nullch;
fc36a67e 1777#else
1778# define MAX_EXT_LEN 0
a38d6535 1779#endif
79072805 1780
2a92aaa0
GS
1781 /*
1782 * If dosearch is true and if scriptname does not contain path
1783 * delimiters, search the PATH for scriptname.
1784 *
1785 * If SEARCH_EXTS is also defined, will look for each
1786 * scriptname{SEARCH_EXTS} whenever scriptname is not found
1787 * while searching the PATH.
1788 *
1789 * Assuming SEARCH_EXTS is C<".foo",".bar",NULL>, PATH search
1790 * proceeds as follows:
1791 * If DOSISH:
1792 * + look for ./scriptname{,.foo,.bar}
1793 * + search the PATH for scriptname{,.foo,.bar}
1794 *
1795 * If !DOSISH:
1796 * + look *only* in the PATH for scriptname{,.foo,.bar} (note
1797 * this will not look in '.' if it's not in the PATH)
1798 */
1799
c07a80fd 1800#ifdef VMS
6e72f9df 1801 if (dosearch) {
1802 int hasdir, idx = 0, deftypes = 1;
1a2dec3c 1803 bool seen_dot = 1;
6e72f9df 1804
1805 hasdir = (strpbrk(scriptname,":[</") != Nullch) ;
1806 /* The first time through, just add SEARCH_EXTS to whatever we
1807 * already have, so we can check for default file types. */
fc36a67e 1808 while (deftypes ||
1809 (!hasdir && my_trnlnm("DCL$PATH",tokenbuf,idx++)) )
1810 {
1811 if (deftypes) {
1812 deftypes = 0;
1813 *tokenbuf = '\0';
1814 }
1815 if ((strlen(tokenbuf) + strlen(scriptname)
1816 + MAX_EXT_LEN) >= sizeof tokenbuf)
1817 continue; /* don't search dir with too-long name */
1818 strcat(tokenbuf, scriptname);
c07a80fd 1819#else /* !VMS */
2a92aaa0 1820
fc36a67e 1821#ifdef DOSISH
2a92aaa0 1822 if (strEQ(scriptname, "-"))
84902520 1823 dosearch = 0;
2a92aaa0
GS
1824 if (dosearch) { /* Look in '.' first. */
1825 char *cur = scriptname;
1826#ifdef SEARCH_EXTS
1827 if ((curext = strrchr(scriptname,'.'))) /* possible current ext */
1828 while (ext[i])
1829 if (strEQ(ext[i++],curext)) {
1830 extidx = -1; /* already has an ext */
1831 break;
1832 }
1833 do {
79072805 1834#endif
2a92aaa0
GS
1835 DEBUG_p(PerlIO_printf(Perl_debug_log,
1836 "Looking for %s\n",cur));
1837 if (Stat(cur,&statbuf) >= 0) {
1838 dosearch = 0;
1839 scriptname = cur;
84902520 1840#ifdef SEARCH_EXTS
2a92aaa0 1841 break;
84902520 1842#endif
2a92aaa0
GS
1843 }
1844#ifdef SEARCH_EXTS
1845 if (cur == scriptname) {
1846 len = strlen(scriptname);
1847 if (len+MAX_EXT_LEN+1 >= sizeof(tokenbuf))
1848 break;
1849 cur = strcpy(tokenbuf, scriptname);
1850 }
1851 } while (extidx >= 0 && ext[extidx] /* try an extension? */
1852 && strcpy(tokenbuf+len, ext[extidx++]));
1853#endif
1854 }
1855#endif
84902520 1856
e92c4225
WJ
1857 if (dosearch && !strchr(scriptname, '/')
1858#ifdef DOSISH
1859 && !strchr(scriptname, '\\')
1860#endif
1861 && (s = getenv("PATH"))) {
2a92aaa0 1862 bool seen_dot = 0;
84902520 1863
79072805 1864 bufend = s + strlen(s);
fc36a67e 1865 while (s < bufend) {
2a92aaa0
GS
1866#if defined(atarist) || defined(DOSISH)
1867 for (len = 0; *s
1868# ifdef atarist
1869 && *s != ','
1870# endif
1871 && *s != ';'; len++, s++) {
fc36a67e 1872 if (len < sizeof tokenbuf)
1873 tokenbuf[len] = *s;
1874 }
1875 if (len < sizeof tokenbuf)
1876 tokenbuf[len] = '\0';
84902520
TB
1877#else /* ! (atarist || DOSISH) */
1878 s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend,
1879 ':',
1880 &len);
1881#endif /* ! (atarist || DOSISH) */
fc36a67e 1882 if (s < bufend)
79072805 1883 s++;
fc36a67e 1884 if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tokenbuf)
1885 continue; /* don't search dir with too-long name */
1886 if (len
fc36a67e 1887#if defined(atarist) || defined(DOSISH)
2a92aaa0 1888 && tokenbuf[len - 1] != '/'
fc36a67e 1889 && tokenbuf[len - 1] != '\\'
79072805 1890#endif
fc36a67e 1891 )
1892 tokenbuf[len++] = '/';
84902520 1893 if (len == 2 && tokenbuf[0] == '.')
2a92aaa0 1894 seen_dot = 1;
fc36a67e 1895 (void)strcpy(tokenbuf + len, scriptname);
c07a80fd 1896#endif /* !VMS */
a38d6535
LW
1897
1898#ifdef SEARCH_EXTS
1899 len = strlen(tokenbuf);
1900 if (extidx > 0) /* reset after previous loop */
1901 extidx = 0;
1902 do {
1903#endif
760ac839 1904 DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tokenbuf));
a38d6535
LW
1905 retval = Stat(tokenbuf,&statbuf);
1906#ifdef SEARCH_EXTS
1907 } while ( retval < 0 /* not there */
1908 && extidx>=0 && ext[extidx] /* try an extension? */
1909 && strcpy(tokenbuf+len, ext[extidx++])
1910 );
1911#endif
1912 if (retval < 0)
79072805
LW
1913 continue;
1914 if (S_ISREG(statbuf.st_mode)
c90c0ff4 1915 && cando(S_IRUSR,TRUE,&statbuf)
1916#ifndef DOSISH
1917 && cando(S_IXUSR,TRUE,&statbuf)
1918#endif
1919 )
1920 {
79072805
LW
1921 xfound = tokenbuf; /* bingo! */
1922 break;
1923 }
1924 if (!xfailed)
a0d0e21e 1925 xfailed = savepv(tokenbuf);
79072805 1926 }
2a92aaa0
GS
1927#ifndef DOSISH
1928 if (!xfound && !seen_dot && !xfailed && (Stat(scriptname,&statbuf) < 0))
84902520
TB
1929#endif
1930 seen_dot = 1; /* Disable message. */
79072805 1931 if (!xfound)
84902520 1932 croak("Can't %s %s%s%s",
2a92aaa0
GS
1933 (xfailed ? "execute" : "find"),
1934 (xfailed ? xfailed : scriptname),
1935 (xfailed ? "" : " on PATH"),
1936 (xfailed || seen_dot) ? "" : ", '.' not in PATH");
79072805
LW
1937 if (xfailed)
1938 Safefree(xfailed);
1939 scriptname = xfound;
1940 }
1941
96436eeb 1942 if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
1943 char *s = scriptname + 8;
1944 fdscript = atoi(s);
1945 while (isDIGIT(*s))
1946 s++;
1947 if (*s)
1948 scriptname = s + 1;
1949 }
1950 else
1951 fdscript = -1;
ab821d7f 1952 origfilename = savepv(e_tmpname ? "-e" : scriptname);
79072805
LW
1953 curcop->cop_filegv = gv_fetchfile(origfilename);
1954 if (strEQ(origfilename,"-"))
1955 scriptname = "";
96436eeb 1956 if (fdscript >= 0) {
760ac839 1957 rsfp = PerlIO_fdopen(fdscript,"r");
96436eeb 1958#if defined(HAS_FCNTL) && defined(F_SETFD)
7aa04957
CS
1959 if (rsfp)
1960 fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
96436eeb 1961#endif
1962 }
1963 else if (preprocess) {
46fc3d4c 1964 char *cpp_cfg = CPPSTDIN;
1965 SV *cpp = NEWSV(0,0);
1966 SV *cmd = NEWSV(0,0);
1967
1968 if (strEQ(cpp_cfg, "cppstdin"))
1969 sv_catpvf(cpp, "%s/", BIN_EXP);
1970 sv_catpv(cpp, cpp_cfg);
79072805 1971
79072805 1972 sv_catpv(sv,"-I");
fed7345c 1973 sv_catpv(sv,PRIVLIB_EXP);
46fc3d4c 1974
79072805 1975#ifdef MSDOS
46fc3d4c 1976 sv_setpvf(cmd, "\
79072805
LW
1977sed %s -e \"/^[^#]/b\" \
1978 -e \"/^#[ ]*include[ ]/b\" \
1979 -e \"/^#[ ]*define[ ]/b\" \
1980 -e \"/^#[ ]*if[ ]/b\" \
1981 -e \"/^#[ ]*ifdef[ ]/b\" \
1982 -e \"/^#[ ]*ifndef[ ]/b\" \
1983 -e \"/^#[ ]*else/b\" \
1984 -e \"/^#[ ]*elif[ ]/b\" \
1985 -e \"/^#[ ]*undef[ ]/b\" \
1986 -e \"/^#[ ]*endif/b\" \
1987 -e \"s/^#.*//\" \
fc36a67e 1988 %s | %_ -C %_ %s",
79072805
LW
1989 (doextract ? "-e \"1,/^#/d\n\"" : ""),
1990#else
46fc3d4c 1991 sv_setpvf(cmd, "\
79072805
LW
1992%s %s -e '/^[^#]/b' \
1993 -e '/^#[ ]*include[ ]/b' \
1994 -e '/^#[ ]*define[ ]/b' \
1995 -e '/^#[ ]*if[ ]/b' \
1996 -e '/^#[ ]*ifdef[ ]/b' \
1997 -e '/^#[ ]*ifndef[ ]/b' \
1998 -e '/^#[ ]*else/b' \
1999 -e '/^#[ ]*elif[ ]/b' \
2000 -e '/^#[ ]*undef[ ]/b' \
2001 -e '/^#[ ]*endif/b' \
2002 -e 's/^[ ]*#.*//' \
fc36a67e 2003 %s | %_ -C %_ %s",
79072805
LW
2004#ifdef LOC_SED
2005 LOC_SED,
2006#else
2007 "sed",
2008#endif
2009 (doextract ? "-e '1,/^#/d\n'" : ""),
2010#endif
46fc3d4c 2011 scriptname, cpp, sv, CPPMINUS);
79072805
LW
2012 doextract = FALSE;
2013#ifdef IAMSUID /* actually, this is caught earlier */
2014 if (euid != uid && !euid) { /* if running suidperl */
2015#ifdef HAS_SETEUID
2016 (void)seteuid(uid); /* musn't stay setuid root */
2017#else
2018#ifdef HAS_SETREUID
85e6fe83
LW
2019 (void)setreuid((Uid_t)-1, uid);
2020#else
2021#ifdef HAS_SETRESUID
2022 (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
79072805
LW
2023#else
2024 setuid(uid);
2025#endif
2026#endif
85e6fe83 2027#endif
79072805 2028 if (geteuid() != uid)
463ee0b2 2029 croak("Can't do seteuid!\n");
79072805
LW
2030 }
2031#endif /* IAMSUID */
46fc3d4c 2032 rsfp = my_popen(SvPVX(cmd), "r");
2033 SvREFCNT_dec(cmd);
2034 SvREFCNT_dec(cpp);
79072805
LW
2035 }
2036 else if (!*scriptname) {
bbce6d69 2037 forbid_setid("program input from stdin");
760ac839 2038 rsfp = PerlIO_stdin();
79072805 2039 }
96436eeb 2040 else {
760ac839 2041 rsfp = PerlIO_open(scriptname,"r");
96436eeb 2042#if defined(HAS_FCNTL) && defined(F_SETFD)
7aa04957
CS
2043 if (rsfp)
2044 fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
96436eeb 2045#endif
2046 }
5dd60ef7 2047 if (e_tmpname) {
2048 e_fp = rsfp;
2049 }
7aa04957 2050 if (!rsfp) {
13281fa4 2051#ifdef DOSUID
a687059c 2052#ifndef IAMSUID /* in case script is not readable before setuid */
a0d0e21e 2053 if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
13281fa4 2054 statbuf.st_mode & (S_ISUID|S_ISGID)) {
46fc3d4c 2055 /* try again */
2056 execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv);
463ee0b2 2057 croak("Can't do setuid\n");
13281fa4
LW
2058 }
2059#endif
2060#endif
463ee0b2 2061 croak("Can't open perl script \"%s\": %s\n",
2304df62 2062 SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
13281fa4 2063 }
79072805 2064}
8d063cd8 2065
79072805 2066static void
96436eeb 2067validate_suid(validarg, scriptname)
79072805 2068char *validarg;
96436eeb 2069char *scriptname;
79072805 2070{
96436eeb 2071 int which;
2072
13281fa4
LW
2073 /* do we need to emulate setuid on scripts? */
2074
2075 /* This code is for those BSD systems that have setuid #! scripts disabled
2076 * in the kernel because of a security problem. Merely defining DOSUID
2077 * in perl will not fix that problem, but if you have disabled setuid
2078 * scripts in the kernel, this will attempt to emulate setuid and setgid
2079 * on scripts that have those now-otherwise-useless bits set. The setuid
27e2fb84
LW
2080 * root version must be called suidperl or sperlN.NNN. If regular perl
2081 * discovers that it has opened a setuid script, it calls suidperl with
2082 * the same argv that it had. If suidperl finds that the script it has
2083 * just opened is NOT setuid root, it sets the effective uid back to the
2084 * uid. We don't just make perl setuid root because that loses the
2085 * effective uid we had before invoking perl, if it was different from the
2086 * uid.
13281fa4
LW
2087 *
2088 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
2089 * be defined in suidperl only. suidperl must be setuid root. The
2090 * Configure script will set this up for you if you want it.
2091 */
a687059c 2092
13281fa4 2093#ifdef DOSUID
6e72f9df 2094 char *s, *s2;
a0d0e21e 2095
760ac839 2096 if (Fstat(PerlIO_fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
463ee0b2 2097 croak("Can't stat script \"%s\"",origfilename);
96436eeb 2098 if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) {
79072805 2099 I32 len;
13281fa4 2100
a687059c 2101#ifdef IAMSUID
fe14fcc3 2102#ifndef HAS_SETREUID
a687059c
LW
2103 /* On this access check to make sure the directories are readable,
2104 * there is actually a small window that the user could use to make
2105 * filename point to an accessible directory. So there is a faint
2106 * chance that someone could execute a setuid script down in a
2107 * non-accessible directory. I don't know what to do about that.
2108 * But I don't think it's too important. The manual lies when
2109 * it says access() is useful in setuid programs.
2110 */
463ee0b2
LW
2111 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
2112 croak("Permission denied");
a687059c
LW
2113#else
2114 /* If we can swap euid and uid, then we can determine access rights
2115 * with a simple stat of the file, and then compare device and
2116 * inode to make sure we did stat() on the same file we opened.
2117 * Then we just have to make sure he or she can execute it.
2118 */
2119 {
2120 struct stat tmpstatbuf;
2121
85e6fe83
LW
2122 if (
2123#ifdef HAS_SETREUID
2124 setreuid(euid,uid) < 0
a0d0e21e
LW
2125#else
2126# if HAS_SETRESUID
85e6fe83 2127 setresuid(euid,uid,(Uid_t)-1) < 0
a0d0e21e 2128# endif
85e6fe83
LW
2129#endif
2130 || getuid() != euid || geteuid() != uid)
463ee0b2 2131 croak("Can't swap uid and euid"); /* really paranoid */
a0d0e21e 2132 if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
463ee0b2 2133 croak("Permission denied"); /* testing full pathname here */
a687059c
LW
2134 if (tmpstatbuf.st_dev != statbuf.st_dev ||
2135 tmpstatbuf.st_ino != statbuf.st_ino) {
760ac839 2136 (void)PerlIO_close(rsfp);
79072805 2137 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
760ac839 2138 PerlIO_printf(rsfp,
ff0cee69 2139"User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\
2140(Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n",
2141 (long)uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino,
2142 (long)statbuf.st_dev, (long)statbuf.st_ino,
463ee0b2 2143 SvPVX(GvSV(curcop->cop_filegv)),
ff0cee69 2144 (long)statbuf.st_uid, (long)statbuf.st_gid);
79072805 2145 (void)my_pclose(rsfp);
a687059c 2146 }
463ee0b2 2147 croak("Permission denied\n");
a687059c 2148 }
85e6fe83
LW
2149 if (
2150#ifdef HAS_SETREUID
2151 setreuid(uid,euid) < 0
a0d0e21e
LW
2152#else
2153# if defined(HAS_SETRESUID)
85e6fe83 2154 setresuid(uid,euid,(Uid_t)-1) < 0
a0d0e21e 2155# endif
85e6fe83
LW
2156#endif
2157 || getuid() != uid || geteuid() != euid)
463ee0b2 2158 croak("Can't reswap uid and euid");
27e2fb84 2159 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
463ee0b2 2160 croak("Permission denied\n");
a687059c 2161 }
fe14fcc3 2162#endif /* HAS_SETREUID */
a687059c
LW
2163#endif /* IAMSUID */
2164
27e2fb84 2165 if (!S_ISREG(statbuf.st_mode))
463ee0b2 2166 croak("Permission denied");
27e2fb84 2167 if (statbuf.st_mode & S_IWOTH)
463ee0b2 2168 croak("Setuid/gid script is writable by world");
13281fa4 2169 doswitches = FALSE; /* -s is insecure in suid */
79072805 2170 curcop->cop_line++;
760ac839
LW
2171 if (sv_gets(linestr, rsfp, 0) == Nullch ||
2172 strnNE(SvPV(linestr,na),"#!",2) ) /* required even on Sys V */
463ee0b2 2173 croak("No #! line");
760ac839 2174 s = SvPV(linestr,na)+2;
663a0e37 2175 if (*s == ' ') s++;
45d8adaa 2176 while (!isSPACE(*s)) s++;
760ac839 2177 for (s2 = s; (s2 > SvPV(linestr,na)+2 &&
6e72f9df 2178 (isDIGIT(s2[-1]) || strchr("._-", s2[-1]))); s2--) ;
2179 if (strnNE(s2-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
463ee0b2 2180 croak("Not a perl script");
a687059c 2181 while (*s == ' ' || *s == '\t') s++;
13281fa4
LW
2182 /*
2183 * #! arg must be what we saw above. They can invoke it by
2184 * mentioning suidperl explicitly, but they may not add any strange
2185 * arguments beyond what #! says if they do invoke suidperl that way.
2186 */
2187 len = strlen(validarg);
2188 if (strEQ(validarg," PHOOEY ") ||
45d8adaa 2189 strnNE(s,validarg,len) || !isSPACE(s[len]))
463ee0b2 2190 croak("Args must match #! line");
a687059c
LW
2191
2192#ifndef IAMSUID
2193 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
2194 euid == statbuf.st_uid)
2195 if (!do_undump)
463ee0b2 2196 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
2197FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
2198#endif /* IAMSUID */
13281fa4
LW
2199
2200 if (euid) { /* oops, we're not the setuid root perl */
760ac839 2201 (void)PerlIO_close(rsfp);
13281fa4 2202#ifndef IAMSUID
46fc3d4c 2203 /* try again */
2204 execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv);
13281fa4 2205#endif
463ee0b2 2206 croak("Can't do setuid\n");
13281fa4
LW
2207 }
2208
83025b21 2209 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
fe14fcc3 2210#ifdef HAS_SETEGID
a687059c
LW
2211 (void)setegid(statbuf.st_gid);
2212#else
fe14fcc3 2213#ifdef HAS_SETREGID
85e6fe83
LW
2214 (void)setregid((Gid_t)-1,statbuf.st_gid);
2215#else
2216#ifdef HAS_SETRESGID
2217 (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
a687059c
LW
2218#else
2219 setgid(statbuf.st_gid);
2220#endif
2221#endif
85e6fe83 2222#endif
83025b21 2223 if (getegid() != statbuf.st_gid)
463ee0b2 2224 croak("Can't do setegid!\n");
83025b21 2225 }
a687059c
LW
2226 if (statbuf.st_mode & S_ISUID) {
2227 if (statbuf.st_uid != euid)
fe14fcc3 2228#ifdef HAS_SETEUID
a687059c
LW
2229 (void)seteuid(statbuf.st_uid); /* all that for this */
2230#else
fe14fcc3 2231#ifdef HAS_SETREUID
85e6fe83
LW
2232 (void)setreuid((Uid_t)-1,statbuf.st_uid);
2233#else
2234#ifdef HAS_SETRESUID
2235 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
a687059c
LW
2236#else
2237 setuid(statbuf.st_uid);
2238#endif
2239#endif
85e6fe83 2240#endif
83025b21 2241 if (geteuid() != statbuf.st_uid)
463ee0b2 2242 croak("Can't do seteuid!\n");
a687059c 2243 }
83025b21 2244 else if (uid) { /* oops, mustn't run as root */
fe14fcc3 2245#ifdef HAS_SETEUID
85e6fe83 2246 (void)seteuid((Uid_t)uid);
a687059c 2247#else
fe14fcc3 2248#ifdef HAS_SETREUID
85e6fe83 2249 (void)setreuid((Uid_t)-1,(Uid_t)uid);
a687059c 2250#else
85e6fe83
LW
2251#ifdef HAS_SETRESUID
2252 (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
2253#else
2254 setuid((Uid_t)uid);
2255#endif
a687059c
LW
2256#endif
2257#endif
83025b21 2258 if (geteuid() != uid)
463ee0b2 2259 croak("Can't do seteuid!\n");
83025b21 2260 }
748a9306 2261 init_ids();
27e2fb84 2262 if (!cando(S_IXUSR,TRUE,&statbuf))
463ee0b2 2263 croak("Permission denied\n"); /* they can't do this */
13281fa4
LW
2264 }
2265#ifdef IAMSUID
2266 else if (preprocess)
463ee0b2 2267 croak("-P not allowed for setuid/setgid script\n");
96436eeb 2268 else if (fdscript >= 0)
2269 croak("fd script not allowed in suidperl\n");
13281fa4 2270 else
463ee0b2 2271 croak("Script is not setuid/setgid in suidperl\n");
96436eeb 2272
2273 /* We absolutely must clear out any saved ids here, so we */
2274 /* exec the real perl, substituting fd script for scriptname. */
2275 /* (We pass script name as "subdir" of fd, which perl will grok.) */
760ac839
LW
2276 PerlIO_rewind(rsfp);
2277 lseek(PerlIO_fileno(rsfp),(Off_t)0,0); /* just in case rewind didn't */
96436eeb 2278 for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ;
2279 if (!origargv[which])
2280 croak("Permission denied");
46fc3d4c 2281 origargv[which] = savepv(form("/dev/fd/%d/%s",
2282 PerlIO_fileno(rsfp), origargv[which]));
96436eeb 2283#if defined(HAS_FCNTL) && defined(F_SETFD)
760ac839 2284 fcntl(PerlIO_fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */
96436eeb 2285#endif
46fc3d4c 2286 execv(form("%s/perl%s", BIN_EXP, patchlevel), origargv); /* try again */
96436eeb 2287 croak("Can't do setuid\n");
13281fa4 2288#endif /* IAMSUID */
a687059c 2289#else /* !DOSUID */
a687059c
LW
2290 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
2291#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
96827780 2292 dTHR;
760ac839 2293 Fstat(PerlIO_fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
a687059c
LW
2294 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
2295 ||
2296 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
2297 )
2298 if (!do_undump)
463ee0b2 2299 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
2300FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
2301#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
2302 /* not set-id, must be wrapped */
a687059c 2303 }
13281fa4 2304#endif /* DOSUID */
79072805 2305}
13281fa4 2306
79072805
LW
2307static void
2308find_beginning()
2309{
6e72f9df 2310 register char *s, *s2;
33b78306
LW
2311
2312 /* skip forward in input to the real script? */
2313
bbce6d69 2314 forbid_setid("-x");
33b78306 2315 while (doextract) {
79072805 2316 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
463ee0b2 2317 croak("No Perl script found in input\n");
6e72f9df 2318 if (*s == '#' && s[1] == '!' && (s = instr(s,"perl"))) {
760ac839 2319 PerlIO_ungetc(rsfp, '\n'); /* to keep line count right */
33b78306 2320 doextract = FALSE;
6e72f9df 2321 while (*s && !(isSPACE (*s) || *s == '#')) s++;
2322 s2 = s;
2323 while (*s == ' ' || *s == '\t') s++;
2324 if (*s++ == '-') {
2325 while (isDIGIT(s2[-1]) || strchr("-._", s2[-1])) s2--;
2326 if (strnEQ(s2-4,"perl",4))
2327 /*SUPPRESS 530*/
2328 while (s = moreswitches(s)) ;
33b78306 2329 }
79072805 2330 if (cddir && chdir(cddir) < 0)
463ee0b2 2331 croak("Can't chdir to %s",cddir);
83025b21
LW
2332 }
2333 }
2334}
2335
79072805 2336static void
748a9306 2337init_ids()
352d5a3a 2338{
748a9306
LW
2339 uid = (int)getuid();
2340 euid = (int)geteuid();
2341 gid = (int)getgid();
2342 egid = (int)getegid();
2343#ifdef VMS
2344 uid |= gid << 16;
2345 euid |= egid << 16;
2346#endif
4633a7c4 2347 tainting |= (uid && (euid != uid || egid != gid));
748a9306 2348}
79072805 2349
748a9306 2350static void
bbce6d69 2351forbid_setid(s)
2352char *s;
2353{
2354 if (euid != uid)
2355 croak("No %s allowed while running setuid", s);
2356 if (egid != gid)
2357 croak("No %s allowed while running setgid", s);
2358}
2359
2360static void
748a9306
LW
2361init_debugger()
2362{
11343788 2363 dTHR;
79072805 2364 curstash = debstash;
748a9306 2365 dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
79072805 2366 AvREAL_off(dbargs);
a0d0e21e
LW
2367 DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
2368 DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
748a9306
LW
2369 DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
2370 DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
c07a80fd 2371 sv_setiv(DBsingle, 0);
748a9306 2372 DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
c07a80fd 2373 sv_setiv(DBtrace, 0);
748a9306 2374 DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
c07a80fd 2375 sv_setiv(DBsignal, 0);
79072805 2376 curstash = defstash;
352d5a3a
LW
2377}
2378
11343788
MB
2379void
2380init_stacks(ARGS)
2381dARGS
79072805 2382{
6e72f9df 2383 curstack = newAV();
5f05dabc 2384 mainstack = curstack; /* remember in case we switch stacks */
2385 AvREAL_off(curstack); /* not a real array */
6e72f9df 2386 av_extend(curstack,127);
79072805 2387
6e72f9df 2388 stack_base = AvARRAY(curstack);
79072805 2389 stack_sp = stack_base;
8990e307 2390 stack_max = stack_base + 127;
79072805 2391
a5f75d66
AD
2392 cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */
2393 New(50,cxstack,cxstack_max + 1,CONTEXT);
8990e307 2394 cxstack_ix = -1;
8990e307
LW
2395
2396 New(50,tmps_stack,128,SV*);
6d4ff0d2 2397 tmps_floor = -1;
8990e307
LW
2398 tmps_ix = -1;
2399 tmps_max = 128;
2400
5f05dabc 2401 /*
2402 * The following stacks almost certainly should be per-interpreter,
2403 * but for now they're not. XXX
2404 */
2405
6e72f9df 2406 if (markstack) {
2407 markstack_ptr = markstack;
2408 } else {
2409 New(54,markstack,64,I32);
2410 markstack_ptr = markstack;
2411 markstack_max = markstack + 64;
2412 }
79072805 2413
6e72f9df 2414 if (scopestack) {
2415 scopestack_ix = 0;
2416 } else {
2417 New(54,scopestack,32,I32);
2418 scopestack_ix = 0;
2419 scopestack_max = 32;
2420 }
79072805 2421
6e72f9df 2422 if (savestack) {
2423 savestack_ix = 0;
2424 } else {
2425 New(54,savestack,128,ANY);
2426 savestack_ix = 0;
2427 savestack_max = 128;
2428 }
79072805 2429
6e72f9df 2430 if (retstack) {
2431 retstack_ix = 0;
2432 } else {
2433 New(54,retstack,16,OP*);
2434 retstack_ix = 0;
2435 retstack_max = 16;
5f05dabc 2436 }
378cc40b 2437}
33b78306 2438
6e72f9df 2439static void
2440nuke_stacks()
2441{
e858de61 2442 dTHR;
6e72f9df 2443 Safefree(cxstack);
2444 Safefree(tmps_stack);
5f05dabc 2445 DEBUG( {
2446 Safefree(debname);
2447 Safefree(debdelim);
2448 } )
378cc40b 2449}
33b78306 2450
760ac839 2451static PerlIO *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
7aa04957 2452
79072805 2453static void
8990e307
LW
2454init_lexer()
2455{
a0d0e21e 2456 tmpfp = rsfp;
90248788 2457 rsfp = Nullfp;
8990e307
LW
2458 lex_start(linestr);
2459 rsfp = tmpfp;
2460 subname = newSVpv("main",4);
2461}
2462
2463static void
79072805 2464init_predump_symbols()
45d8adaa 2465{
11343788 2466 dTHR;
93a17b20 2467 GV *tmpgv;
a0d0e21e 2468 GV *othergv;
79072805 2469
85e6fe83 2470 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
79072805 2471
85e6fe83 2472 stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
a5f75d66 2473 GvMULTI_on(stdingv);
760ac839 2474 IoIFP(GvIOp(stdingv)) = PerlIO_stdin();
adbc6bb1 2475 tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
a5f75d66 2476 GvMULTI_on(tmpgv);
a0d0e21e 2477 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
79072805 2478
85e6fe83 2479 tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
a5f75d66 2480 GvMULTI_on(tmpgv);
760ac839 2481 IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = PerlIO_stdout();
4633a7c4 2482 setdefout(tmpgv);
adbc6bb1 2483 tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
a5f75d66 2484 GvMULTI_on(tmpgv);
a0d0e21e 2485 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
79072805 2486
a0d0e21e 2487 othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
a5f75d66 2488 GvMULTI_on(othergv);
760ac839 2489 IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = PerlIO_stderr();
adbc6bb1 2490 tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
a5f75d66 2491 GvMULTI_on(tmpgv);
a0d0e21e 2492 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
79072805
LW
2493
2494 statname = NEWSV(66,0); /* last filename we did stat on */
ab821d7f 2495
6e72f9df 2496 if (!osname)
2497 osname = savepv(OSNAME);
79072805 2498}
33b78306 2499
79072805
LW
2500static void
2501init_postdump_symbols(argc,argv,env)
2502register int argc;
2503register char **argv;
2504register char **env;
33b78306 2505{
79072805
LW
2506 char *s;
2507 SV *sv;
2508 GV* tmpgv;
fe14fcc3 2509
79072805
LW
2510 argc--,argv++; /* skip name of script */
2511 if (doswitches) {
2512 for (; argc > 0 && **argv == '-'; argc--,argv++) {
2513 if (!argv[0][1])
2514 break;
2515 if (argv[0][1] == '-') {
2516 argc--,argv++;
2517 break;
2518 }
93a17b20 2519 if (s = strchr(argv[0], '=')) {
79072805 2520 *s++ = '\0';
85e6fe83 2521 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
79072805
LW
2522 }
2523 else
85e6fe83 2524 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
fe14fcc3 2525 }
79072805
LW
2526 }
2527 toptarget = NEWSV(0,0);
2528 sv_upgrade(toptarget, SVt_PVFM);
2529 sv_setpvn(toptarget, "", 0);
748a9306 2530 bodytarget = NEWSV(0,0);
79072805
LW
2531 sv_upgrade(bodytarget, SVt_PVFM);
2532 sv_setpvn(bodytarget, "", 0);
2533 formtarget = bodytarget;
2534
bbce6d69 2535 TAINT;
85e6fe83 2536 if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
79072805
LW
2537 sv_setpv(GvSV(tmpgv),origfilename);
2538 magicname("0", "0", 1);
2539 }
85e6fe83 2540 if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
79072805 2541 sv_setpv(GvSV(tmpgv),origargv[0]);
85e6fe83 2542 if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
a5f75d66 2543 GvMULTI_on(argvgv);
79072805
LW
2544 (void)gv_AVadd(argvgv);
2545 av_clear(GvAVn(argvgv));
2546 for (; argc > 0; argc--,argv++) {
a0d0e21e 2547 av_push(GvAVn(argvgv),newSVpv(argv[0],0));
79072805
LW
2548 }
2549 }
85e6fe83 2550 if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
79072805 2551 HV *hv;
a5f75d66 2552 GvMULTI_on(envgv);
79072805 2553 hv = GvHVn(envgv);
5aabfad6 2554 hv_magic(hv, envgv, 'E');
a0d0e21e 2555#ifndef VMS /* VMS doesn't have environ array */
4633a7c4
LW
2556 /* Note that if the supplied env parameter is actually a copy
2557 of the global environ then it may now point to free'd memory
2558 if the environment has been modified since. To avoid this
2559 problem we treat env==NULL as meaning 'use the default'
2560 */
2561 if (!env)
2562 env = environ;
5aabfad6 2563 if (env != environ)
79072805
LW
2564 environ[0] = Nullch;
2565 for (; *env; env++) {
93a17b20 2566 if (!(s = strchr(*env,'=')))
79072805
LW
2567 continue;
2568 *s++ = '\0';
137443ea 2569#ifdef WIN32
2570 (void)strupr(*env);
2571#endif
79072805
LW
2572 sv = newSVpv(s--,0);
2573 (void)hv_store(hv, *env, s - *env, sv, 0);
2574 *s = '=';
3e3baf6d
TB
2575#if defined(__BORLANDC__) && defined(USE_WIN32_RTL_ENV)
2576 /* Sins of the RTL. See note in my_setenv(). */
2577 (void)putenv(savepv(*env));
2578#endif
fe14fcc3 2579 }
4550b24a 2580#endif
2581#ifdef DYNAMIC_ENV_FETCH
2582 HvNAME(hv) = savepv(ENV_HV_NAME);
2583#endif
79072805 2584 }
bbce6d69 2585 TAINT_NOT;
85e6fe83 2586 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
1e422769 2587 sv_setiv(GvSV(tmpgv), (IV)getpid());
33b78306 2588}
34de22dd 2589
79072805
LW
2590static void
2591init_perllib()
34de22dd 2592{
85e6fe83
LW
2593 char *s;
2594 if (!tainting) {
552a7a9b 2595#ifndef VMS
85e6fe83
LW
2596 s = getenv("PERL5LIB");
2597 if (s)
774d564b 2598 incpush(s, TRUE);
85e6fe83 2599 else
774d564b 2600 incpush(getenv("PERLLIB"), FALSE);
552a7a9b 2601#else /* VMS */
2602 /* Treat PERL5?LIB as a possible search list logical name -- the
2603 * "natural" VMS idiom for a Unix path string. We allow each
2604 * element to be a set of |-separated directories for compatibility.
2605 */
2606 char buf[256];
2607 int idx = 0;
2608 if (my_trnlnm("PERL5LIB",buf,0))
774d564b 2609 do { incpush(buf,TRUE); } while (my_trnlnm("PERL5LIB",buf,++idx));
552a7a9b 2610 else
774d564b 2611 while (my_trnlnm("PERLLIB",buf,idx++)) incpush(buf,FALSE);
552a7a9b 2612#endif /* VMS */
85e6fe83 2613 }
34de22dd 2614
c90c0ff4 2615/* Use the ~-expanded versions of APPLLIB (undocumented),
df5cef82 2616 ARCHLIB PRIVLIB SITEARCH SITELIB and OLDARCHLIB
2617*/
4633a7c4 2618#ifdef APPLLIB_EXP
774d564b 2619 incpush(APPLLIB_EXP, FALSE);
16d20bd9 2620#endif
4633a7c4 2621
fed7345c 2622#ifdef ARCHLIB_EXP
774d564b 2623 incpush(ARCHLIB_EXP, FALSE);
a0d0e21e 2624#endif
fed7345c
AD
2625#ifndef PRIVLIB_EXP
2626#define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
34de22dd 2627#endif
774d564b 2628 incpush(PRIVLIB_EXP, FALSE);
4633a7c4
LW
2629
2630#ifdef SITEARCH_EXP
774d564b 2631 incpush(SITEARCH_EXP, FALSE);
4633a7c4
LW
2632#endif
2633#ifdef SITELIB_EXP
774d564b 2634 incpush(SITELIB_EXP, FALSE);
4633a7c4
LW
2635#endif
2636#ifdef OLDARCHLIB_EXP /* 5.00[01] compatibility */
774d564b 2637 incpush(OLDARCHLIB_EXP, FALSE);
4633a7c4 2638#endif
a0d0e21e 2639
4633a7c4 2640 if (!tainting)
774d564b 2641 incpush(".", FALSE);
2642}
2643
2644#if defined(DOSISH)
2645# define PERLLIB_SEP ';'
2646#else
2647# if defined(VMS)
2648# define PERLLIB_SEP '|'
2649# else
2650# define PERLLIB_SEP ':'
2651# endif
2652#endif
2653#ifndef PERLLIB_MANGLE
2654# define PERLLIB_MANGLE(s,n) (s)
2655#endif
2656
2657static void
2658incpush(p, addsubdirs)
2659char *p;
2660int addsubdirs;
2661{
2662 SV *subdir = Nullsv;
2663 static char *archpat_auto;
2664
2665 if (!p)
2666 return;
2667
2668 if (addsubdirs) {
2669 subdir = newSV(0);
2670 if (!archpat_auto) {
2671 STRLEN len = (sizeof(ARCHNAME) + strlen(patchlevel)
2672 + sizeof("//auto"));
2673 New(55, archpat_auto, len, char);
2674 sprintf(archpat_auto, "/%s/%s/auto", ARCHNAME, patchlevel);
aa689395 2675#ifdef VMS
2676 for (len = sizeof(ARCHNAME) + 2;
2677 archpat_auto[len] != '\0' && archpat_auto[len] != '/'; len++)
2678 if (archpat_auto[len] == '.') archpat_auto[len] = '_';
2679#endif
774d564b 2680 }
2681 }
2682
2683 /* Break at all separators */
2684 while (p && *p) {
2685 SV *libdir = newSV(0);
2686 char *s;
2687
2688 /* skip any consecutive separators */
2689 while ( *p == PERLLIB_SEP ) {
2690 /* Uncomment the next line for PATH semantics */
2691 /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
2692 p++;
2693 }
2694
2695 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
2696 sv_setpvn(libdir, PERLLIB_MANGLE(p, (STRLEN)(s - p)),
2697 (STRLEN)(s - p));
2698 p = s + 1;
2699 }
2700 else {
2701 sv_setpv(libdir, PERLLIB_MANGLE(p, 0));
2702 p = Nullch; /* break out */
2703 }
2704
2705 /*
2706 * BEFORE pushing libdir onto @INC we may first push version- and
2707 * archname-specific sub-directories.
2708 */
2709 if (addsubdirs) {
2710 struct stat tmpstatbuf;
aa689395 2711#ifdef VMS
2712 char *unix;
2713 STRLEN len;
774d564b 2714
aa689395 2715 if ((unix = tounixspec_ts(SvPV(libdir,na),Nullch)) != Nullch) {
2716 len = strlen(unix);
2717 while (unix[len-1] == '/') len--; /* Cosmetic */
2718 sv_usepvn(libdir,unix,len);
2719 }
2720 else
2721 PerlIO_printf(PerlIO_stderr(),
2722 "Failed to unixify @INC element \"%s\"\n",
2723 SvPV(libdir,na));
2724#endif
4fdae800 2725 /* .../archname/version if -d .../archname/version/auto */
774d564b 2726 sv_setsv(subdir, libdir);
2727 sv_catpv(subdir, archpat_auto);
2728 if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
2729 S_ISDIR(tmpstatbuf.st_mode))
2730 av_push(GvAVn(incgv),
2731 newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto"));
2732
4fdae800 2733 /* .../archname if -d .../archname/auto */
774d564b 2734 sv_insert(subdir, SvCUR(libdir) + sizeof(ARCHNAME),
2735 strlen(patchlevel) + 1, "", 0);
2736 if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
2737 S_ISDIR(tmpstatbuf.st_mode))
2738 av_push(GvAVn(incgv),
2739 newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto"));
2740 }
2741
2742 /* finally push this lib directory on the end of @INC */
2743 av_push(GvAVn(incgv), libdir);
2744 }
2745
2746 SvREFCNT_dec(subdir);
34de22dd 2747}
93a17b20
LW
2748
2749void
68dc0745 2750call_list(oldscope, list)
2ae324a7 2751I32 oldscope;
93a17b20
LW
2752AV* list;
2753{
11343788 2754 dTHR;
a0d0e21e 2755 line_t oldline = curcop->cop_line;
22921e25
CS
2756 STRLEN len;
2757 dJMPENV;
2758 int ret;
93a17b20 2759
8990e307
LW
2760 while (AvFILL(list) >= 0) {
2761 CV *cv = (CV*)av_shift(list);
93a17b20 2762
8990e307 2763 SAVEFREESV(cv);
a0d0e21e 2764
22921e25
CS
2765 JMPENV_PUSH(ret);
2766 switch (ret) {
748a9306 2767 case 0: {
4633a7c4 2768 SV* atsv = GvSV(errgv);
748a9306
LW
2769 PUSHMARK(stack_sp);
2770 perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
2771 (void)SvPV(atsv, len);
2772 if (len) {
54310121 2773 JMPENV_POP;
748a9306
LW
2774 curcop = &compiling;
2775 curcop->cop_line = oldline;
2776 if (list == beginav)
2777 sv_catpv(atsv, "BEGIN failed--compilation aborted");
2778 else
2779 sv_catpv(atsv, "END failed--cleanup aborted");
2ae324a7 2780 while (scopestack_ix > oldscope)
2781 LEAVE;
748a9306
LW
2782 croak("%s", SvPVX(atsv));
2783 }
a0d0e21e 2784 }
85e6fe83
LW
2785 break;
2786 case 1:
f86702cc 2787 STATUS_ALL_FAILURE;
85e6fe83
LW
2788 /* FALL THROUGH */
2789 case 2:
2790 /* my_exit() was called */
2ae324a7 2791 while (scopestack_ix > oldscope)
2792 LEAVE;
84902520 2793 FREETMPS;
85e6fe83
LW
2794 curstash = defstash;
2795 if (endav)
68dc0745 2796 call_list(oldscope, endav);
54310121 2797 JMPENV_POP;
a0d0e21e
LW
2798 curcop = &compiling;
2799 curcop->cop_line = oldline;
85e6fe83
LW
2800 if (statusvalue) {
2801 if (list == beginav)
a0d0e21e 2802 croak("BEGIN failed--compilation aborted");
85e6fe83 2803 else
a0d0e21e 2804 croak("END failed--cleanup aborted");
85e6fe83 2805 }
f86702cc 2806 my_exit_jump();
85e6fe83 2807 /* NOTREACHED */
85e6fe83
LW
2808 case 3:
2809 if (!restartop) {
760ac839 2810 PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
a0d0e21e 2811 FREETMPS;
85e6fe83
LW
2812 break;
2813 }
54310121 2814 JMPENV_POP;
a0d0e21e
LW
2815 curcop = &compiling;
2816 curcop->cop_line = oldline;
54310121 2817 JMPENV_JUMP(3);
8990e307 2818 }
54310121 2819 JMPENV_POP;
93a17b20 2820 }
93a17b20 2821}
93a17b20 2822
f86702cc 2823void
2824my_exit(status)
2825U32 status;
2826{
5dc0d613
MB
2827 dTHR;
2828
2829#ifdef USE_THREADS
2830 DEBUG_L(PerlIO_printf(Perl_debug_log, "my_exit: thread 0x%lx, status %lu\n",
2831 (unsigned long) thr, (unsigned long) status));
2832#endif /* USE_THREADS */
f86702cc 2833 switch (status) {
2834 case 0:
2835 STATUS_ALL_SUCCESS;
2836 break;
2837 case 1:
2838 STATUS_ALL_FAILURE;
2839 break;
2840 default:
2841 STATUS_NATIVE_SET(status);
2842 break;
2843 }
2844 my_exit_jump();
2845}
2846
2847void
2848my_failure_exit()
2849{
2850#ifdef VMS
2851 if (vaxc$errno & 1) {
4fdae800 2852 if (STATUS_NATIVE & 1) /* fortuitiously includes "-1" */
2853 STATUS_NATIVE_SET(44);
f86702cc 2854 }
2855 else {
ff0cee69 2856 if (!vaxc$errno && errno) /* unlikely */
4fdae800 2857 STATUS_NATIVE_SET(44);
f86702cc 2858 else
4fdae800 2859 STATUS_NATIVE_SET(vaxc$errno);
f86702cc 2860 }
2861#else
2862 if (errno & 255)
2863 STATUS_POSIX_SET(errno);
2864 else if (STATUS_POSIX == 0)
2865 STATUS_POSIX_SET(255);
2866#endif
2867 my_exit_jump();
93a17b20
LW
2868}
2869
f86702cc 2870static void
2871my_exit_jump()
2872{
e858de61 2873 dTHR;
f86702cc 2874 register CONTEXT *cx;
2875 I32 gimme;
2876 SV **newsp;
2877
2878 if (e_tmpname) {
2879 if (e_fp) {
2880 PerlIO_close(e_fp);
2881 e_fp = Nullfp;
2882 }
2883 (void)UNLINK(e_tmpname);
2884 Safefree(e_tmpname);
2885 e_tmpname = Nullch;
2886 }
2887
2888 if (cxstack_ix >= 0) {
2889 if (cxstack_ix > 0)
2890 dounwind(0);
2891 POPBLOCK(cx,curpm);
2892 LEAVE;
2893 }
ff0cee69 2894
54310121 2895 JMPENV_JUMP(2);
f86702cc 2896}