Modified README.bs2000
[p5sagit/p5-mst-13.2.git] / win32 / perlhost.h
index 01ff73d..a260d08 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef ___PerlHost_H___
 #define ___PerlHost_H___
 
+#include <signal.h>
 #include "iperlsys.h"
 #include "vmem.h"
 #include "vdir.h"
@@ -17,8 +18,9 @@
 #if !defined(PERL_OBJECT)
 START_EXTERN_C
 #endif
-extern char *          g_win32_get_privlib(char *pl);
-extern char *          g_win32_get_sitelib(char *pl);
+extern char *          g_win32_get_privlib(const char *pl);
+extern char *          g_win32_get_sitelib(const char *pl);
+extern char *          g_win32_get_vendorlib(const char *pl);
 extern char *          g_getlogin(void);
 extern int             do_spawn2(char *cmd, int exectype);
 #if !defined(PERL_OBJECT)
@@ -33,6 +35,7 @@ extern int            g_do_aspawn(void *vreally, void **vmark, void **vsp);
 class CPerlHost
 {
 public:
+    /* Constructors */
     CPerlHost(void);
     CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
                 struct IPerlMem** ppMemParse, struct IPerlEnv** ppEnv,
@@ -195,8 +198,13 @@ protected:
 
     DWORD   m_dwEnvCount;
     LPSTR*  m_lppEnvList;
+    static long num_hosts;
+public:
+    inline  int LastHost(void) { return num_hosts == 1L; };
 };
 
+long CPerlHost::num_hosts = 0L;
+
 
 #define STRUCT2PTR(x, y) (CPerlHost*)(((LPBYTE)x)-offsetof(CPerlHost, y))
 
@@ -475,17 +483,29 @@ PerlEnvOsId(struct IPerlEnv* piPerl)
 }
 
 char*
-PerlEnvLibPath(struct IPerlEnv* piPerl, char *pl)
+PerlEnvLibPath(struct IPerlEnv* piPerl, const char *pl)
 {
     return g_win32_get_privlib(pl);
 }
 
 char*
-PerlEnvSiteLibPath(struct IPerlEnv* piPerl, char *pl)
+PerlEnvSiteLibPath(struct IPerlEnv* piPerl, const char *pl)
 {
     return g_win32_get_sitelib(pl);
 }
 
+char*
+PerlEnvVendorLibPath(struct IPerlEnv* piPerl, const char *pl)
+{
+    return g_win32_get_vendorlib(pl);
+}
+
+void
+PerlEnvGetChildIO(struct IPerlEnv* piPerl, child_IO_table* ptr)
+{
+    win32_get_child_IO(ptr);
+}
+
 struct IPerlEnv perlEnv = 
 {
     PerlEnvGetenv,
@@ -500,71 +520,73 @@ struct IPerlEnv perlEnv =
     PerlEnvOsId,
     PerlEnvLibPath,
     PerlEnvSiteLibPath,
+    PerlEnvVendorLibPath,
+    PerlEnvGetChildIO,
 };
 
 #undef IPERL2HOST
 #define IPERL2HOST(x) IPerlStdIO2Host(x)
 
 /* PerlStdIO */
-PerlIO*
+FILE*
 PerlStdIOStdin(struct IPerlStdIO* piPerl)
 {
-    return (PerlIO*)win32_stdin();
+    return win32_stdin();
 }
 
-PerlIO*
+FILE*
 PerlStdIOStdout(struct IPerlStdIO* piPerl)
 {
-    return (PerlIO*)win32_stdout();
+    return win32_stdout();
 }
 
-PerlIO*
+FILE*
 PerlStdIOStderr(struct IPerlStdIO* piPerl)
 {
-    return (PerlIO*)win32_stderr();
+    return win32_stderr();
 }
 
-PerlIO*
+FILE*
 PerlStdIOOpen(struct IPerlStdIO* piPerl, const char *path, const char *mode)
 {
-    return (PerlIO*)win32_fopen(path, mode);
+    return win32_fopen(path, mode);
 }
 
 int
