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