#define errgv (curinterp->Ierrgv)
#define eval_root (curinterp->Ieval_root)
#define eval_start (curinterp->Ieval_start)
+#define exitlist (curinterp->Iexitlist)
+#define exitlistlen (curinterp->Iexitlistlen)
#define fdpid (curinterp->Ifdpid)
#define filemode (curinterp->Ifilemode)
#define firstgv (curinterp->Ifirstgv)
#define incgv (curinterp->Iincgv)
#define initav (curinterp->Iinitav)
#define inplace (curinterp->Iinplace)
+#define intern (curinterp->Iintern)
#define lastfd (curinterp->Ilastfd)
#define lastscream (curinterp->Ilastscream)
#define lastsize (curinterp->Ilastsize)
#define minus_l (curinterp->Iminus_l)
#define minus_n (curinterp->Iminus_n)
#define minus_p (curinterp->Iminus_p)
+#define modglobal (curinterp->Imodglobal)
#define multiline (curinterp->Imultiline)
#define mystrk (curinterp->Imystrk)
#define ofmt (curinterp->Iofmt)
#define Ierrgv errgv
#define Ieval_root eval_root
#define Ieval_start eval_start
+#define Iexitlist exitlist
+#define Iexitlistlen exitlistlen
#define Ifdpid fdpid
#define Ifilemode filemode
#define Ifirstgv firstgv
#define Iincgv incgv
#define Iinitav initav
#define Iinplace inplace
+#define Iintern intern
#define Ilastfd lastfd
#define Ilastscream lastscream
#define Ilastsize lastsize
#define Iminus_l minus_l
#define Iminus_n minus_n
#define Iminus_p minus_p
+#define Imodglobal modglobal
#define Imultiline multiline
#define Imystrk mystrk
#define Iofmt ofmt
#define errgv Perl_errgv
#define eval_root Perl_eval_root
#define eval_start Perl_eval_start
+#define exitlist Perl_exitlist
+#define exitlistlen Perl_exitlistlen
#define fdpid Perl_fdpid
#define filemode Perl_filemode
#define firstgv Perl_firstgv
#define incgv Perl_incgv
#define initav Perl_initav
#define inplace Perl_inplace
+#define intern Perl_intern
#define lastfd Perl_lastfd
#define lastscream Perl_lastscream
#define lastsize Perl_lastsize
#define minus_l Perl_minus_l
#define minus_n Perl_minus_n
#define minus_p Perl_minus_p
+#define modglobal Perl_modglobal
#define multiline Perl_multiline
#define mystrk Perl_mystrk
#define ofmt Perl_ofmt
errgv
eval_root
eval_start
+exitlist
+exitlistlen
fdpid
filemode
firstgv
incgv
initav
inplace
+intern
last_in_gv
lastfd
lastscream
minus_l
minus_n
minus_p
+modglobal
multiline
mystrk
nrs
PERLVAR(Iorslen, STRLEN)
PERLVAR(Iofmt, char *) /* $# */
+/* interpreter atexit processing */
+PERLVARI(Iexitlist, PerlExitListEntry *, NULL) /* list of exit functions */
+PERLVARI(Iexitlistlen, I32, 0) /* length of same */
+PERLVAR(Imodglobal, HV *) /* per-interp module data */
+
+#ifdef HAVE_INTERP_INTERN
+PERLVAR(Iintern, struct interp_intern) /* platform internals */
+#endif
+
#ifdef USE_THREADS
PERLVAR(Ithrsv, SV *) /* holds struct perl_thread for main thread */
PERLVARI(Ithreadnum, U32, 0) /* incremented each thread creation */
localpatches = local_patches; /* For possible -v */
#endif
- PerlIO_init(); /* Hook to IO system */
+ PerlIO_init(); /* Hook to IO system */
- fdpid = newAV(); /* for remembering popen pids by fd */
+ fdpid = newAV(); /* for remembering popen pids by fd */
+ modglobal = newHV(); /* pointers to per-interpreter module globals */
DEBUG( {
New(51,debname,128,char);
SvREFCNT_dec(parsehook);
parsehook = Nullsv;
+ /* call exit list functions */
+ while (exitlistlen-- > 0)
+ exitlist[exitlistlen].fn(exitlist[exitlistlen].ptr);
+
+ Safefree(exitlist);
+
if (destruct_level == 0){
DEBUG_P(debprofdump());
Safefree(sv_interp);
}
+void
+perl_atexit(void (*fn) (void *), void *ptr)
+{
+ Renew(exitlist, exitlistlen+1, PerlExitListEntry);
+ exitlist[exitlistlen].fn = fn;
+ exitlist[exitlistlen].ptr = ptr;
+ ++exitlistlen;
+}
+
int
perl_parse(PerlInterpreter *sv_interp, void (*xsinit) (void), int argc, char **argv, char **env)
{
#define PERLVARI(var,type,init) type var;
#define PERLVARIC(var,type,init) type var;
+/* Interpreter exitlist entry */
+typedef struct exitlistentry {
+ void (*fn) _((void*));
+ void *ptr;
+} PerlExitListEntry;
+
#ifdef PERL_GLOBAL_STRUCT
struct perl_vars {
#include "perlvars.h"
void pad_swipe _((PADOFFSET po));
void peep _((OP* o));
PerlInterpreter* perl_alloc _((void));
+void perl_atexit _((void(*fn)(void *), void*));
I32 perl_call_argv _((char* subname, I32 flags, char** argv));
I32 perl_call_method _((char* methname, I32 flags));
I32 perl_call_pv _((char* subname, I32 flags));
perl_init_i18nl10n
perl_init_ext
perl_alloc
+perl_atexit
perl_construct
perl_destruct
perl_free
static long filetime_to_clock(PFILETIME ft);
static BOOL filetime_from_time(PFILETIME ft, time_t t);
-char * w32_perlshell_tokens = Nullch;
-char ** w32_perlshell_vec;
-long w32_perlshell_items = -1;
-DWORD w32_platform = (DWORD)-1;
-char w32_perllib_root[MAX_PATH+1];
HANDLE w32_perldll_handle = INVALID_HANDLE_VALUE;
-#ifndef __BORLANDC__
-long w32_num_children = 0;
-HANDLE w32_child_pids[MAXIMUM_WAIT_OBJECTS];
-#endif
+static DWORD w32_platform = (DWORD)-1;
#ifdef USE_THREADS
# ifdef USE_DECLSPEC_THREAD
__declspec(thread) char strerror_buffer[512];
__declspec(thread) char getlogin_buffer[128];
+__declspec(thread) char w32_perllib_root[MAX_PATH+1];
# ifdef HAVE_DES_FCRYPT
__declspec(thread) char crypt_buffer[30];
# endif
# else
# define strerror_buffer (thr->i.Wstrerror_buffer)
# define getlogin_buffer (thr->i.Wgetlogin_buffer)
+# define w32_perllib_root (thr->i.Ww32_perllib_root)
# define crypt_buffer (thr->i.Wcrypt_buffer)
# endif
#else
-char strerror_buffer[512];
-char getlogin_buffer[128];
+static char strerror_buffer[512];
+static char getlogin_buffer[128];
+static char w32_perllib_root[MAX_PATH+1];
# ifdef HAVE_DES_FCRYPT
-char crypt_buffer[30];
+static char crypt_buffer[30];
# endif
#endif
char *
win32_perllib_path(char *sfx,...)
{
+ dTHR;
va_list ap;
char *end;
+
va_start(ap,sfx);
GetModuleFileName((w32_perldll_handle == INVALID_HANDLE_VALUE)
? GetModuleHandle(NULL)
DllExport int
win32_wait(int *status)
{
-#ifdef __BORLANDC__
+#ifdef USE_RTL_WAIT
return wait(status);
#else
/* XXX this wait emulation only knows about processes
DllExport FILE*
win32_popen(const char *command, const char *mode)
{
-#ifdef USE_CRT_POPEN
+#ifdef USE_RTL_POPEN
return _popen(command, mode);
#else
int p[2];
/* close saved handle */
win32_close(oldfd);
- sv_setiv(*av_fetch(fdpid, p[parent], TRUE), childpid);
+
+ sv_setiv(*av_fetch(w32_fdpid, p[parent], TRUE), childpid);
/* we have an fd, return a file stream */
return (win32_fdopen(p[parent], (char *)mode));
}
return (NULL);
-#endif /* USE_CRT_POPEN */
+#endif /* USE_RTL_POPEN */
}
/*
DllExport int
win32_pclose(FILE *pf)
{
-#ifdef USE_CRT_POPEN
+#ifdef USE_RTL_POPEN
return _pclose(pf);
#else
-#ifndef __BORLANDC__
+#ifndef USE_RTL_WAIT
int child;
#endif
int childpid, status;
SV *sv;
- sv = *av_fetch(fdpid, win32_fileno(pf), TRUE);
+ sv = *av_fetch(w32_fdpid, win32_fileno(pf), TRUE);
if (SvIOK(sv))
childpid = SvIVX(sv);
else
win32_fclose(pf);
SvIVX(sv) = 0;
-#ifndef __BORLANDC__
+#ifndef USE_RTL_WAIT
for (child = 0 ; child < w32_num_children ; ++child) {
if (w32_child_pids[child] == (HANDLE)childpid) {
Copy(&w32_child_pids[child+1], &w32_child_pids[child],
return (status);
#endif
-#endif /* USE_CRT_OPEN */
+#endif /* USE_RTL_POPEN */
}
DllExport int
{
int status;
-#ifndef __BORLANDC__
+#ifndef USE_RTL_WAIT
if (mode == P_NOWAIT && w32_num_children >= MAXIMUM_WAIT_OBJECTS)
return -1;
#endif
status = spawnvp(mode, cmdname, (char * const *) argv);
-#ifndef __BORLANDC__
+#ifndef USE_RTL_WAIT
/* XXX For the P_NOWAIT case, Borland RTL returns pinfo.dwProcessId
* while VC RTL returns pinfo.hProcess. For purposes of the custom
* implementation of win32_wait(), we assume the latter.
char *file = __FILE__;
dXSUB_SYS;
+ w32_perlshell_tokens = Nullch;
+ w32_perlshell_items = -1;
+ w32_fdpid = newAV(); /* XXX needs to be in Perl_win32_init()? */
+#ifndef USE_RTL_WAIT
+ w32_num_children = 0;
+#endif
+
/* these names are Activeware compatible */
newXS("Win32::GetCwd", w32_GetCwd, file);
newXS("Win32::SetCwd", w32_SetCwd, file);
#if !defined(_ALPHA_) && !defined(__GNUC__)
_control87(MCW_EM, MCW_EM);
#endif
- MALLOC_INIT;
+ MALLOC_INIT;
}
#ifdef USE_BINMODE_SCRIPTS
#pragma warn -csu /* "comparing signed and unsigned values" */
#pragma warn -pro /* "call to function with no prototype" */
+#define USE_RTL_WAIT /* Borland has a working wait() */
+
#endif
#ifdef _MSC_VER /* Microsoft Visual C++ */
#define win32_strip_return(sv) NOOP
#endif
+#define HAVE_INTERP_INTERN
+struct interp_intern {
+ char * w32_perlshell_tokens;
+ char ** w32_perlshell_vec;
+ long w32_perlshell_items;
+ struct av * w32_fdpid;
+#ifndef USE_RTL_WAIT
+ long w32_num_children;
+ HANDLE w32_child_pids[MAXIMUM_WAIT_OBJECTS];
+#endif
+};
+
+#define w32_perlshell_tokens (intern.w32_perlshell_tokens)
+#define w32_perlshell_vec (intern.w32_perlshell_vec)
+#define w32_perlshell_items (intern.w32_perlshell_items)
+#define w32_fdpid (intern.w32_fdpid)
+
+#ifndef USE_RTL_WAIT
+# define w32_num_children (intern.w32_num_children)
+# define w32_child_pids (intern.w32_child_pids)
+#endif
+
/*
* Now Win32 specific per-thread data stuff
*/
char Wstrerror_buffer[512];
struct servent Wservent;
char Wgetlogin_buffer[128];
+ char Ww32_perllib_root[MAX_PATH+1];
# ifdef USE_SOCKETS_AS_HANDLES
int Winit_socktype;
# endif