/* util.c
*
- * Copyright (c) 1991-1999, Larry Wall
+ * Copyright (c) 1991-2000, 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.
# define vfork fork
#endif
-#ifdef I_FCNTL
-# include <fcntl.h>
-#endif
-#ifdef I_SYS_FILE
-# include <sys/file.h>
-#endif
-
#ifdef I_SYS_WAIT
# include <sys/wait.h>
#endif
{
dTHX;
Malloc_t ptr;
-#if !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE)
+#if !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) && !defined(PERL_MICRO)
Malloc_t PerlMem_realloc();
#endif /* !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) */
Free_t
Perl_safesysfree(Malloc_t where)
{
+#ifdef PERL_IMPLICIT_SYS
dTHX;
+#endif
DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) free\n",PTR2UV(where),(long)PL_an++));
if (where) {
/*SUPPRESS 701*/
if (setlocale_failure) {
char *p;
bool locwarn = (printwarn > 1 ||
- printwarn &&
- (!(p = PerlEnv_getenv("PERL_BADLANG")) || atoi(p)));
+ (printwarn &&
+ (!(p = PerlEnv_getenv("PERL_BADLANG")) || atoi(p))));
if (locwarn) {
#ifdef LC_ALL
If FBMcf_TAIL, the table is created as if the string has a trailing \n. */
+/*
+=for apidoc fbm_compile
+
+Analyses the string in order to make fast searches on it using fbm_instr()
+-- the Boyer-Moore algorithm.
+
+=cut
+*/
+
void
Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
{
/* If SvTAIL is actually due to \Z or \z, this gives false positives
if multiline */
+/*
+=for apidoc fbm_instr
+
+Returns the location of the SV in the string delimited by C<str> and
+C<strend>. It returns C<Nullch> if the string can't be found. The C<sv>
+does not have to be fbm_compiled, but the search will not be as fast
+then.
+
+=cut
+*/
+
char *
Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *littlestr, U32 flags)
{
register I32 multiline = flags & FBMrf_MULTILINE;
if (bigend - big < littlelen) {
- check_tail:
if ( SvTAIL(littlestr)
&& (bigend - big == littlelen - 1)
&& (littlelen == 1
- || *big == *little && memEQ(big, little, littlelen - 1)))
+ || (*big == *little && memEQ(big, little, littlelen - 1))))
return (char*)big;
return Nullch;
}
if (littlelen <= 2) { /* Special-cased */
- register char c;
if (littlelen == 1) {
if (SvTAIL(littlestr) && !multiline) { /* Anchor only! */
while (tmp--) {
if (*--s == *--little)
continue;
- differ:
s = olds + 1; /* here we pay the price for failure */
little = oldlittle;
if (s < bigend) /* fake up continue to outer loop */
/* copy a string to a safe spot */
+/*
+=for apidoc savepv
+
+Copy a string to a safe spot. This does not use an SV.
+
+=cut
+*/
+
char *
Perl_savepv(pTHX_ const char *sv)
{
/* same thing but with a known length */
+/*
+=for apidoc savepvn
+
+Copy a string to a safe spot. The C<len> indicates number of bytes to
+copy. This does not use an SV.
+
+=cut
+*/
+
char *
Perl_savepvn(pTHX_ const char *sv, register I32 len)
{
sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') {
dTHR;
- if (PL_curcop->cop_line)
- Perl_sv_catpvf(aTHX_ sv, " at %_ line %"IVdf,
- CopFILESV(PL_curcop), (IV)PL_curcop->cop_line);
+ if (CopLINE(PL_curcop))
+ Perl_sv_catpvf(aTHX_ sv, " at %s line %"IVdf,
+ CopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
if (GvIO(PL_last_in_gv) && IoLINES(GvIOp(PL_last_in_gv))) {
bool line_mode = (RsSIMPLE(PL_rs) &&
SvCUR(PL_rs) == 1 && *SvPVX(PL_rs) == '\n');
}
else {
message = Nullch;
+ msglen = 0;
}
DEBUG_S(PerlIO_printf(Perl_debug_log,
}
#endif /* PERL_IMPLICIT_CONTEXT */
+/*
+=for apidoc croak
+
+This is the XSUB-writer's interface to Perl's C<die> function. Use this
+function the same way you use the C C<printf> function. See
+C<warn>.
+
+=cut
+*/
+
void
Perl_croak(pTHX_ const char *pat, ...)
{
}
#endif /* PERL_IMPLICIT_CONTEXT */
+/*
+=for apidoc warn
+
+This is the XSUB-writer's interface to Perl's C<warn> function. Use this
+function the same way you use the C C<printf> function. See
+C<croak>.
+
+=cut
+*/
+
void
Perl_warn(pTHX_ const char *pat, ...)
{
}
#ifndef VMS /* VMS' my_setenv() is in VMS.c */
-#if !defined(WIN32) && !defined(CYGWIN)
+#if !defined(WIN32) && !defined(__CYGWIN__)
void
Perl_my_setenv(pTHX_ char *nam, char *val)
{
#endif /* PERL_USE_SAFE_PUTENV */
}
-#else /* WIN32 || CYGWIN */
-#if defined(CYGWIN)
+#else /* WIN32 || __CYGWIN__ */
+#if defined(__CYGWIN__)
/*
* Save environ of perl.exe, currently Cygwin links in separate environ's
* for each exe/dll. Probably should be a member of impure_ptr.
}
void
-my_setenv(char *nam, char *val)
+Perl_my_setenv(pTHX_ char *nam, char *val)
{
/* You can not directly manipulate the environ[] array because
* the routines do some additional work that syncs the Cygwin
if (!oldstr)
return;
unsetenv(nam);
- Safefree(oldstr);
+ safesysfree(oldstr);
return;
}
setenv(nam, val, 1);
environ = *Perl_main_environ; /* environ realloc can occur in setenv */
if(oldstr && environ[setenv_getix(nam)] != oldstr)
- Safefree(oldstr);
+ safesysfree(oldstr);
}
#else /* if WIN32 */
}
#endif
+/* this is a drop-in replacement for bcopy() */
#if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY)
char *
-Perl_my_bcopy(pTHX_ register const char *from,register char *to,register I32 len)
+Perl_my_bcopy(register const char *from,register char *to,register I32 len)
{
char *retval = to;
}
#endif
+/* this is a drop-in replacement for memset() */
#ifndef HAS_MEMSET
void *
-Perl_my_memset(pTHX_ register char *loc, register I32 ch, register I32 len)
+Perl_my_memset(register char *loc, register I32 ch, register I32 len)
{
char *retval = loc;
}
#endif
+/* this is a drop-in replacement for bzero() */
#if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
char *
-Perl_my_bzero(pTHX_ register char *loc, register I32 len)
+Perl_my_bzero(register char *loc, register I32 len)
{
char *retval = loc;
}
#endif
+/* this is a drop-in replacement for memcmp() */
#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
I32
-Perl_my_memcmp(pTHX_ const char *s1, const char *s2, register I32 len)
+Perl_my_memcmp(const char *s1, const char *s2, register I32 len)
{
register U8 *a = (U8 *)s1;
register U8 *b = (U8 *)s2;
}
#endif /* defined OS2 */
/*SUPPRESS 560*/
- if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
- sv_setiv(GvSV(tmpgv), getpid());
+ if ((tmpgv = gv_fetchpv("$",TRUE, SVt_PV)))
+ sv_setiv(GvSV(tmpgv), PerlProc_getpid());
PL_forkprocess = 0;
hv_clear(PL_pidstatus); /* we have no children */
return Nullfp;
oldsig = PerlProc_signal(signo, sig_trap);
PerlProc_signal(signo, oldsig);
if (sig_trapped)
- PerlProc_kill(getpid(), signo);
+ PerlProc_kill(PerlProc_getpid(), signo);
return oldsig;
}
HE *entry;
hv_iterinit(PL_pidstatus);
- if (entry = hv_iternext(PL_pidstatus)) {
+ if ((entry = hv_iternext(PL_pidstatus))) {
pid = atoi(hv_iterkey(entry,(I32*)statusp));
sv = hv_iterval(PL_pidstatus,entry);
*statusp = SvIVX(sv);
continue;
if (S_ISREG(PL_statbuf.st_mode)
&& cando(S_IRUSR,TRUE,&PL_statbuf)
-#if !defined(DOSISH) && !defined(MACOS_TRDITIONAL)
+#if !defined(DOSISH) && !defined(MACOS_TRADITIONAL)
&& cando(S_IXUSR,TRUE,&PL_statbuf)
#endif
)
return (scriptname ? savepv(scriptname) : Nullch);
}
+#ifndef PERL_GET_CONTEXT_DEFINED
+
+void *
+Perl_get_context(void)
+{
+#if defined(USE_THREADS) || defined(USE_ITHREADS)
+# ifdef OLD_PTHREADS_API
+ pthread_addr_t t;
+ if (pthread_getspecific(PL_thr_key, &t))
+ Perl_croak_nocontext("panic: pthread_getspecific");
+ return (void*)t;
+# else
+# ifdef I_MACH_CTHREADS
+ return (void*)cthread_data(cthread_self());
+# else
+ return (void*)pthread_getspecific(PL_thr_key);
+# endif
+# endif
+#else
+ return (void*)NULL;
+#endif
+}
+
+void
+Perl_set_context(void *t)
+{
+#if defined(USE_THREADS) || defined(USE_ITHREADS)
+# ifdef I_MACH_CTHREADS
+ cthread_set_data(cthread_self(), t);
+# else
+ if (pthread_setspecific(PL_thr_key, t))
+ Perl_croak_nocontext("panic: pthread_setspecific");
+# endif
+#endif
+}
+
+#endif /* !PERL_GET_CONTEXT_DEFINED */
#ifdef USE_THREADS
+
#ifdef FAKE_THREADS
/* Very simplistic scheduler for now */
void
}
#endif /* FAKE_THREADS */
-#ifdef PTHREAD_GETSPECIFIC_INT
-struct perl_thread *
-Perl_getTHR(pTHX)
-{
- pthread_addr_t t;
-
- if (pthread_getspecific(PL_thr_key, &t))
- Perl_croak(aTHX_ "panic: pthread_getspecific");
- return (struct perl_thread *) t;
-}
-#endif
-
MAGIC *
Perl_condpair_magic(pTHX_ SV *sv)
{
COND_INIT(&cp->owner_cond);
COND_INIT(&cp->cond);
cp->owner = 0;
- MUTEX_LOCK(&PL_cred_mutex); /* XXX need separate mutex? */
+ LOCK_CRED_MUTEX; /* XXX need separate mutex? */
mg = mg_find(sv, 'm');
if (mg) {
/* someone else beat us to initialising it */
- MUTEX_UNLOCK(&PL_cred_mutex); /* XXX need separate mutex? */
+ UNLOCK_CRED_MUTEX; /* XXX need separate mutex? */
MUTEX_DESTROY(&cp->mutex);
COND_DESTROY(&cp->owner_cond);
COND_DESTROY(&cp->cond);
mg = SvMAGIC(sv);
mg->mg_ptr = (char *)cp;
mg->mg_len = sizeof(cp);
- MUTEX_UNLOCK(&PL_cred_mutex); /* XXX need separate mutex? */
+ UNLOCK_CRED_MUTEX; /* XXX need separate mutex? */
DEBUG_S(WITH_THR(PerlIO_printf(Perl_debug_log,
"%p: condpair_magic %p\n", thr, sv));)
}
Zero(thr, 1, struct perl_thread);
#endif
- PL_protect = MEMBER_TO_FPTR(Perl_default_protect);
-
thr->oursv = sv;
init_stacks();
thr->flags = THRf_R_JOINABLE;
MUTEX_INIT(&thr->mutex);
- /* top_env needs to be non-zero. It points to an area
- in which longjmp() stuff is stored, as C callstack
- info there at least is thread specific this has to
- be per-thread. Otherwise a 'die' in a thread gives
- that thread the C stack of last thread to do an eval {}!
- See comments in scope.h
- Initialize top entry (as in perl.c for main thread)
- */
- PL_start_env.je_prev = NULL;
- PL_start_env.je_ret = -1;
- PL_start_env.je_mustcatch = TRUE;
- PL_top_env = &PL_start_env;
+ JMPENV_BOOTSTRAP;
PL_in_eval = EVAL_NULL; /* ~(EVAL_INEVAL|EVAL_WARNONLY|EVAL_KEEPERR) */
PL_restartop = 0;
/* parent thread's data needs to be locked while we make copy */
MUTEX_LOCK(&t->mutex);
+#ifdef PERL_FLEXIBLE_EXCEPTIONS
PL_protect = t->Tprotect;
+#endif
PL_curcop = t->Tcurcop; /* XXX As good a guess as any? */
PL_defstash = t->Tdefstash; /* XXX maybe these should */
PL_ofs = savepvn(t->Tofs, PL_ofslen);
PL_defoutgv = (GV*)SvREFCNT_inc(t->Tdefoutgv);
PL_chopset = t->Tchopset;
- PL_formtarget = newSVsv(t->Tformtarget);
PL_bodytarget = newSVsv(t->Tbodytarget);
PL_toptarget = newSVsv(t->Ttoptarget);
+ if (t->Tformtarget == t->Ttoptarget)
+ PL_formtarget = PL_toptarget;
+ else
+ PL_formtarget = PL_bodytarget;
/* Initialise all per-thread SVs that the template thread used */
svp = AvARRAY(t->threadsv);
av_store(thr->threadsv, i, sv);
sv_magic(sv, 0, 0, &PL_threadsv_names[i], 1);
DEBUG_S(PerlIO_printf(Perl_debug_log,
- "new_struct_thread: copied threadsv %d %p->%p\n",i, t, thr));
+ "new_struct_thread: copied threadsv %"IVdf" %p->%p\n",
+ (IV)i, t, thr));
}
}
thr->threadsvp = AvARRAY(thr->threadsv);
}
NV
-Perl_my_atof(pTHX_ const char* s) {
+Perl_my_atof(pTHX_ const char* s)
+{
#ifdef USE_LOCALE_NUMERIC
if ((PL_hints & HINT_LOCALE) && PL_numeric_local) {
NV x, y;
return Perl_atof(s);
#endif
}
+
+void
+Perl_report_closed_fh(pTHX_ GV *gv, IO *io, const char *func, const char *obj)
+{
+ SV *sv;
+ char *name;
+
+ assert(gv);
+
+ sv = sv_newmortal();
+ gv_efullname3(sv, gv, Nullch);
+ name = SvPVX(sv);
+
+ Perl_warner(aTHX_ WARN_CLOSED, "%s() on closed %s %s", func, obj, name);
+
+ if (io && IoDIRP(io))
+ Perl_warner(aTHX_ WARN_CLOSED,
+ "(Are you trying to call %s() on dirhandle %s?)\n",
+ func, name);
+}