This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Revert #29307. It doesn't fix the XXX after all. Using "$(shell @type )"
[perl5.git] / win32 / perlhost.h
index 475158f..fe026dd 100644 (file)
@@ -7,10 +7,16 @@
  *    License or the Artistic License, as specified in the README file.
  */
 
+#ifndef UNDER_CE
+#define CHECK_HOST_INTERP
+#endif
+
 #ifndef ___PerlHost_H___
 #define ___PerlHost_H___
 
+#ifndef UNDER_CE
 #include <signal.h>
+#endif
 #include "iperlsys.h"
 #include "vmem.h"
 #include "vdir.h"
@@ -20,7 +26,6 @@ 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);
 END_EXTERN_C
 
 class CPerlHost
@@ -210,30 +215,42 @@ protected:
 
     DWORD   m_dwEnvCount;
     LPSTR*  m_lppEnvList;
-    BOOL    m_bTopLevel;       /* is this a toplevel host? */
+    BOOL    m_bTopLevel;       // is this a toplevel host?
     static long num_hosts;
 public:
     inline  int LastHost(void) { return num_hosts == 1L; };
+    struct interpreter *host_perl;
 };
 
 long CPerlHost::num_hosts = 0L;
 
+extern "C" void win32_checkTLS(struct interpreter *host_perl);
 
-#define STRUCT2PTR(x, y) (CPerlHost*)(((LPBYTE)x)-offsetof(CPerlHost, y))
+#define STRUCT2RAWPTR(x, y) (CPerlHost*)(((LPBYTE)x)-offsetof(CPerlHost, y))
+#ifdef CHECK_HOST_INTERP
+inline CPerlHost* CheckInterp(CPerlHost *host)
+{
+ win32_checkTLS(host->host_perl);
+ return host;
+}
+#define STRUCT2PTR(x, y) CheckInterp(STRUCT2RAWPTR(x, y))
+#else
+#define STRUCT2PTR(x, y) STRUCT2RAWPTR(x, y)
+#endif
 
 inline CPerlHost* IPerlMem2Host(struct IPerlMem* piPerl)
 {
-    return STRUCT2PTR(piPerl, m_hostperlMem);
+    return STRUCT2RAWPTR(piPerl, m_hostperlMem);
 }
 
 inline CPerlHost* IPerlMemShared2Host(struct IPerlMem* piPerl)
 {
-    return STRUCT2PTR(piPerl, m_hostperlMemShared);
+    return STRUCT2RAWPTR(piPerl, m_hostperlMemShared);
 }
 
 inline CPerlHost* IPerlMemParse2Host(struct IPerlMem* piPerl)
 {
-    return STRUCT2PTR(piPerl, m_hostperlMemParse);
+    return STRUCT2RAWPTR(piPerl, m_hostperlMemParse);
 }
 
 inline CPerlHost* IPerlEnv2Host(struct IPerlEnv* piPerl)
@@ -749,14 +766,14 @@ PerlStdIOVprintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format, va_lis
     return win32_vfprintf(pf, format, arglist);
 }
 
-long
+Off_t
 PerlStdIOTell(struct IPerlStdIO* piPerl, FILE* pf)
 {
     return win32_ftell(pf);
 }
 
 int
-PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, off_t offset, int origin)
+PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, Off_t offset, int origin)
 {
     return win32_fseek(pf, offset, origin);
 }
@@ -796,12 +813,12 @@ PerlStdIOInitOSExtras(struct IPerlStdIO* piPerl)
 }
 
 int
-PerlStdIOOpenOSfhandle(struct IPerlStdIO* piPerl, long osfhandle, int flags)
+PerlStdIOOpenOSfhandle(struct IPerlStdIO* piPerl, intptr_t osfhandle, int flags)
 {
     return win32_open_osfhandle(osfhandle, flags);
 }
 
-int
+intptr_t
 PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum)
 {
     return win32_get_osfhandle(filenum);
@@ -810,6 +827,7 @@ PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum)
 FILE*
 PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf)
 {
+#ifndef UNDER_CE
     FILE* pfdup;
     fpos_t pos;
     char mode[3];
@@ -857,6 +875,9 @@ PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf)
        fsetpos(pfdup, &pos);
     }
     return pfdup;
+#else
+    return 0;
+#endif
 }
 
 struct IPerlStdIO perlStdIO =
@@ -926,9 +947,9 @@ PerlLIOChown(struct IPerlLIO* piPerl, const char *filename, uid_t owner, gid_t g
 }
 
 int