-PerlStdIOClose(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOClose(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    return win32_fclose(((FILE*)pf));
+    return win32_fclose((pf));
 }
 
 int
-PerlStdIOEof(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOEof(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    return win32_feof((FILE*)pf);
+    return win32_feof(pf);
 }
 
 int
-PerlStdIOError(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOError(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    return win32_ferror((FILE*)pf);
+    return win32_ferror(pf);
 }
 
 void
-PerlStdIOClearerr(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOClearerr(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    win32_clearerr((FILE*)pf);
+    win32_clearerr(pf);
 }
 
 int
-PerlStdIOGetc(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOGetc(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    return win32_getc((FILE*)pf);
+    return win32_getc(pf);
 }
 
 char*
-PerlStdIOGetBase(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOGetBase(struct IPerlStdIO* piPerl, FILE* pf)
 {
 #ifdef FILE_base
-    FILE *f = (FILE*)pf;
+    FILE *f = pf;
     return FILE_base(f);
 #else
     return Nullch;
@@ -572,10 +594,10 @@ PerlStdIOGetBase(struct IPerlStdIO* piPerl, PerlIO* pf)
 }
 
 int
-PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, FILE* pf)
 {
 #ifdef FILE_bufsiz
-    FILE *f = (FILE*)pf;
+    FILE *f = pf;
     return FILE_bufsiz(f);
 #else
     return (-1);
@@ -583,10 +605,10 @@ PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, PerlIO* pf)
 }
 
 int
-PerlStdIOGetCnt(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOGetCnt(struct IPerlStdIO* piPerl, FILE* pf)
 {
 #ifdef USE_STDIO_PTR
-    FILE *f = (FILE*)pf;
+    FILE *f = pf;
     return FILE_cnt(f);
 #else
     return (-1);
@@ -594,10 +616,10 @@ PerlStdIOGetCnt(struct IPerlStdIO* piPerl, PerlIO* pf)
 }
 
 char*
-PerlStdIOGetPtr(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOGetPtr(struct IPerlStdIO* piPerl, FILE* pf)
 {
 #ifdef USE_STDIO_PTR
-    FILE *f = (FILE*)pf;
+    FILE *f = pf;
     return FILE_ptr(f);
 #else
     return Nullch;
@@ -605,150 +627,149 @@ PerlStdIOGetPtr(struct IPerlStdIO* piPerl, PerlIO* pf)
 }
 
 char*
-PerlStdIOGets(struct IPerlStdIO* piPerl, PerlIO* pf, char* s, int n)
+PerlStdIOGets(struct IPerlStdIO* piPerl, FILE* pf, char* s, int n)
 {
-    return win32_fgets(s, n, (FILE*)pf);
+    return win32_fgets(s, n, pf);
 }
 
 int
-PerlStdIOPutc(struct IPerlStdIO* piPerl, PerlIO* pf, int c)
+PerlStdIOPutc(struct IPerlStdIO* piPerl, FILE* pf, int c)
 {
-    return win32_fputc(c, (FILE*)pf);
+    return win32_fputc(c, pf);
 }
 
 int
-PerlStdIOPuts(struct IPerlStdIO* piPerl, PerlIO* pf, const char *s)
+PerlStdIOPuts(struct IPerlStdIO* piPerl, FILE* pf, const char *s)
 {
-    return win32_fputs(s, (FILE*)pf);
+    return win32_fputs(s, pf);
 }
 
 int
-PerlStdIOFlush(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOFlush(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    return win32_fflush((FILE*)pf);
+    return win32_fflush(pf);
 }
 
 int
-PerlStdIOUngetc(struct IPerlStdIO* piPerl, PerlIO* pf,int c)
+PerlStdIOUngetc(struct IPerlStdIO* piPerl,int c, FILE* pf)
 {
-    return win32_ungetc(c, (FILE*)pf);
+    return win32_ungetc(c, pf);
 }
 
 int
-PerlStdIOFileno(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOFileno(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    return win32_fileno((FILE*)pf);
+    return win32_fileno(pf);
 }
 
-PerlIO*
+FILE*
 PerlStdIOFdopen(struct IPerlStdIO* piPerl, int fd, const char *mode)
 {
-    return (PerlIO*)win32_fdopen(fd, mode);
+    return win32_fdopen(fd, mode);
 }
 
-PerlIO*
-PerlStdIOReopen(struct IPerlStdIO* piPerl, const char*path, const char*mode, PerlIO* pf)
+FILE*
+PerlStdIOReopen(struct IPerlStdIO* piPerl, const char*path, const char*mode, FILE* pf)
 {
-    return (PerlIO*)win32_freopen(path, mode, (FILE*)pf);
+    return win32_freopen(path, mode, (FILE*)pf);
 }
 
 SSize_t
-PerlStdIORead(struct IPerlStdIO* piPerl, PerlIO* pf, void *buffer, Size_t size)
+PerlStdIORead(struct IPerlStdIO* piPerl, void *buffer, Size_t size, Size_t count, FILE* pf)
 {
-    return win32_fread(buffer, 1, size, (FILE*)pf);
+    return win32_fread(buffer, size, count, pf);
 }
 
 SSize_t
-PerlStdIOWrite(struct IPerlStdIO* piPerl, PerlIO* pf, const void *buffer, Size_t size)
+PerlStdIOWrite(struct IPerlStdIO* piPerl, const void *buffer, Size_t size, Size_t count, FILE* pf)
 {
-    return win32_fwrite(buffer, 1, size, (FILE*)pf);
+    return win32_fwrite(buffer, size, count, pf);
 }
 
 void
-PerlStdIOSetBuf(struct IPerlStdIO* piPerl, PerlIO* pf, char* buffer)
+PerlStdIOSetBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer)
 {
-    win32_setbuf((FILE*)pf, buffer);
+    win32_setbuf(pf, buffer);
 }
 
 int
-PerlStdIOSetVBuf(struct IPerlStdIO* piPerl, PerlIO* pf, char* buffer, int type, Size_t size)
+PerlStdIOSetVBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer, int type, Size_t size)
 {
-    return win32_setvbuf((FILE*)pf, buffer, type, size);
+    return win32_setvbuf(pf, buffer, type, size);
 }
 
 void
-PerlStdIOSetCnt(struct IPerlStdIO* piPerl, PerlIO* pf, int n)
+PerlStdIOSetCnt(struct IPerlStdIO* piPerl, FILE* pf, int n)
 {
 #ifdef STDIO_CNT_LVALUE
-    FILE *f = (FILE*)pf;
+    FILE *f = pf;
     FILE_cnt(f) = n;
 #endif
 }
 
 void
-PerlStdIOSetPtrCnt(struct IPerlStdIO* piPerl, PerlIO* pf, char * ptr, int n)
+PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, char * ptr)
 {
 #ifdef STDIO_PTR_LVALUE
-    FILE *f = (FILE*)pf;
+    FILE *f = pf;
     FILE_ptr(f) = ptr;
-    FILE_cnt(f) = n;
 #endif
 }
 
 void
-PerlStdIOSetlinebuf(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOSetlinebuf(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    win32_setvbuf((FILE*)pf, NULL, _IOLBF, 0);
+    win32_setvbuf(pf, NULL, _IOLBF, 0);
 }
 
 int
-PerlStdIOPrintf(struct IPerlStdIO* piPerl, PerlIO* pf, const char *format,...)
+PerlStdIOPrintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format,...)
 {
     va_list(arglist);
     va_start(arglist, format);
-    return win32_vfprintf((FILE*)pf, format, arglist);
+    return win32_vfprintf(pf, format, arglist);
 }
 
 int
-PerlStdIOVprintf(struct IPerlStdIO* piPerl, PerlIO* pf, const char *format, va_list arglist)
+PerlStdIOVprintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format, va_list arglist)
 {
-    return win32_vfprintf((FILE*)pf, format, arglist);
+    return win32_vfprintf(pf, format, arglist);
 }
 
 long
-PerlStdIOTell(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIOTell(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    return win32_ftell((FILE*)pf);
+    return win32_ftell(pf);
 }
 
 int
-PerlStdIOSeek(struct IPerlStdIO* piPerl, PerlIO* pf, off_t offset, int origin)
+PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, off_t offset, int origin)
 {
-    return win32_fseek((FILE*)pf, offset, origin);
+    return win32_fseek(pf, offset, origin);
 }
 
 void
-PerlStdIORewind(struct IPerlStdIO* piPerl, PerlIO* pf)
+PerlStdIORewind(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    win32_rewind((FILE*)pf);
+    win32_rewind(pf);
 }
 
-PerlIO*
+FILE*
 PerlStdIOTmpfile(struct IPerlStdIO* piPerl)
 {
-    return (PerlIO*)win32_tmpfile();
+    return win32_tmpfile();
 }
 
 int
-PerlStdIOGetpos(struct IPerlStdIO* piPerl, PerlIO* pf, Fpos_t *p)
+PerlStdIOGetpos(struct IPerlStdIO* piPerl, FILE* pf, Fpos_t *p)
 {
-    return win32_fgetpos((FILE*)pf, p);
+    return win32_fgetpos(pf, p);
 }
 
 int
-PerlStdIOSetpos(struct IPerlStdIO* piPerl, PerlIO* pf, const Fpos_t *p)
+PerlStdIOSetpos(struct IPerlStdIO* piPerl, FILE* pf, const Fpos_t *p)
 {
-    return win32_fsetpos((FILE*)pf, p);
+    return win32_fsetpos(pf, p);
 }
 void
 PerlStdIOInit(struct IPerlStdIO* piPerl)
@@ -773,39 +794,39 @@ PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum)
     return win32_get_osfhandle(filenum);
 }
 
-PerlIO*
-PerlStdIOFdupopen(struct IPerlStdIO* piPerl, PerlIO* pf)
+FILE*
+PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf)
 {
-    PerlIO* pfdup;
+    FILE* pfdup;
     fpos_t pos;
     char mode[3];
-    int fileno = win32_dup(win32_fileno((FILE*)pf));
+    int fileno = win32_dup(win32_fileno(pf));
 
     /* open the file in the same mode */
 #ifdef __BORLANDC__
-    if(((FILE*)pf)->flags & _F_READ) {
+    if((pf)->flags & _F_READ) {
        mode[0] = 'r';
        mode[1] = 0;
     }
-    else if(((FILE*)pf)->flags & _F_WRIT) {
+    else if((pf)->flags & _F_WRIT) {
        mode[0] = 'a';
        mode[1] = 0;
     }
-    else if(((FILE*)pf)->flags & _F_RDWR) {
+    else if((pf)->flags & _F_RDWR) {
        mode[0] = 'r';
        mode[1] = '+';
        mode[2] = 0;
     }
 #else
-    if(((FILE*)pf)->_flag & _IOREAD) {
+    if((pf)->_flag & _IOREAD) {
        mode[0] = 'r';
        mode[1] = 0;
     }
-    else if(((FILE*)pf)->_flag & _IOWRT) {
+    else if((pf)->_flag & _IOWRT) {
        mode[0] = 'a';
        mode[1] = 0;
     }
-    else if(((FILE*)pf)->_flag & _IORW) {
+    else if((pf)->_flag & _IORW) {
        mode[0] = 'r';
        mode[1] = '+';
        mode[2] = 0;
@@ -816,11 +837,11 @@ PerlStdIOFdupopen(struct IPerlStdIO* piPerl, PerlIO* pf)
      * file descriptor so binmode files will be handled
      * correctly
      */
-    pfdup = (PerlIO*)win32_fdopen(fileno, mode);
+    pfdup = win32_fdopen(fileno, mode);
 
     /* move the file pointer to the same position */
-    if (!fgetpos((FILE*)pf, &pos)) {
-       fsetpos((FILE*)pfdup, &pos);
+    if (!fgetpos(pf, &pos)) {
+       fsetpos(pfdup, &pos);
     }
     return pfdup;
 }
@@ -853,7 +874,7 @@ struct IPerlStdIO perlStdIO =
     PerlStdIOSetBuf,
     PerlStdIOSetVBuf,
     PerlStdIOSetCnt,
-    PerlStdIOSetPtrCnt,
+    PerlStdIOSetPtr,
     PerlStdIOSetlinebuf,
     PerlStdIOPrintf,
     PerlStdIOVprintf,
@@ -924,7 +945,7 @@ PerlLIOFlock(struct IPerlLIO* piPerl, int fd, int oper)
 int
 PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, struct stat *buffer)
 {
-    return fstat(handle, buffer);
+    return win32_fstat(handle, buffer);
 }
 
 int
@@ -1570,13 +1591,13 @@ PerlProcPopen(struct IPerlProc* piPerl, const char *command, const char *mode)
 {
     dTHXo;
     PERL_FLUSHALL_FOR_CHILD;
-    return (PerlIO*)win32_popen(command, mode);
+    return win32_popen(command, mode);
 }
 
 int
 PerlProcPclose(struct IPerlProc* piPerl, PerlIO *stream)
 {
-    return win32_pclose((FILE*)stream);
+    return win32_pclose(stream);
 }
 
 int
@@ -1624,11 +1645,11 @@ PerlProcWaitpid(struct IPerlProc* piPerl, int pid, int *status, int flags)
 Sighandler_t
 PerlProcSignal(struct IPerlProc* piPerl, int sig, Sighandler_t subcode)
 {
-    return 0;
+    return signal(sig, subcode);
 }
 
 #ifdef USE_ITHREADS
-static DWORD WINAPI
+static THREAD_RET_TYPE
 win32_start_child(LPVOID arg)
 {
     PerlInterpreter *my_perl = (PerlInterpreter*)arg;
@@ -1643,13 +1664,18 @@ win32_start_child(LPVOID arg)
 #endif
 
 
-    PERL_SET_INTERP(my_perl);
+    PERL_SET_THX(my_perl);
 
     /* set $$ to pseudo id */
 #ifdef PERL_SYNC_FORK
     w32_pseudo_id = id;
 #else
     w32_pseudo_id = GetCurrentThreadId();
+    if (IsWin95()) {
+       int pid = (int)w32_pseudo_id;
+       if (pid < 0)
+           w32_pseudo_id = -pid;
+    }
 #endif
     if (tmpgv = gv_fetchpv("$", TRUE, SVt_PV))
        sv_setiv(GvSV(tmpgv), -(IV)w32_pseudo_id);
@@ -1668,7 +1694,7 @@ win32_start_child(LPVOID arg)
 
     {
        dJMPENV;
-       volatile oldscope = PL_scopestack_ix;
+       volatile int oldscope = PL_scopestack_ix;
 
 restart:
        JMPENV_PUSH(status);
@@ -1704,6 +1730,13 @@ restart:
        PL_main_root = Nullop;
     }
 
+    /* close the std handles to avoid fd leaks */
+    {
+       do_close(gv_fetchpv("STDIN", TRUE, SVt_PVIO), FALSE);
+       do_close(gv_fetchpv("STDOUT", TRUE, SVt_PVIO), FALSE);
+       do_close(gv_fetchpv("STDERR", TRUE, SVt_PVIO), FALSE);
+    }
+
     /* destroy everything (waits for any pseudo-forked children) */
     perl_destruct(my_perl);
     perl_free(my_perl);
@@ -1723,7 +1756,13 @@ PerlProcFork(struct IPerlProc* piPerl)
 #ifdef USE_ITHREADS
     DWORD id;
     HANDLE handle;
-    CPerlHost *h = new CPerlHost();
+    CPerlHost *h;
+
+    if (w32_num_pseudo_children >= MAXIMUM_WAIT_OBJECTS) {
+       errno = EAGAIN;
+       return -1;
+    }
+    h = new CPerlHost(*(CPerlHost*)w32_internal_host);
     PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHXo, 1,
                                                 h->m_pHostperlMem,
                                                 h->m_pHostperlMemShared,
@@ -1735,15 +1774,28 @@ PerlProcFork(struct IPerlProc* piPerl)
                                                 h->m_pHostperlSock,
                                                 h->m_pHostperlProc
                                                 );
+    new_perl->Isys_intern.internal_host = h;
 #  ifdef PERL_SYNC_FORK
     id = win32_start_child((LPVOID)new_perl);
-    PERL_SET_INTERP(aTHXo);
+    PERL_SET_THX(aTHXo);
 #  else
+#    ifdef USE_RTL_THREAD_API
+    handle = (HANDLE)_beginthreadex((void*)NULL, 0, win32_start_child,
+                                   (void*)new_perl, 0, (unsigned*)&id);
+#    else
     handle = CreateThread(NULL, 0, win32_start_child,
                          (LPVOID)new_perl, 0, &id);
-    PERL_SET_INTERP(aTHXo);
-    if (!handle)
-       Perl_croak(aTHX_ "panic: pseudo fork() failed");
+#    endif
+    PERL_SET_THX(aTHXo);       /* XXX perl_clone*() set TLS */
+    if (!handle) {
+       errno = EAGAIN;
+       return -1;
+    }
+    if (IsWin95()) {
+       int pid = (int)id;
+       if (pid < 0)
+           id = -pid;
+    }
     w32_pseudo_child_handles[w32_num_pseudo_children] = handle;
     w32_pseudo_child_pids[w32_num_pseudo_children] = id;
     ++w32_num_pseudo_children;
@@ -1798,6 +1850,14 @@ PerlProcASpawn(struct IPerlProc* piPerl, void *vreally, void **vmark, void **vsp
     return do_aspawn(vreally, vmark, vsp);
 }
 
+int
+PerlProcLastHost(struct IPerlProc* piPerl)
+{
+ dTHXo;
+ CPerlHost *h = (CPerlHost*)w32_internal_host;
+ return h->LastHost();
+}
+
 struct IPerlProc perlProc =
 {
     PerlProcAbort,
@@ -1833,6 +1893,7 @@ struct IPerlProc perlProc =
     PerlProcSpawn,
     PerlProcSpawnvp,
     PerlProcASpawn,
+    PerlProcLastHost
 };
 
 
@@ -1842,6 +1903,8 @@ struct IPerlProc perlProc =
 
 CPerlHost::CPerlHost(void)
 {
+    /* Construct a host from scratch */
+    InterlockedIncrement(&num_hosts);
     m_pvDir = new VDir();
     m_pVMem = new VMem();
     m_pVMemShared = new VMem();
@@ -1890,7 +1953,8 @@ CPerlHost::CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
                 struct IPerlDir** ppDir, struct IPerlSock** ppSock,
                 struct IPerlProc** ppProc)
 {
-    m_pvDir = new VDir();
+    InterlockedIncrement(&num_hosts);
+    m_pvDir = new VDir(0);
     m_pVMem = new VMem();
     m_pVMemShared = new VMem();
     m_pVMemParse =  new VMem();
@@ -1924,12 +1988,14 @@ CPerlHost::CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
 
 CPerlHost::CPerlHost(CPerlHost& host)
 {
+    /* Construct a host from another host */
+    InterlockedIncrement(&num_hosts);
     m_pVMem = new VMem();
     m_pVMemShared = host.GetMemShared();
     m_pVMemParse =  host.GetMemParse();
 
     /* duplicate directory info */
-    m_pvDir = new VDir();
+    m_pvDir = new VDir(0);
     m_pvDir->Init(host.GetDir(), m_pVMem);
 
     CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
@@ -1941,15 +2007,15 @@ CPerlHost::CPerlHost(CPerlHost& host)
     CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
     CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
     CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
-    m_pHostperlMem         = &host.m_hostperlMem;
-    m_pHostperlMemShared    = &host.m_hostperlMemShared;
-    m_pHostperlMemParse            = &host.m_hostperlMemParse;
-    m_pHostperlEnv         = &host.m_hostperlEnv;
-    m_pHostperlStdIO       = &host.m_hostperlStdIO;
-    m_pHostperlLIO         = &host.m_hostperlLIO;
-    m_pHostperlDir         = &host.m_hostperlDir;
-    m_pHostperlSock        = &host.m_hostperlSock;
-    m_pHostperlProc        = &host.m_hostperlProc;
+    m_pHostperlMem         = &m_hostperlMem;
+    m_pHostperlMemShared    = &m_hostperlMemShared;
+    m_pHostperlMemParse            = &m_hostperlMemParse;
+    m_pHostperlEnv         = &m_hostperlEnv;
+    m_pHostperlStdIO       = &m_hostperlStdIO;
+    m_pHostperlLIO         = &m_hostperlLIO;
+    m_pHostperlDir         = &m_hostperlDir;
+    m_pHostperlSock        = &m_hostperlSock;
+    m_pHostperlProc        = &m_hostperlProc;
 
     m_dwEnvCount = 0;
     m_lppEnvList = NULL;
@@ -1964,6 +2030,7 @@ CPerlHost::CPerlHost(CPerlHost& host)
 CPerlHost::~CPerlHost(void)
 {
 //  Reset();
+    InterlockedDecrement(&num_hosts);
     delete m_pvDir;
     m_pVMemParse->Release();
     m_pVMemShared->Release();
@@ -2171,7 +2238,7 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
        dwEnvIndex = 0;
        lpLocalEnv = GetIndex(dwEnvIndex);
        while(*lpEnvPtr != '\0') {
-           if(lpLocalEnv == NULL) {
+           if(!lpLocalEnv) {
                // all environment overrides have been added
                // so copy string into place
                strcpy(lpStr, lpEnvPtr);
@@ -2203,6 +2270,16 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
            }
        }
 
+       while(lpLocalEnv) {
+           // still have environment overrides to add
+           // so copy the strings into place
+           strcpy(lpStr, lpLocalEnv);
+           nLength = strlen(lpLocalEnv) + 1;
+           lpStr += nLength;
+           lpEnvPtr += nLength;
+           lpLocalEnv = GetIndex(dwEnvIndex);
+       }
+
        // add final NULL
        *lpStr = '\0';
     }