#ifndef ___PerlHost_H___
#define ___PerlHost_H___
+#include <signal.h>
#include "iperlsys.h"
#include "vmem.h"
#include "vdir.h"
#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)
}
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,
PerlEnvOsId,
PerlEnvLibPath,
PerlEnvSiteLibPath,
+ PerlEnvVendorLibPath,
+ PerlEnvGetChildIO,
};
#undef IPERL2HOST
int
PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, struct stat *buffer)
{
- return fstat(handle, buffer);
+ return win32_fstat(handle, buffer);
}
int
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;
#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);
/* push a zero on the stack (we are the child) */
{
- djSP;
+ dSP;
dTARGET;
PUSHi(0);
PUTBACK;
{
dJMPENV;
- volatile oldscope = PL_scopestack_ix;
+ volatile int oldscope = PL_scopestack_ix;
restart:
JMPENV_PUSH(status);
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);
#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,
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;
struct IPerlDir** ppDir, struct IPerlSock** ppSock,
struct IPerlProc** ppProc)
{
- m_pvDir = new VDir();
+ m_pvDir = new VDir(0);
m_pVMem = new VMem();
m_pVMemShared = new VMem();
m_pVMemParse = new VMem();
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));
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;
New(0, ptr, MAX_PATH+1, char);
if(ptr) {
m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr);
- length = strlen(ptr)-1;
- if(length > 0) {
- if((ptr[length] == '\\') || (ptr[length] == '/'))
- ptr[length] = 0;
+ length = strlen(ptr);
+ if (length > 3) {
+ if ((ptr[length-1] == '\\') || (ptr[length-1] == '/'))
+ ptr[length-1] = 0;
}
}
return ptr;
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);
}
}
+ 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';
}
void
CPerlHost::Clearenv(void)
{
+ dTHXo;
char ch;
LPSTR lpPtr, lpStr, lpEnvPtr;
- if(m_lppEnvList != NULL) {
+ if (m_lppEnvList != NULL) {
/* set every entry to an empty string */
for(DWORD index = 0; index < m_dwEnvCount; ++index) {
char* ptr = strchr(m_lppEnvList[index], '=');
ch = *++lpPtr;
*lpPtr = 0;
Add(lpStr);
+ if (!w32_pseudo_id)
+ (void)win32_putenv(lpStr);
*lpPtr = ch;
}
lpStr += strlen(lpStr) + 1;
char*
CPerlHost::Getenv(const char *varname)
{
- char* pEnv = Find(varname);
- if(pEnv == NULL) {
- pEnv = win32_getenv(varname);
- }
- else {
- if(!*pEnv)
- pEnv = 0;
+ dTHXo;
+ if (w32_pseudo_id) {
+ char *pEnv = Find(varname);
+ if (pEnv && *pEnv)
+ return pEnv;
}
-
- return pEnv;
+ return win32_getenv(varname);
}
int
CPerlHost::Putenv(const char *envstring)
{
+ dTHXo;
Add(envstring);
+ if (!w32_pseudo_id)
+ return win32_putenv(envstring);
+
return 0;
}
{
dTHXo;
int ret;
+ if (!dirname) {
+ errno = ENOENT;
+ return -1;
+ }
if (USING_WIDE()) {
WCHAR wBuffer[MAX_PATH];
A2WHELPER(dirname, wBuffer, sizeof(wBuffer));