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