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.
11 #define CHECK_HOST_INTERP
14 #ifndef ___PerlHost_H___
15 #define ___PerlHost_H___
24 #ifndef WC_NO_BEST_FIT_CHARS
25 # define WC_NO_BEST_FIT_CHARS 0x00000400
29 extern char * g_win32_get_privlib(const char *pl, STRLEN *const len);
30 extern char * g_win32_get_sitelib(const char *pl, STRLEN *const len);
31 extern char * g_win32_get_vendorlib(const char *pl,
33 extern char * g_getlogin(void);
41 CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
42 struct IPerlMem** ppMemParse, struct IPerlEnv** ppEnv,
43 struct IPerlStdIO** ppStdIO, struct IPerlLIO** ppLIO,
44 struct IPerlDir** ppDir, struct IPerlSock** ppSock,
45 struct IPerlProc** ppProc);
46 CPerlHost(CPerlHost& host);
49 static CPerlHost* IPerlMem2Host(struct IPerlMem* piPerl);
50 static CPerlHost* IPerlMemShared2Host(struct IPerlMem* piPerl);
51 static CPerlHost* IPerlMemParse2Host(struct IPerlMem* piPerl);
52 static CPerlHost* IPerlEnv2Host(struct IPerlEnv* piPerl);
53 static CPerlHost* IPerlStdIO2Host(struct IPerlStdIO* piPerl);
54 static CPerlHost* IPerlLIO2Host(struct IPerlLIO* piPerl);
55 static CPerlHost* IPerlDir2Host(struct IPerlDir* piPerl);
56 static CPerlHost* IPerlSock2Host(struct IPerlSock* piPerl);
57 static CPerlHost* IPerlProc2Host(struct IPerlProc* piPerl);
59 BOOL PerlCreate(void);
60 int PerlParse(int argc, char** argv, char** env);
62 void PerlDestroy(void);
65 /* Locks provided but should be unnecessary as this is private pool */
66 inline void* Malloc(size_t size) { return m_pVMem->Malloc(size); };
67 inline void* Realloc(void* ptr, size_t size) { return m_pVMem->Realloc(ptr, size); };
68 inline void Free(void* ptr) { m_pVMem->Free(ptr); };
69 inline void* Calloc(size_t num, size_t size)
71 size_t count = num*size;
72 void* lpVoid = Malloc(count);
74 ZeroMemory(lpVoid, count);
77 inline void GetLock(void) { m_pVMem->GetLock(); };
78 inline void FreeLock(void) { m_pVMem->FreeLock(); };
79 inline int IsLocked(void) { return m_pVMem->IsLocked(); };
82 /* Locks used to serialize access to the pool */
83 inline void GetLockShared(void) { m_pVMemShared->GetLock(); };
84 inline void FreeLockShared(void) { m_pVMemShared->FreeLock(); };
85 inline int IsLockedShared(void) { return m_pVMemShared->IsLocked(); };
86 inline void* MallocShared(size_t size)
90 result = m_pVMemShared->Malloc(size);
94 inline void* ReallocShared(void* ptr, size_t size)
98 result = m_pVMemShared->Realloc(ptr, size);
102 inline void FreeShared(void* ptr)
105 m_pVMemShared->Free(ptr);
108 inline void* CallocShared(size_t num, size_t size)
110 size_t count = num*size;
111 void* lpVoid = MallocShared(count);
113 ZeroMemory(lpVoid, count);
118 /* Assume something else is using locks to mangaging serialize
121 inline void GetLockParse(void) { m_pVMemParse->GetLock(); };
122 inline void FreeLockParse(void) { m_pVMemParse->FreeLock(); };
123 inline int IsLockedParse(void) { return m_pVMemParse->IsLocked(); };
124 inline void* MallocParse(size_t size) { return m_pVMemParse->Malloc(size); };
125 inline void* ReallocParse(void* ptr, size_t size) { return m_pVMemParse->Realloc(ptr, size); };
126 inline void FreeParse(void* ptr) { m_pVMemParse->Free(ptr); };
127 inline void* CallocParse(size_t num, size_t size)
129 size_t count = num*size;
130 void* lpVoid = MallocParse(count);
132 ZeroMemory(lpVoid, count);
137 char *Getenv(const char *varname);
138 int Putenv(const char *envstring);
139 inline char *Getenv(const char *varname, unsigned long *len)
142 char *e = Getenv(varname);
147 void* CreateChildEnv(void) { return CreateLocalEnvironmentStrings(*m_pvDir); };
148 void FreeChildEnv(void* pStr) { FreeLocalEnvironmentStrings((char*)pStr); };
149 char* GetChildDir(void);
150 void FreeChildDir(char* pStr);
154 inline LPSTR GetIndex(DWORD &dwIndex)
156 if(dwIndex < m_dwEnvCount)
159 return m_lppEnvList[dwIndex-1];
165 LPSTR Find(LPCSTR lpStr);
166 void Add(LPCSTR lpStr);
168 LPSTR CreateLocalEnvironmentStrings(VDir &vDir);
169 void FreeLocalEnvironmentStrings(LPSTR lpStr);
170 LPSTR* Lookup(LPCSTR lpStr);
171 DWORD CalculateEnvironmentSpace(void);
176 virtual int Chdir(const char *dirname);
180 void Exit(int status);
181 void _Exit(int status);
182 int Execl(const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3);
183 int Execv(const char *cmdname, const char *const *argv);
184 int Execvp(const char *cmdname, const char *const *argv);
186 inline VMem* GetMemShared(void) { m_pVMemShared->AddRef(); return m_pVMemShared; };
187 inline VMem* GetMemParse(void) { m_pVMemParse->AddRef(); return m_pVMemParse; };
188 inline VDir* GetDir(void) { return m_pvDir; };
192 struct IPerlMem m_hostperlMem;
193 struct IPerlMem m_hostperlMemShared;
194 struct IPerlMem m_hostperlMemParse;
195 struct IPerlEnv m_hostperlEnv;
196 struct IPerlStdIO m_hostperlStdIO;
197 struct IPerlLIO m_hostperlLIO;
198 struct IPerlDir m_hostperlDir;
199 struct IPerlSock m_hostperlSock;
200 struct IPerlProc m_hostperlProc;
202 struct IPerlMem* m_pHostperlMem;
203 struct IPerlMem* m_pHostperlMemShared;
204 struct IPerlMem* m_pHostperlMemParse;
205 struct IPerlEnv* m_pHostperlEnv;
206 struct IPerlStdIO* m_pHostperlStdIO;
207 struct IPerlLIO* m_pHostperlLIO;
208 struct IPerlDir* m_pHostperlDir;
209 struct IPerlSock* m_pHostperlSock;
210 struct IPerlProc* m_pHostperlProc;
212 inline char* MapPathA(const char *pInName) { return m_pvDir->MapPathA(pInName); };
213 inline WCHAR* MapPathW(const WCHAR *pInName) { return m_pvDir->MapPathW(pInName); };
223 BOOL m_bTopLevel; // is this a toplevel host?
224 static long num_hosts;
226 inline int LastHost(void) { return num_hosts == 1L; };
227 struct interpreter *host_perl;
230 long CPerlHost::num_hosts = 0L;
232 extern "C" void win32_checkTLS(struct interpreter *host_perl);
234 #define STRUCT2RAWPTR(x, y) (CPerlHost*)(((LPBYTE)x)-offsetof(CPerlHost, y))
235 #ifdef CHECK_HOST_INTERP
236 inline CPerlHost* CheckInterp(CPerlHost *host)
238 win32_checkTLS(host->host_perl);
241 #define STRUCT2PTR(x, y) CheckInterp(STRUCT2RAWPTR(x, y))
243 #define STRUCT2PTR(x, y) STRUCT2RAWPTR(x, y)
246 inline CPerlHost* IPerlMem2Host(struct IPerlMem* piPerl)
248 return STRUCT2RAWPTR(piPerl, m_hostperlMem);
251 inline CPerlHost* IPerlMemShared2Host(struct IPerlMem* piPerl)
253 return STRUCT2RAWPTR(piPerl, m_hostperlMemShared);
256 inline CPerlHost* IPerlMemParse2Host(struct IPerlMem* piPerl)
258 return STRUCT2RAWPTR(piPerl, m_hostperlMemParse);
261 inline CPerlHost* IPerlEnv2Host(struct IPerlEnv* piPerl)
263 return STRUCT2PTR(piPerl, m_hostperlEnv);
266 inline CPerlHost* IPerlStdIO2Host(struct IPerlStdIO* piPerl)
268 return STRUCT2PTR(piPerl, m_hostperlStdIO);
271 inline CPerlHost* IPerlLIO2Host(struct IPerlLIO* piPerl)
273 return STRUCT2PTR(piPerl, m_hostperlLIO);
276 inline CPerlHost* IPerlDir2Host(struct IPerlDir* piPerl)
278 return STRUCT2PTR(piPerl, m_hostperlDir);
281 inline CPerlHost* IPerlSock2Host(struct IPerlSock* piPerl)
283 return STRUCT2PTR(piPerl, m_hostperlSock);
286 inline CPerlHost* IPerlProc2Host(struct IPerlProc* piPerl)
288 return STRUCT2PTR(piPerl, m_hostperlProc);
294 #define IPERL2HOST(x) IPerlMem2Host(x)
298 PerlMemMalloc(struct IPerlMem* piPerl, size_t size)
300 return IPERL2HOST(piPerl)->Malloc(size);
303 PerlMemRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
305 return IPERL2HOST(piPerl)->Realloc(ptr, size);
308 PerlMemFree(struct IPerlMem* piPerl, void* ptr)
310 IPERL2HOST(piPerl)->Free(ptr);
313 PerlMemCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
315 return IPERL2HOST(piPerl)->Calloc(num, size);
319 PerlMemGetLock(struct IPerlMem* piPerl)
321 IPERL2HOST(piPerl)->GetLock();
325 PerlMemFreeLock(struct IPerlMem* piPerl)
327 IPERL2HOST(piPerl)->FreeLock();
331 PerlMemIsLocked(struct IPerlMem* piPerl)
333 return IPERL2HOST(piPerl)->IsLocked();
336 struct IPerlMem perlMem =
348 #define IPERL2HOST(x) IPerlMemShared2Host(x)
352 PerlMemSharedMalloc(struct IPerlMem* piPerl, size_t size)
354 return IPERL2HOST(piPerl)->MallocShared(size);
357 PerlMemSharedRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
359 return IPERL2HOST(piPerl)->ReallocShared(ptr, size);
362 PerlMemSharedFree(struct IPerlMem* piPerl, void* ptr)
364 IPERL2HOST(piPerl)->FreeShared(ptr);
367 PerlMemSharedCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
369 return IPERL2HOST(piPerl)->CallocShared(num, size);
373 PerlMemSharedGetLock(struct IPerlMem* piPerl)
375 IPERL2HOST(piPerl)->GetLockShared();
379 PerlMemSharedFreeLock(struct IPerlMem* piPerl)
381 IPERL2HOST(piPerl)->FreeLockShared();
385 PerlMemSharedIsLocked(struct IPerlMem* piPerl)
387 return IPERL2HOST(piPerl)->IsLockedShared();
390 struct IPerlMem perlMemShared =
393 PerlMemSharedRealloc,
396 PerlMemSharedGetLock,
397 PerlMemSharedFreeLock,
398 PerlMemSharedIsLocked,
402 #define IPERL2HOST(x) IPerlMemParse2Host(x)
406 PerlMemParseMalloc(struct IPerlMem* piPerl, size_t size)
408 return IPERL2HOST(piPerl)->MallocParse(size);
411 PerlMemParseRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
413 return IPERL2HOST(piPerl)->ReallocParse(ptr, size);
416 PerlMemParseFree(struct IPerlMem* piPerl, void* ptr)
418 IPERL2HOST(piPerl)->FreeParse(ptr);
421 PerlMemParseCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
423 return IPERL2HOST(piPerl)->CallocParse(num, size);
427 PerlMemParseGetLock(struct IPerlMem* piPerl)
429 IPERL2HOST(piPerl)->GetLockParse();
433 PerlMemParseFreeLock(struct IPerlMem* piPerl)
435 IPERL2HOST(piPerl)->FreeLockParse();
439 PerlMemParseIsLocked(struct IPerlMem* piPerl)
441 return IPERL2HOST(piPerl)->IsLockedParse();
444 struct IPerlMem perlMemParse =
451 PerlMemParseFreeLock,
452 PerlMemParseIsLocked,
457 #define IPERL2HOST(x) IPerlEnv2Host(x)
461 PerlEnvGetenv(struct IPerlEnv* piPerl, const char *varname)
463 return IPERL2HOST(piPerl)->Getenv(varname);
467 PerlEnvPutenv(struct IPerlEnv* piPerl, const char *envstring)
469 return IPERL2HOST(piPerl)->Putenv(envstring);
473 PerlEnvGetenv_len(struct IPerlEnv* piPerl, const char* varname, unsigned long* len)
475 return IPERL2HOST(piPerl)->Getenv(varname, len);
479 PerlEnvUname(struct IPerlEnv* piPerl, struct utsname *name)
481 return win32_uname(name);
485 PerlEnvClearenv(struct IPerlEnv* piPerl)
487 IPERL2HOST(piPerl)->Clearenv();
491 PerlEnvGetChildenv(struct IPerlEnv* piPerl)
493 return IPERL2HOST(piPerl)->CreateChildEnv();
497 PerlEnvFreeChildenv(struct IPerlEnv* piPerl, void* childEnv)
499 IPERL2HOST(piPerl)->FreeChildEnv(childEnv);
503 PerlEnvGetChilddir(struct IPerlEnv* piPerl)
505 return IPERL2HOST(piPerl)->GetChildDir();
509 PerlEnvFreeChilddir(struct IPerlEnv* piPerl, char* childDir)
511 IPERL2HOST(piPerl)->FreeChildDir(childDir);
515 PerlEnvOsId(struct IPerlEnv* piPerl)
517 return win32_os_id();
521 PerlEnvLibPath(struct IPerlEnv* piPerl, const char *pl, STRLEN *const len)
523 return g_win32_get_privlib(pl, len);
527 PerlEnvSiteLibPath(struct IPerlEnv* piPerl, const char *pl, STRLEN *const len)
529 return g_win32_get_sitelib(pl, len);
533 PerlEnvVendorLibPath(struct IPerlEnv* piPerl, const char *pl,
536 return g_win32_get_vendorlib(pl, len);
540 PerlEnvGetChildIO(struct IPerlEnv* piPerl, child_IO_table* ptr)
542 win32_get_child_IO(ptr);
545 struct IPerlEnv perlEnv =
559 PerlEnvVendorLibPath,
564 #define IPERL2HOST(x) IPerlStdIO2Host(x)
568 PerlStdIOStdin(struct IPerlStdIO* piPerl)
570 return win32_stdin();
574 PerlStdIOStdout(struct IPerlStdIO* piPerl)
576 return win32_stdout();
580 PerlStdIOStderr(struct IPerlStdIO* piPerl)
582 return win32_stderr();
586 PerlStdIOOpen(struct IPerlStdIO* piPerl, const char *path, const char *mode)
588 return win32_fopen(path, mode);
592 PerlStdIOClose(struct IPerlStdIO* piPerl, FILE* pf)
594 return win32_fclose((pf));
598 PerlStdIOEof(struct IPerlStdIO* piPerl, FILE* pf)
600 return win32_feof(pf);
604 PerlStdIOError(struct IPerlStdIO* piPerl, FILE* pf)
606 return win32_ferror(pf);
610 PerlStdIOClearerr(struct IPerlStdIO* piPerl, FILE* pf)
616 PerlStdIOGetc(struct IPerlStdIO* piPerl, FILE* pf)
618 return win32_getc(pf);
622 PerlStdIOGetBase(struct IPerlStdIO* piPerl, FILE* pf)
633 PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, FILE* pf)
637 return FILE_bufsiz(f);
644 PerlStdIOGetCnt(struct IPerlStdIO* piPerl, FILE* pf)
655 PerlStdIOGetPtr(struct IPerlStdIO* piPerl, FILE* pf)
666 PerlStdIOGets(struct IPerlStdIO* piPerl, FILE* pf, char* s, int n)
668 return win32_fgets(s, n, pf);
672 PerlStdIOPutc(struct IPerlStdIO* piPerl, FILE* pf, int c)
674 return win32_fputc(c, pf);
678 PerlStdIOPuts(struct IPerlStdIO* piPerl, FILE* pf, const char *s)
680 return win32_fputs(s, pf);
684 PerlStdIOFlush(struct IPerlStdIO* piPerl, FILE* pf)
686 return win32_fflush(pf);
690 PerlStdIOUngetc(struct IPerlStdIO* piPerl,int c, FILE* pf)
692 return win32_ungetc(c, pf);
696 PerlStdIOFileno(struct IPerlStdIO* piPerl, FILE* pf)
698 return win32_fileno(pf);
702 PerlStdIOFdopen(struct IPerlStdIO* piPerl, int fd, const char *mode)
704 return win32_fdopen(fd, mode);
708 PerlStdIOReopen(struct IPerlStdIO* piPerl, const char*path, const char*mode, FILE* pf)
710 return win32_freopen(path, mode, (FILE*)pf);
714 PerlStdIORead(struct IPerlStdIO* piPerl, void *buffer, Size_t size, Size_t count, FILE* pf)
716 return win32_fread(buffer, size, count, pf);
720 PerlStdIOWrite(struct IPerlStdIO* piPerl, const void *buffer, Size_t size, Size_t count, FILE* pf)
722 return win32_fwrite(buffer, size, count, pf);
726 PerlStdIOSetBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer)
728 win32_setbuf(pf, buffer);
732 PerlStdIOSetVBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer, int type, Size_t size)
734 return win32_setvbuf(pf, buffer, type, size);
738 PerlStdIOSetCnt(struct IPerlStdIO* piPerl, FILE* pf, int n)
740 #ifdef STDIO_CNT_LVALUE
747 PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, STDCHAR * ptr)
749 #ifdef STDIO_PTR_LVALUE
756 PerlStdIOSetlinebuf(struct IPerlStdIO* piPerl, FILE* pf)
758 win32_setvbuf(pf, NULL, _IOLBF, 0);
762 PerlStdIOPrintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format,...)
765 va_start(arglist, format);
766 return win32_vfprintf(pf, format, arglist);
770 PerlStdIOVprintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format, va_list arglist)
772 return win32_vfprintf(pf, format, arglist);
776 PerlStdIOTell(struct IPerlStdIO* piPerl, FILE* pf)
778 return win32_ftell(pf);
782 PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, Off_t offset, int origin)
784 return win32_fseek(pf, offset, origin);
788 PerlStdIORewind(struct IPerlStdIO* piPerl, FILE* pf)
794 PerlStdIOTmpfile(struct IPerlStdIO* piPerl)
796 return win32_tmpfile();
800 PerlStdIOGetpos(struct IPerlStdIO* piPerl, FILE* pf, Fpos_t *p)
802 return win32_fgetpos(pf, p);
806 PerlStdIOSetpos(struct IPerlStdIO* piPerl, FILE* pf, const Fpos_t *p)
808 return win32_fsetpos(pf, p);
811 PerlStdIOInit(struct IPerlStdIO* piPerl)
816 PerlStdIOInitOSExtras(struct IPerlStdIO* piPerl)
818 Perl_init_os_extras();
822 PerlStdIOOpenOSfhandle(struct IPerlStdIO* piPerl, intptr_t osfhandle, int flags)
824 return win32_open_osfhandle(osfhandle, flags);
828 PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum)
830 return win32_get_osfhandle(filenum);
834 PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf)
840 int fileno = win32_dup(win32_fileno(pf));
842 /* open the file in the same mode */
844 if((pf)->flags & _F_READ) {
848 else if((pf)->flags & _F_WRIT) {
852 else if((pf)->flags & _F_RDWR) {
858 if((pf)->_flag & _IOREAD) {
862 else if((pf)->_flag & _IOWRT) {
866 else if((pf)->_flag & _IORW) {
873 /* it appears that the binmode is attached to the
874 * file descriptor so binmode files will be handled
877 pfdup = win32_fdopen(fileno, mode);
879 /* move the file pointer to the same position */
880 if (!fgetpos(pf, &pos)) {
881 fsetpos(pfdup, &pos);
889 struct IPerlStdIO perlStdIO =
928 PerlStdIOInitOSExtras,
934 #define IPERL2HOST(x) IPerlLIO2Host(x)
938 PerlLIOAccess(struct IPerlLIO* piPerl, const char *path, int mode)
940 return win32_access(path, mode);
944 PerlLIOChmod(struct IPerlLIO* piPerl, const char *filename, int pmode)
946 return win32_chmod(filename, pmode);
950 PerlLIOChown(struct IPerlLIO* piPerl, const char *filename, uid_t owner, gid_t group)
952 return chown(filename, owner, group);
956 PerlLIOChsize(struct IPerlLIO* piPerl, int handle, Off_t size)
958 return win32_chsize(handle, size);
962 PerlLIOClose(struct IPerlLIO* piPerl, int handle)
964 return win32_close(handle);
968 PerlLIODup(struct IPerlLIO* piPerl, int handle)
970 return win32_dup(handle);
974 PerlLIODup2(struct IPerlLIO* piPerl, int handle1, int handle2)
976 return win32_dup2(handle1, handle2);
980 PerlLIOFlock(struct IPerlLIO* piPerl, int fd, int oper)
982 return win32_flock(fd, oper);
986 PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, Stat_t *buffer)
988 return win32_fstat(handle, buffer);
992 PerlLIOIOCtl(struct IPerlLIO* piPerl, int i, unsigned int u, char *data)
997 /* mauke says using memcpy avoids alignment issues */
998 memcpy(&u_long_arg, data, sizeof u_long_arg);
999 retval = win32_ioctlsocket((SOCKET)i, (long)u, &u_long_arg);
1000 memcpy(data, &u_long_arg, sizeof u_long_arg);
1005 PerlLIOIsatty(struct IPerlLIO* piPerl, int fd)
1007 /* The Microsoft isatty() function returns true for *all*
1008 * character mode devices, including "nul". Our implementation
1009 * should only return true if the handle has a console buffer.
1012 HANDLE fh = (HANDLE)_get_osfhandle(fd);
1013 if (fh == (HANDLE)-1) {
1014 /* errno is already set to EBADF */
1018 if (GetConsoleMode(fh, &mode))
1026 PerlLIOLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
1028 return win32_link(oldname, newname);
1032 PerlLIOLseek(struct IPerlLIO* piPerl, int handle, Off_t offset, int origin)
1034 return win32_lseek(handle, offset, origin);
1038 PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
1040 return win32_stat(path, buffer);
1044 PerlLIOMktemp(struct IPerlLIO* piPerl, char *Template)
1046 return mktemp(Template);
1050 PerlLIOOpen(struct IPerlLIO* piPerl, const char *filename, int oflag)
1052 return win32_open(filename, oflag);
1056 PerlLIOOpen3(struct IPerlLIO* piPerl, const char *filename, int oflag, int pmode)
1058 return win32_open(filename, oflag, pmode);
1062 PerlLIORead(struct IPerlLIO* piPerl, int handle, void *buffer, unsigned int count)
1064 return win32_read(handle, buffer, count);
1068 PerlLIORename(struct IPerlLIO* piPerl, const char *OldFileName, const char *newname)
1070 return win32_rename(OldFileName, newname);
1074 PerlLIOSetmode(struct IPerlLIO* piPerl, int handle, int mode)
1076 return win32_setmode(handle, mode);
1080 PerlLIONameStat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
1082 return win32_stat(path, buffer);
1086 PerlLIOTmpnam(struct IPerlLIO* piPerl, char *string)
1088 return tmpnam(string);
1092 PerlLIOUmask(struct IPerlLIO* piPerl, int pmode)
1094 return umask(pmode);
1098 PerlLIOUnlink(struct IPerlLIO* piPerl, const char *filename)
1100 return win32_unlink(filename);
1104 PerlLIOUtime(struct IPerlLIO* piPerl, const char *filename, struct utimbuf *times)
1106 return win32_utime(filename, times);
1110 PerlLIOWrite(struct IPerlLIO* piPerl, int handle, const void *buffer, unsigned int count)
1112 return win32_write(handle, buffer, count);
1115 struct IPerlLIO perlLIO =
1147 #define IPERL2HOST(x) IPerlDir2Host(x)
1151 PerlDirMakedir(struct IPerlDir* piPerl, const char *dirname, int mode)
1153 return win32_mkdir(dirname, mode);
1157 PerlDirChdir(struct IPerlDir* piPerl, const char *dirname)
1159 return IPERL2HOST(piPerl)->Chdir(dirname);
1163 PerlDirRmdir(struct IPerlDir* piPerl, const char *dirname)
1165 return win32_rmdir(dirname);
1169 PerlDirClose(struct IPerlDir* piPerl, DIR *dirp)
1171 return win32_closedir(dirp);
1175 PerlDirOpen(struct IPerlDir* piPerl, const char *filename)
1177 return win32_opendir(filename);
1181 PerlDirRead(struct IPerlDir* piPerl, DIR *dirp)
1183 return win32_readdir(dirp);
1187 PerlDirRewind(struct IPerlDir* piPerl, DIR *dirp)
1189 win32_rewinddir(dirp);
1193 PerlDirSeek(struct IPerlDir* piPerl, DIR *dirp, long loc)
1195 win32_seekdir(dirp, loc);
1199 PerlDirTell(struct IPerlDir* piPerl, DIR *dirp)
1201 return win32_telldir(dirp);
1205 PerlDirMapPathA(struct IPerlDir* piPerl, const char* path)
1207 return IPERL2HOST(piPerl)->MapPathA(path);
1211 PerlDirMapPathW(struct IPerlDir* piPerl, const WCHAR* path)
1213 return IPERL2HOST(piPerl)->MapPathW(path);
1216 struct IPerlDir perlDir =
1234 PerlSockHtonl(struct IPerlSock* piPerl, u_long hostlong)
1236 return win32_htonl(hostlong);
1240 PerlSockHtons(struct IPerlSock* piPerl, u_short hostshort)
1242 return win32_htons(hostshort);
1246 PerlSockNtohl(struct IPerlSock* piPerl, u_long netlong)
1248 return win32_ntohl(netlong);
1252 PerlSockNtohs(struct IPerlSock* piPerl, u_short netshort)
1254 return win32_ntohs(netshort);
1257 SOCKET PerlSockAccept(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* addr, int* addrlen)
1259 return win32_accept(s, addr, addrlen);
1263 PerlSockBind(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
1265 return win32_bind(s, name, namelen);
1269 PerlSockConnect(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
1271 return win32_connect(s, name, namelen);
1275 PerlSockEndhostent(struct IPerlSock* piPerl)
1281 PerlSockEndnetent(struct IPerlSock* piPerl)
1287 PerlSockEndprotoent(struct IPerlSock* piPerl)
1289 win32_endprotoent();
1293 PerlSockEndservent(struct IPerlSock* piPerl)
1299 PerlSockGethostbyaddr(struct IPerlSock* piPerl, const char* addr, int len, int type)
1301 return win32_gethostbyaddr(addr, len, type);
1305 PerlSockGethostbyname(struct IPerlSock* piPerl, const char* name)
1307 return win32_gethostbyname(name);
1311 PerlSockGethostent(struct IPerlSock* piPerl)
1314 Perl_croak(aTHX_ "gethostent not implemented!\n");
1319 PerlSockGethostname(struct IPerlSock* piPerl, char* name, int namelen)
1321 return win32_gethostname(name, namelen);
1325 PerlSockGetnetbyaddr(struct IPerlSock* piPerl, long net, int type)
1327 return win32_getnetbyaddr(net, type);
1331 PerlSockGetnetbyname(struct IPerlSock* piPerl, const char *name)
1333 return win32_getnetbyname((char*)name);
1337 PerlSockGetnetent(struct IPerlSock* piPerl)
1339 return win32_getnetent();
1342 int PerlSockGetpeername(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
1344 return win32_getpeername(s, name, namelen);
1348 PerlSockGetprotobyname(struct IPerlSock* piPerl, const char* name)
1350 return win32_getprotobyname(name);
1354 PerlSockGetprotobynumber(struct IPerlSock* piPerl, int number)
1356 return win32_getprotobynumber(number);
1360 PerlSockGetprotoent(struct IPerlSock* piPerl)
1362 return win32_getprotoent();
1366 PerlSockGetservbyname(struct IPerlSock* piPerl, const char* name, const char* proto)
1368 return win32_getservbyname(name, proto);
1372 PerlSockGetservbyport(struct IPerlSock* piPerl, int port, const char* proto)
1374 return win32_getservbyport(port, proto);
1378 PerlSockGetservent(struct IPerlSock* piPerl)
1380 return win32_getservent();
1384 PerlSockGetsockname(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
1386 return win32_getsockname(s, name, namelen);
1390 PerlSockGetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, char* optval, int* optlen)
1392 return win32_getsockopt(s, level, optname, optval, optlen);
1396 PerlSockInetAddr(struct IPerlSock* piPerl, const char* cp)
1398 return win32_inet_addr(cp);
1402 PerlSockInetNtoa(struct IPerlSock* piPerl, struct in_addr in)
1404 return win32_inet_ntoa(in);
1408 PerlSockListen(struct IPerlSock* piPerl, SOCKET s, int backlog)
1410 return win32_listen(s, backlog);
1414 PerlSockRecv(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags)
1416 return win32_recv(s, buffer, len, flags);
1420 PerlSockRecvfrom(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen)
1422 return win32_recvfrom(s, buffer, len, flags, from, fromlen);
1426 PerlSockSelect(struct IPerlSock* piPerl, int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout)
1428 return win32_select(nfds, (Perl_fd_set*)readfds, (Perl_fd_set*)writefds, (Perl_fd_set*)exceptfds, timeout);
1432 PerlSockSend(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags)
1434 return win32_send(s, buffer, len, flags);
1438 PerlSockSendto(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen)
1440 return win32_sendto(s, buffer, len, flags, to, tolen);
1444 PerlSockSethostent(struct IPerlSock* piPerl, int stayopen)
1446 win32_sethostent(stayopen);
1450 PerlSockSetnetent(struct IPerlSock* piPerl, int stayopen)
1452 win32_setnetent(stayopen);
1456 PerlSockSetprotoent(struct IPerlSock* piPerl, int stayopen)
1458 win32_setprotoent(stayopen);
1462 PerlSockSetservent(struct IPerlSock* piPerl, int stayopen)
1464 win32_setservent(stayopen);
1468 PerlSockSetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, const char* optval, int optlen)
1470 return win32_setsockopt(s, level, optname, optval, optlen);
1474 PerlSockShutdown(struct IPerlSock* piPerl, SOCKET s, int how)
1476 return win32_shutdown(s, how);
1480 PerlSockSocket(struct IPerlSock* piPerl, int af, int type, int protocol)
1482 return win32_socket(af, type, protocol);
1486 PerlSockSocketpair(struct IPerlSock* piPerl, int domain, int type, int protocol, int* fds)
1488 return Perl_my_socketpair(domain, type, protocol, fds);
1492 PerlSockClosesocket(struct IPerlSock* piPerl, SOCKET s)
1494 return win32_closesocket(s);
1498 PerlSockIoctlsocket(struct IPerlSock* piPerl, SOCKET s, long cmd, u_long *argp)
1500 return win32_ioctlsocket(s, cmd, argp);
1503 struct IPerlSock perlSock =
1514 PerlSockEndprotoent,
1516 PerlSockGethostname,
1517 PerlSockGetpeername,
1518 PerlSockGethostbyaddr,
1519 PerlSockGethostbyname,
1521 PerlSockGetnetbyaddr,
1522 PerlSockGetnetbyname,
1524 PerlSockGetprotobyname,
1525 PerlSockGetprotobynumber,
1526 PerlSockGetprotoent,
1527 PerlSockGetservbyname,
1528 PerlSockGetservbyport,
1530 PerlSockGetsockname,
1542 PerlSockSetprotoent,
1548 PerlSockClosesocket,
1554 #define EXECF_EXEC 1
1555 #define EXECF_SPAWN 2
1558 PerlProcAbort(struct IPerlProc* piPerl)
1564 PerlProcCrypt(struct IPerlProc* piPerl, const char* clear, const char* salt)
1566 return win32_crypt(clear, salt);
1570 PerlProcExit(struct IPerlProc* piPerl, int status)
1576 PerlProc_Exit(struct IPerlProc* piPerl, int status)
1582 PerlProcExecl(struct IPerlProc* piPerl, const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3)
1584 return execl(cmdname, arg0, arg1, arg2, arg3);
1588 PerlProcExecv(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
1590 return win32_execvp(cmdname, argv);
1594 PerlProcExecvp(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
1596 return win32_execvp(cmdname, argv);
1600 PerlProcGetuid(struct IPerlProc* piPerl)
1606 PerlProcGeteuid(struct IPerlProc* piPerl)
1612 PerlProcGetgid(struct IPerlProc* piPerl)
1618 PerlProcGetegid(struct IPerlProc* piPerl)
1624 PerlProcGetlogin(struct IPerlProc* piPerl)
1626 return g_getlogin();
1630 PerlProcKill(struct IPerlProc* piPerl, int pid, int sig)
1632 return win32_kill(pid, sig);
1636 PerlProcKillpg(struct IPerlProc* piPerl, int pid, int sig)
1638 return win32_kill(pid, -sig);
1642 PerlProcPauseProc(struct IPerlProc* piPerl)
1644 return win32_sleep((32767L << 16) + 32767);
1648 PerlProcPopen(struct IPerlProc* piPerl, const char *command, const char *mode)
1651 PERL_FLUSHALL_FOR_CHILD;
1652 return win32_popen(command, mode);
1656 PerlProcPopenList(struct IPerlProc* piPerl, const char *mode, IV narg, SV **args)
1659 PERL_FLUSHALL_FOR_CHILD;
1660 return win32_popenlist(mode, narg, args);
1664 PerlProcPclose(struct IPerlProc* piPerl, PerlIO *stream)
1666 return win32_pclose(stream);
1670 PerlProcPipe(struct IPerlProc* piPerl, int *phandles)
1672 return win32_pipe(phandles, 512, O_BINARY);
1676 PerlProcSetuid(struct IPerlProc* piPerl, uid_t u)
1682 PerlProcSetgid(struct IPerlProc* piPerl, gid_t g)
1688 PerlProcSleep(struct IPerlProc* piPerl, unsigned int s)
1690 return win32_sleep(s);
1694 PerlProcTimes(struct IPerlProc* piPerl, struct tms *timebuf)
1696 return win32_times(timebuf);
1700 PerlProcWait(struct IPerlProc* piPerl, int *status)
1702 return win32_wait(status);
1706 PerlProcWaitpid(struct IPerlProc* piPerl, int pid, int *status, int flags)
1708 return win32_waitpid(pid, status, flags);
1712 PerlProcSignal(struct IPerlProc* piPerl, int sig, Sighandler_t subcode)
1714 return win32_signal(sig, subcode);
1718 PerlProcGetTimeOfDay(struct IPerlProc* piPerl, struct timeval *t, void *z)
1720 return win32_gettimeofday(t, z);
1724 static THREAD_RET_TYPE
1725 win32_start_child(LPVOID arg)
1727 PerlInterpreter *my_perl = (PerlInterpreter*)arg;
1730 HWND parent_message_hwnd;
1731 #ifdef PERL_SYNC_FORK
1732 static long sync_fork_id = 0;
1733 long id = ++sync_fork_id;
1737 PERL_SET_THX(my_perl);
1738 win32_checkTLS(my_perl);
1740 /* set $$ to pseudo id */
1741 #ifdef PERL_SYNC_FORK
1744 w32_pseudo_id = GetCurrentThreadId();
1746 int pid = (int)w32_pseudo_id;
1748 w32_pseudo_id = -pid;
1751 if (tmpgv = gv_fetchpv("$", TRUE, SVt_PV)) {
1752 SV *sv = GvSV(tmpgv);
1754 sv_setiv(sv, -(IV)w32_pseudo_id);
1757 #ifdef PERL_USES_PL_PIDSTATUS
1758 hv_clear(PL_pidstatus);
1761 /* create message window and tell parent about it */
1762 parent_message_hwnd = w32_message_hwnd;
1763 w32_message_hwnd = win32_create_message_window();
1764 if (parent_message_hwnd != NULL)
1765 PostMessage(parent_message_hwnd, WM_USER_MESSAGE, w32_pseudo_id, (LPARAM)w32_message_hwnd);
1767 /* push a zero on the stack (we are the child) */
1775 /* continue from next op */
1776 PL_op = PL_op->op_next;
1780 volatile int oldscope = 1; /* We are responsible for all scopes */
1783 JMPENV_PUSH(status);
1787 /* We may have additional unclosed scopes if fork() was called
1788 * from within a BEGIN block. See perlfork.pod for more details.
1789 * We cannot clean up these other scopes because they belong to a
1790 * different interpreter, but we also cannot leave PL_scopestack_ix
1791 * dangling because that can trigger an assertion in perl_destruct().
1793 if (PL_scopestack_ix > oldscope) {
1794 PL_scopestack[oldscope-1] = PL_scopestack[PL_scopestack_ix-1];
1795 PL_scopestack_ix = oldscope;
1800 while (PL_scopestack_ix > oldscope)
1803 PL_curstash = PL_defstash;
1804 if (PL_endav && !PL_minus_c)
1805 call_list(oldscope, PL_endav);
1806 status = STATUS_EXIT;
1810 POPSTACK_TO(PL_mainstack);
1811 PL_op = PL_restartop;
1812 PL_restartop = (OP*)NULL;
1815 PerlIO_printf(Perl_error_log, "panic: restartop\n");
1822 /* XXX hack to avoid perl_destruct() freeing optree */
1823 win32_checkTLS(my_perl);
1824 PL_main_root = (OP*)NULL;
1827 win32_checkTLS(my_perl);
1828 /* close the std handles to avoid fd leaks */
1830 do_close(PL_stdingv, FALSE);
1831 do_close(gv_fetchpv("STDOUT", TRUE, SVt_PVIO), FALSE); /* PL_stdoutgv - ISAGN */
1832 do_close(PL_stderrgv, FALSE);
1835 /* destroy everything (waits for any pseudo-forked children) */
1836 win32_checkTLS(my_perl);
1837 perl_destruct(my_perl);
1838 win32_checkTLS(my_perl);
1841 #ifdef PERL_SYNC_FORK
1844 return (DWORD)status;
1847 #endif /* USE_ITHREADS */
1850 PerlProcFork(struct IPerlProc* piPerl)
1858 if (w32_num_pseudo_children >= MAXIMUM_WAIT_OBJECTS) {
1862 h = new CPerlHost(*(CPerlHost*)w32_internal_host);
1863 PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHX,
1866 h->m_pHostperlMemShared,
1867 h->m_pHostperlMemParse,
1869 h->m_pHostperlStdIO,
1875 new_perl->Isys_intern.internal_host = h;
1876 h->host_perl = new_perl;
1877 # ifdef PERL_SYNC_FORK
1878 id = win32_start_child((LPVOID)new_perl);
1881 if (w32_message_hwnd == INVALID_HANDLE_VALUE)
1882 w32_message_hwnd = win32_create_message_window();
1883 new_perl->Isys_intern.message_hwnd = w32_message_hwnd;
1884 w32_pseudo_child_message_hwnds[w32_num_pseudo_children] =
1885 (w32_message_hwnd == NULL) ? (HWND)NULL : (HWND)INVALID_HANDLE_VALUE;
1886 # ifdef USE_RTL_THREAD_API
1887 handle = (HANDLE)_beginthreadex((void*)NULL, 0, win32_start_child,
1888 (void*)new_perl, 0, (unsigned*)&id);
1890 handle = CreateThread(NULL, 0, win32_start_child,
1891 (LPVOID)new_perl, 0, &id);
1893 PERL_SET_THX(aTHX); /* XXX perl_clone*() set TLS */
1903 w32_pseudo_child_handles[w32_num_pseudo_children] = handle;
1904 w32_pseudo_child_pids[w32_num_pseudo_children] = id;
1905 ++w32_num_pseudo_children;
1909 Perl_croak(aTHX_ "fork() not implemented!\n");
1911 #endif /* USE_ITHREADS */
1915 PerlProcGetpid(struct IPerlProc* piPerl)
1917 return win32_getpid();
1921 PerlProcDynaLoader(struct IPerlProc* piPerl, const char* filename)
1923 return win32_dynaload(filename);
1927 PerlProcGetOSError(struct IPerlProc* piPerl, SV* sv, DWORD dwErr)
1929 win32_str_os_error(sv, dwErr);
1933 PerlProcSpawnvp(struct IPerlProc* piPerl, int mode, const char *cmdname, const char *const *argv)
1935 return win32_spawnvp(mode, cmdname, argv);
1939 PerlProcLastHost(struct IPerlProc* piPerl)
1942 CPerlHost *h = (CPerlHost*)w32_internal_host;
1943 return h->LastHost();
1946 struct IPerlProc perlProc =
1980 PerlProcGetTimeOfDay
1988 CPerlHost::CPerlHost(void)
1990 /* Construct a host from scratch */
1991 InterlockedIncrement(&num_hosts);
1992 m_pvDir = new VDir();
1993 m_pVMem = new VMem();
1994 m_pVMemShared = new VMem();
1995 m_pVMemParse = new VMem();
1997 m_pvDir->Init(NULL, m_pVMem);
2000 m_lppEnvList = NULL;
2003 CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2004 CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2005 CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2006 CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2007 CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2008 CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2009 CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2010 CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2011 CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2013 m_pHostperlMem = &m_hostperlMem;
2014 m_pHostperlMemShared = &m_hostperlMemShared;
2015 m_pHostperlMemParse = &m_hostperlMemParse;
2016 m_pHostperlEnv = &m_hostperlEnv;
2017 m_pHostperlStdIO = &m_hostperlStdIO;
2018 m_pHostperlLIO = &m_hostperlLIO;
2019 m_pHostperlDir = &m_hostperlDir;
2020 m_pHostperlSock = &m_hostperlSock;
2021 m_pHostperlProc = &m_hostperlProc;
2024 #define SETUPEXCHANGE(xptr, iptr, table) \
2035 CPerlHost::CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
2036 struct IPerlMem** ppMemParse, struct IPerlEnv** ppEnv,
2037 struct IPerlStdIO** ppStdIO, struct IPerlLIO** ppLIO,
2038 struct IPerlDir** ppDir, struct IPerlSock** ppSock,
2039 struct IPerlProc** ppProc)
2041 InterlockedIncrement(&num_hosts);
2042 m_pvDir = new VDir(0);
2043 m_pVMem = new VMem();
2044 m_pVMemShared = new VMem();
2045 m_pVMemParse = new VMem();
2047 m_pvDir->Init(NULL, m_pVMem);
2050 m_lppEnvList = NULL;
2051 m_bTopLevel = FALSE;
2053 CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2054 CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2055 CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2056 CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2057 CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2058 CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2059 CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2060 CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2061 CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2063 SETUPEXCHANGE(ppMem, m_pHostperlMem, m_hostperlMem);
2064 SETUPEXCHANGE(ppMemShared, m_pHostperlMemShared, m_hostperlMemShared);
2065 SETUPEXCHANGE(ppMemParse, m_pHostperlMemParse, m_hostperlMemParse);
2066 SETUPEXCHANGE(ppEnv, m_pHostperlEnv, m_hostperlEnv);
2067 SETUPEXCHANGE(ppStdIO, m_pHostperlStdIO, m_hostperlStdIO);
2068 SETUPEXCHANGE(ppLIO, m_pHostperlLIO, m_hostperlLIO);
2069 SETUPEXCHANGE(ppDir, m_pHostperlDir, m_hostperlDir);
2070 SETUPEXCHANGE(ppSock, m_pHostperlSock, m_hostperlSock);
2071 SETUPEXCHANGE(ppProc, m_pHostperlProc, m_hostperlProc);
2073 #undef SETUPEXCHANGE
2075 CPerlHost::CPerlHost(CPerlHost& host)
2077 /* Construct a host from another host */
2078 InterlockedIncrement(&num_hosts);
2079 m_pVMem = new VMem();
2080 m_pVMemShared = host.GetMemShared();
2081 m_pVMemParse = host.GetMemParse();
2083 /* duplicate directory info */
2084 m_pvDir = new VDir(0);
2085 m_pvDir->Init(host.GetDir(), m_pVMem);
2087 CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2088 CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2089 CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2090 CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2091 CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2092 CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2093 CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2094 CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2095 CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2096 m_pHostperlMem = &m_hostperlMem;
2097 m_pHostperlMemShared = &m_hostperlMemShared;
2098 m_pHostperlMemParse = &m_hostperlMemParse;
2099 m_pHostperlEnv = &m_hostperlEnv;
2100 m_pHostperlStdIO = &m_hostperlStdIO;
2101 m_pHostperlLIO = &m_hostperlLIO;
2102 m_pHostperlDir = &m_hostperlDir;
2103 m_pHostperlSock = &m_hostperlSock;
2104 m_pHostperlProc = &m_hostperlProc;
2107 m_lppEnvList = NULL;
2108 m_bTopLevel = FALSE;
2110 /* duplicate environment info */
2113 while(lpPtr = host.GetIndex(dwIndex))
2117 CPerlHost::~CPerlHost(void)
2120 InterlockedDecrement(&num_hosts);
2122 m_pVMemParse->Release();
2123 m_pVMemShared->Release();
2128 CPerlHost::Find(LPCSTR lpStr)
2131 LPSTR* lppPtr = Lookup(lpStr);
2132 if(lppPtr != NULL) {
2133 for(lpPtr = *lppPtr; *lpPtr != '\0' && *lpPtr != '='; ++lpPtr)
2145 lookup(const void *arg1, const void *arg2)
2146 { // Compare strings
2150 ptr1 = *(char**)arg1;
2151 ptr2 = *(char**)arg2;
2155 if(c1 == '\0' || c1 == '=') {
2156 if(c2 == '\0' || c2 == '=')
2159 return -1; // string 1 < string 2
2161 else if(c2 == '\0' || c2 == '=')
2162 return 1; // string 1 > string 2
2168 return -1; // string 1 < string 2
2170 return 1; // string 1 > string 2
2178 CPerlHost::Lookup(LPCSTR lpStr)
2181 if (!m_lppEnvList || !m_dwEnvCount)
2186 return (LPSTR*)bsearch(&lpStr, m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), lookup);
2190 compare(const void *arg1, const void *arg2)
2191 { // Compare strings
2195 ptr1 = *(char**)arg1;
2196 ptr2 = *(char**)arg2;
2200 if(c1 == '\0' || c1 == '=') {
2204 return -1; // string 1 < string 2
2206 else if(c2 == '\0' || c2 == '=')
2207 return 1; // string 1 > string 2
2213 return -1; // string 1 < string 2
2215 return 1; // string 1 > string 2
2223 CPerlHost::Add(LPCSTR lpStr)
2226 char szBuffer[1024];
2228 int index, length = strlen(lpStr)+1;
2230 for(index = 0; lpStr[index] != '\0' && lpStr[index] != '='; ++index)
2231 szBuffer[index] = lpStr[index];
2233 szBuffer[index] = '\0';
2236 lpPtr = Lookup(szBuffer);
2237 if (lpPtr != NULL) {
2238 // must allocate things via host memory allocation functions
2239 // rather than perl's Renew() et al, as the perl interpreter
2240 // may either not be initialized enough when we allocate these,
2241 // or may already be dead when we go to free these
2242 *lpPtr = (char*)Realloc(*lpPtr, length * sizeof(char));
2243 strcpy(*lpPtr, lpStr);
2246 m_lppEnvList = (LPSTR*)Realloc(m_lppEnvList, (m_dwEnvCount+1) * sizeof(LPSTR));
2248 m_lppEnvList[m_dwEnvCount] = (char*)Malloc(length * sizeof(char));
2249 if (m_lppEnvList[m_dwEnvCount] != NULL) {
2250 strcpy(m_lppEnvList[m_dwEnvCount], lpStr);
2252 qsort(m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), compare);
2259 CPerlHost::CalculateEnvironmentSpace(void)
2263 for(index = 0; index < m_dwEnvCount; ++index)
2264 dwSize += strlen(m_lppEnvList[index]) + 1;
2270 CPerlHost::FreeLocalEnvironmentStrings(LPSTR lpStr)
2277 CPerlHost::GetChildDir(void)
2283 Newx(ptr, MAX_PATH+1, char);
2284 m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr);
2285 length = strlen(ptr);
2287 if ((ptr[length-1] == '\\') || (ptr[length-1] == '/'))
2294 CPerlHost::FreeChildDir(char* pStr)
2301 CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
2304 LPSTR lpStr, lpPtr, lpEnvPtr, lpTmp, lpLocalEnv, lpAllocPtr;
2305 DWORD dwSize, dwEnvIndex;
2306 int nLength, compVal;
2308 // get the process environment strings
2309 lpAllocPtr = lpTmp = (LPSTR)GetEnvironmentStrings();
2311 // step over current directory stuff
2312 while(*lpTmp == '=')
2313 lpTmp += strlen(lpTmp) + 1;
2315 // save the start of the environment strings
2317 for(dwSize = 1; *lpTmp != '\0'; lpTmp += strlen(lpTmp) + 1) {
2318 // calculate the size of the environment strings
2319 dwSize += strlen(lpTmp) + 1;
2322 // add the size of current directories
2323 dwSize += vDir.CalculateEnvironmentSpace();
2325 // add the additional space used by changes made to the environment
2326 dwSize += CalculateEnvironmentSpace();
2328 Newx(lpStr, dwSize, char);
2331 // build the local environment
2332 lpStr = vDir.BuildEnvironmentSpace(lpStr);
2335 lpLocalEnv = GetIndex(dwEnvIndex);
2336 while(*lpEnvPtr != '\0') {
2338 // all environment overrides have been added
2339 // so copy string into place
2340 strcpy(lpStr, lpEnvPtr);
2341 nLength = strlen(lpEnvPtr) + 1;
2343 lpEnvPtr += nLength;
2346 // determine which string to copy next
2347 compVal = compare(&lpEnvPtr, &lpLocalEnv);
2349 strcpy(lpStr, lpEnvPtr);
2350 nLength = strlen(lpEnvPtr) + 1;
2352 lpEnvPtr += nLength;
2355 char *ptr = strchr(lpLocalEnv, '=');
2357 strcpy(lpStr, lpLocalEnv);
2358 lpStr += strlen(lpLocalEnv) + 1;
2360 lpLocalEnv = GetIndex(dwEnvIndex);
2362 // this string was replaced
2363 lpEnvPtr += strlen(lpEnvPtr) + 1;
2370 // still have environment overrides to add
2371 // so copy the strings into place if not an override
2372 char *ptr = strchr(lpLocalEnv, '=');
2374 strcpy(lpStr, lpLocalEnv);
2375 lpStr += strlen(lpLocalEnv) + 1;
2377 lpLocalEnv = GetIndex(dwEnvIndex);
2384 // release the process environment strings
2385 FreeEnvironmentStrings(lpAllocPtr);
2391 CPerlHost::Reset(void)
2394 if(m_lppEnvList != NULL) {
2395 for(DWORD index = 0; index < m_dwEnvCount; ++index) {
2396 Free(m_lppEnvList[index]);
2397 m_lppEnvList[index] = NULL;
2402 m_lppEnvList = NULL;
2406 CPerlHost::Clearenv(void)
2410 LPSTR lpPtr, lpStr, lpEnvPtr;
2411 if (m_lppEnvList != NULL) {
2412 /* set every entry to an empty string */
2413 for(DWORD index = 0; index < m_dwEnvCount; ++index) {
2414 char* ptr = strchr(m_lppEnvList[index], '=');
2421 /* get the process environment strings */
2422 lpStr = lpEnvPtr = (LPSTR)GetEnvironmentStrings();
2424 /* step over current directory stuff */
2425 while(*lpStr == '=')
2426 lpStr += strlen(lpStr) + 1;
2429 lpPtr = strchr(lpStr, '=');
2435 (void)win32_putenv(lpStr);
2438 lpStr += strlen(lpStr) + 1;
2441 FreeEnvironmentStrings(lpEnvPtr);
2446 CPerlHost::Getenv(const char *varname)
2450 char *pEnv = Find(varname);
2454 return win32_getenv(varname);
2458 CPerlHost::Putenv(const char *envstring)
2463 return win32_putenv(envstring);
2469 CPerlHost::Chdir(const char *dirname)
2477 ret = m_pvDir->SetCurrentDirectoryA((char*)dirname);
2484 #endif /* ___PerlHost_H___ */