-PerlLIOChsize(struct IPerlLIO* piPerl, int handle, long size)
+PerlLIOChsize(struct IPerlLIO* piPerl, int handle, Off_t size)
 {
-    return chsize(handle, size);
+    return win32_chsize(handle, size);
 }
 
 int
@@ -956,7 +977,7 @@ PerlLIOFlock(struct IPerlLIO* piPerl, int fd, int oper)
 }
 
 int
-PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, struct stat *buffer)
+PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, Stat_t *buffer)
 {
     return win32_fstat(handle, buffer);
 }
@@ -979,14 +1000,14 @@ PerlLIOLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
     return win32_link(oldname, newname);
 }
 
-long
-PerlLIOLseek(struct IPerlLIO* piPerl, int handle, long offset, int origin)
+Off_t
+PerlLIOLseek(struct IPerlLIO* piPerl, int handle, Off_t offset, int origin)
 {
     return win32_lseek(handle, offset, origin);
 }
 
 int
-PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, struct stat *buffer)
+PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
 {
     return win32_stat(path, buffer);
 }
@@ -1028,7 +1049,7 @@ PerlLIOSetmode(struct IPerlLIO* piPerl, int handle, int mode)
 }
 
 int
-PerlLIONameStat(struct IPerlLIO* piPerl, const char *path, struct stat *buffer)
+PerlLIONameStat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
 {
     return win32_stat(path, buffer);
 }
@@ -1052,7 +1073,7 @@ PerlLIOUnlink(struct IPerlLIO* piPerl, const char *filename)
 }
 
 int
-PerlLIOUtime(struct IPerlLIO* piPerl, char *filename, struct utimbuf *times)
+PerlLIOUtime(struct IPerlLIO* piPerl, const char *filename, struct utimbuf *times)
 {
     return win32_utime(filename, times);
 }
@@ -1123,7 +1144,7 @@ PerlDirClose(struct IPerlDir* piPerl, DIR *dirp)
 }
 
 DIR*
-PerlDirOpen(struct IPerlDir* piPerl, char *filename)
+PerlDirOpen(struct IPerlDir* piPerl, const char *filename)
 {
     return win32_opendir(filename);
 }
@@ -1436,9 +1457,7 @@ PerlSockSocket(struct IPerlSock* piPerl, int af, int type, int protocol)
 int
 PerlSockSocketpair(struct IPerlSock* piPerl, int domain, int type, int protocol, int* fds)
 {
-    dTHX;
-    Perl_croak(aTHX_ "socketpair not implemented!\n");
-    return 0;
+    return Perl_my_socketpair(domain, type, protocol, fds);
 }
 
 int
@@ -1666,7 +1685,13 @@ PerlProcWaitpid(struct IPerlProc* piPerl, int pid, int *status, int flags)
 Sighandler_t
 PerlProcSignal(struct IPerlProc* piPerl, int sig, Sighandler_t subcode)
 {
-    return signal(sig, subcode);
+    return win32_signal(sig, subcode);
+}
+
+int
+PerlProcGetTimeOfDay(struct IPerlProc* piPerl, struct timeval *t, void *z)
+{
+    return win32_gettimeofday(t, z);
 }
 
 #ifdef USE_ITHREADS
@@ -1676,6 +1701,7 @@ win32_start_child(LPVOID arg)
     PerlInterpreter *my_perl = (PerlInterpreter*)arg;
     GV *tmpgv;
     int status;
+    HWND parent_message_hwnd;
 #ifdef PERL_SYNC_FORK
     static long sync_fork_id = 0;
     long id = ++sync_fork_id;
@@ -1683,6 +1709,7 @@ win32_start_child(LPVOID arg)
 
 
     PERL_SET_THX(my_perl);
+    win32_checkTLS(my_perl);
 
     /* set $$ to pseudo id */
 #ifdef PERL_SYNC_FORK
@@ -1695,9 +1722,21 @@ win32_start_child(LPVOID arg)
            w32_pseudo_id = -pid;
     }
 #endif
-    if (tmpgv = gv_fetchpv("$", TRUE, SVt_PV))
-       sv_setiv(GvSV(tmpgv), -(IV)w32_pseudo_id);
+    if (tmpgv = gv_fetchpv("$", TRUE, SVt_PV)) {
+       SV *sv = GvSV(tmpgv);
+       SvREADONLY_off(sv);
+       sv_setiv(sv, -(IV)w32_pseudo_id);
+       SvREADONLY_on(sv);
+    }
+#ifdef PERL_USES_PL_PIDSTATUS    
     hv_clear(PL_pidstatus);
