summaryrefslogtreecommitdiffstats
path: root/contrib/perl5/perl.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/perl5/perl.c')
-rw-r--r--contrib/perl5/perl.c3905
1 files changed, 0 insertions, 3905 deletions
diff --git a/contrib/perl5/perl.c b/contrib/perl5/perl.c
deleted file mode 100644
index d18107c..0000000
--- a/contrib/perl5/perl.c
+++ /dev/null
@@ -1,3905 +0,0 @@
-/* perl.c
- *
- * Copyright (c) 1987-2001 Larry Wall
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Artistic License, as specified in the README file.
- *
- * $FreeBSD$
- */
-
-/*
- * "A ship then new they built for him/of mithril and of elven glass" --Bilbo
- */
-
-#include "EXTERN.h"
-#define PERL_IN_PERL_C
-#include "perl.h"
-#include "patchlevel.h" /* for local_patches */
-
-/* XXX If this causes problems, set i_unistd=undef in the hint file. */
-#ifdef I_UNISTD
-#include <unistd.h>
-#endif
-
-#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
-char *getenv (char *); /* Usually in <stdlib.h> */
-#endif
-
-static I32 read_e_script(pTHXo_ int idx, SV *buf_sv, int maxlen);
-
-#ifdef IAMSUID
-#ifndef DOSUID
-#define DOSUID
-#endif
-#endif
-
-#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
-#ifdef DOSUID
-#undef DOSUID
-#endif
-#endif
-
-#ifdef PERL_OBJECT
-#define perl_construct Perl_construct
-#define perl_parse Perl_parse
-#define perl_run Perl_run
-#define perl_destruct Perl_destruct
-#define perl_free Perl_free
-#endif
-
-#if defined(USE_THREADS)
-# define INIT_TLS_AND_INTERP \
- STMT_START { \
- if (!PL_curinterp) { \
- PERL_SET_INTERP(my_perl); \
- INIT_THREADS; \
- ALLOC_THREAD_KEY; \
- } \
- } STMT_END
-#else
-# if defined(USE_ITHREADS)
-# define INIT_TLS_AND_INTERP \
- STMT_START { \
- if (!PL_curinterp) { \
- PERL_SET_INTERP(my_perl); \
- INIT_THREADS; \
- ALLOC_THREAD_KEY; \
- PERL_SET_THX(my_perl); \
- OP_REFCNT_INIT; \
- } \
- else { \
- PERL_SET_THX(my_perl); \
- } \
- } STMT_END
-# else
-# define INIT_TLS_AND_INTERP \
- STMT_START { \
- if (!PL_curinterp) { \
- PERL_SET_INTERP(my_perl); \
- } \
- PERL_SET_THX(my_perl); \
- } STMT_END
-# endif
-#endif
-
-#ifdef PERL_IMPLICIT_SYS
-PerlInterpreter *
-perl_alloc_using(struct IPerlMem* ipM, struct IPerlMem* ipMS,
- struct IPerlMem* ipMP, struct IPerlEnv* ipE,
- struct IPerlStdIO* ipStd, struct IPerlLIO* ipLIO,
- struct IPerlDir* ipD, struct IPerlSock* ipS,
- struct IPerlProc* ipP)
-{
- PerlInterpreter *my_perl;
-#ifdef PERL_OBJECT
- my_perl = (PerlInterpreter*)new(ipM) CPerlObj(ipM, ipMS, ipMP, ipE, ipStd,
- ipLIO, ipD, ipS, ipP);
- INIT_TLS_AND_INTERP;
-#else
- /* New() needs interpreter, so call malloc() instead */
- my_perl = (PerlInterpreter*)(*ipM->pMalloc)(ipM, sizeof(PerlInterpreter));
- INIT_TLS_AND_INTERP;
- Zero(my_perl, 1, PerlInterpreter);
- PL_Mem = ipM;
- PL_MemShared = ipMS;
- PL_MemParse = ipMP;
- PL_Env = ipE;
- PL_StdIO = ipStd;
- PL_LIO = ipLIO;
- PL_Dir = ipD;
- PL_Sock = ipS;
- PL_Proc = ipP;
-#endif
-
- return my_perl;
-}
-#else
-
-/*
-=for apidoc perl_alloc
-
-Allocates a new Perl interpreter. See L<perlembed>.
-
-=cut
-*/
-
-PerlInterpreter *
-perl_alloc(void)
-{
- PerlInterpreter *my_perl;
-
- /* New() needs interpreter, so call malloc() instead */
- my_perl = (PerlInterpreter*)PerlMem_malloc(sizeof(PerlInterpreter));
-
- INIT_TLS_AND_INTERP;
- Zero(my_perl, 1, PerlInterpreter);
- return my_perl;
-}
-#endif /* PERL_IMPLICIT_SYS */
-
-/*
-=for apidoc perl_construct
-
-Initializes a new Perl interpreter. See L<perlembed>.
-
-=cut
-*/
-
-void
-perl_construct(pTHXx)
-{
-#ifdef USE_THREADS
- int i;
-#ifndef FAKE_THREADS
- struct perl_thread *thr = NULL;
-#endif /* FAKE_THREADS */
-#endif /* USE_THREADS */
-
-#ifdef MULTIPLICITY
- init_interp();
- PL_perl_destruct_level = 1;
-#else
- if (PL_perl_destruct_level > 0)
- init_interp();
-#endif
-
- /* Init the real globals (and main thread)? */
- if (!PL_linestr) {
-#ifdef USE_THREADS
- MUTEX_INIT(&PL_sv_mutex);
- /*
- * Safe to use basic SV functions from now on (though
- * not things like mortals or tainting yet).
- */
- MUTEX_INIT(&PL_eval_mutex);
- COND_INIT(&PL_eval_cond);
- MUTEX_INIT(&PL_threads_mutex);
- COND_INIT(&PL_nthreads_cond);
-# ifdef EMULATE_ATOMIC_REFCOUNTS
- MUTEX_INIT(&PL_svref_mutex);
-# endif /* EMULATE_ATOMIC_REFCOUNTS */
-
- MUTEX_INIT(&PL_cred_mutex);
- MUTEX_INIT(&PL_sv_lock_mutex);
- MUTEX_INIT(&PL_fdpid_mutex);
-
- thr = init_main_thread();
-#endif /* USE_THREADS */
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
- PL_protect = MEMBER_TO_FPTR(Perl_default_protect); /* for exceptions */
-#endif
-
- PL_curcop = &PL_compiling; /* needed by ckWARN, right away */
-
- PL_linestr = NEWSV(65,79);
- sv_upgrade(PL_linestr,SVt_PVIV);
-
- if (!SvREADONLY(&PL_sv_undef)) {
- /* set read-only and try to insure than we wont see REFCNT==0
- very often */
-
- SvREADONLY_on(&PL_sv_undef);
- SvREFCNT(&PL_sv_undef) = (~(U32)0)/2;
-
- sv_setpv(&PL_sv_no,PL_No);
- SvNV(&PL_sv_no);
- SvREADONLY_on(&PL_sv_no);
- SvREFCNT(&PL_sv_no) = (~(U32)0)/2;
-
- sv_setpv(&PL_sv_yes,PL_Yes);
- SvNV(&PL_sv_yes);
- SvREADONLY_on(&PL_sv_yes);
- SvREFCNT(&PL_sv_yes) = (~(U32)0)/2;
- }
-
-#ifdef PERL_OBJECT
- /* TODO: */
- /* PL_sighandlerp = sighandler; */
-#else
- PL_sighandlerp = Perl_sighandler;
-#endif
- PL_pidstatus = newHV();
-
-#ifdef MSDOS
- /*
- * There is no way we can refer to them from Perl so close them to save
- * space. The other alternative would be to provide STDAUX and STDPRN
- * filehandles.
- */
- (void)fclose(stdaux);
- (void)fclose(stdprn);
-#endif
- }
-
- PL_nrs = newSVpvn("\n", 1);
- PL_rs = SvREFCNT_inc(PL_nrs);
-
- init_stacks();
-
- init_ids();
- PL_lex_state = LEX_NOTPARSING;
-
- JMPENV_BOOTSTRAP;
- STATUS_ALL_SUCCESS;
-
- init_i18nl10n(1);
- SET_NUMERIC_STANDARD();
-
- {
- U8 *s;
- PL_patchlevel = NEWSV(0,4);
- (void)SvUPGRADE(PL_patchlevel, SVt_PVNV);
- if (PERL_REVISION > 127 || PERL_VERSION > 127 || PERL_SUBVERSION > 127)
- SvGROW(PL_patchlevel, UTF8_MAXLEN*3+1);
- s = (U8*)SvPVX(PL_patchlevel);
- s = uv_to_utf8(s, (UV)PERL_REVISION);
- s = uv_to_utf8(s, (UV)PERL_VERSION);
- s = uv_to_utf8(s, (UV)PERL_SUBVERSION);
- *s = '\0';
- SvCUR_set(PL_patchlevel, s - (U8*)SvPVX(PL_patchlevel));
- SvPOK_on(PL_patchlevel);
- SvNVX(PL_patchlevel) = (NV)PERL_REVISION
- + ((NV)PERL_VERSION / (NV)1000)
-#if defined(PERL_SUBVERSION) && PERL_SUBVERSION > 0
- + ((NV)PERL_SUBVERSION / (NV)1000000)
-#endif
- ;
- SvNOK_on(PL_patchlevel); /* dual valued */
- SvUTF8_on(PL_patchlevel);
- SvREADONLY_on(PL_patchlevel);
- }
-
-#if defined(LOCAL_PATCH_COUNT)
- PL_localpatches = local_patches; /* For possible -v */
-#endif
-
-#ifdef HAVE_INTERP_INTERN
- sys_intern_init();
-#endif
-
- PerlIO_init(); /* Hook to IO system */
-
- PL_fdpid = newAV(); /* for remembering popen pids by fd */
- PL_modglobal = newHV(); /* pointers to per-interpreter module globals */
- PL_errors = newSVpvn("",0);
-
- ENTER;
-}
-
-/*
-=for apidoc perl_destruct
-
-Shuts down a Perl interpreter. See L<perlembed>.
-
-=cut
-*/
-
-void
-perl_destruct(pTHXx)
-{
- int destruct_level; /* 0=none, 1=full, 2=full with checks */
- HV *hv;
-#ifdef USE_THREADS
- Thread t;
- dTHX;
-#endif /* USE_THREADS */
-
- /* wait for all pseudo-forked children to finish */
- PERL_WAIT_FOR_CHILDREN;
-
-#ifdef USE_THREADS
-#ifndef FAKE_THREADS
- /* Pass 1 on any remaining threads: detach joinables, join zombies */
- retry_cleanup:
- MUTEX_LOCK(&PL_threads_mutex);
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "perl_destruct: waiting for %d threads...\n",
- PL_nthreads - 1));
- for (t = thr->next; t != thr; t = t->next) {
- MUTEX_LOCK(&t->mutex);
- switch (ThrSTATE(t)) {
- AV *av;
- case THRf_ZOMBIE:
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "perl_destruct: joining zombie %p\n", t));
- ThrSETSTATE(t, THRf_DEAD);
- MUTEX_UNLOCK(&t->mutex);
- PL_nthreads--;
- /*
- * The SvREFCNT_dec below may take a long time (e.g. av
- * may contain an object scalar whose destructor gets
- * called) so we have to unlock threads_mutex and start
- * all over again.
- */
- MUTEX_UNLOCK(&PL_threads_mutex);
- JOIN(t, &av);
- SvREFCNT_dec((SV*)av);
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "perl_destruct: joined zombie %p OK\n", t));
- goto retry_cleanup;
- case THRf_R_JOINABLE:
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "perl_destruct: detaching thread %p\n", t));
- ThrSETSTATE(t, THRf_R_DETACHED);
- /*
- * We unlock threads_mutex and t->mutex in the opposite order
- * from which we locked them just so that DETACH won't
- * deadlock if it panics. It's only a breach of good style
- * not a bug since they are unlocks not locks.
- */
- MUTEX_UNLOCK(&PL_threads_mutex);
- DETACH(t);
- MUTEX_UNLOCK(&t->mutex);
- goto retry_cleanup;
- default:
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "perl_destruct: ignoring %p (state %u)\n",
- t, ThrSTATE(t)));
- MUTEX_UNLOCK(&t->mutex);
- /* fall through and out */
- }
- }
- /* We leave the above "Pass 1" loop with threads_mutex still locked */
-
- /* Pass 2 on remaining threads: wait for the thread count to drop to one */
- while (PL_nthreads > 1)
- {
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "perl_destruct: final wait for %d threads\n",
- PL_nthreads - 1));
- COND_WAIT(&PL_nthreads_cond, &PL_threads_mutex);
- }
- /* At this point, we're the last thread */
- MUTEX_UNLOCK(&PL_threads_mutex);
- DEBUG_S(PerlIO_printf(Perl_debug_log, "perl_destruct: armageddon has arrived\n"));
- MUTEX_DESTROY(&PL_threads_mutex);
- COND_DESTROY(&PL_nthreads_cond);
- PL_nthreads--;
-#endif /* !defined(FAKE_THREADS) */
-#endif /* USE_THREADS */
-
- destruct_level = PL_perl_destruct_level;
-#ifdef DEBUGGING
- {
- char *s;
- if ((s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL"))) {
- int i = atoi(s);
- if (destruct_level < i)
- destruct_level = i;
- }
- }
-#endif
-
- LEAVE;
- FREETMPS;
-
- /* We must account for everything. */
-
- /* Destroy the main CV and syntax tree */
- if (PL_main_root) {
- PL_curpad = AvARRAY(PL_comppad);
- op_free(PL_main_root);
- PL_main_root = Nullop;
- }
- PL_curcop = &PL_compiling;
- PL_main_start = Nullop;
- SvREFCNT_dec(PL_main_cv);
- PL_main_cv = Nullcv;
- PL_dirty = TRUE;
-
- if (PL_sv_objcount) {
- /*
- * Try to destruct global references. We do this first so that the
- * destructors and destructees still exist. Some sv's might remain.
- * Non-referenced objects are on their own.
- */
- sv_clean_objs();
- }
-
- /* unhook hooks which will soon be, or use, destroyed data */
- SvREFCNT_dec(PL_warnhook);
- PL_warnhook = Nullsv;
- SvREFCNT_dec(PL_diehook);
- PL_diehook = Nullsv;
-
- /* call exit list functions */
- while (PL_exitlistlen-- > 0)
- PL_exitlist[PL_exitlistlen].fn(aTHXo_ PL_exitlist[PL_exitlistlen].ptr);
-
- Safefree(PL_exitlist);
-
- if (destruct_level == 0){
-
- DEBUG_P(debprofdump());
-
- /* The exit() function will do everything that needs doing. */
- return;
- }
-
- /* jettison our possibly duplicated environment */
-
-#ifdef USE_ENVIRON_ARRAY
- if (environ != PL_origenviron) {
- I32 i;
-
- for (i = 0; environ[i]; i++)
- safesysfree(environ[i]);
- /* Must use safesysfree() when working with environ. */
- safesysfree(environ);
-
- environ = PL_origenviron;
- }
-#endif
-
- /* loosen bonds of global variables */
-
- if(PL_rsfp) {
- (void)PerlIO_close(PL_rsfp);
- PL_rsfp = Nullfp;
- }
-
- /* Filters for program text */
- SvREFCNT_dec(PL_rsfp_filters);
- PL_rsfp_filters = Nullav;
-
- /* switches */
- PL_preprocess = FALSE;
- PL_minus_n = FALSE;
- PL_minus_p = FALSE;
- PL_minus_l = FALSE;
- PL_minus_a = FALSE;
- PL_minus_F = FALSE;
- PL_doswitches = FALSE;
- PL_dowarn = G_WARN_OFF;
- PL_doextract = FALSE;
- PL_sawampersand = FALSE; /* must save all match strings */
- PL_unsafe = FALSE;
-
- Safefree(PL_inplace);
- PL_inplace = Nullch;
- SvREFCNT_dec(PL_patchlevel);
-
- if (PL_e_script) {
- SvREFCNT_dec(PL_e_script);
- PL_e_script = Nullsv;
- }
-
- /* magical thingies */
-
- Safefree(PL_ofs); /* $, */
- PL_ofs = Nullch;
-
- Safefree(PL_ors); /* $\ */
- PL_ors = Nullch;
-
- SvREFCNT_dec(PL_rs); /* $/ */
- PL_rs = Nullsv;
-
- SvREFCNT_dec(PL_nrs); /* $/ helper */
- PL_nrs = Nullsv;
-
- PL_multiline = 0; /* $* */
- Safefree(PL_osname); /* $^O */
- PL_osname = Nullch;
-
- SvREFCNT_dec(PL_statname);
- PL_statname = Nullsv;
- PL_statgv = Nullgv;
-
- /* defgv, aka *_ should be taken care of elsewhere */
-
- /* clean up after study() */
- SvREFCNT_dec(PL_lastscream);
- PL_lastscream = Nullsv;
- Safefree(PL_screamfirst);
- PL_screamfirst = 0;
- Safefree(PL_screamnext);
- PL_screamnext = 0;
-
- /* float buffer */
- Safefree(PL_efloatbuf);
- PL_efloatbuf = Nullch;
- PL_efloatsize = 0;
-
- /* startup and shutdown function lists */
- SvREFCNT_dec(PL_beginav);
- SvREFCNT_dec(PL_endav);
- SvREFCNT_dec(PL_checkav);
- SvREFCNT_dec(PL_initav);
- PL_beginav = Nullav;
- PL_endav = Nullav;
- PL_checkav = Nullav;
- PL_initav = Nullav;
-
- /* shortcuts just get cleared */
- PL_envgv = Nullgv;
- PL_incgv = Nullgv;
- PL_hintgv = Nullgv;
- PL_errgv = Nullgv;
- PL_argvgv = Nullgv;
- PL_argvoutgv = Nullgv;
- PL_stdingv = Nullgv;
- PL_stderrgv = Nullgv;
- PL_last_in_gv = Nullgv;
- PL_replgv = Nullgv;
- PL_debstash = Nullhv;
-
- /* reset so print() ends up where we expect */
- setdefout(Nullgv);
-
- SvREFCNT_dec(PL_argvout_stack);
- PL_argvout_stack = Nullav;
-
- SvREFCNT_dec(PL_modglobal);
- PL_modglobal = Nullhv;
- SvREFCNT_dec(PL_preambleav);
- PL_preambleav = Nullav;
- SvREFCNT_dec(PL_subname);
- PL_subname = Nullsv;
- SvREFCNT_dec(PL_linestr);
- PL_linestr = Nullsv;
- SvREFCNT_dec(PL_pidstatus);
- PL_pidstatus = Nullhv;
- SvREFCNT_dec(PL_toptarget);
- PL_toptarget = Nullsv;
- SvREFCNT_dec(PL_bodytarget);
- PL_bodytarget = Nullsv;
- PL_formtarget = Nullsv;
-
- /* free locale stuff */
-#ifdef USE_LOCALE_COLLATE
- Safefree(PL_collation_name);
- PL_collation_name = Nullch;
-#endif
-
-#ifdef USE_LOCALE_NUMERIC
- Safefree(PL_numeric_name);
- PL_numeric_name = Nullch;
- SvREFCNT_dec(PL_numeric_radix_sv);
-#endif
-
- /* clear utf8 character classes */
- SvREFCNT_dec(PL_utf8_alnum);
- SvREFCNT_dec(PL_utf8_alnumc);
- SvREFCNT_dec(PL_utf8_ascii);
- SvREFCNT_dec(PL_utf8_alpha);
- SvREFCNT_dec(PL_utf8_space);
- SvREFCNT_dec(PL_utf8_cntrl);
- SvREFCNT_dec(PL_utf8_graph);
- SvREFCNT_dec(PL_utf8_digit);
- SvREFCNT_dec(PL_utf8_upper);
- SvREFCNT_dec(PL_utf8_lower);
- SvREFCNT_dec(PL_utf8_print);
- SvREFCNT_dec(PL_utf8_punct);
- SvREFCNT_dec(PL_utf8_xdigit);
- SvREFCNT_dec(PL_utf8_mark);
- SvREFCNT_dec(PL_utf8_toupper);
- SvREFCNT_dec(PL_utf8_tolower);
- PL_utf8_alnum = Nullsv;
- PL_utf8_alnumc = Nullsv;
- PL_utf8_ascii = Nullsv;
- PL_utf8_alpha = Nullsv;
- PL_utf8_space = Nullsv;
- PL_utf8_cntrl = Nullsv;
- PL_utf8_graph = Nullsv;
- PL_utf8_digit = Nullsv;
- PL_utf8_upper = Nullsv;
- PL_utf8_lower = Nullsv;
- PL_utf8_print = Nullsv;
- PL_utf8_punct = Nullsv;
- PL_utf8_xdigit = Nullsv;
- PL_utf8_mark = Nullsv;
- PL_utf8_toupper = Nullsv;
- PL_utf8_totitle = Nullsv;
- PL_utf8_tolower = Nullsv;
-
- if (!specialWARN(PL_compiling.cop_warnings))
- SvREFCNT_dec(PL_compiling.cop_warnings);
- PL_compiling.cop_warnings = Nullsv;
-#ifdef USE_ITHREADS
- Safefree(CopFILE(&PL_compiling));
- CopFILE(&PL_compiling) = Nullch;
- Safefree(CopSTASHPV(&PL_compiling));
-#else
- SvREFCNT_dec(CopFILEGV(&PL_compiling));
- CopFILEGV(&PL_compiling) = Nullgv;
- /* cop_stash is not refcounted */
-#endif
-
- /* Prepare to destruct main symbol table. */
-
- hv = PL_defstash;
- PL_defstash = 0;
- SvREFCNT_dec(hv);
- SvREFCNT_dec(PL_curstname);
- PL_curstname = Nullsv;
-
- /* clear queued errors */
- SvREFCNT_dec(PL_errors);
- PL_errors = Nullsv;
-
- FREETMPS;
- if (destruct_level >= 2 && ckWARN_d(WARN_INTERNAL)) {
- if (PL_scopestack_ix != 0)
- Perl_warner(aTHX_ WARN_INTERNAL,
- "Unbalanced scopes: %ld more ENTERs than LEAVEs\n",
- (long)PL_scopestack_ix);
- if (PL_savestack_ix != 0)
- Perl_warner(aTHX_ WARN_INTERNAL,
- "Unbalanced saves: %ld more saves than restores\n",
- (long)PL_savestack_ix);
- if (PL_tmps_floor != -1)
- Perl_warner(aTHX_ WARN_INTERNAL,"Unbalanced tmps: %ld more allocs than frees\n",
- (long)PL_tmps_floor + 1);
- if (cxstack_ix != -1)
- Perl_warner(aTHX_ WARN_INTERNAL,"Unbalanced context: %ld more PUSHes than POPs\n",
- (long)cxstack_ix + 1);
- }
-
- /* Now absolutely destruct everything, somehow or other, loops or no. */
- SvFLAGS(PL_fdpid) |= SVTYPEMASK; /* don't clean out pid table now */
- SvFLAGS(PL_strtab) |= SVTYPEMASK; /* don't clean out strtab now */
-
- /* the 2 is for PL_fdpid and PL_strtab */
- while (PL_sv_count > 2 && sv_clean_all())
- ;
-
- SvFLAGS(PL_fdpid) &= ~SVTYPEMASK;
- SvFLAGS(PL_fdpid) |= SVt_PVAV;
- SvFLAGS(PL_strtab) &= ~SVTYPEMASK;
- SvFLAGS(PL_strtab) |= SVt_PVHV;
-
- AvREAL_off(PL_fdpid); /* no surviving entries */
- SvREFCNT_dec(PL_fdpid); /* needed in io_close() */
- PL_fdpid = Nullav;
-
-#ifdef HAVE_INTERP_INTERN
- sys_intern_clear();
-#endif
-
- /* Destruct the global string table. */
- {
- /* Yell and reset the HeVAL() slots that are still holding refcounts,
- * so that sv_free() won't fail on them.
- */
- I32 riter;
- I32 max;
- HE *hent;
- HE **array;
-
- riter = 0;
- max = HvMAX(PL_strtab);
- array = HvARRAY(PL_strtab);
- hent = array[0];
- for (;;) {
- if (hent && ckWARN_d(WARN_INTERNAL)) {
- Perl_warner(aTHX_ WARN_INTERNAL,
- "Unbalanced string table refcount: (%d) for \"%s\"",
- HeVAL(hent) - Nullsv, HeKEY(hent));
- HeVAL(hent) = Nullsv;
- hent = HeNEXT(hent);
- }
- if (!hent) {
- if (++riter > max)
- break;
- hent = array[riter];
- }
- }
- }
- SvREFCNT_dec(PL_strtab);
-
-#ifdef USE_ITHREADS
- /* free the pointer table used for cloning */
- ptr_table_free(PL_ptr_table);
-#endif
-
- /* free special SVs */
-
- SvREFCNT(&PL_sv_yes) = 0;
- sv_clear(&PL_sv_yes);
- SvANY(&PL_sv_yes) = NULL;
- SvFLAGS(&PL_sv_yes) = 0;
-
- SvREFCNT(&PL_sv_no) = 0;
- sv_clear(&PL_sv_no);
- SvANY(&PL_sv_no) = NULL;
- SvFLAGS(&PL_sv_no) = 0;
-
- SvREFCNT(&PL_sv_undef) = 0;
- SvREADONLY_off(&PL_sv_undef);
-
- if (PL_sv_count != 0 && ckWARN_d(WARN_INTERNAL))
- Perl_warner(aTHX_ WARN_INTERNAL,"Scalars leaked: %ld\n", (long)PL_sv_count);
-
- Safefree(PL_origfilename);
- Safefree(PL_reg_start_tmp);
- if (PL_reg_curpm)
- Safefree(PL_reg_curpm);
- Safefree(PL_reg_poscache);
- Safefree(HeKEY_hek(&PL_hv_fetch_ent_mh));
- Safefree(PL_op_mask);
- Safefree(PL_psig_ptr);
- Safefree(PL_psig_name);
- Safefree(PL_bitcount);
- nuke_stacks();
- PL_hints = 0; /* Reset hints. Should hints be per-interpreter ? */
-
- DEBUG_P(debprofdump());
-#ifdef USE_THREADS
- MUTEX_DESTROY(&PL_strtab_mutex);
- MUTEX_DESTROY(&PL_sv_mutex);
- MUTEX_DESTROY(&PL_eval_mutex);
- MUTEX_DESTROY(&PL_cred_mutex);
- MUTEX_DESTROY(&PL_fdpid_mutex);
- COND_DESTROY(&PL_eval_cond);
-#ifdef EMULATE_ATOMIC_REFCOUNTS
- MUTEX_DESTROY(&PL_svref_mutex);
-#endif /* EMULATE_ATOMIC_REFCOUNTS */
-
- /* As the penultimate thing, free the non-arena SV for thrsv */
- Safefree(SvPVX(PL_thrsv));
- Safefree(SvANY(PL_thrsv));
- Safefree(PL_thrsv);
- PL_thrsv = Nullsv;
-#endif /* USE_THREADS */
-
- sv_free_arenas();
-
- /* As the absolutely last thing, free the non-arena SV for mess() */
-
- if (PL_mess_sv) {
- /* it could have accumulated taint magic */
- if (SvTYPE(PL_mess_sv) >= SVt_PVMG) {
- MAGIC* mg;
- MAGIC* moremagic;
- for (mg = SvMAGIC(PL_mess_sv); mg; mg = moremagic) {
- moremagic = mg->mg_moremagic;
- if (mg->mg_ptr && mg->mg_type != 'g' && mg->mg_len >= 0)
- Safefree(mg->mg_ptr);
- Safefree(mg);
- }
- }
- /* we know that type >= SVt_PV */
- (void)SvOOK_off(PL_mess_sv);
- Safefree(SvPVX(PL_mess_sv));
- Safefree(SvANY(PL_mess_sv));
- Safefree(PL_mess_sv);
- PL_mess_sv = Nullsv;
- }
-}
-
-/*
-=for apidoc perl_free
-
-Releases a Perl interpreter. See L<perlembed>.
-
-=cut
-*/
-
-void
-perl_free(pTHXx)
-{
-#if defined(PERL_OBJECT)
- PerlMem_free(this);
-#else
-# if defined(PERL_IMPLICIT_SYS) && defined(WIN32)
- void *host = w32_internal_host;
- PerlMem_free(aTHXx);
- win32_delete_internal_host(host);
-# else
- PerlMem_free(aTHXx);
-# endif
-#endif
-}
-
-void
-Perl_call_atexit(pTHX_ ATEXIT_t fn, void *ptr)
-{
- Renew(PL_exitlist, PL_exitlistlen+1, PerlExitListEntry);
- PL_exitlist[PL_exitlistlen].fn = fn;
- PL_exitlist[PL_exitlistlen].ptr = ptr;
- ++PL_exitlistlen;
-}
-
-/*
-=for apidoc perl_parse
-
-Tells a Perl interpreter to parse a Perl script. See L<perlembed>.
-
-=cut
-*/
-
-int
-perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
-{
- I32 oldscope;
- int ret;
- dJMPENV;
-#ifdef USE_THREADS
- dTHX;
-#endif
-
-#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
-#ifdef IAMSUID
-#undef IAMSUID
- Perl_croak(aTHX_ "suidperl is no longer needed since the kernel can now execute\n\
-setuid perl scripts securely.\n");
-#endif
-#endif
-
-#if defined(__DYNAMIC__) && (defined(NeXT) || defined(__NeXT__))
- _dyld_lookup_and_bind
- ("__environ", (unsigned long *) &environ_pointer, NULL);
-#endif /* environ */
-
- PL_origargv = argv;
- PL_origargc = argc;
-#ifdef USE_ENVIRON_ARRAY
- PL_origenviron = environ;
-#endif
-
- if (PL_do_undump) {
-
- /* Come here if running an undumped a.out. */
-
- PL_origfilename = savepv(argv[0]);
- PL_do_undump = FALSE;
- cxstack_ix = -1; /* start label stack again */
- init_ids();
- init_postdump_symbols(argc,argv,env);
- return 0;
- }
-
- if (PL_main_root) {
- PL_curpad = AvARRAY(PL_comppad);
- op_free(PL_main_root);
- PL_main_root = Nullop;
- }
- PL_main_start = Nullop;
- SvREFCNT_dec(PL_main_cv);
- PL_main_cv = Nullcv;
-
- time(&PL_basetime);
- oldscope = PL_scopestack_ix;
- PL_dowarn = G_WARN_OFF;
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
- CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_vparse_body), env, xsinit);
-#else
- JMPENV_PUSH(ret);
-#endif
- switch (ret) {
- case 0:
-#ifndef PERL_FLEXIBLE_EXCEPTIONS
- parse_body(env,xsinit);
-#endif
- if (PL_checkav)
- call_list(oldscope, PL_checkav);
- ret = 0;
- break;
- case 1:
- STATUS_ALL_FAILURE;
- /* FALL THROUGH */
- case 2:
- /* my_exit() was called */
- while (PL_scopestack_ix > oldscope)
- LEAVE;
- FREETMPS;
- PL_curstash = PL_defstash;
- if (PL_checkav)
- call_list(oldscope, PL_checkav);
- ret = STATUS_NATIVE_EXPORT;
- break;
- case 3:
- PerlIO_printf(Perl_error_log, "panic: top_env\n");
- ret = 1;
- break;
- }
- JMPENV_POP;
- return ret;
-}
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
-STATIC void *
-S_vparse_body(pTHX_ va_list args)
-{
- char **env = va_arg(args, char**);
- XSINIT_t xsinit = va_arg(args, XSINIT_t);
-
- return parse_body(env, xsinit);
-}
-#endif
-
-STATIC void *
-S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
-{
- int argc = PL_origargc;
- char **argv = PL_origargv;
- char *scriptname = NULL;
- int fdscript = -1;
- VOL bool dosearch = FALSE;
- char *validarg = "";
- AV* comppadlist;
- register SV *sv;
- register char *s;
- char *cddir = Nullch;
-
- sv_setpvn(PL_linestr,"",0);
- sv = newSVpvn("",0); /* first used for -I flags */
- SAVEFREESV(sv);
- init_main_stash();
-
- for (argc--,argv++; argc > 0; argc--,argv++) {
- if (argv[0][0] != '-' || !argv[0][1])
- break;
-#ifdef DOSUID
- if (*validarg)
- validarg = " PHOOEY ";
- else
- validarg = argv[0];
-#endif
- s = argv[0]+1;
- reswitch:
- switch (*s) {
- case 'C':
-#ifdef WIN32
- win32_argv2utf8(argc-1, argv+1);
- /* FALL THROUGH */
-#endif
-#ifndef PERL_STRICT_CR
- case '\r':
-#endif
- case ' ':
- case '0':
- case 'F':
- case 'a':
- case 'c':
- case 'd':
- case 'D':
- case 'h':
- case 'i':
- case 'l':
- case 'M':
- case 'm':
- case 'n':
- case 'p':
- case 's':
- case 'u':
- case 'U':
- case 'v':
- case 'W':
- case 'X':
- case 'w':
- if ((s = moreswitches(s)))
- goto reswitch;
- break;
-
- case 'T':
- PL_tainting = TRUE;
- s++;
- goto reswitch;
-
- case 'e':
-#ifdef MACOS_TRADITIONAL
- /* ignore -e for Dev:Pseudo argument */
- if (argv[1] && !strcmp(argv[1], "Dev:Pseudo"))
- break;
-#endif
- if (PL_euid != PL_uid || PL_egid != PL_gid)
- Perl_croak(aTHX_ "No -e allowed in setuid scripts");
- if (!PL_e_script) {
- PL_e_script = newSVpvn("",0);
- filter_add(read_e_script, NULL);
- }
- if (*++s)
- sv_catpv(PL_e_script, s);
- else if (argv[1]) {
- sv_catpv(PL_e_script, argv[1]);
- argc--,argv++;
- }
- else
- Perl_croak(aTHX_ "No code specified for -e");
- sv_catpv(PL_e_script, "\n");
- break;
-
- case 'I': /* -I handled both here and in moreswitches() */
- forbid_setid("-I");
- if (!*++s && (s=argv[1]) != Nullch) {
- argc--,argv++;
- }
- if (s && *s) {
- char *p;
- STRLEN len = strlen(s);
- p = savepvn(s, len);
- incpush(p, TRUE, TRUE);
- sv_catpvn(sv, "-I", 2);
- sv_catpvn(sv, p, len);
- sv_catpvn(sv, " ", 1);
- Safefree(p);
- }
- else
- Perl_croak(aTHX_ "No directory specified for -I");
- break;
- case 'P':
- forbid_setid("-P");
- PL_preprocess = TRUE;
- s++;
- goto reswitch;
- case 'S':
- forbid_setid("-S");
- dosearch = TRUE;
- s++;
- goto reswitch;
- case 'V':
- if (!PL_preambleav)
- PL_preambleav = newAV();
- av_push(PL_preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
- if (*++s != ':') {
- PL_Sv = newSVpv("print myconfig();",0);
-#ifdef VMS
- sv_catpv(PL_Sv,"print \"\\nCharacteristics of this PERLSHR image: \\n\",");
-#else
- sv_catpv(PL_Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\",");
-#endif
- sv_catpv(PL_Sv,"\" Compile-time options:");
-# ifdef DEBUGGING
- sv_catpv(PL_Sv," DEBUGGING");
-# endif
-# ifdef MULTIPLICITY
- sv_catpv(PL_Sv," MULTIPLICITY");
-# endif
-# ifdef USE_THREADS
- sv_catpv(PL_Sv," USE_THREADS");
-# endif
-# ifdef USE_ITHREADS
- sv_catpv(PL_Sv," USE_ITHREADS");
-# endif
-# ifdef USE_64_BIT_INT
- sv_catpv(PL_Sv," USE_64_BIT_INT");
-# endif
-# ifdef USE_64_BIT_ALL
- sv_catpv(PL_Sv," USE_64_BIT_ALL");
-# endif
-# ifdef USE_LONG_DOUBLE
- sv_catpv(PL_Sv," USE_LONG_DOUBLE");
-# endif
-# ifdef USE_LARGE_FILES
- sv_catpv(PL_Sv," USE_LARGE_FILES");
-# endif
-# ifdef USE_SOCKS
- sv_catpv(PL_Sv," USE_SOCKS");
-# endif
-# ifdef PERL_OBJECT
- sv_catpv(PL_Sv," PERL_OBJECT");
-# endif
-# ifdef PERL_IMPLICIT_CONTEXT
- sv_catpv(PL_Sv," PERL_IMPLICIT_CONTEXT");
-# endif
-# ifdef PERL_IMPLICIT_SYS
- sv_catpv(PL_Sv," PERL_IMPLICIT_SYS");
-# endif
- sv_catpv(PL_Sv,"\\n\",");
-
-#if defined(LOCAL_PATCH_COUNT)
- if (LOCAL_PATCH_COUNT > 0) {
- int i;
- sv_catpv(PL_Sv,"\" Locally applied patches:\\n\",");
- for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
- if (PL_localpatches[i])
- Perl_sv_catpvf(aTHX_ PL_Sv,"q\" \t%s\n\",",PL_localpatches[i]);
- }
- }
-#endif
- Perl_sv_catpvf(aTHX_ PL_Sv,"\" Built under %s\\n\"",OSNAME);
-#ifdef __DATE__
-# ifdef __TIME__
- Perl_sv_catpvf(aTHX_ PL_Sv,",\" Compiled at %s %s\\n\"",__DATE__,__TIME__);
-# else
- Perl_sv_catpvf(aTHX_ PL_Sv,",\" Compiled on %s\\n\"",__DATE__);
-# endif
-#endif
- sv_catpv(PL_Sv, "; \
-$\"=\"\\n \"; \
-@env = map { \"$_=\\\"$ENV{$_}\\\"\" } sort grep {/^PERL/} keys %ENV; \
-print \" \\%ENV:\\n @env\\n\" if @env; \
-print \" \\@INC:\\n @INC\\n\";");
- }
- else {
- PL_Sv = newSVpv("config_vars(qw(",0);
- sv_catpv(PL_Sv, ++s);
- sv_catpv(PL_Sv, "))");
- s += strlen(s);
- }
- av_push(PL_preambleav, PL_Sv);
- scriptname = BIT_BUCKET; /* don't look for script or read stdin */
- goto reswitch;
- case 'x':
- PL_doextract = TRUE;
- s++;
- if (*s)
- cddir = s;
- break;
- case 0:
- break;
- case '-':
- if (!*++s || isSPACE(*s)) {
- argc--,argv++;
- goto switch_end;
- }
- /* catch use of gnu style long options */
- if (strEQ(s, "version")) {
- s = "v";
- goto reswitch;
- }
- if (strEQ(s, "help")) {
- s = "h";
- goto reswitch;
- }
- s--;
- /* FALL THROUGH */
- default:
- Perl_croak(aTHX_ "Unrecognized switch: -%s (-h will show valid options)",s);
- }
- }
- switch_end:
-
- if (
-#ifndef SECURE_INTERNAL_GETENV
- !PL_tainting &&
-#endif
- (s = PerlEnv_getenv("PERL5OPT")))
- {
- while (isSPACE(*s))
- s++;
- if (*s == '-' && *(s+1) == 'T')
- PL_tainting = TRUE;
- else {
- while (s && *s) {
- char *d;
- while (isSPACE(*s))
- s++;
- if (*s == '-') {
- s++;
- if (isSPACE(*s))
- continue;
- }
- d = s;
- if (!*s)
- break;
- if (!strchr("DIMUdmw", *s))
- Perl_croak(aTHX_ "Illegal switch in PERL5OPT: -%c", *s);
- while (++s && *s) {
- if (isSPACE(*s)) {
- *s++ = '\0';
- break;
- }
- }
- moreswitches(d);
- }
- }
- }
-
- if (!scriptname)
- scriptname = argv[0];
- if (PL_e_script) {
- argc++,argv--;
- scriptname = BIT_BUCKET; /* don't look for script or read stdin */
- }
- else if (scriptname == Nullch) {
-#ifdef MSDOS
- if ( PerlLIO_isatty(PerlIO_fileno(PerlIO_stdin())) )
- moreswitches("h");
-#endif
- scriptname = "-";
- }
-
- init_perllib();
-
- open_script(scriptname,dosearch,sv,&fdscript);
-
- validate_suid(validarg, scriptname,fdscript);
-
-#if defined(SIGCHLD) || defined(SIGCLD)
- {
-#ifndef SIGCHLD
-# define SIGCHLD SIGCLD
-#endif
- Sighandler_t sigstate = rsignal_state(SIGCHLD);
- if (sigstate == SIG_IGN) {
- if (ckWARN(WARN_SIGNAL))
- Perl_warner(aTHX_ WARN_SIGNAL,
- "Can't ignore signal CHLD, forcing to default");
- (void)rsignal(SIGCHLD, (Sighandler_t)SIG_DFL);
- }
- }
-#endif
-
-#ifdef MACOS_TRADITIONAL
- if (PL_doextract || gMacPerl_AlwaysExtract) {
-#else
- if (PL_doextract) {
-#endif
- find_beginning();
- if (cddir && PerlDir_chdir(cddir) < 0)
- Perl_croak(aTHX_ "Can't chdir to %s",cddir);
-
- }
-
- PL_main_cv = PL_compcv = (CV*)NEWSV(1104,0);
- sv_upgrade((SV *)PL_compcv, SVt_PVCV);
- CvUNIQUE_on(PL_compcv);
-
- PL_comppad = newAV();
- av_push(PL_comppad, Nullsv);
- PL_curpad = AvARRAY(PL_comppad);
- PL_comppad_name = newAV();
- PL_comppad_name_fill = 0;
- PL_min_intro_pending = 0;
- PL_padix = 0;
-#ifdef USE_THREADS
- av_store(PL_comppad_name, 0, newSVpvn("@_", 2));
- PL_curpad[0] = (SV*)newAV();
- SvPADMY_on(PL_curpad[0]); /* XXX Needed? */
- CvOWNER(PL_compcv) = 0;
- New(666, CvMUTEXP(PL_compcv), 1, perl_mutex);
- MUTEX_INIT(CvMUTEXP(PL_compcv));
-#endif /* USE_THREADS */
-
- comppadlist = newAV();
- AvREAL_off(comppadlist);
- av_store(comppadlist, 0, (SV*)PL_comppad_name);
- av_store(comppadlist, 1, (SV*)PL_comppad);
- CvPADLIST(PL_compcv) = comppadlist;
-
- boot_core_UNIVERSAL();
-#ifndef PERL_MICRO
- boot_core_xsutils();
-#endif
-
- if (xsinit)
- (*xsinit)(aTHXo); /* in case linked C routines want magical variables */
-#if defined(VMS) || defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(EPOC)
- init_os_extras();
-#endif
-
-#ifdef USE_SOCKS
-# ifdef HAS_SOCKS5_INIT
- socks5_init(argv[0]);
-# else
- SOCKSinit(argv[0]);
-# endif
-#endif
-
- init_predump_symbols();
- /* init_postdump_symbols not currently designed to be called */
- /* more than once (ENV isn't cleared first, for example) */
- /* But running with -u leaves %ENV & @ARGV undefined! XXX */
- if (!PL_do_undump)
- init_postdump_symbols(argc,argv,env);
-
- init_lexer();
-
- /* now parse the script */
-
- SETERRNO(0,SS$_NORMAL);
- PL_error_count = 0;
-#ifdef MACOS_TRADITIONAL
- if (gMacPerl_SyntaxError = (yyparse() || PL_error_count)) {
- if (PL_minus_c)
- Perl_croak(aTHX_ "%s had compilation errors.\n", MacPerl_MPWFileName(PL_origfilename));
- else {
- Perl_croak(aTHX_ "Execution of %s aborted due to compilation errors.\n",
- MacPerl_MPWFileName(PL_origfilename));
- }
- }
-#else
- if (yyparse() || PL_error_count) {
- if (PL_minus_c)
- Perl_croak(aTHX_ "%s had compilation errors.\n", PL_origfilename);
- else {
- Perl_croak(aTHX_ "Execution of %s aborted due to compilation errors.\n",
- PL_origfilename);
- }
- }
-#endif
- CopLINE_set(PL_curcop, 0);
- PL_curstash = PL_defstash;
- PL_preprocess = FALSE;
- if (PL_e_script) {
- SvREFCNT_dec(PL_e_script);
- PL_e_script = Nullsv;
- }
-
- /* now that script is parsed, we can modify record separator */
- SvREFCNT_dec(PL_rs);
- PL_rs = SvREFCNT_inc(PL_nrs);
- sv_setsv(get_sv("/", TRUE), PL_rs);
- if (PL_do_undump)
- my_unexec();
-
- if (isWARN_ONCE) {
- SAVECOPFILE(PL_curcop);
- SAVECOPLINE(PL_curcop);
- gv_check(PL_defstash);
- }
-
- LEAVE;
- FREETMPS;
-
-#ifdef MYMALLOC
- if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
- dump_mstats("after compilation:");
-#endif
-
- ENTER;
- PL_restartop = 0;
- return NULL;
-}
-
-/*
-=for apidoc perl_run
-
-Tells a Perl interpreter to run. See L<perlembed>.
-
-=cut
-*/
-
-int
-perl_run(pTHXx)
-{
- I32 oldscope;
- int ret = 0;
- dJMPENV;
-#ifdef USE_THREADS
- dTHX;
-#endif
-
- oldscope = PL_scopestack_ix;
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
- redo_body:
- CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_vrun_body), oldscope);
-#else
- JMPENV_PUSH(ret);
-#endif
- switch (ret) {
- case 1:
- cxstack_ix = -1; /* start context stack again */
- goto redo_body;
- case 0: /* normal completion */
-#ifndef PERL_FLEXIBLE_EXCEPTIONS
- redo_body:
- run_body(oldscope);
-#endif
- /* FALL THROUGH */
- case 2: /* my_exit() */
- while (PL_scopestack_ix > oldscope)
- LEAVE;
- FREETMPS;
- PL_curstash = PL_defstash;
- if (PL_endav && !PL_minus_c)
- call_list(oldscope, PL_endav);
-#ifdef MYMALLOC
- if (PerlEnv_getenv("PERL_DEBUG_MSTATS"))
- dump_mstats("after execution: ");
-#endif
- ret = STATUS_NATIVE_EXPORT;
- break;
- case 3:
- if (PL_restartop) {
- POPSTACK_TO(PL_mainstack);
- goto redo_body;
- }
- PerlIO_printf(Perl_error_log, "panic: restartop\n");
- FREETMPS;
- ret = 1;
- break;
- }
-
- JMPENV_POP;
- return ret;
-}
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
-STATIC void *
-S_vrun_body(pTHX_ va_list args)
-{
- I32 oldscope = va_arg(args, I32);
-
- return run_body(oldscope);
-}
-#endif
-
-
-STATIC void *
-S_run_body(pTHX_ I32 oldscope)
-{
- DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support.\n",
- PL_sawampersand ? "Enabling" : "Omitting"));
-
- if (!PL_restartop) {
- DEBUG_x(dump_all());
- DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n"));
- DEBUG_S(PerlIO_printf(Perl_debug_log, "main thread is 0x%"UVxf"\n",
- PTR2UV(thr)));
-
- if (PL_minus_c) {
-#ifdef MACOS_TRADITIONAL
- PerlIO_printf(Perl_error_log, "%s syntax OK\n", MacPerl_MPWFileName(PL_origfilename));
-#else
- PerlIO_printf(Perl_error_log, "%s syntax OK\n", PL_origfilename);
-#endif
- my_exit(0);
- }
- if (PERLDB_SINGLE && PL_DBsingle)
- sv_setiv(PL_DBsingle, 1);
- if (PL_initav)
- call_list(oldscope, PL_initav);
- }
-
- /* do it */
-
- if (PL_restartop) {
- PL_op = PL_restartop;
- PL_restartop = 0;
- CALLRUNOPS(aTHX);
- }
- else if (PL_main_start) {
- CvDEPTH(PL_main_cv) = 1;
- PL_op = PL_main_start;
- CALLRUNOPS(aTHX);
- }
-
- my_exit(0);
- /* NOTREACHED */
- return NULL;
-}
-
-/*
-=for apidoc p||get_sv
-
-Returns the SV of the specified Perl scalar. If C<create> is set and the
-Perl variable does not exist then it will be created. If C<create> is not
-set and the variable does not exist then NULL is returned.
-
-=cut
-*/
-
-SV*
-Perl_get_sv(pTHX_ const char *name, I32 create)
-{
- GV *gv;
-#ifdef USE_THREADS
- if (name[1] == '\0' && !isALPHA(name[0])) {
- PADOFFSET tmp = find_threadsv(name);
- if (tmp != NOT_IN_PAD)
- return THREADSV(tmp);
- }
-#endif /* USE_THREADS */
- gv = gv_fetchpv(name, create, SVt_PV);
- if (gv)
- return GvSV(gv);
- return Nullsv;
-}
-
-/*
-=for apidoc p||get_av
-
-Returns the AV of the specified Perl array. If C<create> is set and the
-Perl variable does not exist then it will be created. If C<create> is not
-set and the variable does not exist then NULL is returned.
-
-=cut
-*/
-
-AV*
-Perl_get_av(pTHX_ const char *name, I32 create)
-{
- GV* gv = gv_fetchpv(name, create, SVt_PVAV);
- if (create)
- return GvAVn(gv);
- if (gv)
- return GvAV(gv);
- return Nullav;
-}
-
-/*
-=for apidoc p||get_hv
-
-Returns the HV of the specified Perl hash. If C<create> is set and the
-Perl variable does not exist then it will be created. If C<create> is not
-set and the variable does not exist then NULL is returned.
-
-=cut
-*/
-
-HV*
-Perl_get_hv(pTHX_ const char *name, I32 create)
-{
- GV* gv = gv_fetchpv(name, create, SVt_PVHV);
- if (create)
- return GvHVn(gv);
- if (gv)
- return GvHV(gv);
- return Nullhv;
-}
-
-/*
-=for apidoc p||get_cv
-
-Returns the CV of the specified Perl subroutine. If C<create> is set and
-the Perl subroutine does not exist then it will be declared (which has the
-same effect as saying C<sub name;>). If C<create> is not set and the
-subroutine does not exist then NULL is returned.
-
-=cut
-*/
-
-CV*
-Perl_get_cv(pTHX_ const char *name, I32 create)
-{
- GV* gv = gv_fetchpv(name, create, SVt_PVCV);
- /* XXX unsafe for threads if eval_owner isn't held */
- /* XXX this is probably not what they think they're getting.
- * It has the same effect as "sub name;", i.e. just a forward
- * declaration! */
- if (create && !GvCVu(gv))
- return newSUB(start_subparse(FALSE, 0),
- newSVOP(OP_CONST, 0, newSVpv(name,0)),
- Nullop,
- Nullop);
- if (gv)
- return GvCVu(gv);
- return Nullcv;
-}
-
-/* Be sure to refetch the stack pointer after calling these routines. */
-
-/*
-=for apidoc p||call_argv
-
-Performs a callback to the specified Perl sub. See L<perlcall>.
-
-=cut
-*/
-
-I32
-Perl_call_argv(pTHX_ const char *sub_name, I32 flags, register char **argv)
-
- /* See G_* flags in cop.h */
- /* null terminated arg list */
-{
- dSP;
-
- PUSHMARK(SP);
- if (argv) {
- while (*argv) {
- XPUSHs(sv_2mortal(newSVpv(*argv,0)));
- argv++;
- }
- PUTBACK;
- }
- return call_pv(sub_name, flags);
-}
-
-/*
-=for apidoc p||call_pv
-
-Performs a callback to the specified Perl sub. See L<perlcall>.
-
-=cut
-*/
-
-I32
-Perl_call_pv(pTHX_ const char *sub_name, I32 flags)
- /* name of the subroutine */
- /* See G_* flags in cop.h */
-{
- return call_sv((SV*)get_cv(sub_name, TRUE), flags);
-}
-
-/*
-=for apidoc p||call_method
-
-Performs a callback to the specified Perl method. The blessed object must
-be on the stack. See L<perlcall>.
-
-=cut
-*/
-
-I32
-Perl_call_method(pTHX_ const char *methname, I32 flags)
- /* name of the subroutine */
- /* See G_* flags in cop.h */
-{
- return call_sv(sv_2mortal(newSVpv(methname,0)), flags | G_METHOD);
-}
-
-/* May be called with any of a CV, a GV, or an SV containing the name. */
-/*
-=for apidoc p||call_sv
-
-Performs a callback to the Perl sub whose name is in the SV. See
-L<perlcall>.
-
-=cut
-*/
-
-I32
-Perl_call_sv(pTHX_ SV *sv, I32 flags)
- /* See G_* flags in cop.h */
-{
- dSP;
- LOGOP myop; /* fake syntax tree node */
- UNOP method_op;
- I32 oldmark;
- I32 retval;
- I32 oldscope;
- bool oldcatch = CATCH_GET;
- int ret;
- OP* oldop = PL_op;
- dJMPENV;
-
- if (flags & G_DISCARD) {
- ENTER;
- SAVETMPS;
- }
-
- Zero(&myop, 1, LOGOP);
- myop.op_next = Nullop;
- if (!(flags & G_NOARGS))
- myop.op_flags |= OPf_STACKED;
- myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
- (flags & G_ARRAY) ? OPf_WANT_LIST :
- OPf_WANT_SCALAR);
- SAVEOP();
- PL_op = (OP*)&myop;
-
- EXTEND(PL_stack_sp, 1);
- *++PL_stack_sp = sv;
- oldmark = TOPMARK;
- oldscope = PL_scopestack_ix;
-
- if (PERLDB_SUB && PL_curstash != PL_debstash
- /* Handle first BEGIN of -d. */
- && (PL_DBcv || (PL_DBcv = GvCV(PL_DBsub)))
- /* Try harder, since this may have been a sighandler, thus
- * curstash may be meaningless. */
- && (SvTYPE(sv) != SVt_PVCV || CvSTASH((CV*)sv) != PL_debstash)
- && !(flags & G_NODEBUG))
- PL_op->op_private |= OPpENTERSUB_DB;
-
- if (flags & G_METHOD) {
- Zero(&method_op, 1, UNOP);
- method_op.op_next = PL_op;
- method_op.op_ppaddr = PL_ppaddr[OP_METHOD];
- myop.op_ppaddr = PL_ppaddr[OP_ENTERSUB];
- PL_op = (OP*)&method_op;
- }
-
- if (!(flags & G_EVAL)) {
- CATCH_SET(TRUE);
- call_body((OP*)&myop, FALSE);
- retval = PL_stack_sp - (PL_stack_base + oldmark);
- CATCH_SET(oldcatch);
- }
- else {
- myop.op_other = (OP*)&myop;
- PL_markstack_ptr--;
- /* we're trying to emulate pp_entertry() here */
- {
- register PERL_CONTEXT *cx;
- I32 gimme = GIMME_V;
-
- ENTER;
- SAVETMPS;
-
- push_return(Nullop);
- PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
- PUSHEVAL(cx, 0, 0);
- PL_eval_root = PL_op; /* Only needed so that goto works right. */
-
- PL_in_eval = EVAL_INEVAL;
- if (flags & G_KEEPERR)
- PL_in_eval |= EVAL_KEEPERR;
- else
- sv_setpv(ERRSV,"");
- }
- PL_markstack_ptr++;
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
- redo_body:
- CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_vcall_body),
- (OP*)&myop, FALSE);
-#else
- JMPENV_PUSH(ret);
-#endif
- switch (ret) {
- case 0:
-#ifndef PERL_FLEXIBLE_EXCEPTIONS
- redo_body:
- call_body((OP*)&myop, FALSE);
-#endif
- retval = PL_stack_sp - (PL_stack_base + oldmark);
- if (!(flags & G_KEEPERR))
- sv_setpv(ERRSV,"");
- break;
- case 1:
- STATUS_ALL_FAILURE;
- /* FALL THROUGH */
- case 2:
- /* my_exit() was called */
- PL_curstash = PL_defstash;
- FREETMPS;
- JMPENV_POP;
- if (PL_statusvalue && !(PL_exit_flags & PERL_EXIT_EXPECTED))
- Perl_croak(aTHX_ "Callback called exit");
- my_exit_jump();
- /* NOTREACHED */
- case 3:
- if (PL_restartop) {
- PL_op = PL_restartop;
- PL_restartop = 0;
- goto redo_body;
- }
- PL_stack_sp = PL_stack_base + oldmark;
- if (flags & G_ARRAY)
- retval = 0;
- else {
- retval = 1;
- *++PL_stack_sp = &PL_sv_undef;
- }
- break;
- }
-
- if (PL_scopestack_ix > oldscope) {
- SV **newsp;
- PMOP *newpm;
- I32 gimme;
- register PERL_CONTEXT *cx;
- I32 optype;
-
- POPBLOCK(cx,newpm);
- POPEVAL(cx);
- pop_return();
- PL_curpm = newpm;
- LEAVE;
- }
- JMPENV_POP;
- }
-
- if (flags & G_DISCARD) {
- PL_stack_sp = PL_stack_base + oldmark;
- retval = 0;
- FREETMPS;
- LEAVE;
- }
- PL_op = oldop;
- return retval;
-}
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
-STATIC void *
-S_vcall_body(pTHX_ va_list args)
-{
- OP *myop = va_arg(args, OP*);
- int is_eval = va_arg(args, int);
-
- call_body(myop, is_eval);
- return NULL;
-}
-#endif
-
-STATIC void
-S_call_body(pTHX_ OP *myop, int is_eval)
-{
- if (PL_op == myop) {
- if (is_eval)
- PL_op = Perl_pp_entereval(aTHX); /* this doesn't do a POPMARK */
- else
- PL_op = Perl_pp_entersub(aTHX); /* this does */
- }
- if (PL_op)
- CALLRUNOPS(aTHX);
-}
-
-/* Eval a string. The G_EVAL flag is always assumed. */
-
-/*
-=for apidoc p||eval_sv
-
-Tells Perl to C<eval> the string in the SV.
-
-=cut
-*/
-
-I32
-Perl_eval_sv(pTHX_ SV *sv, I32 flags)
-
- /* See G_* flags in cop.h */
-{
- dSP;
- UNOP myop; /* fake syntax tree node */
- I32 oldmark = SP - PL_stack_base;
- I32 retval;
- I32 oldscope;
- int ret;
- OP* oldop = PL_op;
- dJMPENV;
-
- if (flags & G_DISCARD) {
- ENTER;
- SAVETMPS;
- }
-
- SAVEOP();
- PL_op = (OP*)&myop;
- Zero(PL_op, 1, UNOP);
- EXTEND(PL_stack_sp, 1);
- *++PL_stack_sp = sv;
- oldscope = PL_scopestack_ix;
-
- if (!(flags & G_NOARGS))
- myop.op_flags = OPf_STACKED;
- myop.op_next = Nullop;
- myop.op_type = OP_ENTEREVAL;
- myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
- (flags & G_ARRAY) ? OPf_WANT_LIST :
- OPf_WANT_SCALAR);
- if (flags & G_KEEPERR)
- myop.op_flags |= OPf_SPECIAL;
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
- redo_body:
- CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_vcall_body),
- (OP*)&myop, TRUE);
-#else
- JMPENV_PUSH(ret);
-#endif
- switch (ret) {
- case 0:
-#ifndef PERL_FLEXIBLE_EXCEPTIONS
- redo_body:
- call_body((OP*)&myop,TRUE);
-#endif
- retval = PL_stack_sp - (PL_stack_base + oldmark);
- if (!(flags & G_KEEPERR))
- sv_setpv(ERRSV,"");
- break;
- case 1:
- STATUS_ALL_FAILURE;
- /* FALL THROUGH */
- case 2:
- /* my_exit() was called */
- PL_curstash = PL_defstash;
- FREETMPS;
- JMPENV_POP;
- if (PL_statusvalue && !(PL_exit_flags & PERL_EXIT_EXPECTED))
- Perl_croak(aTHX_ "Callback called exit");
- my_exit_jump();
- /* NOTREACHED */
- case 3:
- if (PL_restartop) {
- PL_op = PL_restartop;
- PL_restartop = 0;
- goto redo_body;
- }
- PL_stack_sp = PL_stack_base + oldmark;
- if (flags & G_ARRAY)
- retval = 0;
- else {
- retval = 1;
- *++PL_stack_sp = &PL_sv_undef;
- }
- break;
- }
-
- JMPENV_POP;
- if (flags & G_DISCARD) {
- PL_stack_sp = PL_stack_base + oldmark;
- retval = 0;
- FREETMPS;
- LEAVE;
- }
- PL_op = oldop;
- return retval;
-}
-
-/*
-=for apidoc p||eval_pv
-
-Tells Perl to C<eval> the given string and return an SV* result.
-
-=cut
-*/
-
-SV*
-Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error)
-{
- dSP;
- SV* sv = newSVpv(p, 0);
-
- eval_sv(sv, G_SCALAR);
- SvREFCNT_dec(sv);
-
- SPAGAIN;
- sv = POPs;
- PUTBACK;
-
- if (croak_on_error && SvTRUE(ERRSV)) {
- STRLEN n_a;
- Perl_croak(aTHX_ SvPVx(ERRSV, n_a));
- }
-
- return sv;
-}
-
-/* Require a module. */
-
-/*
-=for apidoc p||require_pv
-
-Tells Perl to C<require> a module.
-
-=cut
-*/
-
-void
-Perl_require_pv(pTHX_ const char *pv)
-{
- SV* sv;
- dSP;
- PUSHSTACKi(PERLSI_REQUIRE);
- PUTBACK;
- sv = sv_newmortal();
- sv_setpv(sv, "require '");
- sv_catpv(sv, pv);
- sv_catpv(sv, "'");
- eval_sv(sv, G_DISCARD);
- SPAGAIN;
- POPSTACK;
-}
-
-void
-Perl_magicname(pTHX_ char *sym, char *name, I32 namlen)
-{
- register GV *gv;
-
- if ((gv = gv_fetchpv(sym,TRUE, SVt_PV)))
- sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
-}
-
-STATIC void
-S_usage(pTHX_ char *name) /* XXX move this out into a module ? */
-{
- /* This message really ought to be max 23 lines.
- * Removed -h because the user already knows that opton. Others? */
-
- static char *usage_msg[] = {
-"-0[octal] specify record separator (\\0, if no argument)",
-"-a autosplit mode with -n or -p (splits $_ into @F)",
-"-C enable native wide character system interfaces",
-"-c check syntax only (runs BEGIN and CHECK blocks)",
-"-d[:debugger] run program under debugger",
-"-D[number/list] set debugging flags (argument is a bit mask or alphabets)",
-"-e 'command' one line of program (several -e's allowed, omit programfile)",
-"-F/pattern/ split() pattern for -a switch (//'s are optional)",
-"-i[extension] edit <> files in place (makes backup if extension supplied)",
-"-Idirectory specify @INC/#include directory (several -I's allowed)",
-"-l[octal] enable line ending processing, specifies line terminator",
-"-[mM][-]module execute `use/no module...' before executing program",
-"-n assume 'while (<>) { ... }' loop around program",
-"-p assume loop like -n but print line also, like sed",
-"-P run program through C preprocessor before compilation",
-"-s enable rudimentary parsing for switches after programfile",
-"-S look for programfile using PATH environment variable",
-"-T enable tainting checks",
-"-u dump core after parsing program",
-"-U allow unsafe operations",
-"-v print version, subversion (includes VERY IMPORTANT perl info)",
-"-V[:variable] print configuration summary (or a single Config.pm variable)",
-"-w enable many useful warnings (RECOMMENDED)",
-"-W enable all warnings",
-"-X disable all warnings",
-"-x[directory] strip off text before #!perl line and perhaps cd to directory",
-"\n",
-NULL
-};
- char **p = usage_msg;
-
- PerlIO_printf(PerlIO_stdout(),
- "\nUsage: %s [switches] [--] [programfile] [arguments]",
- name);
- while (*p)
- PerlIO_printf(PerlIO_stdout(), "\n %s", *p++);
-}
-
-/* This routine handles any switches that can be given during run */
-
-char *
-Perl_moreswitches(pTHX_ char *s)
-{
- STRLEN numlen;
- U32 rschar;
-
- switch (*s) {
- case '0':
- {
- numlen = 0; /* disallow underscores */
- rschar = (U32)scan_oct(s, 4, &numlen);
- SvREFCNT_dec(PL_nrs);
- if (rschar & ~((U8)~0))
- PL_nrs = &PL_sv_undef;
- else if (!rschar && numlen >= 2)
- PL_nrs = newSVpvn("", 0);
- else {
- char ch = rschar;
- PL_nrs = newSVpvn(&ch, 1);
- }
- return s + numlen;
- }
- case 'C':
- PL_widesyscalls = TRUE;
- s++;
- return s;
- case 'F':
- PL_minus_F = TRUE;
- PL_splitstr = savepv(s + 1);
- s += strlen(s);
- return s;
- case 'a':
- PL_minus_a = TRUE;
- s++;
- return s;
- case 'c':
- PL_minus_c = TRUE;
- s++;
- return s;
- case 'd':
- forbid_setid("-d");
- s++;
- /* The following permits -d:Mod to accepts arguments following an =
- in the fashion that -MSome::Mod does. */
- if (*s == ':' || *s == '=') {
- char *start;
- SV *sv;
- sv = newSVpv("use Devel::", 0);
- start = ++s;
- /* We now allow -d:Module=Foo,Bar */
- while(isALNUM(*s) || *s==':') ++s;
- if (*s != '=')
- sv_catpv(sv, start);
- else {
- sv_catpvn(sv, start, s-start);
- sv_catpv(sv, " split(/,/,q{");
- sv_catpv(sv, ++s);
- sv_catpv(sv, "})");
- }
- s += strlen(s);
- my_setenv("PERL5DB", SvPV(sv, PL_na));
- }
- if (!PL_perldb) {
- PL_perldb = PERLDB_ALL;
- init_debugger();
- }
- return s;
- case 'D':
- {
-#ifdef DEBUGGING
- forbid_setid("-D");
- if (isALPHA(s[1])) {
- static char debopts[] = "psltocPmfrxuLHXDST";
- char *d;
-
- for (s++; *s && (d = strchr(debopts,*s)); s++)
- PL_debug |= 1 << (d - debopts);
- }
- else {
- PL_debug = atoi(s+1);
- for (s++; isDIGIT(*s); s++) ;
- }
- PL_debug |= 0x80000000;
-#else
- if (ckWARN_d(WARN_DEBUGGING))
- Perl_warner(aTHX_ WARN_DEBUGGING,
- "Recompile perl with -DDEBUGGING to use -D switch\n");
- for (s++; isALNUM(*s); s++) ;
-#endif
- /*SUPPRESS 530*/
- return s;
- }
- case 'h':
- usage(PL_origargv[0]);
- PerlProc_exit(0);
- case 'i':
- if (PL_inplace)
- Safefree(PL_inplace);
- PL_inplace = savepv(s+1);
- /*SUPPRESS 530*/
- for (s = PL_inplace; *s && !isSPACE(*s); s++) ;
- if (*s) {
- *s++ = '\0';
- if (*s == '-') /* Additional switches on #! line. */
- s++;
- }
- return s;
- case 'I': /* -I handled both here and in parse_perl() */
- forbid_setid("-I");
- ++s;
- while (*s && isSPACE(*s))
- ++s;
- if (*s) {
- char *e, *p;
- p = s;
- /* ignore trailing spaces (possibly followed by other switches) */
- do {
- for (e = p; *e && !isSPACE(*e); e++) ;
- p = e;
- while (isSPACE(*p))
- p++;
- } while (*p && *p != '-');
- e = savepvn(s, e-s);
- incpush(e, TRUE, TRUE);
- Safefree(e);
- s = p;
- if (*s == '-')
- s++;
- }
- else
- Perl_croak(aTHX_ "No directory specified for -I");
- return s;
- case 'l':
- PL_minus_l = TRUE;
- s++;
- if (PL_ors)
- Safefree(PL_ors);
- if (isDIGIT(*s)) {
- PL_ors = savepv("\n");
- PL_orslen = 1;
- numlen = 0; /* disallow underscores */
- *PL_ors = (char)scan_oct(s, 3 + (*s == '0'), &numlen);
- s += numlen;
- }
- else {
- if (RsPARA(PL_nrs)) {
- PL_ors = "\n\n";
- PL_orslen = 2;
- }
- else
- PL_ors = SvPV(PL_nrs, PL_orslen);
- PL_ors = savepvn(PL_ors, PL_orslen);
- }
- return s;
- case 'M':
- forbid_setid("-M"); /* XXX ? */
- /* FALL THROUGH */
- case 'm':
- forbid_setid("-m"); /* XXX ? */
- if (*++s) {
- char *start;
- SV *sv;
- char *use = "use ";
- /* -M-foo == 'no foo' */
- if (*s == '-') { use = "no "; ++s; }
- sv = newSVpv(use,0);
- start = s;
- /* We allow -M'Module qw(Foo Bar)' */
- while(isALNUM(*s) || *s==':') ++s;
- if (*s != '=') {
- sv_catpv(sv, start);
- if (*(start-1) == 'm') {
- if (*s != '\0')
- Perl_croak(aTHX_ "Can't use '%c' after -mname", *s);
- sv_catpv( sv, " ()");
- }
- } else {
- if (s == start)
- Perl_croak(aTHX_ "Module name required with -%c option",
- s[-1]);
- sv_catpvn(sv, start, s-start);
- sv_catpv(sv, " split(/,/,q{");
- sv_catpv(sv, ++s);
- sv_catpv(sv, "})");
- }
- s += strlen(s);
- if (!PL_preambleav)
- PL_preambleav = newAV();
- av_push(PL_preambleav, sv);
- }
- else
- Perl_croak(aTHX_ "No space allowed after -%c", *(s-1));
- return s;
- case 'n':
- PL_minus_n = TRUE;
- s++;
- return s;
- case 'p':
- PL_minus_p = TRUE;
- s++;
- return s;
- case 's':
- forbid_setid("-s");
- PL_doswitches = TRUE;
- s++;
- return s;
- case 'T':
- if (!PL_tainting)
- Perl_croak(aTHX_ "Too late for \"-T\" option");
- s++;
- return s;
- case 'u':
-#ifdef MACOS_TRADITIONAL
- Perl_croak(aTHX_ "Believe me, you don't want to use \"-u\" on a Macintosh");
-#endif
- PL_do_undump = TRUE;
- s++;
- return s;
- case 'U':
- PL_unsafe = TRUE;
- s++;
- return s;
- case 'v':
- PerlIO_printf(PerlIO_stdout(),
- Perl_form(aTHX_ "\nThis is perl, v%"VDf" built for %s",
- PL_patchlevel, ARCHNAME));
-#if defined(LOCAL_PATCH_COUNT)
- if (LOCAL_PATCH_COUNT > 0)
- PerlIO_printf(PerlIO_stdout(),
- "\n(with %d registered patch%s, "
- "see perl -V for more detail)",
- (int)LOCAL_PATCH_COUNT,
- (LOCAL_PATCH_COUNT!=1) ? "es" : "");
-#endif
-
- PerlIO_printf(PerlIO_stdout(),
- "\n\nCopyright 1987-2001, Larry Wall\n");
-#ifdef MACOS_TRADITIONAL
- PerlIO_printf(PerlIO_stdout(),
- "\nMac OS port Copyright (c) 1991-2001, Matthias Neeracher\n");
-#endif
-#ifdef MSDOS
- PerlIO_printf(PerlIO_stdout(),
- "\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
-#endif
-#ifdef DJGPP
- PerlIO_printf(PerlIO_stdout(),
- "djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n"
- "djgpp v2 port (perl5004+) by Laszlo Molnar, 1997-1999\n");
-#endif
-#ifdef OS2
- PerlIO_printf(PerlIO_stdout(),
- "\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
- "Version 5 port Copyright (c) 1994-1999, Andreas Kaiser, Ilya Zakharevich\n");
-#endif
-#ifdef atarist
- PerlIO_printf(PerlIO_stdout(),
- "atariST series port, ++jrb bammi@cadence.com\n");
-#endif
-#ifdef __BEOS__
- PerlIO_printf(PerlIO_stdout(),
- "BeOS port Copyright Tom Spindler, 1997-1999\n");
-#endif
-#ifdef MPE
- PerlIO_printf(PerlIO_stdout(),
- "MPE/iX port Copyright by Mark Klein and Mark Bixby, 1996-1999\n");
-#endif
-#ifdef OEMVS
- PerlIO_printf(PerlIO_stdout(),
- "MVS (OS390) port by Mortice Kern Systems, 1997-1999\n");
-#endif
-#ifdef __VOS__
- PerlIO_printf(PerlIO_stdout(),
- "Stratus VOS port by Paul_Green@stratus.com, 1997-1999\n");
-#endif
-#ifdef __OPEN_VM
- PerlIO_printf(PerlIO_stdout(),
- "VM/ESA port by Neale Ferguson, 1998-1999\n");
-#endif
-#ifdef POSIX_BC
- PerlIO_printf(PerlIO_stdout(),
- "BS2000 (POSIX) port by Start Amadeus GmbH, 1998-1999\n");
-#endif
-#ifdef __MINT__
- PerlIO_printf(PerlIO_stdout(),
- "MiNT port by Guido Flohr, 1997-1999\n");
-#endif
-#ifdef EPOC
- PerlIO_printf(PerlIO_stdout(),
- "EPOC port by Olaf Flebbe, 1999-2000\n");
-#endif
-#ifdef BINARY_BUILD_NOTICE
- BINARY_BUILD_NOTICE;
-#endif
- PerlIO_printf(PerlIO_stdout(),
- "\n\
-Perl may be copied only under the terms of either the Artistic License or the\n\
-GNU General Public License, which may be found in the Perl 5 source kit.\n\n\
-Complete documentation for Perl, including FAQ lists, should be found on\n\
-this system using `man perl' or `perldoc perl'. If you have access to the\n\
-Internet, point your browser at http://www.perl.com/, the Perl Home Page.\n\n");
- PerlProc_exit(0);
- case 'w':
- if (! (PL_dowarn & G_WARN_ALL_MASK))
- PL_dowarn |= G_WARN_ON;
- s++;
- return s;
- case 'W':
- PL_dowarn = G_WARN_ALL_ON|G_WARN_ON;
- PL_compiling.cop_warnings = pWARN_ALL ;
- s++;
- return s;
- case 'X':
- PL_dowarn = G_WARN_ALL_OFF;
- PL_compiling.cop_warnings = pWARN_NONE ;
- s++;
- return s;
- case '*':
- case ' ':
- if (s[1] == '-') /* Additional switches on #! line. */
- return s+2;
- break;
- case '-':
- case 0:
-#if defined(WIN32) || !defined(PERL_STRICT_CR)
- case '\r':
-#endif
- case '\n':
- case '\t':
- break;
-#ifdef ALTERNATE_SHEBANG
- case 'S': /* OS/2 needs -S on "extproc" line. */
- break;
-#endif
- case 'P':
- if (PL_preprocess)
- return s+1;
- /* FALL THROUGH */
- default:
- Perl_croak(aTHX_ "Can't emulate -%.1s on #! line",s);
- }
- return Nullch;
-}
-
-/* compliments of Tom Christiansen */
-
-/* unexec() can be found in the Gnu emacs distribution */
-/* Known to work with -DUNEXEC and using unexelf.c from GNU emacs-20.2 */
-
-void
-Perl_my_unexec(pTHX)
-{
-#ifdef UNEXEC
- SV* prog;
- SV* file;
- int status = 1;
- extern int etext;
-
- prog = newSVpv(BIN_EXP, 0);
- sv_catpv(prog, "/perl");
- file = newSVpv(PL_origfilename, 0);
- sv_catpv(file, ".perldump");
-
- unexec(SvPVX(file), SvPVX(prog), &etext, sbrk(0), 0);
- /* unexec prints msg to stderr in case of failure */
- PerlProc_exit(status);
-#else
-# ifdef VMS
-# include <lib$routines.h>
- lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */
-# else
- ABORT(); /* for use with undump */
-# endif
-#endif
-}
-
-/* initialize curinterp */
-STATIC void
-S_init_interp(pTHX)
-{
-
-#ifdef PERL_OBJECT /* XXX kludge */
-#define I_REINIT \
- STMT_START { \
- PL_chopset = " \n-"; \
- PL_copline = NOLINE; \
- PL_curcop = &PL_compiling;\
- PL_curcopdb = NULL; \
- PL_dbargs = 0; \
- PL_dumpindent = 4; \
- PL_laststatval = -1; \
- PL_laststype = OP_STAT; \
- PL_maxscream = -1; \
- PL_maxsysfd = MAXSYSFD; \
- PL_statname = Nullsv; \
- PL_tmps_floor = -1; \
- PL_tmps_ix = -1; \
- PL_op_mask = NULL; \
- PL_laststatval = -1; \
- PL_laststype = OP_STAT; \
- PL_mess_sv = Nullsv; \
- PL_splitstr = " "; \
- PL_generation = 100; \
- PL_exitlist = NULL; \
- PL_exitlistlen = 0; \
- PL_regindent = 0; \
- PL_in_clean_objs = FALSE; \
- PL_in_clean_all = FALSE; \
- PL_profiledata = NULL; \
- PL_rsfp = Nullfp; \
- PL_rsfp_filters = Nullav; \
- PL_dirty = FALSE; \
- } STMT_END
- I_REINIT;
-#else
-# ifdef MULTIPLICITY
-# define PERLVAR(var,type)
-# define PERLVARA(var,n,type)
-# if defined(PERL_IMPLICIT_CONTEXT)
-# if defined(USE_THREADS)
-# define PERLVARI(var,type,init) PERL_GET_INTERP->var = init;
-# define PERLVARIC(var,type,init) PERL_GET_INTERP->var = init;
-# else /* !USE_THREADS */
-# define PERLVARI(var,type,init) aTHX->var = init;
-# define PERLVARIC(var,type,init) aTHX->var = init;
-# endif /* USE_THREADS */
-# else
-# define PERLVARI(var,type,init) PERL_GET_INTERP->var = init;
-# define PERLVARIC(var,type,init) PERL_GET_INTERP->var = init;
-# endif
-# include "intrpvar.h"
-# ifndef USE_THREADS
-# include "thrdvar.h"
-# endif
-# undef PERLVAR
-# undef PERLVARA
-# undef PERLVARI
-# undef PERLVARIC
-# else
-# define PERLVAR(var,type)
-# define PERLVARA(var,n,type)
-# define PERLVARI(var,type,init) PL_##var = init;
-# define PERLVARIC(var,type,init) PL_##var = init;
-# include "intrpvar.h"
-# ifndef USE_THREADS
-# include "thrdvar.h"
-# endif
-# undef PERLVAR
-# undef PERLVARA
-# undef PERLVARI
-# undef PERLVARIC
-# endif
-#endif
-
-}
-
-STATIC void
-S_init_main_stash(pTHX)
-{
- GV *gv;
-
- /* Note that strtab is a rather special HV. Assumptions are made
- about not iterating on it, and not adding tie magic to it.
- It is properly deallocated in perl_destruct() */
- PL_strtab = newHV();
-#ifdef USE_THREADS
- MUTEX_INIT(&PL_strtab_mutex);
-#endif
- HvSHAREKEYS_off(PL_strtab); /* mandatory */
- hv_ksplit(PL_strtab, 512);
-
- PL_curstash = PL_defstash = newHV();
- PL_curstname = newSVpvn("main",4);
- gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
- SvREFCNT_dec(GvHV(gv));
- GvHV(gv) = (HV*)SvREFCNT_inc(PL_defstash);
- SvREADONLY_on(gv);
- HvNAME(PL_defstash) = savepv("main");
- PL_incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
- GvMULTI_on(PL_incgv);
- PL_hintgv = gv_fetchpv("\010",TRUE, SVt_PV); /* ^H */
- GvMULTI_on(PL_hintgv);
- PL_defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
- PL_errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
- GvMULTI_on(PL_errgv);
- PL_replgv = gv_fetchpv("\022", TRUE, SVt_PV); /* ^R */
- GvMULTI_on(PL_replgv);
- (void)Perl_form(aTHX_ "%240s",""); /* Preallocate temp - for immediate signals. */
- sv_grow(ERRSV, 240); /* Preallocate - for immediate signals. */
- sv_setpvn(ERRSV, "", 0);
- PL_curstash = PL_defstash;
- CopSTASH_set(&PL_compiling, PL_defstash);
- PL_debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
- PL_globalstash = GvHV(gv_fetchpv("CORE::GLOBAL::", GV_ADDMULTI, SVt_PVHV));
- PL_nullstash = GvHV(gv_fetchpv("<none>::", GV_ADDMULTI, SVt_PVHV));
- /* We must init $/ before switches are processed. */
- sv_setpvn(get_sv("/", TRUE), "\n", 1);
-}
-
-STATIC void
-S_open_script(pTHX_ char *scriptname, bool dosearch, SV *sv, int *fdscript)
-{
- *fdscript = -1;
-
- if (PL_e_script) {
- PL_origfilename = savepv("-e");
- }
- else {
- /* if find_script() returns, it returns a malloc()-ed value */
- PL_origfilename = scriptname = find_script(scriptname, dosearch, NULL, 1);
-
- if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
- char *s = scriptname + 8;
- *fdscript = atoi(s);
- while (isDIGIT(*s))
- s++;
- if (*s) {
- scriptname = savepv(s + 1);
- Safefree(PL_origfilename);
- PL_origfilename = scriptname;
- }
- }
- }
-
-#ifdef USE_ITHREADS
- Safefree(CopFILE(PL_curcop));
-#else
- SvREFCNT_dec(CopFILEGV(PL_curcop));
-#endif
- CopFILE_set(PL_curcop, PL_origfilename);
- if (strEQ(PL_origfilename,"-"))
- scriptname = "";
- if (*fdscript >= 0) {
- PL_rsfp = PerlIO_fdopen(*fdscript,PERL_SCRIPT_MODE);
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- if (PL_rsfp)
- fcntl(PerlIO_fileno(PL_rsfp),F_SETFD,1); /* ensure close-on-exec */
-#endif
- }
- else if (PL_preprocess) {
- char *cpp_cfg = CPPSTDIN;
- SV *cpp = newSVpvn("",0);
- SV *cmd = NEWSV(0,0);
-
- if (strEQ(cpp_cfg, "cppstdin"))
- Perl_sv_catpvf(aTHX_ cpp, "%s/", BIN_EXP);
- sv_catpv(cpp, cpp_cfg);
-
- sv_catpvn(sv, "-I", 2);
- sv_catpv(sv,PRIVLIB_EXP);
-
-#if defined(MSDOS) || defined(WIN32)
- Perl_sv_setpvf(aTHX_ cmd, "\
-sed %s -e \"/^[^#]/b\" \
- -e \"/^#[ ]*include[ ]/b\" \
- -e \"/^#[ ]*define[ ]/b\" \
- -e \"/^#[ ]*if[ ]/b\" \
- -e \"/^#[ ]*ifdef[ ]/b\" \
- -e \"/^#[ ]*ifndef[ ]/b\" \
- -e \"/^#[ ]*else/b\" \
- -e \"/^#[ ]*elif[ ]/b\" \
- -e \"/^#[ ]*undef[ ]/b\" \
- -e \"/^#[ ]*endif/b\" \
- -e \"s/^#.*//\" \
- %s | %"SVf" -C %"SVf" %s",
- (PL_doextract ? "-e \"1,/^#/d\n\"" : ""),
-#else
-# ifdef __OPEN_VM
- Perl_sv_setpvf(aTHX_ cmd, "\
-%s %s -e '/^[^#]/b' \
- -e '/^#[ ]*include[ ]/b' \
- -e '/^#[ ]*define[ ]/b' \
- -e '/^#[ ]*if[ ]/b' \
- -e '/^#[ ]*ifdef[ ]/b' \
- -e '/^#[ ]*ifndef[ ]/b' \
- -e '/^#[ ]*else/b' \
- -e '/^#[ ]*elif[ ]/b' \
- -e '/^#[ ]*undef[ ]/b' \
- -e '/^#[ ]*endif/b' \
- -e 's/^[ ]*#.*//' \
- %s | %"SVf" %"SVf" %s",
-# else
- Perl_sv_setpvf(aTHX_ cmd, "\
-%s %s -e '/^[^#]/b' \
- -e '/^#[ ]*include[ ]/b' \
- -e '/^#[ ]*define[ ]/b' \
- -e '/^#[ ]*if[ ]/b' \
- -e '/^#[ ]*ifdef[ ]/b' \
- -e '/^#[ ]*ifndef[ ]/b' \
- -e '/^#[ ]*else/b' \
- -e '/^#[ ]*elif[ ]/b' \
- -e '/^#[ ]*undef[ ]/b' \
- -e '/^#[ ]*endif/b' \
- -e 's/^[ ]*#.*//' \
- %s | %"SVf" -C %"SVf" %s",
-# endif
-#ifdef LOC_SED
- LOC_SED,
-#else
- "sed",
-#endif
- (PL_doextract ? "-e '1,/^#/d\n'" : ""),
-#endif
- scriptname, cpp, sv, CPPMINUS);
- PL_doextract = FALSE;
-#ifdef IAMSUID /* actually, this is caught earlier */
- if (PL_euid != PL_uid && !PL_euid) { /* if running suidperl */
-#ifdef HAS_SETEUID
- (void)seteuid(PL_uid); /* musn't stay setuid root */
-#else
-#ifdef HAS_SETREUID
- (void)setreuid((Uid_t)-1, PL_uid);
-#else
-#ifdef HAS_SETRESUID
- (void)setresuid((Uid_t)-1, PL_uid, (Uid_t)-1);
-#else
- PerlProc_setuid(PL_uid);
-#endif
-#endif
-#endif
- if (PerlProc_geteuid() != PL_uid)
- Perl_croak(aTHX_ "Can't do seteuid!\n");
- }
-#endif /* IAMSUID */
- PL_rsfp = PerlProc_popen(SvPVX(cmd), "r");
- SvREFCNT_dec(cmd);
- SvREFCNT_dec(cpp);
- }
- else if (!*scriptname) {
- forbid_setid("program input from stdin");
- PL_rsfp = PerlIO_stdin();
- }
- else {
- PL_rsfp = PerlIO_open(scriptname,PERL_SCRIPT_MODE);
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- if (PL_rsfp)
- fcntl(PerlIO_fileno(PL_rsfp),F_SETFD,1); /* ensure close-on-exec */
-#endif
- }
- if (!PL_rsfp) {
-#ifdef DOSUID
-#ifndef IAMSUID /* in case script is not readable before setuid */
- if (PL_euid &&
- PerlLIO_stat(CopFILE(PL_curcop),&PL_statbuf) >= 0 &&
- PL_statbuf.st_mode & (S_ISUID|S_ISGID))
- {
- /* try again */
- PerlProc_execv(Perl_form(aTHX_ "%s/sperl"PERL_FS_VER_FMT, BIN_EXP,
- (int)PERL_REVISION, (int)PERL_VERSION,
- (int)PERL_SUBVERSION), PL_origargv);
- Perl_croak(aTHX_ "Can't do setuid; ensure that the setuid bit is set on suidperl\n");
- }
-#endif
-#endif
- Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n",
- CopFILE(PL_curcop), Strerror(errno));
- }
-}
-
-/* Mention
- * I_SYSSTATVFS HAS_FSTATVFS
- * I_SYSMOUNT
- * I_STATFS HAS_FSTATFS HAS_GETFSSTAT
- * I_MNTENT HAS_GETMNTENT HAS_HASMNTOPT
- * here so that metaconfig picks them up. */
-
-#ifdef IAMSUID
-STATIC int
-S_fd_on_nosuid_fs(pTHX_ int fd)
-{
- int check_okay = 0; /* able to do all the required sys/libcalls */
- int on_nosuid = 0; /* the fd is on a nosuid fs */
-/*
- * Preferred order: fstatvfs(), fstatfs(), ustat()+getmnt(), getmntent().
- * fstatvfs() is UNIX98.
- * fstatfs() is 4.3 BSD.
- * ustat()+getmnt() is pre-4.3 BSD.
- * getmntent() is O(number-of-mounted-filesystems) and can hang on
- * an irrelevant filesystem while trying to reach the right one.
- */
-
-#undef FD_ON_NOSUID_CHECK_OKAY /* found the syscalls to do the check? */
-
-# if !defined(FD_ON_NOSUID_CHECK_OKAY) && \
- defined(HAS_FSTATVFS)
-# define FD_ON_NOSUID_CHECK_OKAY
- struct statvfs stfs;
-
- check_okay = fstatvfs(fd, &stfs) == 0;
- on_nosuid = check_okay && (stfs.f_flag & ST_NOSUID);
-# endif /* fstatvfs */
-
-# if !defined(FD_ON_NOSUID_CHECK_OKAY) && \
- defined(PERL_MOUNT_NOSUID) && \
- defined(HAS_FSTATFS) && \
- defined(HAS_STRUCT_STATFS) && \
- defined(HAS_STRUCT_STATFS_F_FLAGS)
-# define FD_ON_NOSUID_CHECK_OKAY
- struct statfs stfs;
-
- check_okay = fstatfs(fd, &stfs) == 0;
- on_nosuid = check_okay && (stfs.f_flags & PERL_MOUNT_NOSUID);
-# endif /* fstatfs */
-
-# if !defined(FD_ON_NOSUID_CHECK_OKAY) && \
- defined(PERL_MOUNT_NOSUID) && \
- defined(HAS_FSTAT) && \
- defined(HAS_USTAT) && \
- defined(HAS_GETMNT) && \
- defined(HAS_STRUCT_FS_DATA) && \
- defined(NOSTAT_ONE)
-# define FD_ON_NOSUID_CHECK_OKAY
- struct stat fdst;
-
- if (fstat(fd, &fdst) == 0) {
- struct ustat us;
- if (ustat(fdst.st_dev, &us) == 0) {
- struct fs_data fsd;
- /* NOSTAT_ONE here because we're not examining fields which
- * vary between that case and STAT_ONE. */
- if (getmnt((int*)0, &fsd, (int)0, NOSTAT_ONE, us.f_fname) == 0) {
- size_t cmplen = sizeof(us.f_fname);
- if (sizeof(fsd.fd_req.path) < cmplen)
- cmplen = sizeof(fsd.fd_req.path);
- if (strnEQ(fsd.fd_req.path, us.f_fname, cmplen) &&
- fdst.st_dev == fsd.fd_req.dev) {
- check_okay = 1;
- on_nosuid = fsd.fd_req.flags & PERL_MOUNT_NOSUID;
- }
- }
- }
- }
- }
-# endif /* fstat+ustat+getmnt */
-
-# if !defined(FD_ON_NOSUID_CHECK_OKAY) && \
- defined(HAS_GETMNTENT) && \
- defined(HAS_HASMNTOPT) && \
- defined(MNTOPT_NOSUID)
-# define FD_ON_NOSUID_CHECK_OKAY
- FILE *mtab = fopen("/etc/mtab", "r");
- struct mntent *entry;
- struct stat stb, fsb;
-
- if (mtab && (fstat(fd, &stb) == 0)) {
- while (entry = getmntent(mtab)) {
- if (stat(entry->mnt_dir, &fsb) == 0
- && fsb.st_dev == stb.st_dev)
- {
- /* found the filesystem */
- check_okay = 1;
- if (hasmntopt(entry, MNTOPT_NOSUID))
- on_nosuid = 1;
- break;
- } /* A single fs may well fail its stat(). */
- }
- }
- if (mtab)
- fclose(mtab);
-# endif /* getmntent+hasmntopt */
-
- if (!check_okay)
- Perl_croak(aTHX_ "Can't check filesystem of script \"%s\" for nosuid", PL_origfilename);
- return on_nosuid;
-}
-#endif /* IAMSUID */
-
-STATIC void
-S_validate_suid(pTHX_ char *validarg, char *scriptname, int fdscript)
-{
-#ifdef IAMSUID
- int which;
-#endif
-
- /* do we need to emulate setuid on scripts? */
-
- /* This code is for those BSD systems that have setuid #! scripts disabled
- * in the kernel because of a security problem. Merely defining DOSUID
- * in perl will not fix that problem, but if you have disabled setuid
- * scripts in the kernel, this will attempt to emulate setuid and setgid
- * on scripts that have those now-otherwise-useless bits set. The setuid
- * root version must be called suidperl or sperlN.NNN. If regular perl
- * discovers that it has opened a setuid script, it calls suidperl with
- * the same argv that it had. If suidperl finds that the script it has
- * just opened is NOT setuid root, it sets the effective uid back to the
- * uid. We don't just make perl setuid root because that loses the
- * effective uid we had before invoking perl, if it was different from the
- * uid.
- *
- * DOSUID must be defined in both perl and suidperl, and IAMSUID must
- * be defined in suidperl only. suidperl must be setuid root. The
- * Configure script will set this up for you if you want it.
- */
-
-#ifdef DOSUID
- char *s, *s2;
-
- if (PerlLIO_fstat(PerlIO_fileno(PL_rsfp),&PL_statbuf) < 0) /* normal stat is insecure */
- Perl_croak(aTHX_ "Can't stat script \"%s\"",PL_origfilename);
- if (fdscript < 0 && PL_statbuf.st_mode & (S_ISUID|S_ISGID)) {
- I32 len;
- STRLEN n_a;
-
-#ifdef IAMSUID
-#ifndef HAS_SETREUID
- /* On this access check to make sure the directories are readable,
- * there is actually a small window that the user could use to make
- * filename point to an accessible directory. So there is a faint
- * chance that someone could execute a setuid script down in a
- * non-accessible directory. I don't know what to do about that.
- * But I don't think it's too important. The manual lies when
- * it says access() is useful in setuid programs.
- */
- if (PerlLIO_access(CopFILE(PL_curcop),1)) /*double check*/
- Perl_croak(aTHX_ "Permission denied");
-#else
- /* If we can swap euid and uid, then we can determine access rights
- * with a simple stat of the file, and then compare device and
- * inode to make sure we did stat() on the same file we opened.
- * Then we just have to make sure he or she can execute it.
- */
- {
- struct stat tmpstatbuf;
-
- if (
-#ifdef HAS_SETREUID
- setreuid(PL_euid,PL_uid) < 0
-#else
-# if HAS_SETRESUID
- setresuid(PL_euid,PL_uid,(Uid_t)-1) < 0
-# endif
-#endif
- || PerlProc_getuid() != PL_euid || PerlProc_geteuid() != PL_uid)
- Perl_croak(aTHX_ "Can't swap uid and euid"); /* really paranoid */
- if (PerlLIO_stat(CopFILE(PL_curcop),&tmpstatbuf) < 0)
- Perl_croak(aTHX_ "Permission denied"); /* testing full pathname here */
-#if defined(IAMSUID) && !defined(NO_NOSUID_CHECK)
- if (fd_on_nosuid_fs(PerlIO_fileno(PL_rsfp)))
- Perl_croak(aTHX_ "Permission denied");
-#endif
- if (tmpstatbuf.st_dev != PL_statbuf.st_dev ||
- tmpstatbuf.st_ino != PL_statbuf.st_ino) {
- (void)PerlIO_close(PL_rsfp);
- Perl_croak(aTHX_ "Permission denied\n");
- }
- if (
-#ifdef HAS_SETREUID
- setreuid(PL_uid,PL_euid) < 0
-#else
-# if defined(HAS_SETRESUID)
- setresuid(PL_uid,PL_euid,(Uid_t)-1) < 0
-# endif
-#endif
- || PerlProc_getuid() != PL_uid || PerlProc_geteuid() != PL_euid)
- Perl_croak(aTHX_ "Can't reswap uid and euid");
- if (!cando(S_IXUSR,FALSE,&PL_statbuf)) /* can real uid exec? */
- Perl_croak(aTHX_ "Permission denied\n");
- }
-#endif /* HAS_SETREUID */
-#endif /* IAMSUID */
-
- if (!S_ISREG(PL_statbuf.st_mode))
- Perl_croak(aTHX_ "Permission denied");
- if (PL_statbuf.st_mode & S_IWOTH)
- Perl_croak(aTHX_ "Setuid/gid script is writable by world");
- PL_doswitches = FALSE; /* -s is insecure in suid */
- CopLINE_inc(PL_curcop);
- if (sv_gets(PL_linestr, PL_rsfp, 0) == Nullch ||
- strnNE(SvPV(PL_linestr,n_a),"#!",2) ) /* required even on Sys V */
- Perl_croak(aTHX_ "No #! line");
- s = SvPV(PL_linestr,n_a)+2;
- if (*s == ' ') s++;
- while (!isSPACE(*s)) s++;
- for (s2 = s; (s2 > SvPV(PL_linestr,n_a)+2 &&
- (isDIGIT(s2[-1]) || strchr("._-", s2[-1]))); s2--) ;
- if (strnNE(s2-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
- Perl_croak(aTHX_ "Not a perl script");
- while (*s == ' ' || *s == '\t') s++;
- /*
- * #! arg must be what we saw above. They can invoke it by
- * mentioning suidperl explicitly, but they may not add any strange
- * arguments beyond what #! says if they do invoke suidperl that way.
- */
- len = strlen(validarg);
- if (strEQ(validarg," PHOOEY ") ||
- strnNE(s,validarg,len) || !isSPACE(s[len]))
- Perl_croak(aTHX_ "Args must match #! line");
-
-#ifndef IAMSUID
- if (PL_euid != PL_uid && (PL_statbuf.st_mode & S_ISUID) &&
- PL_euid == PL_statbuf.st_uid)
- if (!PL_do_undump)
- Perl_croak(aTHX_ "YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
-FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
-#endif /* IAMSUID */
-
- if (PL_euid) { /* oops, we're not the setuid root perl */
- (void)PerlIO_close(PL_rsfp);
-#ifndef IAMSUID
- /* try again */
- PerlProc_execv(Perl_form(aTHX_ "%s/sperl"PERL_FS_VER_FMT, BIN_EXP,
- (int)PERL_REVISION, (int)PERL_VERSION,
- (int)PERL_SUBVERSION), PL_origargv);
-#endif
- Perl_croak(aTHX_ "Can't do setuid; ensure that the setuid bit is set on suidperl\n");
- }
-
- if (PL_statbuf.st_mode & S_ISGID && PL_statbuf.st_gid != PL_egid) {
-#ifdef HAS_SETEGID
- (void)setegid(PL_statbuf.st_gid);
-#else
-#ifdef HAS_SETREGID
- (void)setregid((Gid_t)-1,PL_statbuf.st_gid);
-#else
-#ifdef HAS_SETRESGID
- (void)setresgid((Gid_t)-1,PL_statbuf.st_gid,(Gid_t)-1);
-#else
- PerlProc_setgid(PL_statbuf.st_gid);
-#endif
-#endif
-#endif
- if (PerlProc_getegid() != PL_statbuf.st_gid)
- Perl_croak(aTHX_ "Can't do setegid!\n");
- }
- if (PL_statbuf.st_mode & S_ISUID) {
- if (PL_statbuf.st_uid != PL_euid)
-#ifdef HAS_SETEUID
- (void)seteuid(PL_statbuf.st_uid); /* all that for this */
-#else
-#ifdef HAS_SETREUID
- (void)setreuid((Uid_t)-1,PL_statbuf.st_uid);
-#else
-#ifdef HAS_SETRESUID
- (void)setresuid((Uid_t)-1,PL_statbuf.st_uid,(Uid_t)-1);
-#else
- PerlProc_setuid(PL_statbuf.st_uid);
-#endif
-#endif
-#endif
- if (PerlProc_geteuid() != PL_statbuf.st_uid)
- Perl_croak(aTHX_ "Can't do seteuid!\n");
- }
- else if (PL_uid) { /* oops, mustn't run as root */
-#ifdef HAS_SETEUID
- (void)seteuid((Uid_t)PL_uid);
-#else
-#ifdef HAS_SETREUID
- (void)setreuid((Uid_t)-1,(Uid_t)PL_uid);
-#else
-#ifdef HAS_SETRESUID
- (void)setresuid((Uid_t)-1,(Uid_t)PL_uid,(Uid_t)-1);
-#else
- PerlProc_setuid((Uid_t)PL_uid);
-#endif
-#endif
-#endif
- if (PerlProc_geteuid() != PL_uid)
- Perl_croak(aTHX_ "Can't do seteuid!\n");
- }
- init_ids();
- if (!cando(S_IXUSR,TRUE,&PL_statbuf))
- Perl_croak(aTHX_ "Permission denied\n"); /* they can't do this */
- }
-#ifdef IAMSUID
- else if (PL_preprocess)
- Perl_croak(aTHX_ "-P not allowed for setuid/setgid script\n");
- else if (fdscript >= 0)
- Perl_croak(aTHX_ "fd script not allowed in suidperl\n");
- else
- Perl_croak(aTHX_ "Script is not setuid/setgid in suidperl\n");
-
- /* We absolutely must clear out any saved ids here, so we */
- /* exec the real perl, substituting fd script for scriptname. */
- /* (We pass script name as "subdir" of fd, which perl will grok.) */
- PerlIO_rewind(PL_rsfp);
- PerlLIO_lseek(PerlIO_fileno(PL_rsfp),(Off_t)0,0); /* just in case rewind didn't */
- for (which = 1; PL_origargv[which] && PL_origargv[which] != scriptname; which++) ;
- if (!PL_origargv[which])
- Perl_croak(aTHX_ "Permission denied");
- PL_origargv[which] = savepv(Perl_form(aTHX_ "/dev/fd/%d/%s",
- PerlIO_fileno(PL_rsfp), PL_origargv[which]));
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(PerlIO_fileno(PL_rsfp),F_SETFD,0); /* ensure no close-on-exec */
-#endif
- PerlProc_execv(Perl_form(aTHX_ "%s/perl"PERL_FS_VER_FMT, BIN_EXP,
- (int)PERL_REVISION, (int)PERL_VERSION,
- (int)PERL_SUBVERSION), PL_origargv);/* try again */
- Perl_croak(aTHX_ "Can't do setuid; ensure that the setuid bit is set on suidperl\n");
-#endif /* IAMSUID */
-#else /* !DOSUID */
- if (PL_euid != PL_uid || PL_egid != PL_gid) { /* (suidperl doesn't exist, in fact) */
-#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
- PerlLIO_fstat(PerlIO_fileno(PL_rsfp),&PL_statbuf); /* may be either wrapped or real suid */
- if ((PL_euid != PL_uid && PL_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID)
- ||
- (PL_egid != PL_gid && PL_egid == PL_statbuf.st_gid && PL_statbuf.st_mode & S_ISGID)
- )
- if (!PL_do_undump)
- Perl_croak(aTHX_ "YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
-FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
-#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
- /* not set-id, must be wrapped */
- }
-#endif /* DOSUID */
-}
-
-STATIC void
-S_find_beginning(pTHX)
-{
- register char *s, *s2;
-
- /* skip forward in input to the real script? */
-
- forbid_setid("-x");
-#ifdef MACOS_TRADITIONAL
- /* Since the Mac OS does not honor #! arguments for us, we do it ourselves */
- while (PL_doextract || gMacPerl_AlwaysExtract) {
- if ((s = sv_gets(PL_linestr, PL_rsfp, 0)) == Nullch) {
- if (!gMacPerl_AlwaysExtract)
- Perl_croak(aTHX_ "No Perl script found in input\n");
-
- if (PL_doextract) /* require explicit override ? */
- if (!OverrideExtract(PL_origfilename))
- Perl_croak(aTHX_ "User aborted script\n");
- else
- PL_doextract = FALSE;
-
- /* Pater peccavi, file does not have #! */
- PerlIO_rewind(PL_rsfp);
-
- break;
- }
-#else
- while (PL_doextract) {
- if ((s = sv_gets(PL_linestr, PL_rsfp, 0)) == Nullch)
- Perl_croak(aTHX_ "No Perl script found in input\n");
-#endif
- if (*s == '#' && s[1] == '!' && (s = instr(s,"perl"))) {
- PerlIO_ungetc(PL_rsfp, '\n'); /* to keep line count right */
- PL_doextract = FALSE;
- while (*s && !(isSPACE (*s) || *s == '#')) s++;
- s2 = s;
- while (*s == ' ' || *s == '\t') s++;
- if (*s++ == '-') {
- while (isDIGIT(s2[-1]) || strchr("-._", s2[-1])) s2--;
- if (strnEQ(s2-4,"perl",4))
- /*SUPPRESS 530*/
- while ((s = moreswitches(s)))
- ;
- }
- }
- }
-}
-
-
-STATIC void
-S_init_ids(pTHX)
-{
- PL_uid = PerlProc_getuid();
- PL_euid = PerlProc_geteuid();
- PL_gid = PerlProc_getgid();
- PL_egid = PerlProc_getegid();
-#ifdef VMS
- PL_uid |= PL_gid << 16;
- PL_euid |= PL_egid << 16;
-#endif
- PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
-}
-
-STATIC void
-S_forbid_setid(pTHX_ char *s)
-{
- if (PL_euid != PL_uid)
- Perl_croak(aTHX_ "No %s allowed while running setuid", s);
- if (PL_egid != PL_gid)
- Perl_croak(aTHX_ "No %s allowed while running setgid", s);
-}
-
-void
-Perl_init_debugger(pTHX)
-{
- HV *ostash = PL_curstash;
-
- PL_curstash = PL_debstash;
- PL_dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
- AvREAL_off(PL_dbargs);
- PL_DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
- PL_DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
- PL_DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
- sv_upgrade(GvSV(PL_DBsub), SVt_IV); /* IVX accessed if PERLDB_SUB_NN */
- PL_DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
- sv_setiv(PL_DBsingle, 0);
- PL_DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
- sv_setiv(PL_DBtrace, 0);
- PL_DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
- sv_setiv(PL_DBsignal, 0);
- PL_curstash = ostash;
-}
-
-#ifndef STRESS_REALLOC
-#define REASONABLE(size) (size)
-#else
-#define REASONABLE(size) (1) /* unreasonable */
-#endif
-
-void
-Perl_init_stacks(pTHX)
-{
- /* start with 128-item stack and 8K cxstack */
- PL_curstackinfo = new_stackinfo(REASONABLE(128),
- REASONABLE(8192/sizeof(PERL_CONTEXT) - 1));
- PL_curstackinfo->si_type = PERLSI_MAIN;
- PL_curstack = PL_curstackinfo->si_stack;
- PL_mainstack = PL_curstack; /* remember in case we switch stacks */
-
- PL_stack_base = AvARRAY(PL_curstack);
- PL_stack_sp = PL_stack_base;
- PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
-
- New(50,PL_tmps_stack,REASONABLE(128),SV*);
- PL_tmps_floor = -1;
- PL_tmps_ix = -1;
- PL_tmps_max = REASONABLE(128);
-
- New(54,PL_markstack,REASONABLE(32),I32);
- PL_markstack_ptr = PL_markstack;
- PL_markstack_max = PL_markstack + REASONABLE(32);
-
- SET_MARK_OFFSET;
-
- New(54,PL_scopestack,REASONABLE(32),I32);
- PL_scopestack_ix = 0;
- PL_scopestack_max = REASONABLE(32);
-
- New(54,PL_savestack,REASONABLE(128),ANY);
- PL_savestack_ix = 0;
- PL_savestack_max = REASONABLE(128);
-
- New(54,PL_retstack,REASONABLE(16),OP*);
- PL_retstack_ix = 0;
- PL_retstack_max = REASONABLE(16);
-}
-
-#undef REASONABLE
-
-STATIC void
-S_nuke_stacks(pTHX)
-{
- while (PL_curstackinfo->si_next)
- PL_curstackinfo = PL_curstackinfo->si_next;
- while (PL_curstackinfo) {
- PERL_SI *p = PL_curstackinfo->si_prev;
- /* curstackinfo->si_stack got nuked by sv_free_arenas() */
- Safefree(PL_curstackinfo->si_cxstack);
- Safefree(PL_curstackinfo);
- PL_curstackinfo = p;
- }
- Safefree(PL_tmps_stack);
- Safefree(PL_markstack);
- Safefree(PL_scopestack);
- Safefree(PL_savestack);
- Safefree(PL_retstack);
-}
-
-#ifndef PERL_OBJECT
-static PerlIO *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
-#endif
-
-STATIC void
-S_init_lexer(pTHX)
-{
-#ifdef PERL_OBJECT
- PerlIO *tmpfp;
-#endif
- tmpfp = PL_rsfp;
- PL_rsfp = Nullfp;
- lex_start(PL_linestr);
- PL_rsfp = tmpfp;
- PL_subname = newSVpvn("main",4);
-}
-
-STATIC void
-S_init_predump_symbols(pTHX)
-{
- GV *tmpgv;
- IO *io;
-
- sv_setpvn(get_sv("\"", TRUE), " ", 1);
- PL_stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
- GvMULTI_on(PL_stdingv);
- io = GvIOp(PL_stdingv);
- IoIFP(io) = PerlIO_stdin();
- tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
- GvMULTI_on(tmpgv);
- GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io);
-
- tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
- GvMULTI_on(tmpgv);
- io = GvIOp(tmpgv);
- IoOFP(io) = IoIFP(io) = PerlIO_stdout();
- setdefout(tmpgv);
- tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
- GvMULTI_on(tmpgv);
- GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io);
-
- PL_stderrgv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
- GvMULTI_on(PL_stderrgv);
- io = GvIOp(PL_stderrgv);
- IoOFP(io) = IoIFP(io) = PerlIO_stderr();
- tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
- GvMULTI_on(tmpgv);
- GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io);
-
- PL_statname = NEWSV(66,0); /* last filename we did stat on */
-
- if (PL_osname)
- Safefree(PL_osname);
- PL_osname = savepv(OSNAME);
-}
-
-STATIC void
-S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register char **env)
-{
- char *s;
- SV *sv;
- GV* tmpgv;
- char **dup_env_base = 0;
- int dup_env_count = 0;
-
- argc--,argv++; /* skip name of script */
- if (PL_doswitches) {
- for (; argc > 0 && **argv == '-'; argc--,argv++) {
- if (!argv[0][1])
- break;
- if (argv[0][1] == '-' && !argv[0][2]) {
- argc--,argv++;
- break;
- }
- if ((s = strchr(argv[0], '='))) {
- *s++ = '\0';
- sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
- }
- else
- sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
- }
- }
- PL_toptarget = NEWSV(0,0);
- sv_upgrade(PL_toptarget, SVt_PVFM);
- sv_setpvn(PL_toptarget, "", 0);
- PL_bodytarget = NEWSV(0,0);
- sv_upgrade(PL_bodytarget, SVt_PVFM);
- sv_setpvn(PL_bodytarget, "", 0);
- PL_formtarget = PL_bodytarget;
-
- TAINT;
- if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {
-#ifdef MACOS_TRADITIONAL
- /* $0 is not majick on a Mac */
- sv_setpv(GvSV(tmpgv),MacPerl_MPWFileName(PL_origfilename));
-#else
- sv_setpv(GvSV(tmpgv),PL_origfilename);
- magicname("0", "0", 1);
-#endif
- }
- if ((tmpgv = gv_fetchpv("\030",TRUE, SVt_PV)))
-#ifdef OS2
- sv_setpv(GvSV(tmpgv), os2_execname(aTHX));
-#else
- sv_setpv(GvSV(tmpgv),PL_origargv[0]);
-#endif
- if ((PL_argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV))) {
- GvMULTI_on(PL_argvgv);
- (void)gv_AVadd(PL_argvgv);
- av_clear(GvAVn(PL_argvgv));
- for (; argc > 0; argc--,argv++) {
- SV *sv = newSVpv(argv[0],0);
- av_push(GvAVn(PL_argvgv),sv);
- if (PL_widesyscalls)
- (void)sv_utf8_decode(sv);
- }
- }
- if ((PL_envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV))) {
- HV *hv;
- GvMULTI_on(PL_envgv);
- hv = GvHVn(PL_envgv);
- hv_magic(hv, Nullgv, 'E');
-#ifdef USE_ENVIRON_ARRAY
- /* Note that if the supplied env parameter is actually a copy
- of the global environ then it may now point to free'd memory
- if the environment has been modified since. To avoid this
- problem we treat env==NULL as meaning 'use the default'
- */
- if (!env)
- env = environ;
- if (env != environ)
- environ[0] = Nullch;
-#ifdef NEED_ENVIRON_DUP_FOR_MODIFY
- {
- char **env_base;
- for (env_base = env; *env; env++)
- dup_env_count++;
- if ((dup_env_base = (char **)
- safesysmalloc( sizeof(char *) * (dup_env_count+1) ))) {
- char **dup_env;
- for (env = env_base, dup_env = dup_env_base;
- *env;
- env++, dup_env++) {
- /* With environ one needs to use safesysmalloc(). */
- *dup_env = safesysmalloc(strlen(*env) + 1);
- (void)strcpy(*dup_env, *env);
- }
- *dup_env = Nullch;
- env = dup_env_base;
- } /* else what? */
- }
-#endif /* NEED_ENVIRON_DUP_FOR_MODIFY */
- for (; *env; env++) {
- if (!(s = strchr(*env,'=')))
- continue;
- *s++ = '\0';
-#if defined(MSDOS)
- (void)strupr(*env);
-#endif
- sv = newSVpv(s--,0);
- (void)hv_store(hv, *env, s - *env, sv, 0);
- *s = '=';
- }
-#ifdef NEED_ENVIRON_DUP_FOR_MODIFY
- if (dup_env_base) {
- char **dup_env;
- for (dup_env = dup_env_base; *dup_env; dup_env++)
- safesysfree(*dup_env);
- safesysfree(dup_env_base);
- }
-#endif /* NEED_ENVIRON_DUP_FOR_MODIFY */
-#endif /* USE_ENVIRON_ARRAY */
-#ifdef DYNAMIC_ENV_FETCH
- HvNAME(hv) = savepv(ENV_HV_NAME);
-#endif
- }
- TAINT_NOT;
- if ((tmpgv = gv_fetchpv("$",TRUE, SVt_PV)))
- sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
-}
-
-STATIC void
-S_init_perllib(pTHX)
-{
- char *s;
- if (!PL_tainting) {
-#ifndef VMS
- s = PerlEnv_getenv("PERL5LIB");
- if (s)
- incpush(s, TRUE, TRUE);
- else
- incpush(PerlEnv_getenv("PERLLIB"), FALSE, FALSE);
-#else /* VMS */
- /* Treat PERL5?LIB as a possible search list logical name -- the
- * "natural" VMS idiom for a Unix path string. We allow each
- * element to be a set of |-separated directories for compatibility.
- */
- char buf[256];
- int idx = 0;
- if (my_trnlnm("PERL5LIB",buf,0))
- do { incpush(buf,TRUE,TRUE); } while (my_trnlnm("PERL5LIB",buf,++idx));
- else
- while (my_trnlnm("PERLLIB",buf,idx++)) incpush(buf,FALSE,FALSE);
-#endif /* VMS */
- }
-
-/* Use the ~-expanded versions of APPLLIB (undocumented),
- ARCHLIB PRIVLIB SITEARCH SITELIB VENDORARCH and VENDORLIB
-*/
-#ifdef APPLLIB_EXP
- incpush(APPLLIB_EXP, TRUE, TRUE);
-#endif
-
-#ifdef ARCHLIB_EXP
- incpush(ARCHLIB_EXP, FALSE, FALSE);
-#endif
-#ifdef MACOS_TRADITIONAL
- {
- struct stat tmpstatbuf;
- SV * privdir = NEWSV(55, 0);
- char * macperl = PerlEnv_getenv("MACPERL");
-
- if (!macperl)
- macperl = "";
-
- Perl_sv_setpvf(aTHX_ privdir, "%slib:", macperl);
- if (PerlLIO_stat(SvPVX(privdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode))
- incpush(SvPVX(privdir), TRUE, FALSE);
- Perl_sv_setpvf(aTHX_ privdir, "%ssite_perl:", macperl);
- if (PerlLIO_stat(SvPVX(privdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode))
- incpush(SvPVX(privdir), TRUE, FALSE);
-
- SvREFCNT_dec(privdir);
- }
- if (!PL_tainting)
- incpush(":", FALSE, FALSE);
-#else
-#ifndef PRIVLIB_EXP
-# define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
-#endif
-#if defined(WIN32)
- incpush(PRIVLIB_EXP, TRUE, FALSE);
-#else
- incpush(PRIVLIB_EXP, FALSE, FALSE);
-#endif
-
-#ifdef SITEARCH_EXP
- /* sitearch is always relative to sitelib on Windows for
- * DLL-based path intuition to work correctly */
-# if !defined(WIN32)
- incpush(SITEARCH_EXP, FALSE, FALSE);
-# endif
-#endif
-
-#ifdef SITELIB_EXP
-# if defined(WIN32)
- incpush(SITELIB_EXP, TRUE, FALSE); /* this picks up sitearch as well */
-# else
- incpush(SITELIB_EXP, FALSE, FALSE);
-# endif
-#endif
-
-#ifdef SITELIB_STEM /* Search for version-specific dirs below here */
- incpush(SITELIB_STEM, FALSE, TRUE);
-#endif
-
-#ifdef PERL_VENDORARCH_EXP
- /* vendorarch is always relative to vendorlib on Windows for
- * DLL-based path intuition to work correctly */
-# if !defined(WIN32)
- incpush(PERL_VENDORARCH_EXP, FALSE, FALSE);
-# endif
-#endif
-
-#ifdef PERL_VENDORLIB_EXP
-# if defined(WIN32)
- incpush(PERL_VENDORLIB_EXP, TRUE, FALSE); /* this picks up vendorarch as well */
-# else
- incpush(PERL_VENDORLIB_EXP, FALSE, FALSE);
-# endif
-#endif
-
-#ifdef PERL_VENDORLIB_STEM /* Search for version-specific dirs below here */
- incpush(PERL_VENDORLIB_STEM, FALSE, TRUE);
-#endif
-
-#ifdef PERL_OTHERLIBDIRS
- incpush(PERL_OTHERLIBDIRS, TRUE, TRUE);
-#endif
-
- if (!PL_tainting)
- incpush(".", FALSE, FALSE);
-#endif /* MACOS_TRADITIONAL */
-}
-
-#if defined(DOSISH) || defined(EPOC)
-# define PERLLIB_SEP ';'
-#else
-# if defined(VMS)
-# define PERLLIB_SEP '|'
-# else
-# if defined(MACOS_TRADITIONAL)
-# define PERLLIB_SEP ','
-# else
-# define PERLLIB_SEP ':'
-# endif
-# endif
-#endif
-#ifndef PERLLIB_MANGLE
-# define PERLLIB_MANGLE(s,n) (s)
-#endif
-
-STATIC void
-S_incpush(pTHX_ char *p, int addsubdirs, int addoldvers)
-{
- SV *subdir = Nullsv;
-
- if (!p || !*p)
- return;
-
- if (addsubdirs || addoldvers) {
- subdir = sv_newmortal();
- }
-
- /* Break at all separators */
- while (p && *p) {
- SV *libdir = NEWSV(55,0);
- char *s;
-
- /* skip any consecutive separators */
- while ( *p == PERLLIB_SEP ) {
- /* Uncomment the next line for PATH semantics */
- /* av_push(GvAVn(PL_incgv), newSVpvn(".", 1)); */
- p++;
- }
-
- if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
- sv_setpvn(libdir, PERLLIB_MANGLE(p, (STRLEN)(s - p)),
- (STRLEN)(s - p));
- p = s + 1;
- }
- else {
- sv_setpv(libdir, PERLLIB_MANGLE(p, 0));
- p = Nullch; /* break out */
- }
-#ifdef MACOS_TRADITIONAL
- if (!strchr(SvPVX(libdir), ':'))
- sv_insert(libdir, 0, 0, ":", 1);
- if (SvPVX(libdir)[SvCUR(libdir)-1] != ':')
- sv_catpv(libdir, ":");
-#endif
-
- /*
- * BEFORE pushing libdir onto @INC we may first push version- and
- * archname-specific sub-directories.
- */
- if (addsubdirs || addoldvers) {
-#ifdef PERL_INC_VERSION_LIST
- /* Configure terminates PERL_INC_VERSION_LIST with a NULL */
- const char *incverlist[] = { PERL_INC_VERSION_LIST };
- const char **incver;
-#endif
- struct stat tmpstatbuf;
-#ifdef VMS
- char *unix;
- STRLEN len;
-
- if ((unix = tounixspec_ts(SvPV(libdir,len),Nullch)) != Nullch) {
- len = strlen(unix);
- while (unix[len-1] == '/') len--; /* Cosmetic */
- sv_usepvn(libdir,unix,len);
- }
- else
- PerlIO_printf(Perl_error_log,
- "Failed to unixify @INC element \"%s\"\n",
- SvPV(libdir,len));
-#endif
- if (addsubdirs) {
-#ifdef MACOS_TRADITIONAL
-#define PERL_AV_SUFFIX_FMT ""
-#define PERL_ARCH_FMT "%s:"
-#define PERL_ARCH_FMT_PATH PERL_FS_VER_FMT PERL_AV_SUFFIX_FMT
-#else
-#define PERL_AV_SUFFIX_FMT "/"
-#define PERL_ARCH_FMT "/%s"
-#define PERL_ARCH_FMT_PATH PERL_AV_SUFFIX_FMT PERL_FS_VER_FMT
-#endif
- /* .../version/archname if -d .../version/archname */
- Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT_PATH PERL_ARCH_FMT,
- libdir,
- (int)PERL_REVISION, (int)PERL_VERSION,
- (int)PERL_SUBVERSION, ARCHNAME);
- if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
- S_ISDIR(tmpstatbuf.st_mode))
- av_push(GvAVn(PL_incgv), newSVsv(subdir));
-
- /* .../version if -d .../version */
- Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT_PATH, libdir,
- (int)PERL_REVISION, (int)PERL_VERSION,
- (int)PERL_SUBVERSION);
- if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
- S_ISDIR(tmpstatbuf.st_mode))
- av_push(GvAVn(PL_incgv), newSVsv(subdir));
-
- /* .../archname if -d .../archname */
- Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT, libdir, ARCHNAME);
- if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
- S_ISDIR(tmpstatbuf.st_mode))
- av_push(GvAVn(PL_incgv), newSVsv(subdir));
- }
-
-#ifdef PERL_INC_VERSION_LIST
- if (addoldvers) {
- for (incver = incverlist; *incver; incver++) {
- /* .../xxx if -d .../xxx */
- Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT, libdir, *incver);
- if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 &&
- S_ISDIR(tmpstatbuf.st_mode))
- av_push(GvAVn(PL_incgv), newSVsv(subdir));
- }
- }
-#endif
- }
-
- /* finally push this lib directory on the end of @INC */
- av_push(GvAVn(PL_incgv), libdir);
- }
-}
-
-#ifdef USE_THREADS
-STATIC struct perl_thread *
-S_init_main_thread(pTHX)
-{
-#if !defined(PERL_IMPLICIT_CONTEXT)
- struct perl_thread *thr;
-#endif
- XPV *xpv;
-
- Newz(53, thr, 1, struct perl_thread);
- PL_curcop = &PL_compiling;
- thr->interp = PERL_GET_INTERP;
- thr->cvcache = newHV();
- thr->threadsv = newAV();
- /* thr->threadsvp is set when find_threadsv is called */
- thr->specific = newAV();
- thr->flags = THRf_R_JOINABLE;
- MUTEX_INIT(&thr->mutex);
- /* Handcraft thrsv similarly to mess_sv */
- New(53, PL_thrsv, 1, SV);
- Newz(53, xpv, 1, XPV);
- SvFLAGS(PL_thrsv) = SVt_PV;
- SvANY(PL_thrsv) = (void*)xpv;
- SvREFCNT(PL_thrsv) = 1 << 30; /* practically infinite */
- SvPVX(PL_thrsv) = (char*)thr;
- SvCUR_set(PL_thrsv, sizeof(thr));
- SvLEN_set(PL_thrsv, sizeof(thr));
- *SvEND(PL_thrsv) = '\0'; /* in the trailing_nul field */
- thr->oursv = PL_thrsv;
- PL_chopset = " \n-";
- PL_dumpindent = 4;
-
- MUTEX_LOCK(&PL_threads_mutex);
- PL_nthreads++;
- thr->tid = 0;
- thr->next = thr;
- thr->prev = thr;
- MUTEX_UNLOCK(&PL_threads_mutex);
-
-#ifdef HAVE_THREAD_INTERN
- Perl_init_thread_intern(thr);
-#endif
-
-#ifdef SET_THREAD_SELF
- SET_THREAD_SELF(thr);
-#else
- thr->self = pthread_self();
-#endif /* SET_THREAD_SELF */
- PERL_SET_THX(thr);
-
- /*
- * These must come after the thread self setting
- * because sv_setpvn does SvTAINT and the taint
- * fields thread selfness being set.
- */
- PL_toptarget = NEWSV(0,0);
- sv_upgrade(PL_toptarget, SVt_PVFM);
- sv_setpvn(PL_toptarget, "", 0);
- PL_bodytarget = NEWSV(0,0);
- sv_upgrade(PL_bodytarget, SVt_PVFM);
- sv_setpvn(PL_bodytarget, "", 0);
- PL_formtarget = PL_bodytarget;
- thr->errsv = newSVpvn("", 0);
- (void) find_threadsv("@"); /* Ensure $@ is initialised early */
-
- PL_maxscream = -1;
- PL_regcompp = MEMBER_TO_FPTR(Perl_pregcomp);
- PL_regexecp = MEMBER_TO_FPTR(Perl_regexec_flags);
- PL_regint_start = MEMBER_TO_FPTR(Perl_re_intuit_start);
- PL_regint_string = MEMBER_TO_FPTR(Perl_re_intuit_string);
- PL_regfree = MEMBER_TO_FPTR(Perl_pregfree);
- PL_regindent = 0;
- PL_reginterp_cnt = 0;
-
- return thr;
-}
-#endif /* USE_THREADS */
-
-void
-Perl_call_list(pTHX_ I32 oldscope, AV *paramList)
-{
- SV *atsv;
- line_t oldline = CopLINE(PL_curcop);
- CV *cv;
- STRLEN len;
- int ret;
- dJMPENV;
-
- while (AvFILL(paramList) >= 0) {
- cv = (CV*)av_shift(paramList);
- if ((PL_minus_c & 0x10) && (paramList == PL_beginav)) {
- /* save PL_beginav for compiler */
- if (! PL_beginav_save)
- PL_beginav_save = newAV();
- av_push(PL_beginav_save, (SV*)cv);
- } else {
- SAVEFREESV(cv);
- }
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
- CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_vcall_list_body), cv);
-#else
- JMPENV_PUSH(ret);
-#endif
- switch (ret) {
- case 0:
-#ifndef PERL_FLEXIBLE_EXCEPTIONS
- call_list_body(cv);
-#endif
- atsv = ERRSV;
- (void)SvPV(atsv, len);
- if (len) {
- STRLEN n_a;
- PL_curcop = &PL_compiling;
- CopLINE_set(PL_curcop, oldline);
- if (paramList == PL_beginav)
- sv_catpv(atsv, "BEGIN failed--compilation aborted");
- else
- Perl_sv_catpvf(aTHX_ atsv,
- "%s failed--call queue aborted",
- paramList == PL_checkav ? "CHECK"
- : paramList == PL_initav ? "INIT"
- : "END");
- while (PL_scopestack_ix > oldscope)
- LEAVE;
- JMPENV_POP;
- Perl_croak(aTHX_ "%s", SvPVx(atsv, n_a));
- }
- break;
- case 1:
- STATUS_ALL_FAILURE;
- /* FALL THROUGH */
- case 2:
- /* my_exit() was called */
- while (PL_scopestack_ix > oldscope)
- LEAVE;
- FREETMPS;
- PL_curstash = PL_defstash;
- PL_curcop = &PL_compiling;
- CopLINE_set(PL_curcop, oldline);
- JMPENV_POP;
- if (PL_statusvalue && !(PL_exit_flags & PERL_EXIT_EXPECTED)) {
- if (paramList == PL_beginav)
- Perl_croak(aTHX_ "BEGIN failed--compilation aborted");
- else
- Perl_croak(aTHX_ "%s failed--call queue aborted",
- paramList == PL_checkav ? "CHECK"
- : paramList == PL_initav ? "INIT"
- : "END");
- }
- my_exit_jump();
- /* NOTREACHED */
- case 3:
- if (PL_restartop) {
- PL_curcop = &PL_compiling;
- CopLINE_set(PL_curcop, oldline);
- JMPENV_JUMP(3);
- }
- PerlIO_printf(Perl_error_log, "panic: restartop\n");
- FREETMPS;
- break;
- }
- JMPENV_POP;
- }
-}
-
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
-STATIC void *
-S_vcall_list_body(pTHX_ va_list args)
-{
- CV *cv = va_arg(args, CV*);
- return call_list_body(cv);
-}
-#endif
-
-STATIC void *
-S_call_list_body(pTHX_ CV *cv)
-{
- PUSHMARK(PL_stack_sp);
- call_sv((SV*)cv, G_EVAL|G_DISCARD);
- return NULL;
-}
-
-void
-Perl_my_exit(pTHX_ U32 status)
-{
- DEBUG_S(PerlIO_printf(Perl_debug_log, "my_exit: thread %p, status %lu\n",
- thr, (unsigned long) status));
- switch (status) {
- case 0:
- STATUS_ALL_SUCCESS;
- break;
- case 1:
- STATUS_ALL_FAILURE;
- break;
- default:
- STATUS_NATIVE_SET(status);
- break;
- }
- my_exit_jump();
-}
-
-void
-Perl_my_failure_exit(pTHX)
-{
-#ifdef VMS
- if (vaxc$errno & 1) {
- if (STATUS_NATIVE & 1) /* fortuitiously includes "-1" */
- STATUS_NATIVE_SET(44);
- }
- else {
- if (!vaxc$errno && errno) /* unlikely */
- STATUS_NATIVE_SET(44);
- else
- STATUS_NATIVE_SET(vaxc$errno);
- }
-#else
- int exitstatus;
- if (errno & 255)
- STATUS_POSIX_SET(errno);
- else {
- exitstatus = STATUS_POSIX >> 8;
- if (exitstatus & 255)
- STATUS_POSIX_SET(exitstatus);
- else
- STATUS_POSIX_SET(255);
- }
-#endif
- my_exit_jump();
-}
-
-STATIC void
-S_my_exit_jump(pTHX)
-{
- register PERL_CONTEXT *cx;
- I32 gimme;
- SV **newsp;
-
- if (PL_e_script) {
- SvREFCNT_dec(PL_e_script);
- PL_e_script = Nullsv;
- }
-
- POPSTACK_TO(PL_mainstack);
- if (cxstack_ix >= 0) {
- if (cxstack_ix > 0)
- dounwind(0);
- POPBLOCK(cx,PL_curpm);
- LEAVE;
- }
-
- JMPENV_JUMP(2);
-}
-
-#ifdef PERL_OBJECT
-#include "XSUB.h"
-#endif
-
-static I32
-read_e_script(pTHXo_ int idx, SV *buf_sv, int maxlen)
-{
- char *p, *nl;
- p = SvPVX(PL_e_script);
- nl = strchr(p, '\n');
- nl = (nl) ? nl+1 : SvEND(PL_e_script);
- if (nl-p == 0) {
- filter_del(read_e_script);
- return 0;
- }
- sv_catpvn(buf_sv, p, nl-p);
- sv_chop(PL_e_script, nl);
- return 1;
-}
OpenPOWER on IntegriCloud