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