+#endif    
+
+    /* create message window and tell parent about it */
+    parent_message_hwnd = w32_message_hwnd;
+    w32_message_hwnd = win32_create_message_window();
+    if (parent_message_hwnd != NULL)
+        PostMessage(parent_message_hwnd, WM_USER_MESSAGE, w32_pseudo_id, (LONG)w32_message_hwnd);
 
     /* push a zero on the stack (we are the child) */
     {
@@ -1728,7 +1767,7 @@ restart:
            PL_curstash = PL_defstash;
            if (PL_endav && !PL_minus_c)
                call_list(oldscope, PL_endav);
-           status = STATUS_NATIVE_EXPORT;
+           status = STATUS_EXIT;
            break;
        case 3:
            if (PL_restartop) {
@@ -1745,18 +1784,22 @@ restart:
        JMPENV_POP;
 
        /* XXX hack to avoid perl_destruct() freeing optree */
+        win32_checkTLS(my_perl);
        PL_main_root = Nullop;
     }
 
+    win32_checkTLS(my_perl);
     /* 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);
+       do_close(PL_stdingv, FALSE);
+       do_close(gv_fetchpv("STDOUT", TRUE, SVt_PVIO), FALSE); /* PL_stdoutgv - ISAGN */
+       do_close(PL_stderrgv, FALSE);
     }
 
     /* destroy everything (waits for any pseudo-forked children) */
+    win32_checkTLS(my_perl);
     perl_destruct(my_perl);
+    win32_checkTLS(my_perl);
     perl_free(my_perl);
 
 #ifdef PERL_SYNC_FORK
@@ -1793,10 +1836,16 @@ PerlProcFork(struct IPerlProc* piPerl)
                                                 h->m_pHostperlProc
                                                 );
     new_perl->Isys_intern.internal_host = h;
+    h->host_perl = new_perl;
 #  ifdef PERL_SYNC_FORK
     id = win32_start_child((LPVOID)new_perl);
     PERL_SET_THX(aTHX);
 #  else
+    if (w32_message_hwnd == INVALID_HANDLE_VALUE)
+        w32_message_hwnd = win32_create_message_window();
+    new_perl->Isys_intern.message_hwnd = w32_message_hwnd;
+    w32_pseudo_child_message_hwnds[w32_num_pseudo_children] =
+        (w32_message_hwnd == NULL) ? (HWND)NULL : (HWND)INVALID_HANDLE_VALUE;
 #    ifdef USE_RTL_THREAD_API
     handle = (HANDLE)_beginthreadex((void*)NULL, 0, win32_start_child,
                                    (void*)new_perl, 0, (unsigned*)&id);
@@ -1843,19 +1892,6 @@ PerlProcGetOSError(struct IPerlProc* piPerl, SV* sv, DWORD dwErr)
     win32_str_os_error(sv, dwErr);
 }
 
