X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fperlhost.h;h=651a367021f8693c8378672875952d5fccf9d234;hb=23ae7f173577cbe2d62a4f7d64340f6457c75ee3;hp=a417f6651e8802677f7092ce0753a819b2087fc3;hpb=acfe0abcedaf592fb4b9cb69ce3468308ae99d91;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/perlhost.h b/win32/perlhost.h index a417f66..651a367 100644 --- a/win32/perlhost.h +++ b/win32/perlhost.h @@ -1,26 +1,36 @@ /* perlhost.h * - * (c) 1999 Microsoft Corporation. All rights reserved. + * (c) 1999 Microsoft Corporation. All rights reserved. * Portions (c) 1999 ActiveState Tool Corp, http://www.ActiveState.com/ * * You may distribute under the terms of either the GNU General Public * 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 +#endif #include "iperlsys.h" #include "vmem.h" #include "vdir.h" +#ifndef WC_NO_BEST_FIT_CHARS +# define WC_NO_BEST_FIT_CHARS 0x00000400 +#endif + START_EXTERN_C -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_win32_get_privlib(const char *pl, STRLEN *const len); +extern char * g_win32_get_sitelib(const char *pl, STRLEN *const len); +extern char * g_win32_get_vendorlib(const char *pl, + STRLEN *const len); extern char * g_getlogin(void); -extern int do_spawn2(char *cmd, int exectype); END_EXTERN_C class CPerlHost @@ -52,6 +62,7 @@ public: void PerlDestroy(void); /* IPerlMem */ + /* Locks provided but should be unnecessary as this is private pool */ inline void* Malloc(size_t size) { return m_pVMem->Malloc(size); }; inline void* Realloc(void* ptr, size_t size) { return m_pVMem->Realloc(ptr, size); }; inline void Free(void* ptr) { m_pVMem->Free(ptr); }; @@ -68,12 +79,32 @@ public: inline int IsLocked(void) { return m_pVMem->IsLocked(); }; /* IPerlMemShared */ + /* Locks used to serialize access to the pool */ + inline void GetLockShared(void) { m_pVMemShared->GetLock(); }; + inline void FreeLockShared(void) { m_pVMemShared->FreeLock(); }; + inline int IsLockedShared(void) { return m_pVMemShared->IsLocked(); }; inline void* MallocShared(size_t size) { - return m_pVMemShared->Malloc(size); + void *result; + GetLockShared(); + result = m_pVMemShared->Malloc(size); + FreeLockShared(); + return result; + }; + inline void* ReallocShared(void* ptr, size_t size) + { + void *result; + GetLockShared(); + result = m_pVMemShared->Realloc(ptr, size); + FreeLockShared(); + return result; + }; + inline void FreeShared(void* ptr) + { + GetLockShared(); + m_pVMemShared->Free(ptr); + FreeLockShared(); }; - inline void* ReallocShared(void* ptr, size_t size) { return m_pVMemShared->Realloc(ptr, size); }; - inline void FreeShared(void* ptr) { m_pVMemShared->Free(ptr); }; inline void* CallocShared(size_t num, size_t size) { size_t count = num*size; @@ -82,11 +113,14 @@ public: ZeroMemory(lpVoid, count); return lpVoid; }; - inline void GetLockShared(void) { m_pVMem->GetLock(); }; - inline void FreeLockShared(void) { m_pVMem->FreeLock(); }; - inline int IsLockedShared(void) { return m_pVMem->IsLocked(); }; /* IPerlMemParse */ + /* Assume something else is using locks to mangaging serialize + on a batch basis + */ + inline void GetLockParse(void) { m_pVMemParse->GetLock(); }; + inline void FreeLockParse(void) { m_pVMemParse->FreeLock(); }; + inline int IsLockedParse(void) { return m_pVMemParse->IsLocked(); }; inline void* MallocParse(size_t size) { return m_pVMemParse->Malloc(size); }; inline void* ReallocParse(void* ptr, size_t size) { return m_pVMemParse->Realloc(ptr, size); }; inline void FreeParse(void* ptr) { m_pVMemParse->Free(ptr); }; @@ -98,9 +132,6 @@ public: ZeroMemory(lpVoid, count); return lpVoid; }; - inline void GetLockParse(void) { m_pVMem->GetLock(); }; - inline void FreeLockParse(void) { m_pVMem->FreeLock(); }; - inline int IsLockedParse(void) { return m_pVMem->IsLocked(); }; /* IPerlEnv */ char *Getenv(const char *varname); @@ -189,29 +220,42 @@ protected: DWORD m_dwEnvCount; LPSTR* m_lppEnvList; + 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) @@ -474,21 +518,22 @@ PerlEnvOsId(struct IPerlEnv* piPerl) } char* -PerlEnvLibPath(struct IPerlEnv* piPerl, const char *pl) +PerlEnvLibPath(struct IPerlEnv* piPerl, const char *pl, STRLEN *const len) { - return g_win32_get_privlib(pl); + return g_win32_get_privlib(pl, len); } char* -PerlEnvSiteLibPath(struct IPerlEnv* piPerl, const char *pl) +PerlEnvSiteLibPath(struct IPerlEnv* piPerl, const char *pl, STRLEN *const len) { - return g_win32_get_sitelib(pl); + return g_win32_get_sitelib(pl, len); } char* -PerlEnvVendorLibPath(struct IPerlEnv* piPerl, const char *pl) +PerlEnvVendorLibPath(struct IPerlEnv* piPerl, const char *pl, + STRLEN *const len) { - return g_win32_get_vendorlib(pl); + return g_win32_get_vendorlib(pl, len); } void @@ -497,7 +542,7 @@ PerlEnvGetChildIO(struct IPerlEnv* piPerl, child_IO_table* ptr) win32_get_child_IO(ptr); } -struct IPerlEnv perlEnv = +struct IPerlEnv perlEnv = { PerlEnvGetenv, PerlEnvPutenv, @@ -573,14 +618,14 @@ PerlStdIOGetc(struct IPerlStdIO* piPerl, FILE* pf) return win32_getc(pf); } -char* +STDCHAR* PerlStdIOGetBase(struct IPerlStdIO* piPerl, FILE* pf) { #ifdef FILE_base FILE *f = pf; return FILE_base(f); #else - return Nullch; + return NULL; #endif } @@ -606,31 +651,31 @@ PerlStdIOGetCnt(struct IPerlStdIO* piPerl, FILE* pf) #endif } -char* +STDCHAR* PerlStdIOGetPtr(struct IPerlStdIO* piPerl, FILE* pf) { #ifdef USE_STDIO_PTR FILE *f = pf; return FILE_ptr(f); #else - return Nullch; + return NULL; #endif } char* -PerlStdIOGets(struct IPerlStdIO* piPerl, FILE* pf, char* s, int n) +PerlStdIOGets(struct IPerlStdIO* piPerl, char* s, int n, FILE* pf) { return win32_fgets(s, n, pf); } int -PerlStdIOPutc(struct IPerlStdIO* piPerl, FILE* pf, int c) +PerlStdIOPutc(struct IPerlStdIO* piPerl, int c, FILE* pf) { return win32_fputc(c, pf); } int -PerlStdIOPuts(struct IPerlStdIO* piPerl, FILE* pf, const char *s) +PerlStdIOPuts(struct IPerlStdIO* piPerl, const char *s, FILE* pf) { return win32_fputs(s, pf); } @@ -699,7 +744,7 @@ PerlStdIOSetCnt(struct IPerlStdIO* piPerl, FILE* pf, int n) } void -PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, char * ptr) +PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, STDCHAR * ptr) { #ifdef STDIO_PTR_LVALUE FILE *f = pf; @@ -727,14 +772,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); } @@ -774,12 +819,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); @@ -788,6 +833,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]; @@ -824,7 +870,7 @@ PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf) } #endif - /* it appears that the binmode is attached to the + /* it appears that the binmode is attached to the * file descriptor so binmode files will be handled * correctly */ @@ -835,9 +881,12 @@ PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf) fsetpos(pfdup, &pos); } return pfdup; +#else + return 0; +#endif } -struct IPerlStdIO perlStdIO = +struct IPerlStdIO perlStdIO = { PerlStdIOStdin, PerlStdIOStdout, @@ -904,9 +953,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 @@ -934,7 +983,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); } @@ -942,13 +991,20 @@ PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, struct stat *buffer) int PerlLIOIOCtl(struct IPerlLIO* piPerl, int i, unsigned int u, char *data) { - return win32_ioctlsocket((SOCKET)i, (long)u, (u_long*)data); + u_long u_long_arg; + int retval; + + /* mauke says using memcpy avoids alignment issues */ + memcpy(&u_long_arg, data, sizeof u_long_arg); + retval = win32_ioctlsocket((SOCKET)i, (long)u, &u_long_arg); + memcpy(data, &u_long_arg, sizeof u_long_arg); + return retval; } int PerlLIOIsatty(struct IPerlLIO* piPerl, int fd) { - return isatty(fd); + return win32_isatty(fd); } int @@ -957,14 +1013,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); } @@ -1006,7 +1062,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); } @@ -1030,7 +1086,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); } @@ -1101,7 +1157,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); } @@ -1414,9 +1470,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 @@ -1566,9 +1620,7 @@ PerlProcKill(struct IPerlProc* piPerl, int pid, int sig) int PerlProcKillpg(struct IPerlProc* piPerl, int pid, int sig) { - dTHX; - Perl_croak(aTHX_ "killpg not implemented!\n"); - return 0; + return win32_kill(pid, -sig); } int @@ -1644,7 +1696,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 @@ -1654,6 +1712,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; @@ -1661,6 +1720,7 @@ win32_start_child(LPVOID arg) PERL_SET_THX(my_perl); + win32_checkTLS(my_perl); /* set $$ to pseudo id */ #ifdef PERL_SYNC_FORK @@ -1673,9 +1733,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, (LPARAM)w32_message_hwnd); /* push a zero on the stack (we are the child) */ { @@ -1690,13 +1762,23 @@ win32_start_child(LPVOID arg) { dJMPENV; - volatile int oldscope = PL_scopestack_ix; + volatile int oldscope = 1; /* We are responsible for all scopes */ restart: JMPENV_PUSH(status); switch (status) { case 0: CALLRUNOPS(aTHX); + /* We may have additional unclosed scopes if fork() was called + * from within a BEGIN block. See perlfork.pod for more details. + * We cannot clean up these other scopes because they belong to a + * different interpreter, but we also cannot leave PL_scopestack_ix + * dangling because that can trigger an assertion in perl_destruct(). + */ + if (PL_scopestack_ix > oldscope) { + PL_scopestack[oldscope-1] = PL_scopestack[PL_scopestack_ix-1]; + PL_scopestack_ix = oldscope; + } status = 0; break; case 2: @@ -1706,13 +1788,13 @@ 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) { POPSTACK_TO(PL_mainstack); PL_op = PL_restartop; - PL_restartop = Nullop; + PL_restartop = (OP*)NULL; goto restart; } PerlIO_printf(Perl_error_log, "panic: restartop\n"); @@ -1723,18 +1805,22 @@ restart: JMPENV_POP; /* XXX hack to avoid perl_destruct() freeing optree */ - PL_main_root = Nullop; + win32_checkTLS(my_perl); + PL_main_root = (OP*)NULL; } + 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 @@ -1759,7 +1845,8 @@ PerlProcFork(struct IPerlProc* piPerl) return -1; } h = new CPerlHost(*(CPerlHost*)w32_internal_host); - PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHX, 1, + PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHX, + CLONEf_COPY_STACKS, h->m_pHostperlMem, h->m_pHostperlMemShared, h->m_pHostperlMemParse, @@ -1771,10 +1858,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); @@ -1821,19 +1914,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) { @@ -1841,12 +1921,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; @@ -1885,12 +1959,10 @@ struct IPerlProc perlProc = PerlProcGetpid, PerlProcDynaLoader, PerlProcGetOSError, - PerlProcDoCmd, - PerlProcSpawn, PerlProcSpawnvp, - PerlProcASpawn, PerlProcLastHost, - PerlProcPopenList + PerlProcPopenList, + PerlProcGetTimeOfDay }; @@ -1911,6 +1983,7 @@ CPerlHost::CPerlHost(void) m_dwEnvCount = 0; m_lppEnvList = NULL; + m_bTopLevel = TRUE; CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem)); CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared)); @@ -1960,6 +2033,7 @@ CPerlHost::CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared, m_dwEnvCount = 0; m_lppEnvList = NULL; + m_bTopLevel = FALSE; CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem)); CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared)); @@ -2016,6 +2090,7 @@ CPerlHost::CPerlHost(CPerlHost& host) m_dwEnvCount = 0; m_lppEnvList = NULL; + m_bTopLevel = FALSE; /* duplicate environment info */ LPSTR lpPtr; @@ -2026,7 +2101,7 @@ CPerlHost::CPerlHost(CPerlHost& host) CPerlHost::~CPerlHost(void) { -// Reset(); + Reset(); InterlockedDecrement(&num_hosts); delete m_pvDir; m_pVMemParse->Release(); @@ -2087,6 +2162,12 @@ 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); } @@ -2115,7 +2196,7 @@ compare(const void *arg1, const void *arg2) if(c1 != c2) { if(c1 < c2) return -1; // string 1 < string 2 - + return 1; // string 1 > string 2 } } @@ -2138,20 +2219,24 @@ CPerlHost::Add(LPCSTR lpStr) // 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; } } @@ -2177,16 +2262,15 @@ char* CPerlHost::GetChildDir(void) { dTHX; - int length; char* ptr; - New(0, ptr, MAX_PATH+1, char); - if(ptr) { - m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr); - length = strlen(ptr); - if (length > 3) { - if ((ptr[length-1] == '\\') || (ptr[length-1] == '/')) - ptr[length-1] = 0; - } + size_t length; + + Newx(ptr, MAX_PATH+1, char); + m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr); + length = strlen(ptr); + if (length > 3) { + if ((ptr[length-1] == '\\') || (ptr[length-1] == '/')) + ptr[length-1] = 0; } return ptr; } @@ -2226,7 +2310,7 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir) // 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 @@ -2243,7 +2327,7 @@ CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir) lpStr += nLength; lpEnvPtr += nLength; } - else { + else { // determine which string to copy next compVal = compare(&lpEnvPtr, &lpLocalEnv); if(compVal < 0) { @@ -2269,11 +2353,12 @@ 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; + // so copy the strings into place if not an override + char *ptr = strchr(lpLocalEnv, '='); + if(ptr && ptr[1]) { + strcpy(lpStr, lpLocalEnv); + lpStr += strlen(lpLocalEnv) + 1; + } lpLocalEnv = GetIndex(dwEnvIndex); } @@ -2293,11 +2378,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 @@ -2329,7 +2416,7 @@ CPerlHost::Clearenv(void) ch = *++lpPtr; *lpPtr = 0; Add(lpStr); - if (!w32_pseudo_id) + if (m_bTopLevel) (void)win32_putenv(lpStr); *lpPtr = ch; } @@ -2344,7 +2431,7 @@ char* CPerlHost::Getenv(const char *varname) { dTHX; - if (w32_pseudo_id) { + if (!m_bTopLevel) { char *pEnv = Find(varname); if (pEnv && *pEnv) return pEnv; @@ -2357,7 +2444,7 @@ CPerlHost::Putenv(const char *envstring) { dTHX; Add(envstring); - if (!w32_pseudo_id) + if (m_bTopLevel) return win32_putenv(envstring); return 0; @@ -2368,13 +2455,11 @@ CPerlHost::Chdir(const char *dirname) { dTHX; int ret; - if (USING_WIDE()) { - WCHAR wBuffer[MAX_PATH]; - A2WHELPER(dirname, wBuffer, sizeof(wBuffer)); - ret = m_pvDir->SetCurrentDirectoryW(wBuffer); + if (!dirname) { + errno = ENOENT; + return -1; } - else - ret = m_pvDir->SetCurrentDirectoryA((char*)dirname); + ret = m_pvDir->SetCurrentDirectoryA((char*)dirname); if(ret < 0) { errno = ENOENT; }