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