-BOOL
-PerlProcDoCmd(struct IPerlProc* piPerl, char *cmd)
-{
-    do_spawn2(cmd, EXECF_EXEC);
-    return FALSE;
-}
-
-int
-PerlProcSpawn(struct IPerlProc* piPerl, char* cmds)
-{
-    return do_spawn2(cmds, EXECF_SPAWN);
-}
-
 int
 PerlProcSpawnvp(struct IPerlProc* piPerl, int mode, const char *cmdname, const char *const *argv)
 {
@@ -1863,12 +1899,6 @@ PerlProcSpawnvp(struct IPerlProc* piPerl, int mode, const char *cmdname, const c
 }
 
 int
-PerlProcASpawn(struct IPerlProc* piPerl, void *vreally, void **vmark, void **vsp)
-{
-    return do_aspawn(vreally, vmark, vsp);
-}
-
-int
 PerlProcLastHost(struct IPerlProc* piPerl)
 {
  dTHX;
@@ -1907,12 +1937,10 @@ struct IPerlProc perlProc =
     PerlProcGetpid,
     PerlProcDynaLoader,
     PerlProcGetOSError,
-    PerlProcDoCmd,
-    PerlProcSpawn,
     PerlProcSpawnvp,
-    PerlProcASpawn,
     PerlProcLastHost,
-    PerlProcPopenList
+    PerlProcPopenList,
+    PerlProcGetTimeOfDay
 };
 
 
@@ -2051,7 +2079,7 @@ CPerlHost::CPerlHost(CPerlHost& host)
 
 CPerlHost::~CPerlHost(void)
 {
-/* Reset(); */
+    Reset();
     InterlockedDecrement(&num_hosts);
     delete m_pvDir;
     m_pVMemParse->Release();
@@ -2078,7 +2106,7 @@ CPerlHost::Find(LPCSTR lpStr)
 
 int
 lookup(const void *arg1, const void *arg2)
-{   /* Compare strings */
+{   // Compare strings
     char*ptr1, *ptr2;
     char c1,c2;
 
@@ -2091,18 +2119,18 @@ lookup(const void *arg1, const void *arg2)
            if(c2 == '\0' || c2 == '=')
                break;
 
-           return -1; /* string 1 < string 2 */
+           return -1; // string 1 < string 2
        }
        else if(c2 == '\0' || c2 == '=')
-           return 1; /* string 1 > string 2 */
+           return 1; // string 1 > string 2
        else if(c1 != c2) {
            c1 = toupper(c1);
            c2 = toupper(c2);
            if(c1 != c2) {
                if(c1 < c2)
-                   return -1; /* string 1 < string 2 */
+                   return -1; // string 1 < string 2
 
-               return 1; /* string 1 > string 2 */
+               return 1; // string 1 > string 2
            }
        }
     }
@@ -2112,12 +2140,18 @@ lookup(const void *arg1, const void *arg2)
 LPSTR*
 CPerlHost::Lookup(LPCSTR lpStr)
 {
+#ifdef UNDER_CE
+    if (!m_lppEnvList || !m_dwEnvCount)
+       return NULL;
+#endif
+    if (!lpStr)
+       return NULL;
     return (LPSTR*)bsearch(&lpStr, m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), lookup);
 }
 
 int
 compare(const void *arg1, const void *arg2)
-{   /* Compare strings */
+{   // Compare strings
     char*ptr1, *ptr2;
     char c1,c2;
 
@@ -2130,18 +2164,18 @@ compare(const void *arg1, const void *arg2)
            if(c1 == c2)
                break;
 
-           return -1; /* string 1 < string 2 */
+           return -1; // string 1 < string 2
        }
        else if(c2 == '\0' || c2 == '=')
-           return 1; /* string 1 > string 2 */
+           return 1; // string 1 > string 2
        else if(c1 != c2) {
            c1 = toupper(c1);
            c2 = toupper(c2);
            if(c1 != c2) {
                if(c1 < c2)
-                   return -1; /* string 1 < string 2 */
-       
-               return 1; /* string 1 > string 2 */
+                   return -1; // string 1 < string 2
+
+               return 1; // string 1 > string 2
            }
        }
     }
@@ -2161,22 +2195,26 @@ CPerlHost::Add(LPCSTR lpStr)
 
     szBuffer[index] = '\0';
 
-    /* replacing ? */
+    // replacing ?
     lpPtr = Lookup(szBuffer);
-    if(lpPtr != NULL) {
-       Renew(*lpPtr, length, char);
+    if (lpPtr != NULL) {
+       // must allocate things via host memory allocation functions 
+       // rather than perl's Renew() et al, as the perl interpreter
+       // may either not be initialized enough when we allocate these,
+       // or may already be dead when we go to free these
+       *lpPtr = (char*)Realloc(*lpPtr, length * sizeof(char));
        strcpy(*lpPtr, lpStr);
     }
     else {
-       ++m_dwEnvCount;
-       Renew(m_lppEnvList, m_dwEnvCount, LPSTR);
-       New(1, m_lppEnvList[m_dwEnvCount-1], length, char);
-       if(m_lppEnvList[m_dwEnvCount-1] != NULL) {
-           strcpy(m_lppEnvList[m_dwEnvCount-1], lpStr);
-           qsort(m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), compare);
+       m_lppEnvList = (LPSTR*)Realloc(m_lppEnvList, (m_dwEnvCount+1) * sizeof(LPSTR));
+       if (m_lppEnvList) {
+           m_lppEnvList[m_dwEnvCount] = (char*)Malloc(length * sizeof(char));
+           if (m_lppEnvList[m_dwEnvCount] != NULL) {
+               strcpy(m_lppEnvList[m_dwEnvCount], lpStr);
+               ++m_dwEnvCount;
+               qsort(m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), compare);
+           }
        }
-       else
-           --m_dwEnvCount;
     }
 }
 
@@ -2204,7 +2242,7 @@ CPerlHost::GetChildDir(void)
     dTHX;
     int length;
     char* ptr;
