3 * (c) 1999 Microsoft Corporation. All rights reserved.
4 * Portions (c) 1999 ActiveState Tool Corp, http://www.ActiveState.com/
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
10 #define CHECK_HOST_INTERP
12 #ifndef ___PerlHost_H___
13 #define ___PerlHost_H___
21 #ifndef WC_NO_BEST_FIT_CHARS
22 # define WC_NO_BEST_FIT_CHARS 0x00000400
26 extern char * g_getlogin(void);
34 CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
35 struct IPerlMem** ppMemParse, struct IPerlEnv** ppEnv,
36 struct IPerlStdIO** ppStdIO, struct IPerlLIO** ppLIO,
37 struct IPerlDir** ppDir, struct IPerlSock** ppSock,
38 struct IPerlProc** ppProc);
39 CPerlHost(CPerlHost& host);
42 static CPerlHost* IPerlMem2Host(struct IPerlMem* piPerl);
43 static CPerlHost* IPerlMemShared2Host(struct IPerlMem* piPerl);
44 static CPerlHost* IPerlMemParse2Host(struct IPerlMem* piPerl);
45 static CPerlHost* IPerlEnv2Host(struct IPerlEnv* piPerl);
46 static CPerlHost* IPerlStdIO2Host(struct IPerlStdIO* piPerl);
47 static CPerlHost* IPerlLIO2Host(struct IPerlLIO* piPerl);
48 static CPerlHost* IPerlDir2Host(struct IPerlDir* piPerl);
49 static CPerlHost* IPerlSock2Host(struct IPerlSock* piPerl);
50 static CPerlHost* IPerlProc2Host(struct IPerlProc* piPerl);
52 BOOL PerlCreate(void);
53 int PerlParse(int argc, char** argv, char** env);
55 void PerlDestroy(void);
58 /* Locks provided but should be unnecessary as this is private pool */
59 inline void* Malloc(size_t size) { return m_pVMem->Malloc(size); };
60 inline void* Realloc(void* ptr, size_t size) { return m_pVMem->Realloc(ptr, size); };
61 inline void Free(void* ptr) { m_pVMem->Free(ptr); };
62 inline void* Calloc(size_t num, size_t size)
64 size_t count = num*size;
65 void* lpVoid = Malloc(count);
67 ZeroMemory(lpVoid, count);
70 inline void GetLock(void) { m_pVMem->GetLock(); };
71 inline void FreeLock(void) { m_pVMem->FreeLock(); };
72 inline int IsLocked(void) { return m_pVMem->IsLocked(); };
75 /* Locks used to serialize access to the pool */
76 inline void GetLockShared(void) { m_pVMemShared->GetLock(); };
77 inline void FreeLockShared(void) { m_pVMemShared->FreeLock(); };
78 inline int IsLockedShared(void) { return m_pVMemShared->IsLocked(); };
79 inline void* MallocShared(size_t size)
83 result = m_pVMemShared->Malloc(size);
87 inline void* ReallocShared(void* ptr, size_t size)
91 result = m_pVMemShared->Realloc(ptr, size);
95 inline void FreeShared(void* ptr)
98 m_pVMemShared->Free(ptr);
101 inline void* CallocShared(size_t num, size_t size)
103 size_t count = num*size;
104 void* lpVoid = MallocShared(count);
106 ZeroMemory(lpVoid, count);
111 /* Assume something else is using locks to manage serialization
114 inline void GetLockParse(void) { m_pVMemParse->GetLock(); };
115 inline void FreeLockParse(void) { m_pVMemParse->FreeLock(); };
116 inline int IsLockedParse(void) { return m_pVMemParse->IsLocked(); };
117 inline void* MallocParse(size_t size) { return m_pVMemParse->Malloc(size); };
118 inline void* ReallocParse(void* ptr, size_t size) { return m_pVMemParse->Realloc(ptr, size); };
119 inline void FreeParse(void* ptr) { m_pVMemParse->Free(ptr); };
120 inline void* CallocParse(size_t num, size_t size)
122 size_t count = num*size;
123 void* lpVoid = MallocParse(count);
125 ZeroMemory(lpVoid, count);
130 char *Getenv(const char *varname);
131 int Putenv(const char *envstring);
132 inline char *Getenv(const char *varname, unsigned long *len)
135 char *e = Getenv(varname);
140 void* CreateChildEnv(void) { return CreateLocalEnvironmentStrings(*m_pvDir); };
141 void FreeChildEnv(void* pStr) { FreeLocalEnvironmentStrings((char*)pStr); };
142 char* GetChildDir(void);
143 void FreeChildDir(char* pStr);
147 inline LPSTR GetIndex(DWORD &dwIndex)
149 if(dwIndex < m_dwEnvCount)
152 return m_lppEnvList[dwIndex-1];
158 LPSTR Find(LPCSTR lpStr);
159 void Add(LPCSTR lpStr);
161 LPSTR CreateLocalEnvironmentStrings(VDir &vDir);
162 void FreeLocalEnvironmentStrings(LPSTR lpStr);
163 LPSTR* Lookup(LPCSTR lpStr);
164 DWORD CalculateEnvironmentSpace(void);
169 virtual int Chdir(const char *dirname);
173 void Exit(int status);
174 void _Exit(int status);
175 int Execl(const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3);
176 int Execv(const char *cmdname, const char *const *argv);
177 int Execvp(const char *cmdname, const char *const *argv);
179 inline VMem* GetMemShared(void) { m_pVMemShared->AddRef(); return m_pVMemShared; };
180 inline VMem* GetMemParse(void) { m_pVMemParse->AddRef(); return m_pVMemParse; };
181 inline VDir* GetDir(void) { return m_pvDir; };
185 struct IPerlMem m_hostperlMem;
186 struct IPerlMem m_hostperlMemShared;
187 struct IPerlMem m_hostperlMemParse;
188 struct IPerlEnv m_hostperlEnv;
189 struct IPerlStdIO m_hostperlStdIO;
190 struct IPerlLIO m_hostperlLIO;
191 struct IPerlDir m_hostperlDir;
192 struct IPerlSock m_hostperlSock;
193 struct IPerlProc m_hostperlProc;
195 struct IPerlMem* m_pHostperlMem;
196 struct IPerlMem* m_pHostperlMemShared;
197 struct IPerlMem* m_pHostperlMemParse;
198 struct IPerlEnv* m_pHostperlEnv;
199 struct IPerlStdIO* m_pHostperlStdIO;
200 struct IPerlLIO* m_pHostperlLIO;
201 struct IPerlDir* m_pHostperlDir;
202 struct IPerlSock* m_pHostperlSock;
203 struct IPerlProc* m_pHostperlProc;
205 inline char* MapPathA(const char *pInName) { return m_pvDir->MapPathA(pInName); };
206 inline WCHAR* MapPathW(const WCHAR *pInName) { return m_pvDir->MapPathW(pInName); };
216 BOOL m_bTopLevel; // is this a toplevel host?
217 static long num_hosts;
219 inline int LastHost(void) { return num_hosts == 1L; };
220 struct interpreter *host_perl;
223 long CPerlHost::num_hosts = 0L;
225 extern "C" void win32_checkTLS(struct interpreter *host_perl);
227 #define STRUCT2RAWPTR(x, y) (CPerlHost*)(((LPBYTE)x)-offsetof(CPerlHost, y))
228 #ifdef CHECK_HOST_INTERP
229 inline CPerlHost* CheckInterp(CPerlHost *host)
231 win32_checkTLS(host->host_perl);
234 #define STRUCT2PTR(x, y) CheckInterp(STRUCT2RAWPTR(x, y))
236 #define STRUCT2PTR(x, y) STRUCT2RAWPTR(x, y)
239 inline CPerlHost* IPerlMem2Host(struct IPerlMem* piPerl)
241 return STRUCT2RAWPTR(piPerl, m_hostperlMem);
244 inline CPerlHost* IPerlMemShared2Host(struct IPerlMem* piPerl)
246 return STRUCT2RAWPTR(piPerl, m_hostperlMemShared);
249 inline CPerlHost* IPerlMemParse2Host(struct IPerlMem* piPerl)
251 return STRUCT2RAWPTR(piPerl, m_hostperlMemParse);
254 inline CPerlHost* IPerlEnv2Host(struct IPerlEnv* piPerl)
256 return STRUCT2PTR(piPerl, m_hostperlEnv);
259 inline CPerlHost* IPerlStdIO2Host(struct IPerlStdIO* piPerl)
261 return STRUCT2PTR(piPerl, m_hostperlStdIO);
264 inline CPerlHost* IPerlLIO2Host(struct IPerlLIO* piPerl)
266 return STRUCT2PTR(piPerl, m_hostperlLIO);
269 inline CPerlHost* IPerlDir2Host(struct IPerlDir* piPerl)
271 return STRUCT2PTR(piPerl, m_hostperlDir);
274 inline CPerlHost* IPerlSock2Host(struct IPerlSock* piPerl)
276 return STRUCT2PTR(piPerl, m_hostperlSock);
279 inline CPerlHost* IPerlProc2Host(struct IPerlProc* piPerl)
281 return STRUCT2PTR(piPerl, m_hostperlProc);
287 #define IPERL2HOST(x) IPerlMem2Host(x)
291 PerlMemMalloc(struct IPerlMem* piPerl, size_t size)
293 return IPERL2HOST(piPerl)->Malloc(size);
296 PerlMemRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
298 return IPERL2HOST(piPerl)->Realloc(ptr, size);
301 PerlMemFree(struct IPerlMem* piPerl, void* ptr)
303 IPERL2HOST(piPerl)->Free(ptr);
306 PerlMemCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
308 return IPERL2HOST(piPerl)->Calloc(num, size);
312 PerlMemGetLock(struct IPerlMem* piPerl)
314 IPERL2HOST(piPerl)->GetLock();
318 PerlMemFreeLock(struct IPerlMem* piPerl)
320 IPERL2HOST(piPerl)->FreeLock();
324 PerlMemIsLocked(struct IPerlMem* piPerl)
326 return IPERL2HOST(piPerl)->IsLocked();
329 const struct IPerlMem perlMem =
341 #define IPERL2HOST(x) IPerlMemShared2Host(x)
345 PerlMemSharedMalloc(struct IPerlMem* piPerl, size_t size)
347 return IPERL2HOST(piPerl)->MallocShared(size);
350 PerlMemSharedRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
352 return IPERL2HOST(piPerl)->ReallocShared(ptr, size);
355 PerlMemSharedFree(struct IPerlMem* piPerl, void* ptr)
357 IPERL2HOST(piPerl)->FreeShared(ptr);
360 PerlMemSharedCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
362 return IPERL2HOST(piPerl)->CallocShared(num, size);
366 PerlMemSharedGetLock(struct IPerlMem* piPerl)
368 IPERL2HOST(piPerl)->GetLockShared();
372 PerlMemSharedFreeLock(struct IPerlMem* piPerl)
374 IPERL2HOST(piPerl)->FreeLockShared();
378 PerlMemSharedIsLocked(struct IPerlMem* piPerl)
380 return IPERL2HOST(piPerl)->IsLockedShared();
383 const struct IPerlMem perlMemShared =
386 PerlMemSharedRealloc,
389 PerlMemSharedGetLock,
390 PerlMemSharedFreeLock,
391 PerlMemSharedIsLocked,
395 #define IPERL2HOST(x) IPerlMemParse2Host(x)
399 PerlMemParseMalloc(struct IPerlMem* piPerl, size_t size)
401 return IPERL2HOST(piPerl)->MallocParse(size);
404 PerlMemParseRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
406 return IPERL2HOST(piPerl)->ReallocParse(ptr, size);
409 PerlMemParseFree(struct IPerlMem* piPerl, void* ptr)
411 IPERL2HOST(piPerl)->FreeParse(ptr);
414 PerlMemParseCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
416 return IPERL2HOST(piPerl)->CallocParse(num, size);
420 PerlMemParseGetLock(struct IPerlMem* piPerl)
422 IPERL2HOST(piPerl)->GetLockParse();
426 PerlMemParseFreeLock(struct IPerlMem* piPerl)
428 IPERL2HOST(piPerl)->FreeLockParse();
432 PerlMemParseIsLocked(struct IPerlMem* piPerl)
434 return IPERL2HOST(piPerl)->IsLockedParse();
437 const struct IPerlMem perlMemParse =
444 PerlMemParseFreeLock,
445 PerlMemParseIsLocked,
450 #define IPERL2HOST(x) IPerlEnv2Host(x)
454 PerlEnvGetenv(struct IPerlEnv* piPerl, const char *varname)
456 return IPERL2HOST(piPerl)->Getenv(varname);
460 PerlEnvPutenv(struct IPerlEnv* piPerl, const char *envstring)
462 return IPERL2HOST(piPerl)->Putenv(envstring);
466 PerlEnvGetenv_len(struct IPerlEnv* piPerl, const char* varname, unsigned long* len)
468 return IPERL2HOST(piPerl)->Getenv(varname, len);
472 PerlEnvUname(struct IPerlEnv* piPerl, struct utsname *name)
474 return win32_uname(name);
478 PerlEnvClearenv(struct IPerlEnv* piPerl)
480 IPERL2HOST(piPerl)->Clearenv();
484 PerlEnvGetChildenv(struct IPerlEnv* piPerl)
486 return IPERL2HOST(piPerl)->CreateChildEnv();
490 PerlEnvFreeChildenv(struct IPerlEnv* piPerl, void* childEnv)
492 IPERL2HOST(piPerl)->FreeChildEnv(childEnv);
496 PerlEnvGetChilddir(struct IPerlEnv* piPerl)
498 return IPERL2HOST(piPerl)->GetChildDir();
502 PerlEnvFreeChilddir(struct IPerlEnv* piPerl, char* childDir)
504 IPERL2HOST(piPerl)->FreeChildDir(childDir);
508 PerlEnvOsId(struct IPerlEnv* piPerl)
510 return win32_os_id();
514 PerlEnvLibPath(struct IPerlEnv* piPerl, WIN32_NO_REGISTRY_M_(const char *pl) STRLEN *const len)
516 return win32_get_privlib(WIN32_NO_REGISTRY_M_(pl) len);
520 PerlEnvSiteLibPath(struct IPerlEnv* piPerl, const char *pl, STRLEN *const len)
522 return win32_get_sitelib(pl, len);
526 PerlEnvVendorLibPath(struct IPerlEnv* piPerl, const char *pl,
529 return win32_get_vendorlib(pl, len);
533 PerlEnvGetChildIO(struct IPerlEnv* piPerl, child_IO_table* ptr)
535 win32_get_child_IO(ptr);
538 const struct IPerlEnv perlEnv =
552 PerlEnvVendorLibPath,
557 #define IPERL2HOST(x) IPerlStdIO2Host(x)
561 PerlStdIOStdin(struct IPerlStdIO* piPerl)
563 return win32_stdin();
567 PerlStdIOStdout(struct IPerlStdIO* piPerl)
569 return win32_stdout();
573 PerlStdIOStderr(struct IPerlStdIO* piPerl)
575 return win32_stderr();
579 PerlStdIOOpen(struct IPerlStdIO* piPerl, const char *path, const char *mode)
581 return win32_fopen(path, mode);
585 PerlStdIOClose(struct IPerlStdIO* piPerl, FILE* pf)
587 return win32_fclose((pf));
591 PerlStdIOEof(struct IPerlStdIO* piPerl, FILE* pf)
593 return win32_feof(pf);
597 PerlStdIOError(struct IPerlStdIO* piPerl, FILE* pf)
599 return win32_ferror(pf);
603 PerlStdIOClearerr(struct IPerlStdIO* piPerl, FILE* pf)
609 PerlStdIOGetc(struct IPerlStdIO* piPerl, FILE* pf)
611 return win32_getc(pf);
615 PerlStdIOGetBase(struct IPerlStdIO* piPerl, FILE* pf)
626 PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, FILE* pf)
630 return FILE_bufsiz(f);
637 PerlStdIOGetCnt(struct IPerlStdIO* piPerl, FILE* pf)
648 PerlStdIOGetPtr(struct IPerlStdIO* piPerl, FILE* pf)
659 PerlStdIOGets(struct IPerlStdIO* piPerl, char* s, int n, FILE* pf)
661 return win32_fgets(s, n, pf);
665 PerlStdIOPutc(struct IPerlStdIO* piPerl, int c, FILE* pf)
667 return win32_fputc(c, pf);
671 PerlStdIOPuts(struct IPerlStdIO* piPerl, const char *s, FILE* pf)
673 return win32_fputs(s, pf);
677 PerlStdIOFlush(struct IPerlStdIO* piPerl, FILE* pf)
679 return win32_fflush(pf);
683 PerlStdIOUngetc(struct IPerlStdIO* piPerl,int c, FILE* pf)
685 return win32_ungetc(c, pf);
689 PerlStdIOFileno(struct IPerlStdIO* piPerl, FILE* pf)
691 return win32_fileno(pf);
695 PerlStdIOFdopen(struct IPerlStdIO* piPerl, int fd, const char *mode)
697 return win32_fdopen(fd, mode);
701 PerlStdIOReopen(struct IPerlStdIO* piPerl, const char*path, const char*mode, FILE* pf)
703 return win32_freopen(path, mode, (FILE*)pf);
707 PerlStdIORead(struct IPerlStdIO* piPerl, void *buffer, Size_t size, Size_t count, FILE* pf)
709 return win32_fread(buffer, size, count, pf);
713 PerlStdIOWrite(struct IPerlStdIO* piPerl, const void *buffer, Size_t size, Size_t count, FILE* pf)
715 return win32_fwrite(buffer, size, count, pf);
719 PerlStdIOSetBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer)
721 win32_setbuf(pf, buffer);
725 PerlStdIOSetVBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer, int type, Size_t size)
727 return win32_setvbuf(pf, buffer, type, size);
731 PerlStdIOSetCnt(struct IPerlStdIO* piPerl, FILE* pf, int n)
733 #ifdef STDIO_CNT_LVALUE
740 PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, STDCHAR * ptr)
742 #ifdef STDIO_PTR_LVALUE
749 PerlStdIOSetlinebuf(struct IPerlStdIO* piPerl, FILE* pf)
751 win32_setvbuf(pf, NULL, _IOLBF, 0);
755 PerlStdIOPrintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format,...)
758 va_start(arglist, format);
759 return win32_vfprintf(pf, format, arglist);
763 PerlStdIOVprintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format, va_list arglist)
765 return win32_vfprintf(pf, format, arglist);
769 PerlStdIOTell(struct IPerlStdIO* piPerl, FILE* pf)
771 return win32_ftell(pf);
775 PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, Off_t offset, int origin)
777 return win32_fseek(pf, offset, origin);
781 PerlStdIORewind(struct IPerlStdIO* piPerl, FILE* pf)
787 PerlStdIOTmpfile(struct IPerlStdIO* piPerl)
789 return win32_tmpfile();
793 PerlStdIOGetpos(struct IPerlStdIO* piPerl, FILE* pf, Fpos_t *p)
795 return win32_fgetpos(pf, p);
799 PerlStdIOSetpos(struct IPerlStdIO* piPerl, FILE* pf, const Fpos_t *p)
801 return win32_fsetpos(pf, p);
804 PerlStdIOInit(struct IPerlStdIO* piPerl)
809 PerlStdIOInitOSExtras(struct IPerlStdIO* piPerl)
811 Perl_init_os_extras();
815 PerlStdIOOpenOSfhandle(struct IPerlStdIO* piPerl, intptr_t osfhandle, int flags)
817 return win32_open_osfhandle(osfhandle, flags);
821 PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum)
823 return win32_get_osfhandle(filenum);
827 PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf)
832 int fileno = win32_dup(win32_fileno(pf));
834 /* open the file in the same mode */
835 if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RD) {
839 else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_WR) {
843 else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RW) {
849 /* it appears that the binmode is attached to the
850 * file descriptor so binmode files will be handled
853 pfdup = win32_fdopen(fileno, mode);
855 /* move the file pointer to the same position */
856 if (!fgetpos(pf, &pos)) {
857 fsetpos(pfdup, &pos);
862 const struct IPerlStdIO perlStdIO =
901 PerlStdIOInitOSExtras,
907 #define IPERL2HOST(x) IPerlLIO2Host(x)
911 PerlLIOAccess(struct IPerlLIO* piPerl, const char *path, int mode)
913 return win32_access(path, mode);
917 PerlLIOChmod(struct IPerlLIO* piPerl, const char *filename, int pmode)
919 return win32_chmod(filename, pmode);
923 PerlLIOChown(struct IPerlLIO* piPerl, const char *filename, uid_t owner, gid_t group)
925 return chown(filename, owner, group);
929 PerlLIOChsize(struct IPerlLIO* piPerl, int handle, Off_t size)
931 return win32_chsize(handle, size);
935 PerlLIOClose(struct IPerlLIO* piPerl, int handle)
937 return win32_close(handle);
941 PerlLIODup(struct IPerlLIO* piPerl, int handle)
943 return win32_dup(handle);
947 PerlLIODup2(struct IPerlLIO* piPerl, int handle1, int handle2)
949 return win32_dup2(handle1, handle2);
953 PerlLIOFlock(struct IPerlLIO* piPerl, int fd, int oper)
955 return win32_flock(fd, oper);
959 PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, Stat_t *buffer)
961 return win32_fstat(handle, buffer);
965 PerlLIOIOCtl(struct IPerlLIO* piPerl, int i, unsigned int u, char *data)
970 /* mauke says using memcpy avoids alignment issues */
971 memcpy(&u_long_arg, data, sizeof u_long_arg);
972 retval = win32_ioctlsocket((SOCKET)i, (long)u, &u_long_arg);
973 memcpy(data, &u_long_arg, sizeof u_long_arg);
978 PerlLIOIsatty(struct IPerlLIO* piPerl, int fd)
980 return win32_isatty(fd);
984 PerlLIOLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
986 return win32_link(oldname, newname);
990 PerlLIOSymLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
992 return win32_symlink(oldname, newname);
996 PerlLIOReadLink(struct IPerlLIO* piPerl, const char *path, char *buf, size_t bufsiz)
998 return win32_readlink(path, buf, bufsiz);
1002 PerlLIOLseek(struct IPerlLIO* piPerl, int handle, Off_t offset, int origin)
1004 return win32_lseek(handle, offset, origin);
1008 PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
1010 return win32_lstat(path, buffer);
1014 PerlLIOMktemp(struct IPerlLIO* piPerl, char *Template)
1016 return mktemp(Template);
1020 PerlLIOOpen(struct IPerlLIO* piPerl, const char *filename, int oflag)
1022 return win32_open(filename, oflag);
1026 PerlLIOOpen3(struct IPerlLIO* piPerl, const char *filename, int oflag, int pmode)
1028 return win32_open(filename, oflag, pmode);
1032 PerlLIORead(struct IPerlLIO* piPerl, int handle, void *buffer, unsigned int count)
1034 return win32_read(handle, buffer, count);
1038 PerlLIORename(struct IPerlLIO* piPerl, const char *OldFileName, const char *newname)
1040 return win32_rename(OldFileName, newname);
1044 PerlLIOSetmode(struct IPerlLIO* piPerl, int handle, int mode)
1046 return win32_setmode(handle, mode);
1050 PerlLIONameStat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
1052 return win32_stat(path, buffer);
1056 PerlLIOTmpnam(struct IPerlLIO* piPerl, char *string)
1058 return tmpnam(string);
1062 PerlLIOUmask(struct IPerlLIO* piPerl, int pmode)
1064 return umask(pmode);
1068 PerlLIOUnlink(struct IPerlLIO* piPerl, const char *filename)
1070 return win32_unlink(filename);
1074 PerlLIOUtime(struct IPerlLIO* piPerl, const char *filename, struct utimbuf *times)
1076 return win32_utime(filename, times);
1080 PerlLIOWrite(struct IPerlLIO* piPerl, int handle, const void *buffer, unsigned int count)
1082 return win32_write(handle, buffer, count);
1085 const struct IPerlLIO perlLIO =
1119 #define IPERL2HOST(x) IPerlDir2Host(x)
1123 PerlDirMakedir(struct IPerlDir* piPerl, const char *dirname, int mode)
1125 return win32_mkdir(dirname, mode);
1129 PerlDirChdir(struct IPerlDir* piPerl, const char *dirname)
1131 return IPERL2HOST(piPerl)->Chdir(dirname);
1135 PerlDirRmdir(struct IPerlDir* piPerl, const char *dirname)
1137 return win32_rmdir(dirname);
1141 PerlDirClose(struct IPerlDir* piPerl, DIR *dirp)
1143 return win32_closedir(dirp);
1147 PerlDirOpen(struct IPerlDir* piPerl, const char *filename)
1149 return win32_opendir(filename);
1153 PerlDirRead(struct IPerlDir* piPerl, DIR *dirp)
1155 return win32_readdir(dirp);
1159 PerlDirRewind(struct IPerlDir* piPerl, DIR *dirp)
1161 win32_rewinddir(dirp);
1165 PerlDirSeek(struct IPerlDir* piPerl, DIR *dirp, long loc)
1167 win32_seekdir(dirp, loc);
1171 PerlDirTell(struct IPerlDir* piPerl, DIR *dirp)
1173 return win32_telldir(dirp);
1177 PerlDirMapPathA(struct IPerlDir* piPerl, const char* path)
1179 return IPERL2HOST(piPerl)->MapPathA(path);
1183 PerlDirMapPathW(struct IPerlDir* piPerl, const WCHAR* path)
1185 return IPERL2HOST(piPerl)->MapPathW(path);
1188 const struct IPerlDir perlDir =
1206 PerlSockHtonl(struct IPerlSock* piPerl, u_long hostlong)
1208 return win32_htonl(hostlong);
1212 PerlSockHtons(struct IPerlSock* piPerl, u_short hostshort)
1214 return win32_htons(hostshort);
1218 PerlSockNtohl(struct IPerlSock* piPerl, u_long netlong)
1220 return win32_ntohl(netlong);
1224 PerlSockNtohs(struct IPerlSock* piPerl, u_short netshort)
1226 return win32_ntohs(netshort);
1229 SOCKET PerlSockAccept(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* addr, int* addrlen)
1231 return win32_accept(s, addr, addrlen);
1235 PerlSockBind(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
1237 return win32_bind(s, name, namelen);
1241 PerlSockConnect(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
1243 return win32_connect(s, name, namelen);
1247 PerlSockEndhostent(struct IPerlSock* piPerl)
1253 PerlSockEndnetent(struct IPerlSock* piPerl)
1259 PerlSockEndprotoent(struct IPerlSock* piPerl)
1261 win32_endprotoent();
1265 PerlSockEndservent(struct IPerlSock* piPerl)
1271 PerlSockGethostbyaddr(struct IPerlSock* piPerl, const char* addr, int len, int type)
1273 return win32_gethostbyaddr(addr, len, type);
1277 PerlSockGethostbyname(struct IPerlSock* piPerl, const char* name)
1279 return win32_gethostbyname(name);
1283 PerlSockGethostent(struct IPerlSock* piPerl)
1285 win32_croak_not_implemented("gethostent");
1290 PerlSockGethostname(struct IPerlSock* piPerl, char* name, int namelen)
1292 return win32_gethostname(name, namelen);
1296 PerlSockGetnetbyaddr(struct IPerlSock* piPerl, long net, int type)
1298 return win32_getnetbyaddr(net, type);
1302 PerlSockGetnetbyname(struct IPerlSock* piPerl, const char *name)
1304 return win32_getnetbyname((char*)name);
1308 PerlSockGetnetent(struct IPerlSock* piPerl)
1310 return win32_getnetent();
1313 int PerlSockGetpeername(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
1315 return win32_getpeername(s, name, namelen);
1319 PerlSockGetprotobyname(struct IPerlSock* piPerl, const char* name)
1321 return win32_getprotobyname(name);
1325 PerlSockGetprotobynumber(struct IPerlSock* piPerl, int number)
1327 return win32_getprotobynumber(number);
1331 PerlSockGetprotoent(struct IPerlSock* piPerl)
1333 return win32_getprotoent();
1337 PerlSockGetservbyname(struct IPerlSock* piPerl, const char* name, const char* proto)
1339 return win32_getservbyname(name, proto);
1343 PerlSockGetservbyport(struct IPerlSock* piPerl, int port, const char* proto)
1345 return win32_getservbyport(port, proto);
1349 PerlSockGetservent(struct IPerlSock* piPerl)
1351 return win32_getservent();
1355 PerlSockGetsockname(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
1357 return win32_getsockname(s, name, namelen);
1361 PerlSockGetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, char* optval, int* optlen)
1363 return win32_getsockopt(s, level, optname, optval, optlen);
1367 PerlSockInetAddr(struct IPerlSock* piPerl, const char* cp)
1369 return win32_inet_addr(cp);
1373 PerlSockInetNtoa(struct IPerlSock* piPerl, struct in_addr in)
1375 return win32_inet_ntoa(in);
1379 PerlSockListen(struct IPerlSock* piPerl, SOCKET s, int backlog)
1381 return win32_listen(s, backlog);
1385 PerlSockRecv(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags)
1387 return win32_recv(s, buffer, len, flags);
1391 PerlSockRecvfrom(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen)
1393 return win32_recvfrom(s, buffer, len, flags, from, fromlen);
1397 PerlSockSelect(struct IPerlSock* piPerl, int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout)
1399 return win32_select(nfds, (Perl_fd_set*)readfds, (Perl_fd_set*)writefds, (Perl_fd_set*)exceptfds, timeout);
1403 PerlSockSend(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags)
1405 return win32_send(s, buffer, len, flags);
1409 PerlSockSendto(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen)
1411 return win32_sendto(s, buffer, len, flags, to, tolen);
1415 PerlSockSethostent(struct IPerlSock* piPerl, int stayopen)
1417 win32_sethostent(stayopen);
1421 PerlSockSetnetent(struct IPerlSock* piPerl, int stayopen)
1423 win32_setnetent(stayopen);
1427 PerlSockSetprotoent(struct IPerlSock* piPerl, int stayopen)
1429 win32_setprotoent(stayopen);
1433 PerlSockSetservent(struct IPerlSock* piPerl, int stayopen)
1435 win32_setservent(stayopen);
1439 PerlSockSetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, const char* optval, int optlen)
1441 return win32_setsockopt(s, level, optname, optval, optlen);
1445 PerlSockShutdown(struct IPerlSock* piPerl, SOCKET s, int how)
1447 return win32_shutdown(s, how);
1451 PerlSockSocket(struct IPerlSock* piPerl, int af, int type, int protocol)
1453 return win32_socket(af, type, protocol);
1457 PerlSockSocketpair(struct IPerlSock* piPerl, int domain, int type, int protocol, int* fds)
1459 return Perl_my_socketpair(domain, type, protocol, fds);
1463 PerlSockClosesocket(struct IPerlSock* piPerl, SOCKET s)
1465 return win32_closesocket(s);
1469 PerlSockIoctlsocket(struct IPerlSock* piPerl, SOCKET s, long cmd, u_long *argp)
1471 return win32_ioctlsocket(s, cmd, argp);
1474 const struct IPerlSock perlSock =
1485 PerlSockEndprotoent,
1487 PerlSockGethostname,
1488 PerlSockGetpeername,
1489 PerlSockGethostbyaddr,
1490 PerlSockGethostbyname,
1492 PerlSockGetnetbyaddr,
1493 PerlSockGetnetbyname,
1495 PerlSockGetprotobyname,
1496 PerlSockGetprotobynumber,
1497 PerlSockGetprotoent,
1498 PerlSockGetservbyname,
1499 PerlSockGetservbyport,
1501 PerlSockGetsockname,
1513 PerlSockSetprotoent,
1519 PerlSockClosesocket,
1525 #define EXECF_EXEC 1
1526 #define EXECF_SPAWN 2
1529 PerlProcAbort(struct IPerlProc* piPerl)
1535 PerlProcCrypt(struct IPerlProc* piPerl, const char* clear, const char* salt)
1537 return win32_crypt(clear, salt);
1540 PERL_CALLCONV_NO_RET void
1541 PerlProcExit(struct IPerlProc* piPerl, int status)
1546 PERL_CALLCONV_NO_RET void
1547 PerlProc_Exit(struct IPerlProc* piPerl, int status)
1553 PerlProcExecl(struct IPerlProc* piPerl, const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3)
1555 return execl(cmdname, arg0, arg1, arg2, arg3);
1559 PerlProcExecv(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
1561 return win32_execvp(cmdname, argv);
1565 PerlProcExecvp(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
1567 return win32_execvp(cmdname, argv);
1571 PerlProcGetuid(struct IPerlProc* piPerl)
1577 PerlProcGeteuid(struct IPerlProc* piPerl)
1583 PerlProcGetgid(struct IPerlProc* piPerl)
1589 PerlProcGetegid(struct IPerlProc* piPerl)
1595 PerlProcGetlogin(struct IPerlProc* piPerl)
1597 return g_getlogin();
1601 PerlProcKill(struct IPerlProc* piPerl, int pid, int sig)
1603 return win32_kill(pid, sig);
1607 PerlProcKillpg(struct IPerlProc* piPerl, int pid, int sig)
1609 return win32_kill(pid, -sig);
1613 PerlProcPauseProc(struct IPerlProc* piPerl)
1615 return win32_pause();
1619 PerlProcPopen(struct IPerlProc* piPerl, const char *command, const char *mode)
1622 PERL_FLUSHALL_FOR_CHILD;
1623 return win32_popen(command, mode);
1627 PerlProcPopenList(struct IPerlProc* piPerl, const char *mode, IV narg, SV **args)
1630 PERL_FLUSHALL_FOR_CHILD;
1631 return win32_popenlist(mode, narg, args);
1635 PerlProcPclose(struct IPerlProc* piPerl, PerlIO *stream)
1637 return win32_pclose(stream);
1641 PerlProcPipe(struct IPerlProc* piPerl, int *phandles)
1643 return win32_pipe(phandles, 512, O_BINARY);
1647 PerlProcSetuid(struct IPerlProc* piPerl, uid_t u)
1653 PerlProcSetgid(struct IPerlProc* piPerl, gid_t g)
1659 PerlProcSleep(struct IPerlProc* piPerl, unsigned int s)
1661 return win32_sleep(s);
1665 PerlProcTimes(struct IPerlProc* piPerl, struct tms *timebuf)
1667 return win32_times(timebuf);
1671 PerlProcWait(struct IPerlProc* piPerl, int *status)
1673 return win32_wait(status);
1677 PerlProcWaitpid(struct IPerlProc* piPerl, int pid, int *status, int flags)
1679 return win32_waitpid(pid, status, flags);
1683 PerlProcSignal(struct IPerlProc* piPerl, int sig, Sighandler_t subcode)
1685 return win32_signal(sig, subcode);
1689 PerlProcGetTimeOfDay(struct IPerlProc* piPerl, struct timeval *t, void *z)
1691 return win32_gettimeofday(t, z);
1695 static THREAD_RET_TYPE
1696 win32_start_child(LPVOID arg)
1698 PerlInterpreter *my_perl = (PerlInterpreter*)arg;
1700 HWND parent_message_hwnd;
1701 #ifdef PERL_SYNC_FORK
1702 static long sync_fork_id = 0;
1703 long id = ++sync_fork_id;
1707 PERL_SET_THX(my_perl);
1708 win32_checkTLS(my_perl);
1710 #ifdef PERL_SYNC_FORK
1713 w32_pseudo_id = GetCurrentThreadId();
1715 #ifdef PERL_USES_PL_PIDSTATUS
1716 hv_clear(PL_pidstatus);
1719 /* create message window and tell parent about it */
1720 parent_message_hwnd = w32_message_hwnd;
1721 w32_message_hwnd = win32_create_message_window();
1722 if (parent_message_hwnd != NULL)
1723 PostMessage(parent_message_hwnd, WM_USER_MESSAGE, w32_pseudo_id, (LPARAM)w32_message_hwnd);
1725 /* push a zero on the stack (we are the child) */
1733 /* continue from next op */
1734 PL_op = PL_op->op_next;
1738 volatile int oldscope = 1; /* We are responsible for all scopes */
1741 JMPENV_PUSH(status);
1745 /* We may have additional unclosed scopes if fork() was called
1746 * from within a BEGIN block. See perlfork.pod for more details.
1747 * We cannot clean up these other scopes because they belong to a
1748 * different interpreter, but we also cannot leave PL_scopestack_ix
1749 * dangling because that can trigger an assertion in perl_destruct().
1751 if (PL_scopestack_ix > oldscope) {
1752 PL_scopestack[oldscope-1] = PL_scopestack[PL_scopestack_ix-1];
1753 PL_scopestack_ix = oldscope;
1758 while (PL_scopestack_ix > oldscope)
1761 PL_curstash = PL_defstash;
1762 if (PL_curstash != PL_defstash) {
1763 SvREFCNT_dec(PL_curstash);
1764 PL_curstash = (HV *)SvREFCNT_inc(PL_defstash);
1766 if (PL_endav && !PL_minus_c) {
1767 PERL_SET_PHASE(PERL_PHASE_END);
1768 call_list(oldscope, PL_endav);
1770 status = STATUS_EXIT;
1774 POPSTACK_TO(PL_mainstack);
1775 PL_op = PL_restartop;
1776 PL_restartop = (OP*)NULL;
1779 PerlIO_printf(Perl_error_log, "panic: restartop\n");
1786 /* XXX hack to avoid perl_destruct() freeing optree */
1787 win32_checkTLS(my_perl);
1788 PL_main_root = (OP*)NULL;
1791 win32_checkTLS(my_perl);
1792 /* close the std handles to avoid fd leaks */
1794 do_close(PL_stdingv, FALSE);
1795 do_close(gv_fetchpv("STDOUT", TRUE, SVt_PVIO), FALSE); /* PL_stdoutgv - ISAGN */
1796 do_close(PL_stderrgv, FALSE);
1799 /* destroy everything (waits for any pseudo-forked children) */
1800 win32_checkTLS(my_perl);
1801 perl_destruct(my_perl);
1802 win32_checkTLS(my_perl);
1805 #ifdef PERL_SYNC_FORK
1808 return (DWORD)status;
1811 #endif /* USE_ITHREADS */
1814 PerlProcFork(struct IPerlProc* piPerl)
1822 if (w32_num_pseudo_children >= MAXIMUM_WAIT_OBJECTS) {
1826 h = new CPerlHost(*(CPerlHost*)w32_internal_host);
1827 PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHX,
1830 h->m_pHostperlMemShared,
1831 h->m_pHostperlMemParse,
1833 h->m_pHostperlStdIO,
1839 new_perl->Isys_intern.internal_host = h;
1840 h->host_perl = new_perl;
1841 # ifdef PERL_SYNC_FORK
1842 id = win32_start_child((LPVOID)new_perl);
1845 if (w32_message_hwnd == INVALID_HANDLE_VALUE)
1846 w32_message_hwnd = win32_create_message_window();
1847 new_perl->Isys_intern.message_hwnd = w32_message_hwnd;
1848 w32_pseudo_child_message_hwnds[w32_num_pseudo_children] =
1849 (w32_message_hwnd == NULL) ? (HWND)NULL : (HWND)INVALID_HANDLE_VALUE;
1850 # ifdef USE_RTL_THREAD_API
1851 handle = (HANDLE)_beginthreadex((void*)NULL, 0, win32_start_child,
1852 (void*)new_perl, 0, (unsigned*)&id);
1854 handle = CreateThread(NULL, 0, win32_start_child,
1855 (LPVOID)new_perl, 0, &id);
1857 PERL_SET_THX(aTHX); /* XXX perl_clone*() set TLS */
1862 w32_pseudo_child_handles[w32_num_pseudo_children] = handle;
1863 w32_pseudo_child_pids[w32_num_pseudo_children] = id;
1864 w32_pseudo_child_sigterm[w32_num_pseudo_children] = 0;
1865 ++w32_num_pseudo_children;
1869 win32_croak_not_implemented("fork()");
1871 #endif /* USE_ITHREADS */
1875 PerlProcGetpid(struct IPerlProc* piPerl)
1877 return win32_getpid();
1881 PerlProcDynaLoader(struct IPerlProc* piPerl, const char* filename)
1883 return win32_dynaload(filename);
1887 PerlProcGetOSError(struct IPerlProc* piPerl, SV* sv, DWORD dwErr)
1889 win32_str_os_error(sv, dwErr);
1893 PerlProcSpawnvp(struct IPerlProc* piPerl, int mode, const char *cmdname, const char *const *argv)
1895 return win32_spawnvp(mode, cmdname, argv);
1899 PerlProcLastHost(struct IPerlProc* piPerl)
1901 /* this dTHX is unused in an optimized build since CPerlHost::num_hosts
1904 CPerlHost *h = (CPerlHost*)w32_internal_host;
1905 return h->LastHost();
1908 const struct IPerlProc perlProc =
1942 PerlProcGetTimeOfDay
1950 CPerlHost::CPerlHost(void)
1952 /* Construct a host from scratch */
1953 InterlockedIncrement(&num_hosts);
1954 m_pvDir = new VDir();
1955 m_pVMem = new VMem();
1956 m_pVMemShared = new VMem();
1957 m_pVMemParse = new VMem();
1959 m_pvDir->Init(NULL, m_pVMem);
1962 m_lppEnvList = NULL;
1965 CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
1966 CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
1967 CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
1968 CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
1969 CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
1970 CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
1971 CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
1972 CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
1973 CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
1975 m_pHostperlMem = &m_hostperlMem;
1976 m_pHostperlMemShared = &m_hostperlMemShared;
1977 m_pHostperlMemParse = &m_hostperlMemParse;
1978 m_pHostperlEnv = &m_hostperlEnv;
1979 m_pHostperlStdIO = &m_hostperlStdIO;
1980 m_pHostperlLIO = &m_hostperlLIO;
1981 m_pHostperlDir = &m_hostperlDir;
1982 m_pHostperlSock = &m_hostperlSock;
1983 m_pHostperlProc = &m_hostperlProc;
1986 #define SETUPEXCHANGE(xptr, iptr, table) \
1997 CPerlHost::CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
1998 struct IPerlMem** ppMemParse, struct IPerlEnv** ppEnv,
1999 struct IPerlStdIO** ppStdIO, struct IPerlLIO** ppLIO,
2000 struct IPerlDir** ppDir, struct IPerlSock** ppSock,
2001 struct IPerlProc** ppProc)
2003 InterlockedIncrement(&num_hosts);
2004 m_pvDir = new VDir(0);
2005 m_pVMem = new VMem();
2006 m_pVMemShared = new VMem();
2007 m_pVMemParse = new VMem();
2009 m_pvDir->Init(NULL, m_pVMem);
2012 m_lppEnvList = NULL;
2013 m_bTopLevel = FALSE;
2015 CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2016 CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2017 CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2018 CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2019 CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2020 CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2021 CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2022 CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2023 CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2025 SETUPEXCHANGE(ppMem, m_pHostperlMem, m_hostperlMem);
2026 SETUPEXCHANGE(ppMemShared, m_pHostperlMemShared, m_hostperlMemShared);
2027 SETUPEXCHANGE(ppMemParse, m_pHostperlMemParse, m_hostperlMemParse);
2028 SETUPEXCHANGE(ppEnv, m_pHostperlEnv, m_hostperlEnv);
2029 SETUPEXCHANGE(ppStdIO, m_pHostperlStdIO, m_hostperlStdIO);
2030 SETUPEXCHANGE(ppLIO, m_pHostperlLIO, m_hostperlLIO);
2031 SETUPEXCHANGE(ppDir, m_pHostperlDir, m_hostperlDir);
2032 SETUPEXCHANGE(ppSock, m_pHostperlSock, m_hostperlSock);
2033 SETUPEXCHANGE(ppProc, m_pHostperlProc, m_hostperlProc);
2035 #undef SETUPEXCHANGE
2037 CPerlHost::CPerlHost(CPerlHost& host)
2039 /* Construct a host from another host */
2040 InterlockedIncrement(&num_hosts);
2041 m_pVMem = new VMem();
2042 m_pVMemShared = host.GetMemShared();
2043 m_pVMemParse = host.GetMemParse();
2045 /* duplicate directory info */
2046 m_pvDir = new VDir(0);
2047 m_pvDir->Init(host.GetDir(), m_pVMem);
2049 CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2050 CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2051 CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2052 CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2053 CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2054 CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2055 CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2056 CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2057 CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2058 m_pHostperlMem = &m_hostperlMem;
2059 m_pHostperlMemShared = &m_hostperlMemShared;
2060 m_pHostperlMemParse = &m_hostperlMemParse;
2061 m_pHostperlEnv = &m_hostperlEnv;
2062 m_pHostperlStdIO = &m_hostperlStdIO;
2063 m_pHostperlLIO = &m_hostperlLIO;
2064 m_pHostperlDir = &m_hostperlDir;
2065 m_pHostperlSock = &m_hostperlSock;
2066 m_pHostperlProc = &m_hostperlProc;
2069 m_lppEnvList = NULL;
2070 m_bTopLevel = FALSE;
2072 /* duplicate environment info */
2075 while(lpPtr = host.GetIndex(dwIndex))
2079 CPerlHost::~CPerlHost(void)
2082 InterlockedDecrement(&num_hosts);
2084 m_pVMemParse->Release();
2085 m_pVMemShared->Release();
2090 CPerlHost::Find(LPCSTR lpStr)
2093 LPSTR* lppPtr = Lookup(lpStr);
2094 if(lppPtr != NULL) {
2095 for(lpPtr = *lppPtr; *lpPtr != '\0' && *lpPtr != '='; ++lpPtr)
2107 lookup(const void *arg1, const void *arg2)
2108 { // Compare strings
2112 ptr1 = *(char**)arg1;
2113 ptr2 = *(char**)arg2;
2117 if(c1 == '\0' || c1 == '=') {
2118 if(c2 == '\0' || c2 == '=')
2121 return -1; // string 1 < string 2
2123 else if(c2 == '\0' || c2 == '=')
2124 return 1; // string 1 > string 2
2130 return -1; // string 1 < string 2
2132 return 1; // string 1 > string 2
2140 CPerlHost::Lookup(LPCSTR lpStr)
2144 return (LPSTR*)bsearch(&lpStr, m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), lookup);
2148 compare(const void *arg1, const void *arg2)
2149 { // Compare strings
2153 ptr1 = *(char**)arg1;
2154 ptr2 = *(char**)arg2;
2158 if(c1 == '\0' || c1 == '=') {
2162 return -1; // string 1 < string 2
2164 else if(c2 == '\0' || c2 == '=')
2165 return 1; // string 1 > string 2
2171 return -1; // string 1 < string 2
2173 return 1; // string 1 > string 2
2181 CPerlHost::Add(LPCSTR lpStr)
2184 STRLEN length = strlen(lpStr)+1;
2187 lpPtr = Lookup(lpStr);
2188 if (lpPtr != NULL) {
2189 // must allocate things via host memory allocation functions
2190 // rather than perl's Renew() et al, as the perl interpreter
2191 // may either not be initialized enough when we allocate these,
2192 // or may already be dead when we go to free these
2193 *lpPtr = (char*)Realloc(*lpPtr, length * sizeof(char));
2194 strcpy(*lpPtr, lpStr);
2197 m_lppEnvList = (LPSTR*)Realloc(m_lppEnvList, (m_dwEnvCount+1) * sizeof(LPSTR));
2199 m_lppEnvList[m_dwEnvCount] = (char*)Malloc(length * sizeof(char));
2200 if (m_lppEnvList[m_dwEnvCount] != NULL) {
2201 strcpy(m_lppEnvList[m_dwEnvCount], lpStr);
2203 qsort(m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), compare);
2210 CPerlHost::CalculateEnvironmentSpace(void)
2214 for(index = 0; index < m_dwEnvCount; ++index)
2215 dwSize += strlen(m_lppEnvList[index]) + 1;
2221 CPerlHost::FreeLocalEnvironmentStrings(LPSTR lpStr)
2227 CPerlHost::GetChildDir(void)
2232 Newx(ptr, MAX_PATH+1, char);
2233 m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr);
2234 length = strlen(ptr);
2236 if ((ptr[length-1] == '\\') || (ptr[length-1] == '/'))
2243 CPerlHost::FreeChildDir(char* pStr)
2249 CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
2251 LPSTR lpStr, lpPtr, lpEnvPtr, lpTmp, lpLocalEnv, lpAllocPtr;
2252 DWORD dwSize, dwEnvIndex;
2253 int nLength, compVal;
2255 // get the process environment strings
2256 lpAllocPtr = lpTmp = (LPSTR)win32_getenvironmentstrings();
2258 // step over current directory stuff
2259 while(*lpTmp == '=')
2260 lpTmp += strlen(lpTmp) + 1;
2262 // save the start of the environment strings
2264 for(dwSize = 1; *lpTmp != '\0'; lpTmp += strlen(lpTmp) + 1) {
2265 // calculate the size of the environment strings
2266 dwSize += strlen(lpTmp) + 1;
2269 // add the size of current directories
2270 dwSize += vDir.CalculateEnvironmentSpace();
2272 // add the additional space used by changes made to the environment
2273 dwSize += CalculateEnvironmentSpace();
2275 Newx(lpStr, dwSize, char);
2278 // build the local environment
2279 lpStr = vDir.BuildEnvironmentSpace(lpStr);
2282 lpLocalEnv = GetIndex(dwEnvIndex);
2283 while(*lpEnvPtr != '\0') {
2285 // all environment overrides have been added
2286 // so copy string into place
2287 strcpy(lpStr, lpEnvPtr);
2288 nLength = strlen(lpEnvPtr) + 1;
2290 lpEnvPtr += nLength;
2293 // determine which string to copy next
2294 compVal = compare(&lpEnvPtr, &lpLocalEnv);
2296 strcpy(lpStr, lpEnvPtr);
2297 nLength = strlen(lpEnvPtr) + 1;
2299 lpEnvPtr += nLength;
2302 char *ptr = strchr(lpLocalEnv, '=');
2304 strcpy(lpStr, lpLocalEnv);
2305 lpStr += strlen(lpLocalEnv) + 1;
2307 lpLocalEnv = GetIndex(dwEnvIndex);
2309 // this string was replaced
2310 lpEnvPtr += strlen(lpEnvPtr) + 1;
2317 // still have environment overrides to add
2318 // so copy the strings into place if not an override
2319 char *ptr = strchr(lpLocalEnv, '=');
2321 strcpy(lpStr, lpLocalEnv);
2322 lpStr += strlen(lpLocalEnv) + 1;
2324 lpLocalEnv = GetIndex(dwEnvIndex);
2331 // release the process environment strings
2332 win32_freeenvironmentstrings(lpAllocPtr);
2338 CPerlHost::Reset(void)
2340 if(m_lppEnvList != NULL) {
2341 for(DWORD index = 0; index < m_dwEnvCount; ++index) {
2342 Free(m_lppEnvList[index]);
2343 m_lppEnvList[index] = NULL;
2348 m_lppEnvList = NULL;
2352 CPerlHost::Clearenv(void)
2355 LPSTR lpPtr, lpStr, lpEnvPtr;
2356 if (m_lppEnvList != NULL) {
2357 /* set every entry to an empty string */
2358 for(DWORD index = 0; index < m_dwEnvCount; ++index) {
2359 char* ptr = strchr(m_lppEnvList[index], '=');
2366 /* get the process environment strings */
2367 lpStr = lpEnvPtr = (LPSTR)win32_getenvironmentstrings();
2369 /* step over current directory stuff */
2370 while(*lpStr == '=')
2371 lpStr += strlen(lpStr) + 1;
2374 lpPtr = strchr(lpStr, '=');
2380 (void)win32_putenv(lpStr);
2383 lpStr += strlen(lpStr) + 1;
2386 win32_freeenvironmentstrings(lpEnvPtr);
2391 CPerlHost::Getenv(const char *varname)
2394 char *pEnv = Find(varname);
2398 return win32_getenv(varname);
2402 CPerlHost::Putenv(const char *envstring)
2406 return win32_putenv(envstring);
2412 CPerlHost::Chdir(const char *dirname)
2419 ret = m_pvDir->SetCurrentDirectoryA((char*)dirname);
2426 #endif /* ___PerlHost_H___ */