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