-    New(0, ptr, MAX_PATH+1, char);
+    Newx(ptr, MAX_PATH+1, char);
     if(ptr) {
        m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr);
        length = strlen(ptr);
@@ -2231,45 +2269,45 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
     DWORD dwSize, dwEnvIndex;
     int nLength, compVal;
 
-    /* get the process environment strings */
+    // get the process environment strings
     lpAllocPtr = lpTmp = (LPSTR)GetEnvironmentStrings();
 
-    /* step over current directory stuff */
+    // step over current directory stuff
     while(*lpTmp == '=')
        lpTmp += strlen(lpTmp) + 1;
 
-    /* save the start of the environment strings */
+    // save the start of the environment strings
     lpEnvPtr = lpTmp;
     for(dwSize = 1; *lpTmp != '\0'; lpTmp += strlen(lpTmp) + 1) {
-       /* calculate the size of the environment strings */
+       // calculate the size of the environment strings
        dwSize += strlen(lpTmp) + 1;
     }
 
-    /* add the size of current directories */
+    // add the size of current directories
     dwSize += vDir.CalculateEnvironmentSpace();
 
-    /* add the additional space used by changes made to the environment */
+    // add the additional space used by changes made to the environment
     dwSize += CalculateEnvironmentSpace();
 
-    New(1, lpStr, dwSize, char);
+    Newx(lpStr, dwSize, char);
     lpPtr = lpStr;
     if(lpStr != NULL) {
-       /* build the local environment */
+       // build the local environment
        lpStr = vDir.BuildEnvironmentSpace(lpStr);
 
        dwEnvIndex = 0;
        lpLocalEnv = GetIndex(dwEnvIndex);
        while(*lpEnvPtr != '\0') {
            if(!lpLocalEnv) {
-               /* all environment overrides have been added */
-               /* so copy string into place */
+               // all environment overrides have been added
+               // so copy string into place
                strcpy(lpStr, lpEnvPtr);
                nLength = strlen(lpEnvPtr) + 1;
                lpStr += nLength;
                lpEnvPtr += nLength;
            }
-           else {      
-               /* determine which string to copy next */
+           else {
+               // determine which string to copy next
                compVal = compare(&lpEnvPtr, &lpLocalEnv);
                if(compVal < 0) {
                    strcpy(lpStr, lpEnvPtr);
@@ -2285,7 +2323,7 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
                    }
                    lpLocalEnv = GetIndex(dwEnvIndex);
                    if(compVal == 0) {
-                       /* this string was replaced */
+                       // this string was replaced
                        lpEnvPtr += strlen(lpEnvPtr) + 1;
                    }
                }
@@ -2293,8 +2331,8 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
        }
 
        while(lpLocalEnv) {
-           /* still have environment overrides to add */
-           /* so copy the strings into place if not an override */
+           // still have environment overrides to add
+           // so copy the strings into place if not an override
            char *ptr = strchr(lpLocalEnv, '=');
            if(ptr && ptr[1]) {
                strcpy(lpStr, lpLocalEnv);
@@ -2303,11 +2341,11 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
            lpLocalEnv = GetIndex(dwEnvIndex);
        }
 
-       /* add final NULL */
+       // add final NULL
        *lpStr = '\0';
     }
 
-    /* release the process environment strings */
+    // release the process environment strings
     FreeEnvironmentStrings(lpAllocPtr);
 
     return lpPtr;
@@ -2319,11 +2357,13 @@ CPerlHost::Reset(void)
     dTHX;
     if(m_lppEnvList != NULL) {
        for(DWORD index = 0; index < m_dwEnvCount; ++index) {
-           Safefree(m_lppEnvList[index]);
+           Free(m_lppEnvList[index]);
            m_lppEnvList[index] = NULL;
        }
     }
     m_dwEnvCount = 0;
+    Free(m_lppEnvList);
+    m_lppEnvList = NULL;
 }
 
 void
@@ -2398,13 +2438,7 @@ CPerlHost::Chdir(const char *dirname)
        errno = ENOENT;
        return -1;
     }
-    if (USING_WIDE()) {
-       WCHAR wBuffer[MAX_PATH];
-       A2WHELPER(dirname, wBuffer, sizeof(wBuffer));
-       ret = m_pvDir->SetCurrentDirectoryW(wBuffer);
-    }
-    else
-       ret = m_pvDir->SetCurrentDirectoryA((char*)dirname);
+    ret = m_pvDir->SetCurrentDirectoryA((char*)dirname);
     if(ret < 0) {
        errno = ENOENT;
     }