X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl.c;h=bc53f5ec52b81a4d08a4878d7e93101c4ac1212b;hb=b7b1864f76048b3925a3516e05f0ced40aaebf56;hp=3f30f6d63a40428980785cc62385b0471974dda3;hpb=2faa37ccf8e46b865687f0ab4992b29a75eb79ea;p=p5sagit%2Fp5-mst-13.2.git diff --git a/perl.c b/perl.c index 3f30f6d..bc53f5e 100644 --- a/perl.c +++ b/perl.c @@ -1,6 +1,6 @@ /* perl.c * - * Copyright (c) 1987-1997 Larry Wall + * Copyright (c) 1987-1998 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. @@ -24,6 +24,13 @@ char *getenv _((char *)); /* Usually in */ #endif +#ifdef I_FCNTL +#include +#endif +#ifdef I_SYS_FILE +#include +#endif + dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n"; #ifdef IAMSUID @@ -70,7 +77,7 @@ static void init_debugger _((void)); static void init_lexer _((void)); static void init_main_stash _((void)); #ifdef USE_THREADS -static struct thread * init_main_thread _((void)); +static struct perl_thread * init_main_thread _((void)); #endif /* USE_THREADS */ static void init_perllib _((void)); static void init_postdump_symbols _((int, char **, char **)); @@ -83,21 +90,8 @@ static void validate_suid _((char *, char*)); static int fdscript = -1; -#if defined(DEBUGGING) && defined(USE_THREADS) && defined(__linux__) -#include -static void -catch_sigsegv(int signo, struct sigcontext_struct sc) -{ - signal(SIGSEGV, SIG_DFL); - fprintf(stderr, "Segmentation fault dereferencing 0x%lx\n" - "return_address = 0x%lx, eip = 0x%lx\n", - sc.cr2, __builtin_return_address(0), sc.eip); - fprintf(stderr, "thread = 0x%lx\n", (unsigned long)THR); -} -#endif - PerlInterpreter * -perl_alloc() +perl_alloc(void) { PerlInterpreter *sv_interp; @@ -107,13 +101,12 @@ perl_alloc() } void -perl_construct( sv_interp ) -register PerlInterpreter *sv_interp; +perl_construct(register PerlInterpreter *sv_interp) { #ifdef USE_THREADS int i; #ifndef FAKE_THREADS - struct thread *thr; + struct perl_thread *thr; #endif /* FAKE_THREADS */ #endif /* USE_THREADS */ @@ -129,9 +122,12 @@ register PerlInterpreter *sv_interp; #ifdef USE_THREADS INIT_THREADS; +#ifdef ALLOC_THREAD_KEY + ALLOC_THREAD_KEY; +#else if (pthread_key_create(&thr_key, 0)) croak("panic: pthread_key_create"); - MUTEX_INIT(&malloc_mutex); +#endif MUTEX_INIT(&sv_mutex); /* * Safe to use basic SV functions from now on (though @@ -141,6 +137,9 @@ register PerlInterpreter *sv_interp; COND_INIT(&eval_cond); MUTEX_INIT(&threads_mutex); COND_INIT(&nthreads_cond); +#ifdef EMULATE_ATOMIC_REFCOUNTS + MUTEX_INIT(&svref_mutex); +#endif /* EMULATE_ATOMIC_REFCOUNTS */ thr = init_main_thread(); #endif /* USE_THREADS */ @@ -177,6 +176,7 @@ register PerlInterpreter *sv_interp; #endif } + init_stacks(ARGS); #ifdef MULTIPLICITY I_REINIT; perl_destruct_level = 1; @@ -212,7 +212,6 @@ register PerlInterpreter *sv_interp; fdpid = newAV(); /* for remembering popen pids by fd */ - init_stacks(ARGS); DEBUG( { New(51,debname,128,char); New(52,debdelim,128,char); @@ -222,8 +221,7 @@ register PerlInterpreter *sv_interp; } void -perl_destruct(sv_interp) -register PerlInterpreter *sv_interp; +perl_destruct(register PerlInterpreter *sv_interp) { dTHR; int destruct_level; /* 0=none, 1=full, 2=full with checks */ @@ -310,7 +308,7 @@ register PerlInterpreter *sv_interp; #ifdef DEBUGGING { char *s; - if (s = getenv("PERL_DESTRUCT_LEVEL")) { + if (s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL")) { int i = atoi(s); if (destruct_level < i) destruct_level = i; @@ -416,36 +414,6 @@ register PerlInterpreter *sv_interp; /* defgv, aka *_ should be taken care of elsewhere */ -#if 0 /* just about all regexp stuff, seems to be ok */ - - /* shortcuts to regexp stuff */ - leftgv = Nullgv; - ampergv = Nullgv; - - SAVEFREEOP(curpm); - SAVEFREEOP(oldlastpm); /* for saving regexp context during debugger */ - - regprecomp = NULL; /* uncompiled string. */ - regparse = NULL; /* Input-scan pointer. */ - regxend = NULL; /* End of input for compile */ - regnpar = 0; /* () count. */ - regcode = NULL; /* Code-emit pointer; ®dummy = don't. */ - regsize = 0; /* Code size. */ - regnaughty = 0; /* How bad is this pattern? */ - regsawback = 0; /* Did we see \1, ...? */ - - reginput = NULL; /* String-input pointer. */ - regbol = NULL; /* Beginning of input, for ^ check. */ - regeol = NULL; /* End of input, for $ check. */ - regstartp = (char **)NULL; /* Pointer to startp array. */ - regendp = (char **)NULL; /* Ditto for endp. */ - reglastparen = 0; /* Similarly for lastparen. */ - regtill = NULL; /* How far we are required to go. */ - regflags = 0; /* are we folding, multilining? */ - regprev = (char)NULL; /* char before regbol, \n if none */ - -#endif /* if 0 */ - /* clean up after study() */ SvREFCNT_dec(lastscream); lastscream = Nullsv; @@ -462,10 +430,6 @@ register PerlInterpreter *sv_interp; endav = Nullav; initav = Nullav; - /* temp stack during pp_sort() */ - SvREFCNT_dec(sortstack); - sortstack = Nullav; - /* shortcuts just get cleared */ envgv = Nullgv; siggv = Nullgv; @@ -529,7 +493,7 @@ register PerlInterpreter *sv_interp; if (hent) { warn("Unbalanced string table refcount: (%d) for \"%s\"", HeVAL(hent) - Nullsv, HeKEY(hent)); - HeVAL(hent) = Nullsv; + HeVAL(hent) = &sv_undef; hent = HeNEXT(hent); } if (!hent) { @@ -557,7 +521,6 @@ register PerlInterpreter *sv_interp; DEBUG_P(debprofdump()); #ifdef USE_THREADS MUTEX_DESTROY(&sv_mutex); - MUTEX_DESTROY(&malloc_mutex); MUTEX_DESTROY(&eval_mutex); COND_DESTROY(&eval_cond); @@ -581,8 +544,7 @@ register PerlInterpreter *sv_interp; } void -perl_free(sv_interp) -PerlInterpreter *sv_interp; +perl_free(PerlInterpreter *sv_interp) { if (!(curinterp = sv_interp)) return; @@ -590,12 +552,7 @@ PerlInterpreter *sv_interp; } int -perl_parse(sv_interp, xsinit, argc, argv, env) -PerlInterpreter *sv_interp; -void (*xsinit)_((void)); -int argc; -char **argv; -char **env; +perl_parse(PerlInterpreter *sv_interp, void (*xsinit) (void), int argc, char **argv, char **env) { dTHR; register SV *sv; @@ -605,6 +562,7 @@ char **env; char *validarg = ""; I32 oldscope; AV* comppadlist; + int e_tmpfd = -1; dJMPENV; int ret; @@ -724,13 +682,36 @@ setuid perl scripts securely.\n"); if (euid != uid || egid != gid) croak("No -e allowed in setuid scripts"); if (!e_fp) { +#if defined(HAS_UMASK) && !defined(VMS) + int oldumask = PerlLIO_umask(0177); +#endif e_tmpname = savepv(TMPPATH); - (void)mktemp(e_tmpname); +#ifdef HAS_MKSTEMP + e_tmpfd = PerlLIO_mkstemp(e_tmpname); +#else /* use mktemp() */ + (void)PerlLIO_mktemp(e_tmpname); if (!*e_tmpname) - croak("Can't mktemp()"); + croak("Cannot generate temporary filename"); +# if defined(HAS_OPEN3) && defined(O_EXCL) + e_tmpfd = open(e_tmpname, + O_WRONLY | O_CREAT | O_EXCL, + 0600); +# else + (void)UNLINK(e_tmpname); + /* Yes, potential race. But at least we can say we tried. */ e_fp = PerlIO_open(e_tmpname,"w"); - if (!e_fp) - croak("Cannot open temporary file"); +# endif +#endif /* ifdef HAS_MKSTEMP */ +#if defined(HAS_MKSTEMP) || (defined(HAS_OPEN3) && defined(O_EXCL)) + if (e_tmpfd < 0) + croak("Cannot create temporary file \"%s\"", e_tmpname); + e_fp = PerlIO_fdopen(e_tmpfd,"w"); +#endif + if (!e_fp) + croak("Cannot create temporary file \"%s\"", e_tmpname); +#if defined(HAS_UMASK) && !defined(VMS) + (void)PerlLIO_umask(oldumask); +#endif } if (*++s) PerlIO_puts(e_fp,s); @@ -857,7 +838,7 @@ print \" \\@INC:\\n @INC\\n\";"); } switch_end: - if (!tainting && (s = getenv("PERL5OPT"))) { + if (!tainting && (s = PerlEnv_getenv("PERL5OPT"))) { while (s && *s) { while (isSPACE(*s)) s++; @@ -889,7 +870,7 @@ print \" \\@INC:\\n @INC\\n\";"); } else if (scriptname == Nullch) { #ifdef MSDOS - if ( isatty(PerlIO_fileno(PerlIO_stdin())) ) + if ( PerlLIO_isatty(PerlIO_fileno(PerlIO_stdin())) ) moreswitches("h"); #endif scriptname = "-"; @@ -933,14 +914,10 @@ print \" \\@INC:\\n @INC\\n\";"); boot_core_UNIVERSAL(); if (xsinit) (*xsinit)(); /* in case linked C routines want magical variables */ -#if defined(VMS) || defined(WIN32) +#if defined(VMS) || defined(WIN32) || defined(DJGPP) init_os_extras(); #endif -#if defined(DEBUGGING) && defined(USE_THREADS) && defined(__linux__) - DEBUG_L(signal(SIGSEGV, (void(*)(int))catch_sigsegv);); -#endif - init_predump_symbols(); if (!do_undump) init_postdump_symbols(argc,argv,env); @@ -949,6 +926,7 @@ print \" \\@INC:\\n @INC\\n\";"); /* now parse the script */ + SETERRNO(0,SS$_NORMAL); error_count = 0; if (yyparse() || error_count) { if (minus_c) @@ -965,16 +943,13 @@ print \" \\@INC:\\n @INC\\n\";"); (void)UNLINK(e_tmpname); Safefree(e_tmpname); e_tmpname = Nullch; + e_tmpfd = -1; } /* now that script is parsed, we can modify record separator */ SvREFCNT_dec(rs); rs = SvREFCNT_inc(nrs); -#ifdef USE_THREADS - sv_setsv(*av_fetch(thr->magicals, find_thread_magical("/"), FALSE), rs); -#else - sv_setsv(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs); -#endif /* USE_THREADS */ + sv_setsv(perl_get_sv("/", TRUE), rs); if (do_undump) my_unexec(); @@ -985,7 +960,7 @@ print \" \\@INC:\\n @INC\\n\";"); FREETMPS; #ifdef MYMALLOC - if ((s=getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2) + if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2) dump_mstats("after compilation:"); #endif @@ -996,10 +971,9 @@ print \" \\@INC:\\n @INC\\n\";"); } int -perl_run(sv_interp) -PerlInterpreter *sv_interp; +perl_run(PerlInterpreter *sv_interp) { - dTHR; + dSP; I32 oldscope; dJMPENV; int ret; @@ -1023,7 +997,7 @@ PerlInterpreter *sv_interp; if (endav) call_list(oldscope, endav); #ifdef MYMALLOC - if (getenv("PERL_DEBUG_MSTATS")) + if (PerlEnv_getenv("PERL_DEBUG_MSTATS")) dump_mstats("after execution: "); #endif JMPENV_POP; @@ -1035,10 +1009,7 @@ PerlInterpreter *sv_interp; JMPENV_POP; return 1; } - if (curstack != mainstack) { - dSP; - SWITCHSTACK(curstack, mainstack); - } + POPSTACK_TO(mainstack); break; } @@ -1082,17 +1053,15 @@ PerlInterpreter *sv_interp; } SV* -perl_get_sv(name, create) -char* name; -I32 create; +perl_get_sv(char *name, I32 create) { GV *gv; #ifdef USE_THREADS if (name[1] == '\0' && !isALPHA(name[0])) { - PADOFFSET tmp = find_thread_magical(name); + PADOFFSET tmp = find_threadsv(name); if (tmp != NOT_IN_PAD) { dTHR; - return *av_fetch(thr->magicals, tmp, FALSE); + return THREADSV(tmp); } } #endif /* USE_THREADS */ @@ -1103,9 +1072,7 @@ I32 create; } AV* -perl_get_av(name, create) -char* name; -I32 create; +perl_get_av(char *name, I32 create) { GV* gv = gv_fetchpv(name, create, SVt_PVAV); if (create) @@ -1116,9 +1083,7 @@ I32 create; } HV* -perl_get_hv(name, create) -char* name; -I32 create; +perl_get_hv(char *name, I32 create) { GV* gv = gv_fetchpv(name, create, SVt_PVHV); if (create) @@ -1129,9 +1094,7 @@ I32 create; } CV* -perl_get_cv(name, create) -char* name; -I32 create; +perl_get_cv(char *name, I32 create) { GV* gv = gv_fetchpv(name, create, SVt_PVCV); if (create && !GvCVu(gv)) @@ -1147,15 +1110,14 @@ I32 create; /* Be sure to refetch the stack pointer after calling these routines. */ I32 -perl_call_argv(subname, flags, argv) -char *subname; -I32 flags; /* See G_* flags in cop.h */ -register char **argv; /* null terminated arg list */ +perl_call_argv(char *sub_name, I32 flags, register char **argv) + + /* See G_* flags in cop.h */ + /* null terminated arg list */ { - dTHR; dSP; - PUSHMARK(sp); + PUSHMARK(SP); if (argv) { while (*argv) { XPUSHs(sv_2mortal(newSVpv(*argv,0))); @@ -1163,23 +1125,22 @@ register char **argv; /* null terminated arg list */ } PUTBACK; } - return perl_call_pv(subname, flags); + return perl_call_pv(sub_name, flags); } I32 -perl_call_pv(subname, flags) -char *subname; /* name of the subroutine */ -I32 flags; /* See G_* flags in cop.h */ +perl_call_pv(char *sub_name, I32 flags) + /* name of the subroutine */ + /* See G_* flags in cop.h */ { - return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags); + return perl_call_sv((SV*)perl_get_cv(sub_name, TRUE), flags); } I32 -perl_call_method(methname, flags) -char *methname; /* name of the subroutine */ -I32 flags; /* See G_* flags in cop.h */ +perl_call_method(char *methname, I32 flags) + /* name of the subroutine */ + /* See G_* flags in cop.h */ { - dTHR; dSP; OP myop; if (!op) @@ -1192,13 +1153,12 @@ I32 flags; /* See G_* flags in cop.h */ /* May be called with any of a CV, a GV, or an SV containing the name. */ I32 -perl_call_sv(sv, flags) -SV* sv; -I32 flags; /* See G_* flags in cop.h */ +perl_call_sv(SV *sv, I32 flags) + + /* See G_* flags in cop.h */ { - dTHR; + dSP; LOGOP myop; /* fake syntax tree node */ - SV** sp = stack_sp; I32 oldmark; I32 retval; I32 oldscope; @@ -1241,7 +1201,7 @@ I32 flags; /* See G_* flags in cop.h */ markstack_ptr--; /* we're trying to emulate pp_entertry() here */ { - register CONTEXT *cx; + register PERL_CONTEXT *cx; I32 gimme = GIMME_V; ENTER; @@ -1309,7 +1269,7 @@ I32 flags; /* See G_* flags in cop.h */ SV **newsp; PMOP *newpm; I32 gimme; - register CONTEXT *cx; + register PERL_CONTEXT *cx; I32 optype; POPBLOCK(cx,newpm); @@ -1336,14 +1296,13 @@ I32 flags; /* See G_* flags in cop.h */ /* Eval a string. The G_EVAL flag is always assumed. */ I32 -perl_eval_sv(sv, flags) -SV* sv; -I32 flags; /* See G_* flags in cop.h */ +perl_eval_sv(SV *sv, I32 flags) + + /* See G_* flags in cop.h */ { - dTHR; + dSP; UNOP myop; /* fake syntax tree node */ - SV** sp = stack_sp; - I32 oldmark = sp - stack_base; + I32 oldmark = SP - stack_base; I32 retval; I32 oldscope; dJMPENV; @@ -1425,15 +1384,12 @@ I32 flags; /* See G_* flags in cop.h */ } SV* -perl_eval_pv(p, croak_on_error) -char* p; -I32 croak_on_error; +perl_eval_pv(char *p, I32 croak_on_error) { - dTHR; dSP; SV* sv = newSVpv(p, 0); - PUSHMARK(sp); + PUSHMARK(SP); perl_eval_sv(sv, G_SCALAR); SvREFCNT_dec(sv); @@ -1450,8 +1406,7 @@ I32 croak_on_error; /* Require a module. */ void -perl_require_pv(pv) -char* pv; +perl_require_pv(char *pv) { SV* sv = sv_newmortal(); sv_setpv(sv, "require '"); @@ -1461,10 +1416,7 @@ char* pv; } void -magicname(sym,name,namlen) -char *sym; -char *name; -I32 namlen; +magicname(char *sym, char *name, I32 namlen) { register GV *gv; @@ -1473,8 +1425,8 @@ I32 namlen; } static void -usage(name) /* XXX move this out into a module ? */ -char *name; +usage(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? */ @@ -1516,8 +1468,7 @@ NULL /* This routine handles any switches that can be given during run */ char * -moreswitches(s) -char *s; +moreswitches(char *s) { I32 numlen; U32 rschar; @@ -1586,7 +1537,7 @@ char *s; return s; case 'h': usage(origargv[0]); - exit(0); + PerlProc_exit(0); case 'i': if (inplace) Safefree(inplace); @@ -1710,16 +1661,17 @@ char *s; LOCAL_PATCH_COUNT, (LOCAL_PATCH_COUNT!=1) ? "es" : ""); #endif - printf("\n\nCopyright 1987-1997, Larry Wall\n"); + printf("\n\nCopyright 1987-1998, Larry Wall\n"); #ifdef MSDOS printf("\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n"); #endif #ifdef DJGPP printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n"); + printf("djgpp v2 port (perl5004+) by Laszlo Molnar, 1997-1998\n"); #endif #ifdef OS2 printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n" - "Version 5 port Copyright (c) 1994-1997, Andreas Kaiser, Ilya Zakharevich\n"); + "Version 5 port Copyright (c) 1994-1998, Andreas Kaiser, Ilya Zakharevich\n"); #endif #ifdef atarist printf("atariST series port, ++jrb bammi@cadence.com\n"); @@ -1727,7 +1679,7 @@ char *s; printf("\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.0 source kit.\n\n"); - exit(0); + PerlProc_exit(0); case 'w': dowarn = TRUE; s++; @@ -1739,6 +1691,9 @@ GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n") break; case '-': case 0: +#ifdef WIN32 + case '\r': +#endif case '\n': case '\t': break; @@ -1761,7 +1716,7 @@ GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n") /* unexec() can be found in the Gnu emacs distribution */ void -my_unexec() +my_unexec(void) { #ifdef UNEXEC SV* prog; @@ -1778,7 +1733,7 @@ my_unexec() if (status) PerlIO_printf(PerlIO_stderr(), "unexec of %s into %s failed!\n", SvPVX(prog), SvPVX(file)); - exit(status); + PerlProc_exit(status); #else # ifdef VMS # include @@ -1790,7 +1745,7 @@ my_unexec() } static void -init_main_stash() +init_main_stash(void) { dTHR; GV *gv; @@ -1821,20 +1776,13 @@ init_main_stash() curstash = defstash; compiling.cop_stash = defstash; debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV)); + globalstash = GvHV(gv_fetchpv("CORE::GLOBAL::", GV_ADDMULTI, SVt_PVHV)); /* We must init $/ before switches are processed. */ sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1); } -#ifdef CAN_PROTOTYPE static void open_script(char *scriptname, bool dosearch, SV *sv) -#else -static void -open_script(scriptname,dosearch,sv) -char *scriptname; -bool dosearch; -SV *sv; -#endif { dTHR; char *xfound = Nullch; @@ -1873,7 +1821,7 @@ SV *sv; * * Assuming SEARCH_EXTS is C<".foo",".bar",NULL>, PATH search * proceeds as follows: - * If DOSISH: + * If DOSISH or VMSISH: * + look for ./scriptname{,.foo,.bar} * + search the PATH for scriptname{,.foo,.bar} * @@ -1883,11 +1831,20 @@ SV *sv; */ #ifdef VMS +# ifdef ALWAYS_DEFTYPES + len = strlen(scriptname); + if (!(len == 1 && *scriptname == '-') && scriptname[len-1] != ':') { + int hasdir, idx = 0, deftypes = 1; + bool seen_dot = 1; + + hasdir = !dosearch || (strpbrk(scriptname,":[= 0) { + if (PerlLIO_stat(cur,&statbuf) >= 0) { dosearch = 0; scriptname = cur; #ifdef SEARCH_EXTS @@ -1943,7 +1900,7 @@ SV *sv; #ifdef DOSISH && !strchr(scriptname, '\\') #endif - && (s = getenv("PATH"))) { + && (s = PerlEnv_getenv("PATH"))) { bool seen_dot = 0; bufend = s + strlen(s); @@ -1987,7 +1944,7 @@ SV *sv; do { #endif DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tokenbuf)); - retval = Stat(tokenbuf,&statbuf); + retval = PerlLIO_stat(tokenbuf,&statbuf); #ifdef SEARCH_EXTS } while ( retval < 0 /* not there */ && extidx>=0 && ext[extidx] /* try an extension? */ @@ -2010,7 +1967,7 @@ SV *sv; xfailed = savepv(tokenbuf); } #ifndef DOSISH - if (!xfound && !seen_dot && !xfailed && (Stat(scriptname,&statbuf) < 0)) + if (!xfound && !seen_dot && !xfailed && (PerlLIO_stat(scriptname,&statbuf) < 0)) #endif seen_dot = 1; /* Disable message. */ if (!xfound) @@ -2039,7 +1996,7 @@ SV *sv; if (strEQ(origfilename,"-")) scriptname = ""; if (fdscript >= 0) { - rsfp = PerlIO_fdopen(fdscript,"r"); + rsfp = PerlIO_fdopen(fdscript,PERL_SCRIPT_MODE); #if defined(HAS_FCNTL) && defined(F_SETFD) if (rsfp) fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */ @@ -2114,7 +2071,7 @@ sed %s -e \"/^[^#]/b\" \ croak("Can't do seteuid!\n"); } #endif /* IAMSUID */ - rsfp = my_popen(SvPVX(cmd), "r"); + rsfp = PerlProc_popen(SvPVX(cmd), "r"); SvREFCNT_dec(cmd); SvREFCNT_dec(cpp); } @@ -2123,7 +2080,7 @@ sed %s -e \"/^[^#]/b\" \ rsfp = PerlIO_stdin(); } else { - rsfp = PerlIO_open(scriptname,"r"); + rsfp = PerlIO_open(scriptname,PERL_SCRIPT_MODE); #if defined(HAS_FCNTL) && defined(F_SETFD) if (rsfp) fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */ @@ -2135,10 +2092,10 @@ sed %s -e \"/^[^#]/b\" \ if (!rsfp) { #ifdef DOSUID #ifndef IAMSUID /* in case script is not readable before setuid */ - if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 && + if (euid && PerlLIO_stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) { /* try again */ - execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv); + PerlProc_execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv); croak("Can't do setuid\n"); } #endif @@ -2149,9 +2106,7 @@ sed %s -e \"/^[^#]/b\" \ } static void -validate_suid(validarg, scriptname) -char *validarg; -char *scriptname; +validate_suid(char *validarg, char *scriptname) { int which; @@ -2179,7 +2134,7 @@ char *scriptname; dTHR; char *s, *s2; - if (Fstat(PerlIO_fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */ + if (PerlLIO_fstat(PerlIO_fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */ croak("Can't stat script \"%s\"",origfilename); if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) { I32 len; @@ -2194,7 +2149,7 @@ char *scriptname; * But I don't think it's too important. The manual lies when * it says access() is useful in setuid programs. */ - if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/ + if (PerlLIO_access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/ croak("Permission denied"); #else /* If we can swap euid and uid, then we can determine access rights @@ -2215,12 +2170,12 @@ char *scriptname; #endif || getuid() != euid || geteuid() != uid) croak("Can't swap uid and euid"); /* really paranoid */ - if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0) + if (PerlLIO_stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0) croak("Permission denied"); /* testing full pathname here */ if (tmpstatbuf.st_dev != statbuf.st_dev || tmpstatbuf.st_ino != statbuf.st_ino) { (void)PerlIO_close(rsfp); - if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */ + if (rsfp = PerlProc_popen("/bin/mail root","w")) { /* heh, heh */ PerlIO_printf(rsfp, "User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\ (Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n", @@ -2228,7 +2183,7 @@ char *scriptname; (long)statbuf.st_dev, (long)statbuf.st_ino, SvPVX(GvSV(curcop->cop_filegv)), (long)statbuf.st_uid, (long)statbuf.st_gid); - (void)my_pclose(rsfp); + (void)PerlProc_pclose(rsfp); } croak("Permission denied\n"); } @@ -2287,7 +2242,7 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); (void)PerlIO_close(rsfp); #ifndef IAMSUID /* try again */ - execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv); + PerlProc_execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv); #endif croak("Can't do setuid\n"); } @@ -2360,7 +2315,7 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); /* exec the real perl, substituting fd script for scriptname. */ /* (We pass script name as "subdir" of fd, which perl will grok.) */ PerlIO_rewind(rsfp); - lseek(PerlIO_fileno(rsfp),(Off_t)0,0); /* just in case rewind didn't */ + PerlLIO_lseek(PerlIO_fileno(rsfp),(Off_t)0,0); /* just in case rewind didn't */ for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ; if (!origargv[which]) croak("Permission denied"); @@ -2369,14 +2324,14 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); #if defined(HAS_FCNTL) && defined(F_SETFD) fcntl(PerlIO_fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */ #endif - execv(form("%s/perl%s", BIN_EXP, patchlevel), origargv); /* try again */ + PerlProc_execv(form("%s/perl%s", BIN_EXP, patchlevel), origargv); /* try again */ croak("Can't do setuid\n"); #endif /* IAMSUID */ #else /* !DOSUID */ if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */ #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW dTHR; - Fstat(PerlIO_fileno(rsfp),&statbuf); /* may be either wrapped or real suid */ + PerlLIO_fstat(PerlIO_fileno(rsfp),&statbuf); /* may be either wrapped or real suid */ if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID) || (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID) @@ -2391,7 +2346,7 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); } static void -find_beginning() +find_beginning(void) { register char *s, *s2; @@ -2413,14 +2368,14 @@ find_beginning() /*SUPPRESS 530*/ while (s = moreswitches(s)) ; } - if (cddir && chdir(cddir) < 0) + if (cddir && PerlDir_chdir(cddir) < 0) croak("Can't chdir to %s",cddir); } } } static void -init_ids() +init_ids(void) { uid = (int)getuid(); euid = (int)geteuid(); @@ -2434,8 +2389,7 @@ init_ids() } static void -forbid_setid(s) -char *s; +forbid_setid(char *s) { if (euid != uid) croak("No %s allowed while running setuid", s); @@ -2444,7 +2398,7 @@ char *s; } static void -init_debugger() +init_debugger(void) { dTHR; curstash = debstash; @@ -2462,27 +2416,30 @@ init_debugger() curstash = defstash; } +#ifndef STRESS_REALLOC +#define REASONABLE(size) (size) +#else +#define REASONABLE(size) (1) /* unreasonable */ +#endif + void -init_stacks(ARGS) -dARGS +init_stacks(ARGSproto) { - curstack = newAV(); + /* start with 128-item stack and 8K cxstack */ + curstackinfo = new_stackinfo(REASONABLE(128), + REASONABLE(8192/sizeof(PERL_CONTEXT) - 1)); + curstackinfo->si_type = SI_MAIN; + curstack = curstackinfo->si_stack; mainstack = curstack; /* remember in case we switch stacks */ - AvREAL_off(curstack); /* not a real array */ - av_extend(curstack,127); stack_base = AvARRAY(curstack); stack_sp = stack_base; - stack_max = stack_base + 127; + stack_max = stack_base + AvMAX(curstack); - cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */ - New(50,cxstack,cxstack_max + 1,CONTEXT); - cxstack_ix = -1; - - New(50,tmps_stack,128,SV*); + New(50,tmps_stack,REASONABLE(128),SV*); tmps_floor = -1; tmps_ix = -1; - tmps_max = 128; + tmps_max = REASONABLE(128); /* * The following stacks almost certainly should be per-interpreter, @@ -2492,41 +2449,53 @@ dARGS if (markstack) { markstack_ptr = markstack; } else { - New(54,markstack,64,I32); + New(54,markstack,REASONABLE(32),I32); markstack_ptr = markstack; - markstack_max = markstack + 64; + markstack_max = markstack + REASONABLE(32); } + SET_MARKBASE; + if (scopestack) { scopestack_ix = 0; } else { - New(54,scopestack,32,I32); + New(54,scopestack,REASONABLE(32),I32); scopestack_ix = 0; - scopestack_max = 32; + scopestack_max = REASONABLE(32); } if (savestack) { savestack_ix = 0; } else { - New(54,savestack,128,ANY); + New(54,savestack,REASONABLE(128),ANY); savestack_ix = 0; - savestack_max = 128; + savestack_max = REASONABLE(128); } if (retstack) { retstack_ix = 0; } else { - New(54,retstack,16,OP*); + New(54,retstack,REASONABLE(16),OP*); retstack_ix = 0; - retstack_max = 16; + retstack_max = REASONABLE(16); } } +#undef REASONABLE + static void -nuke_stacks() +nuke_stacks(void) { dTHR; - Safefree(cxstack); + while (curstackinfo->si_next) + curstackinfo = curstackinfo->si_next; + while (curstackinfo) { + PERL_SI *p = curstackinfo->si_prev; + SvREFCNT_dec(curstackinfo->si_stack); + Safefree(curstackinfo->si_cxstack); + Safefree(curstackinfo); + curstackinfo = p; + } Safefree(tmps_stack); DEBUG( { Safefree(debname); @@ -2537,7 +2506,7 @@ nuke_stacks() static PerlIO *tmpfp; /* moved outside init_lexer() because of UNICOS bug */ static void -init_lexer() +init_lexer(void) { tmpfp = rsfp; rsfp = Nullfp; @@ -2547,18 +2516,13 @@ init_lexer() } static void -init_predump_symbols() +init_predump_symbols(void) { dTHR; GV *tmpgv; GV *othergv; -#ifdef USE_THREADS - sv_setpvn(*av_fetch(thr->magicals,find_thread_magical("\""),FALSE)," ", 1); -#else - sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1); -#endif /* USE_THREADS */ - + sv_setpvn(perl_get_sv("\"", TRUE), " ", 1); stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO); GvMULTI_on(stdingv); IoIFP(GvIOp(stdingv)) = PerlIO_stdin(); @@ -2588,10 +2552,7 @@ init_predump_symbols() } static void -init_postdump_symbols(argc,argv,env) -register int argc; -register char **argv; -register char **env; +init_postdump_symbols(register int argc, register char **argv, register char **env) { dTHR; char *s; @@ -2657,7 +2618,7 @@ register char **env; if (!(s = strchr(*env,'='))) continue; *s++ = '\0'; -#ifdef WIN32 +#if defined(WIN32) || defined(MSDOS) (void)strupr(*env); #endif sv = newSVpv(s--,0); @@ -2665,7 +2626,7 @@ register char **env; *s = '='; #if defined(__BORLANDC__) && defined(USE_WIN32_RTL_ENV) /* Sins of the RTL. See note in my_setenv(). */ - (void)putenv(savepv(*env)); + (void)PerlEnv_putenv(savepv(*env)); #endif } #endif @@ -2679,16 +2640,16 @@ register char **env; } static void -init_perllib() +init_perllib(void) { char *s; if (!tainting) { #ifndef VMS - s = getenv("PERL5LIB"); + s = PerlEnv_getenv("PERL5LIB"); if (s) incpush(s, TRUE); else - incpush(getenv("PERLLIB"), FALSE); + incpush(PerlEnv_getenv("PERLLIB"), 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 @@ -2704,7 +2665,7 @@ init_perllib() } /* Use the ~-expanded versions of APPLLIB (undocumented), - ARCHLIB PRIVLIB SITEARCH SITELIB and OLDARCHLIB + ARCHLIB PRIVLIB SITEARCH and SITELIB */ #ifdef APPLLIB_EXP incpush(APPLLIB_EXP, FALSE); @@ -2724,10 +2685,6 @@ init_perllib() #ifdef SITELIB_EXP incpush(SITELIB_EXP, FALSE); #endif -#ifdef OLDARCHLIB_EXP /* 5.00[01] compatibility */ - incpush(OLDARCHLIB_EXP, FALSE); -#endif - if (!tainting) incpush(".", FALSE); } @@ -2746,9 +2703,7 @@ init_perllib() #endif static void -incpush(p, addsubdirs) -char *p; -int addsubdirs; +incpush(char *p, int addsubdirs) { SV *subdir = Nullsv; static char *archpat_auto; @@ -2757,7 +2712,7 @@ int addsubdirs; return; if (addsubdirs) { - subdir = newSV(0); + subdir = NEWSV(55,0); if (!archpat_auto) { STRLEN len = (sizeof(ARCHNAME) + strlen(patchlevel) + sizeof("//auto")); @@ -2773,7 +2728,7 @@ int addsubdirs; /* Break at all separators */ while (p && *p) { - SV *libdir = newSV(0); + SV *libdir = NEWSV(55,0); char *s; /* skip any consecutive separators */ @@ -2816,7 +2771,7 @@ int addsubdirs; /* .../archname/version if -d .../archname/version/auto */ sv_setsv(subdir, libdir); sv_catpv(subdir, archpat_auto); - if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 && + if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode)) av_push(GvAVn(incgv), newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto")); @@ -2824,7 +2779,7 @@ int addsubdirs; /* .../archname if -d .../archname/auto */ sv_insert(subdir, SvCUR(libdir) + sizeof(ARCHNAME), strlen(patchlevel) + 1, "", 0); - if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 && + if (PerlLIO_stat(SvPVX(subdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode)) av_push(GvAVn(incgv), newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto")); @@ -2838,16 +2793,17 @@ int addsubdirs; } #ifdef USE_THREADS -static struct thread * +static struct perl_thread * init_main_thread() { - struct thread *thr; + struct perl_thread *thr; XPV *xpv; - Newz(53, thr, 1, struct thread); + Newz(53, thr, 1, struct perl_thread); curcop = &compiling; thr->cvcache = newHV(); - thr->magicals = newAV(); + thr->threadsv = newAV(); + /* thr->threadsvp is set when find_threadsv is called */ thr->specific = newAV(); thr->errhv = newHV(); thr->flags = THRf_R_JOINABLE; @@ -2875,9 +2831,13 @@ init_main_thread() #ifdef HAVE_THREAD_INTERN init_thread_intern(thr); +#endif + +#ifdef SET_THREAD_SELF + SET_THREAD_SELF(thr); #else thr->self = pthread_self(); -#endif /* HAVE_THREAD_INTERN */ +#endif /* SET_THREAD_SELF */ SET_THR(thr); /* @@ -2892,14 +2852,13 @@ init_main_thread() sv_setpvn(bodytarget, "", 0); formtarget = bodytarget; thr->errsv = newSVpv("", 0); + (void) find_threadsv("@"); /* Ensure $@ is initialised early */ return thr; } #endif /* USE_THREADS */ void -call_list(oldscope, list) -I32 oldscope; -AV* list; +call_list(I32 oldscope, AV *list) { dTHR; line_t oldline = curcop->cop_line; @@ -2907,7 +2866,7 @@ AV* list; dJMPENV; int ret; - while (AvFILL(list) >= 0) { + while (AvFILL(list) >= 0) { CV *cv = (CV*)av_shift(list); SAVEFREESV(cv); @@ -2971,8 +2930,7 @@ AV* list; } void -my_exit(status) -U32 status; +my_exit(U32 status) { dTHR; @@ -2995,7 +2953,7 @@ U32 status; } void -my_failure_exit() +my_failure_exit(void) { #ifdef VMS if (vaxc$errno & 1) { @@ -3018,10 +2976,10 @@ my_failure_exit() } static void -my_exit_jump() +my_exit_jump(void) { dTHR; - register CONTEXT *cx; + register PERL_CONTEXT *cx; I32 gimme; SV **newsp; @@ -3044,3 +3002,6 @@ my_exit_jump() JMPENV_JUMP(2); } + + +