xref: /openbsd/gnu/usr.bin/perl/win32/perlhost.h (revision 3d61058a)
1 /* perlhost.h
2  *
3  * (c) 1999 Microsoft Corporation. All rights reserved.
4  * Portions (c) 1999 ActiveState Tool Corp, http://www.ActiveState.com/
5  *
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.
8  */
9 
10 #define CHECK_HOST_INTERP
11 
12 #ifndef ___PerlHost_H___
13 #define ___PerlHost_H___
14 
15 #include <signal.h>
16 #include <wchar.h>
17 #include "iperlsys.h"
18 #include "vmem.h"
19 #include "vdir.h"
20 
21 #ifndef WC_NO_BEST_FIT_CHARS
22 #  define WC_NO_BEST_FIT_CHARS 0x00000400
23 #endif
24 
25 START_EXTERN_C
26 extern char *	g_getlogin(void);
27 END_EXTERN_C
28 
29 class CPerlHost
30 {
31 public:
32     /* Constructors */
33     CPerlHost(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);
40     ~CPerlHost(void);
41 
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);
51 
52     BOOL PerlCreate(void);
53     int PerlParse(int argc, char** argv, char** env);
54     int PerlRun(void);
55     void PerlDestroy(void);
56 
57 /* IPerlMem */
58     /* Locks provided but should be unnecessary as this is private pool */
Malloc(size_t size)59     inline void* Malloc(size_t size) { return m_pVMem->Malloc(size); };
Realloc(void * ptr,size_t size)60     inline void* Realloc(void* ptr, size_t size) { return m_pVMem->Realloc(ptr, size); };
Free(void * ptr)61     inline void Free(void* ptr) { m_pVMem->Free(ptr); };
Calloc(size_t num,size_t size)62     inline void* Calloc(size_t num, size_t size)
63     {
64         size_t count = num*size;
65         void* lpVoid = Malloc(count);
66         if (lpVoid)
67             ZeroMemory(lpVoid, count);
68         return lpVoid;
69     };
GetLock(void)70     inline void GetLock(void) { m_pVMem->GetLock(); };
FreeLock(void)71     inline void FreeLock(void) { m_pVMem->FreeLock(); };
IsLocked(void)72     inline int IsLocked(void) { return m_pVMem->IsLocked(); };
73 
74 /* IPerlMemShared */
75     /* Locks used to serialize access to the pool */
GetLockShared(void)76     inline void GetLockShared(void) { m_pVMemShared->GetLock(); };
FreeLockShared(void)77     inline void FreeLockShared(void) { m_pVMemShared->FreeLock(); };
IsLockedShared(void)78     inline int IsLockedShared(void) { return m_pVMemShared->IsLocked(); };
MallocShared(size_t size)79     inline void* MallocShared(size_t size)
80     {
81         void *result;
82         GetLockShared();
83         result = m_pVMemShared->Malloc(size);
84         FreeLockShared();
85         return result;
86     };
ReallocShared(void * ptr,size_t size)87     inline void* ReallocShared(void* ptr, size_t size)
88     {
89         void *result;
90         GetLockShared();
91         result = m_pVMemShared->Realloc(ptr, size);
92         FreeLockShared();
93         return result;
94     };
FreeShared(void * ptr)95     inline void FreeShared(void* ptr)
96     {
97         GetLockShared();
98         m_pVMemShared->Free(ptr);
99         FreeLockShared();
100     };
CallocShared(size_t num,size_t size)101     inline void* CallocShared(size_t num, size_t size)
102     {
103         size_t count = num*size;
104         void* lpVoid = MallocShared(count);
105         if (lpVoid)
106             ZeroMemory(lpVoid, count);
107         return lpVoid;
108     };
109 
110 /* IPerlMemParse */
111     /* Assume something else is using locks to manage serialization
112        on a batch basis
113      */
GetLockParse(void)114     inline void GetLockParse(void) { m_pVMemParse->GetLock(); };
FreeLockParse(void)115     inline void FreeLockParse(void) { m_pVMemParse->FreeLock(); };
IsLockedParse(void)116     inline int IsLockedParse(void) { return m_pVMemParse->IsLocked(); };
MallocParse(size_t size)117     inline void* MallocParse(size_t size) { return m_pVMemParse->Malloc(size); };
ReallocParse(void * ptr,size_t size)118     inline void* ReallocParse(void* ptr, size_t size) { return m_pVMemParse->Realloc(ptr, size); };
FreeParse(void * ptr)119     inline void FreeParse(void* ptr) { m_pVMemParse->Free(ptr); };
CallocParse(size_t num,size_t size)120     inline void* CallocParse(size_t num, size_t size)
121     {
122         size_t count = num*size;
123         void* lpVoid = MallocParse(count);
124         if (lpVoid)
125             ZeroMemory(lpVoid, count);
126         return lpVoid;
127     };
128 
129 /* IPerlEnv */
130     char *Getenv(const char *varname);
131     int Putenv(const char *envstring);
Getenv(const char * varname,unsigned long * len)132     inline char *Getenv(const char *varname, unsigned long *len)
133     {
134         *len = 0;
135         char *e = Getenv(varname);
136         if (e)
137             *len = strlen(e);
138         return e;
139     }
CreateChildEnv(void)140     void* CreateChildEnv(void) { return CreateLocalEnvironmentStrings(*m_pvDir); };
FreeChildEnv(void * pStr)141     void FreeChildEnv(void* pStr) { FreeLocalEnvironmentStrings((char*)pStr); };
142     char* GetChildDir(void);
143     void FreeChildDir(char* pStr);
144     void Reset(void);
145     void Clearenv(void);
146 
GetIndex(DWORD & dwIndex)147     inline LPSTR GetIndex(DWORD &dwIndex)
148     {
149         if(dwIndex < m_dwEnvCount)
150         {
151             ++dwIndex;
152             return m_lppEnvList[dwIndex-1];
153         }
154         return NULL;
155     };
156 
157 protected:
158     LPSTR Find(LPCSTR lpStr);
159     void Add(LPCSTR lpStr);
160 
161     LPSTR CreateLocalEnvironmentStrings(VDir &vDir);
162     void FreeLocalEnvironmentStrings(LPSTR lpStr);
163     LPSTR* Lookup(LPCSTR lpStr);
164     DWORD CalculateEnvironmentSpace(void);
165 
166 public:
167 
168 /* IPerlDIR */
169     virtual int Chdir(const char *dirname);
170 
171 /* IPerllProc */
172     void Abort(void);
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);
178 
GetMemShared(void)179     inline VMem* GetMemShared(void) { m_pVMemShared->AddRef(); return m_pVMemShared; };
GetMemParse(void)180     inline VMem* GetMemParse(void) { m_pVMemParse->AddRef(); return m_pVMemParse; };
GetDir(void)181     inline VDir* GetDir(void) { return m_pvDir; };
182 
183 public:
184 
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;
194 
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;
204 
MapPathA(const char * pInName)205     inline char* MapPathA(const char *pInName) { return m_pvDir->MapPathA(pInName); };
MapPathW(const WCHAR * pInName)206     inline WCHAR* MapPathW(const WCHAR *pInName) { return m_pvDir->MapPathW(pInName); };
207 protected:
208 
209     VDir*   m_pvDir;
210     VMem*   m_pVMem;
211     VMem*   m_pVMemShared;
212     VMem*   m_pVMemParse;
213 
214     DWORD   m_dwEnvCount;
215     LPSTR*  m_lppEnvList;
216     BOOL    m_bTopLevel;	// is this a toplevel host?
217     static long num_hosts;
218 public:
LastHost(void)219     inline  int LastHost(void) { return num_hosts == 1L; };
220     struct interpreter *host_perl;
221 };
222 
223 long CPerlHost::num_hosts = 0L;
224 
225 extern "C" void win32_checkTLS(struct interpreter *host_perl);
226 
227 #define STRUCT2RAWPTR(x, y) (CPerlHost*)(((LPBYTE)x)-offsetof(CPerlHost, y))
228 #ifdef CHECK_HOST_INTERP
CheckInterp(CPerlHost * host)229 inline CPerlHost* CheckInterp(CPerlHost *host)
230 {
231  win32_checkTLS(host->host_perl);
232  return host;
233 }
234 #define STRUCT2PTR(x, y) CheckInterp(STRUCT2RAWPTR(x, y))
235 #else
236 #define STRUCT2PTR(x, y) STRUCT2RAWPTR(x, y)
237 #endif
238 
IPerlMem2Host(struct IPerlMem * piPerl)239 inline CPerlHost* IPerlMem2Host(struct IPerlMem* piPerl)
240 {
241     return STRUCT2RAWPTR(piPerl, m_hostperlMem);
242 }
243 
IPerlMemShared2Host(struct IPerlMem * piPerl)244 inline CPerlHost* IPerlMemShared2Host(struct IPerlMem* piPerl)
245 {
246     return STRUCT2RAWPTR(piPerl, m_hostperlMemShared);
247 }
248 
IPerlMemParse2Host(struct IPerlMem * piPerl)249 inline CPerlHost* IPerlMemParse2Host(struct IPerlMem* piPerl)
250 {
251     return STRUCT2RAWPTR(piPerl, m_hostperlMemParse);
252 }
253 
IPerlEnv2Host(struct IPerlEnv * piPerl)254 inline CPerlHost* IPerlEnv2Host(struct IPerlEnv* piPerl)
255 {
256     return STRUCT2PTR(piPerl, m_hostperlEnv);
257 }
258 
IPerlStdIO2Host(struct IPerlStdIO * piPerl)259 inline CPerlHost* IPerlStdIO2Host(struct IPerlStdIO* piPerl)
260 {
261     return STRUCT2PTR(piPerl, m_hostperlStdIO);
262 }
263 
IPerlLIO2Host(struct IPerlLIO * piPerl)264 inline CPerlHost* IPerlLIO2Host(struct IPerlLIO* piPerl)
265 {
266     return STRUCT2PTR(piPerl, m_hostperlLIO);
267 }
268 
IPerlDir2Host(struct IPerlDir * piPerl)269 inline CPerlHost* IPerlDir2Host(struct IPerlDir* piPerl)
270 {
271     return STRUCT2PTR(piPerl, m_hostperlDir);
272 }
273 
IPerlSock2Host(struct IPerlSock * piPerl)274 inline CPerlHost* IPerlSock2Host(struct IPerlSock* piPerl)
275 {
276     return STRUCT2PTR(piPerl, m_hostperlSock);
277 }
278 
IPerlProc2Host(struct IPerlProc * piPerl)279 inline CPerlHost* IPerlProc2Host(struct IPerlProc* piPerl)
280 {
281     return STRUCT2PTR(piPerl, m_hostperlProc);
282 }
283 
284 
285 
286 #undef IPERL2HOST
287 #define IPERL2HOST(x) IPerlMem2Host(x)
288 
289 /* IPerlMem */
290 void*
PerlMemMalloc(struct IPerlMem * piPerl,size_t size)291 PerlMemMalloc(struct IPerlMem* piPerl, size_t size)
292 {
293     return IPERL2HOST(piPerl)->Malloc(size);
294 }
295 void*
PerlMemRealloc(struct IPerlMem * piPerl,void * ptr,size_t size)296 PerlMemRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
297 {
298     return IPERL2HOST(piPerl)->Realloc(ptr, size);
299 }
300 void
PerlMemFree(struct IPerlMem * piPerl,void * ptr)301 PerlMemFree(struct IPerlMem* piPerl, void* ptr)
302 {
303     IPERL2HOST(piPerl)->Free(ptr);
304 }
305 void*
PerlMemCalloc(struct IPerlMem * piPerl,size_t num,size_t size)306 PerlMemCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
307 {
308     return IPERL2HOST(piPerl)->Calloc(num, size);
309 }
310 
311 void
PerlMemGetLock(struct IPerlMem * piPerl)312 PerlMemGetLock(struct IPerlMem* piPerl)
313 {
314     IPERL2HOST(piPerl)->GetLock();
315 }
316 
317 void
PerlMemFreeLock(struct IPerlMem * piPerl)318 PerlMemFreeLock(struct IPerlMem* piPerl)
319 {
320     IPERL2HOST(piPerl)->FreeLock();
321 }
322 
323 int
PerlMemIsLocked(struct IPerlMem * piPerl)324 PerlMemIsLocked(struct IPerlMem* piPerl)
325 {
326     return IPERL2HOST(piPerl)->IsLocked();
327 }
328 
329 const struct IPerlMem perlMem =
330 {
331     PerlMemMalloc,
332     PerlMemRealloc,
333     PerlMemFree,
334     PerlMemCalloc,
335     PerlMemGetLock,
336     PerlMemFreeLock,
337     PerlMemIsLocked,
338 };
339 
340 #undef IPERL2HOST
341 #define IPERL2HOST(x) IPerlMemShared2Host(x)
342 
343 /* IPerlMemShared */
344 void*
PerlMemSharedMalloc(struct IPerlMem * piPerl,size_t size)345 PerlMemSharedMalloc(struct IPerlMem* piPerl, size_t size)
346 {
347     return IPERL2HOST(piPerl)->MallocShared(size);
348 }
349 void*
PerlMemSharedRealloc(struct IPerlMem * piPerl,void * ptr,size_t size)350 PerlMemSharedRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
351 {
352     return IPERL2HOST(piPerl)->ReallocShared(ptr, size);
353 }
354 void
PerlMemSharedFree(struct IPerlMem * piPerl,void * ptr)355 PerlMemSharedFree(struct IPerlMem* piPerl, void* ptr)
356 {
357     IPERL2HOST(piPerl)->FreeShared(ptr);
358 }
359 void*
PerlMemSharedCalloc(struct IPerlMem * piPerl,size_t num,size_t size)360 PerlMemSharedCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
361 {
362     return IPERL2HOST(piPerl)->CallocShared(num, size);
363 }
364 
365 void
PerlMemSharedGetLock(struct IPerlMem * piPerl)366 PerlMemSharedGetLock(struct IPerlMem* piPerl)
367 {
368     IPERL2HOST(piPerl)->GetLockShared();
369 }
370 
371 void
PerlMemSharedFreeLock(struct IPerlMem * piPerl)372 PerlMemSharedFreeLock(struct IPerlMem* piPerl)
373 {
374     IPERL2HOST(piPerl)->FreeLockShared();
375 }
376 
377 int
PerlMemSharedIsLocked(struct IPerlMem * piPerl)378 PerlMemSharedIsLocked(struct IPerlMem* piPerl)
379 {
380     return IPERL2HOST(piPerl)->IsLockedShared();
381 }
382 
383 const struct IPerlMem perlMemShared =
384 {
385     PerlMemSharedMalloc,
386     PerlMemSharedRealloc,
387     PerlMemSharedFree,
388     PerlMemSharedCalloc,
389     PerlMemSharedGetLock,
390     PerlMemSharedFreeLock,
391     PerlMemSharedIsLocked,
392 };
393 
394 #undef IPERL2HOST
395 #define IPERL2HOST(x) IPerlMemParse2Host(x)
396 
397 /* IPerlMemParse */
398 void*
PerlMemParseMalloc(struct IPerlMem * piPerl,size_t size)399 PerlMemParseMalloc(struct IPerlMem* piPerl, size_t size)
400 {
401     return IPERL2HOST(piPerl)->MallocParse(size);
402 }
403 void*
PerlMemParseRealloc(struct IPerlMem * piPerl,void * ptr,size_t size)404 PerlMemParseRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
405 {
406     return IPERL2HOST(piPerl)->ReallocParse(ptr, size);
407 }
408 void
PerlMemParseFree(struct IPerlMem * piPerl,void * ptr)409 PerlMemParseFree(struct IPerlMem* piPerl, void* ptr)
410 {
411     IPERL2HOST(piPerl)->FreeParse(ptr);
412 }
413 void*
PerlMemParseCalloc(struct IPerlMem * piPerl,size_t num,size_t size)414 PerlMemParseCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
415 {
416     return IPERL2HOST(piPerl)->CallocParse(num, size);
417 }
418 
419 void
PerlMemParseGetLock(struct IPerlMem * piPerl)420 PerlMemParseGetLock(struct IPerlMem* piPerl)
421 {
422     IPERL2HOST(piPerl)->GetLockParse();
423 }
424 
425 void
PerlMemParseFreeLock(struct IPerlMem * piPerl)426 PerlMemParseFreeLock(struct IPerlMem* piPerl)
427 {
428     IPERL2HOST(piPerl)->FreeLockParse();
429 }
430 
431 int
PerlMemParseIsLocked(struct IPerlMem * piPerl)432 PerlMemParseIsLocked(struct IPerlMem* piPerl)
433 {
434     return IPERL2HOST(piPerl)->IsLockedParse();
435 }
436 
437 const struct IPerlMem perlMemParse =
438 {
439     PerlMemParseMalloc,
440     PerlMemParseRealloc,
441     PerlMemParseFree,
442     PerlMemParseCalloc,
443     PerlMemParseGetLock,
444     PerlMemParseFreeLock,
445     PerlMemParseIsLocked,
446 };
447 
448 
449 #undef IPERL2HOST
450 #define IPERL2HOST(x) IPerlEnv2Host(x)
451 
452 /* IPerlEnv */
453 char*
PerlEnvGetenv(struct IPerlEnv * piPerl,const char * varname)454 PerlEnvGetenv(struct IPerlEnv* piPerl, const char *varname)
455 {
456     return IPERL2HOST(piPerl)->Getenv(varname);
457 };
458 
459 int
PerlEnvPutenv(struct IPerlEnv * piPerl,const char * envstring)460 PerlEnvPutenv(struct IPerlEnv* piPerl, const char *envstring)
461 {
462     return IPERL2HOST(piPerl)->Putenv(envstring);
463 };
464 
465 char*
PerlEnvGetenv_len(struct IPerlEnv * piPerl,const char * varname,unsigned long * len)466 PerlEnvGetenv_len(struct IPerlEnv* piPerl, const char* varname, unsigned long* len)
467 {
468     return IPERL2HOST(piPerl)->Getenv(varname, len);
469 }
470 
471 int
PerlEnvUname(struct IPerlEnv * piPerl,struct utsname * name)472 PerlEnvUname(struct IPerlEnv* piPerl, struct utsname *name)
473 {
474     PERL_UNUSED_ARG(piPerl);
475     return win32_uname(name);
476 }
477 
478 void
PerlEnvClearenv(struct IPerlEnv * piPerl)479 PerlEnvClearenv(struct IPerlEnv* piPerl)
480 {
481     IPERL2HOST(piPerl)->Clearenv();
482 }
483 
484 void*
PerlEnvGetChildenv(struct IPerlEnv * piPerl)485 PerlEnvGetChildenv(struct IPerlEnv* piPerl)
486 {
487     return IPERL2HOST(piPerl)->CreateChildEnv();
488 }
489 
490 void
PerlEnvFreeChildenv(struct IPerlEnv * piPerl,void * childEnv)491 PerlEnvFreeChildenv(struct IPerlEnv* piPerl, void* childEnv)
492 {
493     IPERL2HOST(piPerl)->FreeChildEnv(childEnv);
494 }
495 
496 char*
PerlEnvGetChilddir(struct IPerlEnv * piPerl)497 PerlEnvGetChilddir(struct IPerlEnv* piPerl)
498 {
499     return IPERL2HOST(piPerl)->GetChildDir();
500 }
501 
502 void
PerlEnvFreeChilddir(struct IPerlEnv * piPerl,char * childDir)503 PerlEnvFreeChilddir(struct IPerlEnv* piPerl, char* childDir)
504 {
505     IPERL2HOST(piPerl)->FreeChildDir(childDir);
506 }
507 
508 unsigned long
PerlEnvOsId(struct IPerlEnv * piPerl)509 PerlEnvOsId(struct IPerlEnv* piPerl)
510 {
511     PERL_UNUSED_ARG(piPerl);
512     return win32_os_id();
513 }
514 
515 char*
PerlEnvLibPath(struct IPerlEnv * piPerl,WIN32_NO_REGISTRY_M_ (const char * pl)STRLEN * const len)516 PerlEnvLibPath(struct IPerlEnv* piPerl, WIN32_NO_REGISTRY_M_(const char *pl) STRLEN *const len)
517 {
518     PERL_UNUSED_ARG(piPerl);
519     return win32_get_privlib(WIN32_NO_REGISTRY_M_(pl) len);
520 }
521 
522 char*
PerlEnvSiteLibPath(struct IPerlEnv * piPerl,const char * pl,STRLEN * const len)523 PerlEnvSiteLibPath(struct IPerlEnv* piPerl, const char *pl, STRLEN *const len)
524 {
525     PERL_UNUSED_ARG(piPerl);
526     return win32_get_sitelib(pl, len);
527 }
528 
529 char*
PerlEnvVendorLibPath(struct IPerlEnv * piPerl,const char * pl,STRLEN * const len)530 PerlEnvVendorLibPath(struct IPerlEnv* piPerl, const char *pl,
531                      STRLEN *const len)
532 {
533     PERL_UNUSED_ARG(piPerl);
534     return win32_get_vendorlib(pl, len);
535 }
536 
537 void
PerlEnvGetChildIO(struct IPerlEnv * piPerl,child_IO_table * ptr)538 PerlEnvGetChildIO(struct IPerlEnv* piPerl, child_IO_table* ptr)
539 {
540     PERL_UNUSED_ARG(piPerl);
541     win32_get_child_IO(ptr);
542 }
543 
544 const struct IPerlEnv perlEnv =
545 {
546     PerlEnvGetenv,
547     PerlEnvPutenv,
548     PerlEnvGetenv_len,
549     PerlEnvUname,
550     PerlEnvClearenv,
551     PerlEnvGetChildenv,
552     PerlEnvFreeChildenv,
553     PerlEnvGetChilddir,
554     PerlEnvFreeChilddir,
555     PerlEnvOsId,
556     PerlEnvLibPath,
557     PerlEnvSiteLibPath,
558     PerlEnvVendorLibPath,
559     PerlEnvGetChildIO,
560 };
561 
562 #undef IPERL2HOST
563 #define IPERL2HOST(x) IPerlStdIO2Host(x)
564 
565 /* PerlStdIO */
566 FILE*
PerlStdIOStdin(struct IPerlStdIO * piPerl)567 PerlStdIOStdin(struct IPerlStdIO* piPerl)
568 {
569     PERL_UNUSED_ARG(piPerl);
570     return win32_stdin();
571 }
572 
573 FILE*
PerlStdIOStdout(struct IPerlStdIO * piPerl)574 PerlStdIOStdout(struct IPerlStdIO* piPerl)
575 {
576     PERL_UNUSED_ARG(piPerl);
577     return win32_stdout();
578 }
579 
580 FILE*
PerlStdIOStderr(struct IPerlStdIO * piPerl)581 PerlStdIOStderr(struct IPerlStdIO* piPerl)
582 {
583     PERL_UNUSED_ARG(piPerl);
584     return win32_stderr();
585 }
586 
587 FILE*
PerlStdIOOpen(struct IPerlStdIO * piPerl,const char * path,const char * mode)588 PerlStdIOOpen(struct IPerlStdIO* piPerl, const char *path, const char *mode)
589 {
590     PERL_UNUSED_ARG(piPerl);
591     return win32_fopen(path, mode);
592 }
593 
594 int
PerlStdIOClose(struct IPerlStdIO * piPerl,FILE * pf)595 PerlStdIOClose(struct IPerlStdIO* piPerl, FILE* pf)
596 {
597     PERL_UNUSED_ARG(piPerl);
598     return win32_fclose((pf));
599 }
600 
601 int
PerlStdIOEof(struct IPerlStdIO * piPerl,FILE * pf)602 PerlStdIOEof(struct IPerlStdIO* piPerl, FILE* pf)
603 {
604     PERL_UNUSED_ARG(piPerl);
605     return win32_feof(pf);
606 }
607 
608 int
PerlStdIOError(struct IPerlStdIO * piPerl,FILE * pf)609 PerlStdIOError(struct IPerlStdIO* piPerl, FILE* pf)
610 {
611     PERL_UNUSED_ARG(piPerl);
612     return win32_ferror(pf);
613 }
614 
615 void
PerlStdIOClearerr(struct IPerlStdIO * piPerl,FILE * pf)616 PerlStdIOClearerr(struct IPerlStdIO* piPerl, FILE* pf)
617 {
618     PERL_UNUSED_ARG(piPerl);
619     win32_clearerr(pf);
620 }
621 
622 int
PerlStdIOGetc(struct IPerlStdIO * piPerl,FILE * pf)623 PerlStdIOGetc(struct IPerlStdIO* piPerl, FILE* pf)
624 {
625     PERL_UNUSED_ARG(piPerl);
626     return win32_getc(pf);
627 }
628 
629 STDCHAR*
PerlStdIOGetBase(struct IPerlStdIO * piPerl,FILE * pf)630 PerlStdIOGetBase(struct IPerlStdIO* piPerl, FILE* pf)
631 {
632     PERL_UNUSED_ARG(piPerl);
633 #ifdef FILE_base
634     FILE *f = pf;
635     return FILE_base(f);
636 #else
637     return NULL;
638 #endif
639 }
640 
641 int
PerlStdIOGetBufsiz(struct IPerlStdIO * piPerl,FILE * pf)642 PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, FILE* pf)
643 {
644     PERL_UNUSED_ARG(piPerl);
645 #ifdef FILE_bufsiz
646     FILE *f = pf;
647     return FILE_bufsiz(f);
648 #else
649     return (-1);
650 #endif
651 }
652 
653 int
PerlStdIOGetCnt(struct IPerlStdIO * piPerl,FILE * pf)654 PerlStdIOGetCnt(struct IPerlStdIO* piPerl, FILE* pf)
655 {
656     PERL_UNUSED_ARG(piPerl);
657 #ifdef USE_STDIO_PTR
658     FILE *f = pf;
659     return FILE_cnt(f);
660 #else
661     return (-1);
662 #endif
663 }
664 
665 STDCHAR*
PerlStdIOGetPtr(struct IPerlStdIO * piPerl,FILE * pf)666 PerlStdIOGetPtr(struct IPerlStdIO* piPerl, FILE* pf)
667 {
668     PERL_UNUSED_ARG(piPerl);
669 #ifdef USE_STDIO_PTR
670     FILE *f = pf;
671     return FILE_ptr(f);
672 #else
673     return NULL;
674 #endif
675 }
676 
677 char*
PerlStdIOGets(struct IPerlStdIO * piPerl,char * s,int n,FILE * pf)678 PerlStdIOGets(struct IPerlStdIO* piPerl, char* s, int n, FILE* pf)
679 {
680     PERL_UNUSED_ARG(piPerl);
681     return win32_fgets(s, n, pf);
682 }
683 
684 int
PerlStdIOPutc(struct IPerlStdIO * piPerl,int c,FILE * pf)685 PerlStdIOPutc(struct IPerlStdIO* piPerl, int c, FILE* pf)
686 {
687     PERL_UNUSED_ARG(piPerl);
688     return win32_fputc(c, pf);
689 }
690 
691 int
PerlStdIOPuts(struct IPerlStdIO * piPerl,const char * s,FILE * pf)692 PerlStdIOPuts(struct IPerlStdIO* piPerl, const char *s, FILE* pf)
693 {
694     PERL_UNUSED_ARG(piPerl);
695     return win32_fputs(s, pf);
696 }
697 
698 int
PerlStdIOFlush(struct IPerlStdIO * piPerl,FILE * pf)699 PerlStdIOFlush(struct IPerlStdIO* piPerl, FILE* pf)
700 {
701     PERL_UNUSED_ARG(piPerl);
702     return win32_fflush(pf);
703 }
704 
705 int
PerlStdIOUngetc(struct IPerlStdIO * piPerl,int c,FILE * pf)706 PerlStdIOUngetc(struct IPerlStdIO* piPerl,int c, FILE* pf)
707 {
708     PERL_UNUSED_ARG(piPerl);
709     return win32_ungetc(c, pf);
710 }
711 
712 int
PerlStdIOFileno(struct IPerlStdIO * piPerl,FILE * pf)713 PerlStdIOFileno(struct IPerlStdIO* piPerl, FILE* pf)
714 {
715     PERL_UNUSED_ARG(piPerl);
716     return win32_fileno(pf);
717 }
718 
719 FILE*
PerlStdIOFdopen(struct IPerlStdIO * piPerl,int fd,const char * mode)720 PerlStdIOFdopen(struct IPerlStdIO* piPerl, int fd, const char *mode)
721 {
722     PERL_UNUSED_ARG(piPerl);
723     return win32_fdopen(fd, mode);
724 }
725 
726 FILE*
PerlStdIOReopen(struct IPerlStdIO * piPerl,const char * path,const char * mode,FILE * pf)727 PerlStdIOReopen(struct IPerlStdIO* piPerl, const char*path, const char*mode, FILE* pf)
728 {
729     PERL_UNUSED_ARG(piPerl);
730     return win32_freopen(path, mode, (FILE*)pf);
731 }
732 
733 SSize_t
PerlStdIORead(struct IPerlStdIO * piPerl,void * buffer,Size_t size,Size_t count,FILE * pf)734 PerlStdIORead(struct IPerlStdIO* piPerl, void *buffer, Size_t size, Size_t count, FILE* pf)
735 {
736     PERL_UNUSED_ARG(piPerl);
737     return win32_fread(buffer, size, count, pf);
738 }
739 
740 SSize_t
PerlStdIOWrite(struct IPerlStdIO * piPerl,const void * buffer,Size_t size,Size_t count,FILE * pf)741 PerlStdIOWrite(struct IPerlStdIO* piPerl, const void *buffer, Size_t size, Size_t count, FILE* pf)
742 {
743     PERL_UNUSED_ARG(piPerl);
744     return win32_fwrite(buffer, size, count, pf);
745 }
746 
747 void
PerlStdIOSetBuf(struct IPerlStdIO * piPerl,FILE * pf,char * buffer)748 PerlStdIOSetBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer)
749 {
750     PERL_UNUSED_ARG(piPerl);
751     win32_setbuf(pf, buffer);
752 }
753 
754 int
PerlStdIOSetVBuf(struct IPerlStdIO * piPerl,FILE * pf,char * buffer,int type,Size_t size)755 PerlStdIOSetVBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer, int type, Size_t size)
756 {
757     PERL_UNUSED_ARG(piPerl);
758     return win32_setvbuf(pf, buffer, type, size);
759 }
760 
761 void
PerlStdIOSetCnt(struct IPerlStdIO * piPerl,FILE * pf,int n)762 PerlStdIOSetCnt(struct IPerlStdIO* piPerl, FILE* pf, int n)
763 {
764     PERL_UNUSED_ARG(piPerl);
765 #ifdef STDIO_CNT_LVALUE
766     FILE *f = pf;
767     FILE_cnt(f) = n;
768 #else
769     PERL_UNUSED_ARG(pf);
770     PERL_UNUSED_ARG(n);
771 #endif
772 }
773 
774 void
PerlStdIOSetPtr(struct IPerlStdIO * piPerl,FILE * pf,STDCHAR * ptr)775 PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, STDCHAR * ptr)
776 {
777     PERL_UNUSED_ARG(piPerl);
778 #ifdef STDIO_PTR_LVALUE
779     FILE *f = pf;
780     FILE_ptr(f) = ptr;
781 #else
782     PERL_UNUSED_ARG(pf);
783     PERL_UNUSED_ARG(ptr);
784 #endif
785 }
786 
787 void
PerlStdIOSetlinebuf(struct IPerlStdIO * piPerl,FILE * pf)788 PerlStdIOSetlinebuf(struct IPerlStdIO* piPerl, FILE* pf)
789 {
790     PERL_UNUSED_ARG(piPerl);
791     win32_setvbuf(pf, NULL, _IOLBF, 0);
792 }
793 
794 int
PerlStdIOPrintf(struct IPerlStdIO * piPerl,FILE * pf,const char * format,...)795 PerlStdIOPrintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format,...)
796 {
797     va_list arglist;
798     va_start(arglist, format);
799     PERL_UNUSED_ARG(piPerl);
800     return win32_vfprintf(pf, format, arglist);
801 }
802 
803 int
PerlStdIOVprintf(struct IPerlStdIO * piPerl,FILE * pf,const char * format,va_list arglist)804 PerlStdIOVprintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format, va_list arglist)
805 {
806     PERL_UNUSED_ARG(piPerl);
807     return win32_vfprintf(pf, format, arglist);
808 }
809 
810 Off_t
PerlStdIOTell(struct IPerlStdIO * piPerl,FILE * pf)811 PerlStdIOTell(struct IPerlStdIO* piPerl, FILE* pf)
812 {
813     PERL_UNUSED_ARG(piPerl);
814     return win32_ftell(pf);
815 }
816 
817 int
PerlStdIOSeek(struct IPerlStdIO * piPerl,FILE * pf,Off_t offset,int origin)818 PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, Off_t offset, int origin)
819 {
820     PERL_UNUSED_ARG(piPerl);
821     return win32_fseek(pf, offset, origin);
822 }
823 
824 void
PerlStdIORewind(struct IPerlStdIO * piPerl,FILE * pf)825 PerlStdIORewind(struct IPerlStdIO* piPerl, FILE* pf)
826 {
827     PERL_UNUSED_ARG(piPerl);
828     win32_rewind(pf);
829 }
830 
831 FILE*
PerlStdIOTmpfile(struct IPerlStdIO * piPerl)832 PerlStdIOTmpfile(struct IPerlStdIO* piPerl)
833 {
834     PERL_UNUSED_ARG(piPerl);
835     return win32_tmpfile();
836 }
837 
838 int
PerlStdIOGetpos(struct IPerlStdIO * piPerl,FILE * pf,Fpos_t * p)839 PerlStdIOGetpos(struct IPerlStdIO* piPerl, FILE* pf, Fpos_t *p)
840 {
841     PERL_UNUSED_ARG(piPerl);
842     return win32_fgetpos(pf, p);
843 }
844 
845 int
PerlStdIOSetpos(struct IPerlStdIO * piPerl,FILE * pf,const Fpos_t * p)846 PerlStdIOSetpos(struct IPerlStdIO* piPerl, FILE* pf, const Fpos_t *p)
847 {
848     PERL_UNUSED_ARG(piPerl);
849     return win32_fsetpos(pf, p);
850 }
851 void
PerlStdIOInit(struct IPerlStdIO * piPerl)852 PerlStdIOInit(struct IPerlStdIO* piPerl)
853 {
854     PERL_UNUSED_ARG(piPerl);
855 }
856 
857 void
PerlStdIOInitOSExtras(struct IPerlStdIO * piPerl)858 PerlStdIOInitOSExtras(struct IPerlStdIO* piPerl)
859 {
860     PERL_UNUSED_ARG(piPerl);
861     Perl_init_os_extras();
862 }
863 
864 int
PerlStdIOOpenOSfhandle(struct IPerlStdIO * piPerl,intptr_t osfhandle,int flags)865 PerlStdIOOpenOSfhandle(struct IPerlStdIO* piPerl, intptr_t osfhandle, int flags)
866 {
867     PERL_UNUSED_ARG(piPerl);
868     return win32_open_osfhandle(osfhandle, flags);
869 }
870 
871 intptr_t
PerlStdIOGetOSfhandle(struct IPerlStdIO * piPerl,int filenum)872 PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum)
873 {
874     PERL_UNUSED_ARG(piPerl);
875     return win32_get_osfhandle(filenum);
876 }
877 
878 FILE*
PerlStdIOFdupopen(struct IPerlStdIO * piPerl,FILE * pf)879 PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf)
880 {
881     FILE* pfdup;
882     fpos_t pos;
883     char mode[3];
884     int fileno = win32_dup(win32_fileno(pf));
885     PERL_UNUSED_ARG(piPerl);
886 
887     /* open the file in the same mode */
888     if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RD) {
889         mode[0] = 'r';
890         mode[1] = 0;
891     }
892     else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_WR) {
893         mode[0] = 'a';
894         mode[1] = 0;
895     }
896     else if (PERLIO_FILE_flag(pf) & PERLIO_FILE_flag_RW) {
897         mode[0] = 'r';
898         mode[1] = '+';
899         mode[2] = 0;
900     }
901 
902     /* it appears that the binmode is attached to the
903      * file descriptor so binmode files will be handled
904      * correctly
905      */
906     pfdup = win32_fdopen(fileno, mode);
907 
908     /* move the file pointer to the same position */
909     if (!fgetpos(pf, &pos)) {
910         fsetpos(pfdup, &pos);
911     }
912     return pfdup;
913 }
914 
915 const struct IPerlStdIO perlStdIO =
916 {
917     PerlStdIOStdin,
918     PerlStdIOStdout,
919     PerlStdIOStderr,
920     PerlStdIOOpen,
921     PerlStdIOClose,
922     PerlStdIOEof,
923     PerlStdIOError,
924     PerlStdIOClearerr,
925     PerlStdIOGetc,
926     PerlStdIOGetBase,
927     PerlStdIOGetBufsiz,
928     PerlStdIOGetCnt,
929     PerlStdIOGetPtr,
930     PerlStdIOGets,
931     PerlStdIOPutc,
932     PerlStdIOPuts,
933     PerlStdIOFlush,
934     PerlStdIOUngetc,
935     PerlStdIOFileno,
936     PerlStdIOFdopen,
937     PerlStdIOReopen,
938     PerlStdIORead,
939     PerlStdIOWrite,
940     PerlStdIOSetBuf,
941     PerlStdIOSetVBuf,
942     PerlStdIOSetCnt,
943     PerlStdIOSetPtr,
944     PerlStdIOSetlinebuf,
945     PerlStdIOPrintf,
946     PerlStdIOVprintf,
947     PerlStdIOTell,
948     PerlStdIOSeek,
949     PerlStdIORewind,
950     PerlStdIOTmpfile,
951     PerlStdIOGetpos,
952     PerlStdIOSetpos,
953     PerlStdIOInit,
954     PerlStdIOInitOSExtras,
955     PerlStdIOFdupopen,
956 };
957 
958 
959 #undef IPERL2HOST
960 #define IPERL2HOST(x) IPerlLIO2Host(x)
961 
962 /* IPerlLIO */
963 int
PerlLIOAccess(struct IPerlLIO * piPerl,const char * path,int mode)964 PerlLIOAccess(struct IPerlLIO* piPerl, const char *path, int mode)
965 {
966     PERL_UNUSED_ARG(piPerl);
967     return win32_access(path, mode);
968 }
969 
970 int
PerlLIOChmod(struct IPerlLIO * piPerl,const char * filename,int pmode)971 PerlLIOChmod(struct IPerlLIO* piPerl, const char *filename, int pmode)
972 {
973     PERL_UNUSED_ARG(piPerl);
974     return win32_chmod(filename, pmode);
975 }
976 
977 int
PerlLIOChown(struct IPerlLIO * piPerl,const char * filename,uid_t owner,gid_t group)978 PerlLIOChown(struct IPerlLIO* piPerl, const char *filename, uid_t owner, gid_t group)
979 {
980     PERL_UNUSED_ARG(piPerl);
981     return chown(filename, owner, group);
982 }
983 
984 int
PerlLIOChsize(struct IPerlLIO * piPerl,int handle,Off_t size)985 PerlLIOChsize(struct IPerlLIO* piPerl, int handle, Off_t size)
986 {
987     PERL_UNUSED_ARG(piPerl);
988     return win32_chsize(handle, size);
989 }
990 
991 int
PerlLIOClose(struct IPerlLIO * piPerl,int handle)992 PerlLIOClose(struct IPerlLIO* piPerl, int handle)
993 {
994     PERL_UNUSED_ARG(piPerl);
995     return win32_close(handle);
996 }
997 
998 int
PerlLIODup(struct IPerlLIO * piPerl,int handle)999 PerlLIODup(struct IPerlLIO* piPerl, int handle)
1000 {
1001     PERL_UNUSED_ARG(piPerl);
1002     return win32_dup(handle);
1003 }
1004 
1005 int
PerlLIODup2(struct IPerlLIO * piPerl,int handle1,int handle2)1006 PerlLIODup2(struct IPerlLIO* piPerl, int handle1, int handle2)
1007 {
1008     PERL_UNUSED_ARG(piPerl);
1009     return win32_dup2(handle1, handle2);
1010 }
1011 
1012 int
PerlLIOFlock(struct IPerlLIO * piPerl,int fd,int oper)1013 PerlLIOFlock(struct IPerlLIO* piPerl, int fd, int oper)
1014 {
1015     PERL_UNUSED_ARG(piPerl);
1016     return win32_flock(fd, oper);
1017 }
1018 
1019 int
PerlLIOFileStat(struct IPerlLIO * piPerl,int handle,Stat_t * buffer)1020 PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, Stat_t *buffer)
1021 {
1022     PERL_UNUSED_ARG(piPerl);
1023     return win32_fstat(handle, buffer);
1024 }
1025 
1026 int
PerlLIOIOCtl(struct IPerlLIO * piPerl,int i,unsigned int u,char * data)1027 PerlLIOIOCtl(struct IPerlLIO* piPerl, int i, unsigned int u, char *data)
1028 {
1029     u_long u_long_arg;
1030     int retval;
1031     PERL_UNUSED_ARG(piPerl);
1032 
1033     /* mauke says using memcpy avoids alignment issues */
1034     memcpy(&u_long_arg, data, sizeof u_long_arg);
1035     retval = win32_ioctlsocket((SOCKET)i, (long)u, &u_long_arg);
1036     memcpy(data, &u_long_arg, sizeof u_long_arg);
1037     return retval;
1038 }
1039 
1040 int
PerlLIOIsatty(struct IPerlLIO * piPerl,int fd)1041 PerlLIOIsatty(struct IPerlLIO* piPerl, int fd)
1042 {
1043     PERL_UNUSED_ARG(piPerl);
1044     return win32_isatty(fd);
1045 }
1046 
1047 int
PerlLIOLink(struct IPerlLIO * piPerl,const char * oldname,const char * newname)1048 PerlLIOLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
1049 {
1050     PERL_UNUSED_ARG(piPerl);
1051     return win32_link(oldname, newname);
1052 }
1053 
1054 int
PerlLIOSymLink(struct IPerlLIO * piPerl,const char * oldname,const char * newname)1055 PerlLIOSymLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
1056 {
1057     PERL_UNUSED_ARG(piPerl);
1058     return win32_symlink(oldname, newname);
1059 }
1060 
1061 int
PerlLIOReadLink(struct IPerlLIO * piPerl,const char * path,char * buf,size_t bufsiz)1062 PerlLIOReadLink(struct IPerlLIO* piPerl, const char *path, char *buf, size_t bufsiz)
1063 {
1064     PERL_UNUSED_ARG(piPerl);
1065     return win32_readlink(path, buf, bufsiz);
1066 }
1067 
1068 Off_t
PerlLIOLseek(struct IPerlLIO * piPerl,int handle,Off_t offset,int origin)1069 PerlLIOLseek(struct IPerlLIO* piPerl, int handle, Off_t offset, int origin)
1070 {
1071     PERL_UNUSED_ARG(piPerl);
1072     return win32_lseek(handle, offset, origin);
1073 }
1074 
1075 int
PerlLIOLstat(struct IPerlLIO * piPerl,const char * path,Stat_t * buffer)1076 PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
1077 {
1078     PERL_UNUSED_ARG(piPerl);
1079     return win32_lstat(path, buffer);
1080 }
1081 
1082 char*
PerlLIOMktemp(struct IPerlLIO * piPerl,char * Template)1083 PerlLIOMktemp(struct IPerlLIO* piPerl, char *Template)
1084 {
1085     PERL_UNUSED_ARG(piPerl);
1086     return mktemp(Template);
1087 }
1088 
1089 int
PerlLIOOpen(struct IPerlLIO * piPerl,const char * filename,int oflag)1090 PerlLIOOpen(struct IPerlLIO* piPerl, const char *filename, int oflag)
1091 {
1092     PERL_UNUSED_ARG(piPerl);
1093     return win32_open(filename, oflag);
1094 }
1095 
1096 int
PerlLIOOpen3(struct IPerlLIO * piPerl,const char * filename,int oflag,int pmode)1097 PerlLIOOpen3(struct IPerlLIO* piPerl, const char *filename, int oflag, int pmode)
1098 {
1099     PERL_UNUSED_ARG(piPerl);
1100     return win32_open(filename, oflag, pmode);
1101 }
1102 
1103 int
PerlLIORead(struct IPerlLIO * piPerl,int handle,void * buffer,unsigned int count)1104 PerlLIORead(struct IPerlLIO* piPerl, int handle, void *buffer, unsigned int count)
1105 {
1106     PERL_UNUSED_ARG(piPerl);
1107     return win32_read(handle, buffer, count);
1108 }
1109 
1110 int
PerlLIORename(struct IPerlLIO * piPerl,const char * OldFileName,const char * newname)1111 PerlLIORename(struct IPerlLIO* piPerl, const char *OldFileName, const char *newname)
1112 {
1113     PERL_UNUSED_ARG(piPerl);
1114     return win32_rename(OldFileName, newname);
1115 }
1116 
1117 int
PerlLIOSetmode(struct IPerlLIO * piPerl,int handle,int mode)1118 PerlLIOSetmode(struct IPerlLIO* piPerl, int handle, int mode)
1119 {
1120     PERL_UNUSED_ARG(piPerl);
1121     return win32_setmode(handle, mode);
1122 }
1123 
1124 int
PerlLIONameStat(struct IPerlLIO * piPerl,const char * path,Stat_t * buffer)1125 PerlLIONameStat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
1126 {
1127     PERL_UNUSED_ARG(piPerl);
1128     return win32_stat(path, buffer);
1129 }
1130 
1131 char*
PerlLIOTmpnam(struct IPerlLIO * piPerl,char * string)1132 PerlLIOTmpnam(struct IPerlLIO* piPerl, char *string)
1133 {
1134     PERL_UNUSED_ARG(piPerl);
1135     return tmpnam(string);
1136 }
1137 
1138 int
PerlLIOUmask(struct IPerlLIO * piPerl,int pmode)1139 PerlLIOUmask(struct IPerlLIO* piPerl, int pmode)
1140 {
1141     PERL_UNUSED_ARG(piPerl);
1142     return umask(pmode);
1143 }
1144 
1145 int
PerlLIOUnlink(struct IPerlLIO * piPerl,const char * filename)1146 PerlLIOUnlink(struct IPerlLIO* piPerl, const char *filename)
1147 {
1148     PERL_UNUSED_ARG(piPerl);
1149     return win32_unlink(filename);
1150 }
1151 
1152 int
PerlLIOUtime(struct IPerlLIO * piPerl,const char * filename,struct utimbuf * times)1153 PerlLIOUtime(struct IPerlLIO* piPerl, const char *filename, struct utimbuf *times)
1154 {
1155     PERL_UNUSED_ARG(piPerl);
1156     return win32_utime(filename, times);
1157 }
1158 
1159 int
PerlLIOWrite(struct IPerlLIO * piPerl,int handle,const void * buffer,unsigned int count)1160 PerlLIOWrite(struct IPerlLIO* piPerl, int handle, const void *buffer, unsigned int count)
1161 {
1162     PERL_UNUSED_ARG(piPerl);
1163     return win32_write(handle, buffer, count);
1164 }
1165 
1166 const struct IPerlLIO perlLIO =
1167 {
1168     PerlLIOAccess,
1169     PerlLIOChmod,
1170     PerlLIOChown,
1171     PerlLIOChsize,
1172     PerlLIOClose,
1173     PerlLIODup,
1174     PerlLIODup2,
1175     PerlLIOFlock,
1176     PerlLIOFileStat,
1177     PerlLIOIOCtl,
1178     PerlLIOIsatty,
1179     PerlLIOLink,
1180     PerlLIOLseek,
1181     PerlLIOLstat,
1182     PerlLIOMktemp,
1183     PerlLIOOpen,
1184     PerlLIOOpen3,
1185     PerlLIORead,
1186     PerlLIORename,
1187     PerlLIOSetmode,
1188     PerlLIONameStat,
1189     PerlLIOTmpnam,
1190     PerlLIOUmask,
1191     PerlLIOUnlink,
1192     PerlLIOUtime,
1193     PerlLIOWrite,
1194     PerlLIOSymLink,
1195     PerlLIOReadLink
1196 };
1197 
1198 
1199 #undef IPERL2HOST
1200 #define IPERL2HOST(x) IPerlDir2Host(x)
1201 
1202 /* IPerlDIR */
1203 int
PerlDirMakedir(struct IPerlDir * piPerl,const char * dirname,int mode)1204 PerlDirMakedir(struct IPerlDir* piPerl, const char *dirname, int mode)
1205 {
1206     PERL_UNUSED_ARG(piPerl);
1207     return win32_mkdir(dirname, mode);
1208 }
1209 
1210 int
PerlDirChdir(struct IPerlDir * piPerl,const char * dirname)1211 PerlDirChdir(struct IPerlDir* piPerl, const char *dirname)
1212 {
1213     PERL_UNUSED_ARG(piPerl);
1214     return IPERL2HOST(piPerl)->Chdir(dirname);
1215 }
1216 
1217 int
PerlDirRmdir(struct IPerlDir * piPerl,const char * dirname)1218 PerlDirRmdir(struct IPerlDir* piPerl, const char *dirname)
1219 {
1220     PERL_UNUSED_ARG(piPerl);
1221     return win32_rmdir(dirname);
1222 }
1223 
1224 int
PerlDirClose(struct IPerlDir * piPerl,DIR * dirp)1225 PerlDirClose(struct IPerlDir* piPerl, DIR *dirp)
1226 {
1227     PERL_UNUSED_ARG(piPerl);
1228     return win32_closedir(dirp);
1229 }
1230 
1231 DIR*
PerlDirOpen(struct IPerlDir * piPerl,const char * filename)1232 PerlDirOpen(struct IPerlDir* piPerl, const char *filename)
1233 {
1234     PERL_UNUSED_ARG(piPerl);
1235     return win32_opendir(filename);
1236 }
1237 
1238 struct direct *
PerlDirRead(struct IPerlDir * piPerl,DIR * dirp)1239 PerlDirRead(struct IPerlDir* piPerl, DIR *dirp)
1240 {
1241     PERL_UNUSED_ARG(piPerl);
1242     return win32_readdir(dirp);
1243 }
1244 
1245 void
PerlDirRewind(struct IPerlDir * piPerl,DIR * dirp)1246 PerlDirRewind(struct IPerlDir* piPerl, DIR *dirp)
1247 {
1248     PERL_UNUSED_ARG(piPerl);
1249     win32_rewinddir(dirp);
1250 }
1251 
1252 void
PerlDirSeek(struct IPerlDir * piPerl,DIR * dirp,long loc)1253 PerlDirSeek(struct IPerlDir* piPerl, DIR *dirp, long loc)
1254 {
1255     PERL_UNUSED_ARG(piPerl);
1256     win32_seekdir(dirp, loc);
1257 }
1258 
1259 long
PerlDirTell(struct IPerlDir * piPerl,DIR * dirp)1260 PerlDirTell(struct IPerlDir* piPerl, DIR *dirp)
1261 {
1262     PERL_UNUSED_ARG(piPerl);
1263     return win32_telldir(dirp);
1264 }
1265 
1266 char*
PerlDirMapPathA(struct IPerlDir * piPerl,const char * path)1267 PerlDirMapPathA(struct IPerlDir* piPerl, const char* path)
1268 {
1269     return IPERL2HOST(piPerl)->MapPathA(path);
1270 }
1271 
1272 WCHAR*
PerlDirMapPathW(struct IPerlDir * piPerl,const WCHAR * path)1273 PerlDirMapPathW(struct IPerlDir* piPerl, const WCHAR* path)
1274 {
1275     return IPERL2HOST(piPerl)->MapPathW(path);
1276 }
1277 
1278 const struct IPerlDir perlDir =
1279 {
1280     PerlDirMakedir,
1281     PerlDirChdir,
1282     PerlDirRmdir,
1283     PerlDirClose,
1284     PerlDirOpen,
1285     PerlDirRead,
1286     PerlDirRewind,
1287     PerlDirSeek,
1288     PerlDirTell,
1289     PerlDirMapPathA,
1290     PerlDirMapPathW,
1291 };
1292 
1293 
1294 /* IPerlSock */
1295 u_long
PerlSockHtonl(struct IPerlSock * piPerl,u_long hostlong)1296 PerlSockHtonl(struct IPerlSock* piPerl, u_long hostlong)
1297 {
1298     PERL_UNUSED_ARG(piPerl);
1299     return win32_htonl(hostlong);
1300 }
1301 
1302 u_short
PerlSockHtons(struct IPerlSock * piPerl,u_short hostshort)1303 PerlSockHtons(struct IPerlSock* piPerl, u_short hostshort)
1304 {
1305     PERL_UNUSED_ARG(piPerl);
1306     return win32_htons(hostshort);
1307 }
1308 
1309 u_long
PerlSockNtohl(struct IPerlSock * piPerl,u_long netlong)1310 PerlSockNtohl(struct IPerlSock* piPerl, u_long netlong)
1311 {
1312     PERL_UNUSED_ARG(piPerl);
1313     return win32_ntohl(netlong);
1314 }
1315 
1316 u_short
PerlSockNtohs(struct IPerlSock * piPerl,u_short netshort)1317 PerlSockNtohs(struct IPerlSock* piPerl, u_short netshort)
1318 {
1319     PERL_UNUSED_ARG(piPerl);
1320     return win32_ntohs(netshort);
1321 }
1322 
PerlSockAccept(struct IPerlSock * piPerl,SOCKET s,struct sockaddr * addr,int * addrlen)1323 SOCKET PerlSockAccept(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* addr, int* addrlen)
1324 {
1325     PERL_UNUSED_ARG(piPerl);
1326     return win32_accept(s, addr, addrlen);
1327 }
1328 
1329 int
PerlSockBind(struct IPerlSock * piPerl,SOCKET s,const struct sockaddr * name,int namelen)1330 PerlSockBind(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
1331 {
1332     PERL_UNUSED_ARG(piPerl);
1333     return win32_bind(s, name, namelen);
1334 }
1335 
1336 int
PerlSockConnect(struct IPerlSock * piPerl,SOCKET s,const struct sockaddr * name,int namelen)1337 PerlSockConnect(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
1338 {
1339     PERL_UNUSED_ARG(piPerl);
1340     return win32_connect(s, name, namelen);
1341 }
1342 
1343 void
PerlSockEndhostent(struct IPerlSock * piPerl)1344 PerlSockEndhostent(struct IPerlSock* piPerl)
1345 {
1346     PERL_UNUSED_ARG(piPerl);
1347     win32_endhostent();
1348 }
1349 
1350 void
PerlSockEndnetent(struct IPerlSock * piPerl)1351 PerlSockEndnetent(struct IPerlSock* piPerl)
1352 {
1353     PERL_UNUSED_ARG(piPerl);
1354     win32_endnetent();
1355 }
1356 
1357 void
PerlSockEndprotoent(struct IPerlSock * piPerl)1358 PerlSockEndprotoent(struct IPerlSock* piPerl)
1359 {
1360     PERL_UNUSED_ARG(piPerl);
1361     win32_endprotoent();
1362 }
1363 
1364 void
PerlSockEndservent(struct IPerlSock * piPerl)1365 PerlSockEndservent(struct IPerlSock* piPerl)
1366 {
1367     PERL_UNUSED_ARG(piPerl);
1368     win32_endservent();
1369 }
1370 
1371 struct hostent*
PerlSockGethostbyaddr(struct IPerlSock * piPerl,const char * addr,int len,int type)1372 PerlSockGethostbyaddr(struct IPerlSock* piPerl, const char* addr, int len, int type)
1373 {
1374     PERL_UNUSED_ARG(piPerl);
1375     return win32_gethostbyaddr(addr, len, type);
1376 }
1377 
1378 struct hostent*
PerlSockGethostbyname(struct IPerlSock * piPerl,const char * name)1379 PerlSockGethostbyname(struct IPerlSock* piPerl, const char* name)
1380 {
1381     PERL_UNUSED_ARG(piPerl);
1382     return win32_gethostbyname(name);
1383 }
1384 
1385 struct hostent*
PerlSockGethostent(struct IPerlSock * piPerl)1386 PerlSockGethostent(struct IPerlSock* piPerl)
1387 {
1388     PERL_UNUSED_ARG(piPerl);
1389     win32_croak_not_implemented("gethostent");
1390     return NULL;
1391 }
1392 
1393 int
PerlSockGethostname(struct IPerlSock * piPerl,char * name,int namelen)1394 PerlSockGethostname(struct IPerlSock* piPerl, char* name, int namelen)
1395 {
1396     PERL_UNUSED_ARG(piPerl);
1397     return win32_gethostname(name, namelen);
1398 }
1399 
1400 struct netent *
PerlSockGetnetbyaddr(struct IPerlSock * piPerl,long net,int type)1401 PerlSockGetnetbyaddr(struct IPerlSock* piPerl, long net, int type)
1402 {
1403     PERL_UNUSED_ARG(piPerl);
1404     return win32_getnetbyaddr(net, type);
1405 }
1406 
1407 struct netent *
PerlSockGetnetbyname(struct IPerlSock * piPerl,const char * name)1408 PerlSockGetnetbyname(struct IPerlSock* piPerl, const char *name)
1409 {
1410     PERL_UNUSED_ARG(piPerl);
1411     return win32_getnetbyname((char*)name);
1412 }
1413 
1414 struct netent *
PerlSockGetnetent(struct IPerlSock * piPerl)1415 PerlSockGetnetent(struct IPerlSock* piPerl)
1416 {
1417     PERL_UNUSED_ARG(piPerl);
1418     return win32_getnetent();
1419 }
1420 
PerlSockGetpeername(struct IPerlSock * piPerl,SOCKET s,struct sockaddr * name,int * namelen)1421 int PerlSockGetpeername(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
1422 {
1423     PERL_UNUSED_ARG(piPerl);
1424     return win32_getpeername(s, name, namelen);
1425 }
1426 
1427 struct protoent*
PerlSockGetprotobyname(struct IPerlSock * piPerl,const char * name)1428 PerlSockGetprotobyname(struct IPerlSock* piPerl, const char* name)
1429 {
1430     PERL_UNUSED_ARG(piPerl);
1431     return win32_getprotobyname(name);
1432 }
1433 
1434 struct protoent*
PerlSockGetprotobynumber(struct IPerlSock * piPerl,int number)1435 PerlSockGetprotobynumber(struct IPerlSock* piPerl, int number)
1436 {
1437     PERL_UNUSED_ARG(piPerl);
1438     return win32_getprotobynumber(number);
1439 }
1440 
1441 struct protoent*
PerlSockGetprotoent(struct IPerlSock * piPerl)1442 PerlSockGetprotoent(struct IPerlSock* piPerl)
1443 {
1444     PERL_UNUSED_ARG(piPerl);
1445     return win32_getprotoent();
1446 }
1447 
1448 struct servent*
PerlSockGetservbyname(struct IPerlSock * piPerl,const char * name,const char * proto)1449 PerlSockGetservbyname(struct IPerlSock* piPerl, const char* name, const char* proto)
1450 {
1451     PERL_UNUSED_ARG(piPerl);
1452     return win32_getservbyname(name, proto);
1453 }
1454 
1455 struct servent*
PerlSockGetservbyport(struct IPerlSock * piPerl,int port,const char * proto)1456 PerlSockGetservbyport(struct IPerlSock* piPerl, int port, const char* proto)
1457 {
1458     PERL_UNUSED_ARG(piPerl);
1459     return win32_getservbyport(port, proto);
1460 }
1461 
1462 struct servent*
PerlSockGetservent(struct IPerlSock * piPerl)1463 PerlSockGetservent(struct IPerlSock* piPerl)
1464 {
1465     PERL_UNUSED_ARG(piPerl);
1466     return win32_getservent();
1467 }
1468 
1469 int
PerlSockGetsockname(struct IPerlSock * piPerl,SOCKET s,struct sockaddr * name,int * namelen)1470 PerlSockGetsockname(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
1471 {
1472     PERL_UNUSED_ARG(piPerl);
1473     return win32_getsockname(s, name, namelen);
1474 }
1475 
1476 int
PerlSockGetsockopt(struct IPerlSock * piPerl,SOCKET s,int level,int optname,char * optval,int * optlen)1477 PerlSockGetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, char* optval, int* optlen)
1478 {
1479     PERL_UNUSED_ARG(piPerl);
1480     return win32_getsockopt(s, level, optname, optval, optlen);
1481 }
1482 
1483 unsigned long
PerlSockInetAddr(struct IPerlSock * piPerl,const char * cp)1484 PerlSockInetAddr(struct IPerlSock* piPerl, const char* cp)
1485 {
1486     PERL_UNUSED_ARG(piPerl);
1487     return win32_inet_addr(cp);
1488 }
1489 
1490 char*
PerlSockInetNtoa(struct IPerlSock * piPerl,struct in_addr in)1491 PerlSockInetNtoa(struct IPerlSock* piPerl, struct in_addr in)
1492 {
1493     PERL_UNUSED_ARG(piPerl);
1494     return win32_inet_ntoa(in);
1495 }
1496 
1497 int
PerlSockListen(struct IPerlSock * piPerl,SOCKET s,int backlog)1498 PerlSockListen(struct IPerlSock* piPerl, SOCKET s, int backlog)
1499 {
1500     PERL_UNUSED_ARG(piPerl);
1501     return win32_listen(s, backlog);
1502 }
1503 
1504 int
PerlSockRecv(struct IPerlSock * piPerl,SOCKET s,char * buffer,int len,int flags)1505 PerlSockRecv(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags)
1506 {
1507     PERL_UNUSED_ARG(piPerl);
1508     return win32_recv(s, buffer, len, flags);
1509 }
1510 
1511 int
PerlSockRecvfrom(struct IPerlSock * piPerl,SOCKET s,char * buffer,int len,int flags,struct sockaddr * from,int * fromlen)1512 PerlSockRecvfrom(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen)
1513 {
1514     PERL_UNUSED_ARG(piPerl);
1515     return win32_recvfrom(s, buffer, len, flags, from, fromlen);
1516 }
1517 
1518 int
PerlSockSelect(struct IPerlSock * piPerl,int nfds,char * readfds,char * writefds,char * exceptfds,const struct timeval * timeout)1519 PerlSockSelect(struct IPerlSock* piPerl, int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout)
1520 {
1521     PERL_UNUSED_ARG(piPerl);
1522     return win32_select(nfds, (Perl_fd_set*)readfds, (Perl_fd_set*)writefds, (Perl_fd_set*)exceptfds, timeout);
1523 }
1524 
1525 int
PerlSockSend(struct IPerlSock * piPerl,SOCKET s,const char * buffer,int len,int flags)1526 PerlSockSend(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags)
1527 {
1528     PERL_UNUSED_ARG(piPerl);
1529     return win32_send(s, buffer, len, flags);
1530 }
1531 
1532 int
PerlSockSendto(struct IPerlSock * piPerl,SOCKET s,const char * buffer,int len,int flags,const struct sockaddr * to,int tolen)1533 PerlSockSendto(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen)
1534 {
1535     PERL_UNUSED_ARG(piPerl);
1536     return win32_sendto(s, buffer, len, flags, to, tolen);
1537 }
1538 
1539 void
PerlSockSethostent(struct IPerlSock * piPerl,int stayopen)1540 PerlSockSethostent(struct IPerlSock* piPerl, int stayopen)
1541 {
1542     PERL_UNUSED_ARG(piPerl);
1543     win32_sethostent(stayopen);
1544 }
1545 
1546 void
PerlSockSetnetent(struct IPerlSock * piPerl,int stayopen)1547 PerlSockSetnetent(struct IPerlSock* piPerl, int stayopen)
1548 {
1549     PERL_UNUSED_ARG(piPerl);
1550     win32_setnetent(stayopen);
1551 }
1552 
1553 void
PerlSockSetprotoent(struct IPerlSock * piPerl,int stayopen)1554 PerlSockSetprotoent(struct IPerlSock* piPerl, int stayopen)
1555 {
1556     PERL_UNUSED_ARG(piPerl);
1557     win32_setprotoent(stayopen);
1558 }
1559 
1560 void
PerlSockSetservent(struct IPerlSock * piPerl,int stayopen)1561 PerlSockSetservent(struct IPerlSock* piPerl, int stayopen)
1562 {
1563     PERL_UNUSED_ARG(piPerl);
1564     win32_setservent(stayopen);
1565 }
1566 
1567 int
PerlSockSetsockopt(struct IPerlSock * piPerl,SOCKET s,int level,int optname,const char * optval,int optlen)1568 PerlSockSetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, const char* optval, int optlen)
1569 {
1570     PERL_UNUSED_ARG(piPerl);
1571     return win32_setsockopt(s, level, optname, optval, optlen);
1572 }
1573 
1574 int
PerlSockShutdown(struct IPerlSock * piPerl,SOCKET s,int how)1575 PerlSockShutdown(struct IPerlSock* piPerl, SOCKET s, int how)
1576 {
1577     PERL_UNUSED_ARG(piPerl);
1578     return win32_shutdown(s, how);
1579 }
1580 
1581 SOCKET
PerlSockSocket(struct IPerlSock * piPerl,int af,int type,int protocol)1582 PerlSockSocket(struct IPerlSock* piPerl, int af, int type, int protocol)
1583 {
1584     PERL_UNUSED_ARG(piPerl);
1585     return win32_socket(af, type, protocol);
1586 }
1587 
1588 int
PerlSockSocketpair(struct IPerlSock * piPerl,int domain,int type,int protocol,int * fds)1589 PerlSockSocketpair(struct IPerlSock* piPerl, int domain, int type, int protocol, int* fds)
1590 {
1591     PERL_UNUSED_ARG(piPerl);
1592     return Perl_my_socketpair(domain, type, protocol, fds);
1593 }
1594 
1595 int
PerlSockClosesocket(struct IPerlSock * piPerl,SOCKET s)1596 PerlSockClosesocket(struct IPerlSock* piPerl, SOCKET s)
1597 {
1598     PERL_UNUSED_ARG(piPerl);
1599     return win32_closesocket(s);
1600 }
1601 
1602 int
PerlSockIoctlsocket(struct IPerlSock * piPerl,SOCKET s,long cmd,u_long * argp)1603 PerlSockIoctlsocket(struct IPerlSock* piPerl, SOCKET s, long cmd, u_long *argp)
1604 {
1605     PERL_UNUSED_ARG(piPerl);
1606     return win32_ioctlsocket(s, cmd, argp);
1607 }
1608 
1609 const struct IPerlSock perlSock =
1610 {
1611     PerlSockHtonl,
1612     PerlSockHtons,
1613     PerlSockNtohl,
1614     PerlSockNtohs,
1615     PerlSockAccept,
1616     PerlSockBind,
1617     PerlSockConnect,
1618     PerlSockEndhostent,
1619     PerlSockEndnetent,
1620     PerlSockEndprotoent,
1621     PerlSockEndservent,
1622     PerlSockGethostname,
1623     PerlSockGetpeername,
1624     PerlSockGethostbyaddr,
1625     PerlSockGethostbyname,
1626     PerlSockGethostent,
1627     PerlSockGetnetbyaddr,
1628     PerlSockGetnetbyname,
1629     PerlSockGetnetent,
1630     PerlSockGetprotobyname,
1631     PerlSockGetprotobynumber,
1632     PerlSockGetprotoent,
1633     PerlSockGetservbyname,
1634     PerlSockGetservbyport,
1635     PerlSockGetservent,
1636     PerlSockGetsockname,
1637     PerlSockGetsockopt,
1638     PerlSockInetAddr,
1639     PerlSockInetNtoa,
1640     PerlSockListen,
1641     PerlSockRecv,
1642     PerlSockRecvfrom,
1643     PerlSockSelect,
1644     PerlSockSend,
1645     PerlSockSendto,
1646     PerlSockSethostent,
1647     PerlSockSetnetent,
1648     PerlSockSetprotoent,
1649     PerlSockSetservent,
1650     PerlSockSetsockopt,
1651     PerlSockShutdown,
1652     PerlSockSocket,
1653     PerlSockSocketpair,
1654     PerlSockClosesocket,
1655 };
1656 
1657 
1658 /* IPerlProc */
1659 
1660 #define EXECF_EXEC 1
1661 #define EXECF_SPAWN 2
1662 
1663 void
PerlProcAbort(struct IPerlProc * piPerl)1664 PerlProcAbort(struct IPerlProc* piPerl)
1665 {
1666     PERL_UNUSED_ARG(piPerl);
1667     win32_abort();
1668 }
1669 
1670 char *
PerlProcCrypt(struct IPerlProc * piPerl,const char * clear,const char * salt)1671 PerlProcCrypt(struct IPerlProc* piPerl, const char* clear, const char* salt)
1672 {
1673     PERL_UNUSED_ARG(piPerl);
1674     return win32_crypt(clear, salt);
1675 }
1676 
1677 PERL_CALLCONV_NO_RET void
PerlProcExit(struct IPerlProc * piPerl,int status)1678 PerlProcExit(struct IPerlProc* piPerl, int status)
1679 {
1680     PERL_UNUSED_ARG(piPerl);
1681     exit(status);
1682 }
1683 
1684 PERL_CALLCONV_NO_RET void
PerlProc_Exit(struct IPerlProc * piPerl,int status)1685 PerlProc_Exit(struct IPerlProc* piPerl, int status)
1686 {
1687     PERL_UNUSED_ARG(piPerl);
1688     _exit(status);
1689 }
1690 
1691 int
PerlProcExecl(struct IPerlProc * piPerl,const char * cmdname,const char * arg0,const char * arg1,const char * arg2,const char * arg3)1692 PerlProcExecl(struct IPerlProc* piPerl, const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3)
1693 {
1694     PERL_UNUSED_ARG(piPerl);
1695     return execl(cmdname, arg0, arg1, arg2, arg3);
1696 }
1697 
1698 int
PerlProcExecv(struct IPerlProc * piPerl,const char * cmdname,const char * const * argv)1699 PerlProcExecv(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
1700 {
1701     PERL_UNUSED_ARG(piPerl);
1702     return win32_execvp(cmdname, argv);
1703 }
1704 
1705 int
PerlProcExecvp(struct IPerlProc * piPerl,const char * cmdname,const char * const * argv)1706 PerlProcExecvp(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
1707 {
1708     PERL_UNUSED_ARG(piPerl);
1709     return win32_execvp(cmdname, argv);
1710 }
1711 
1712 uid_t
PerlProcGetuid(struct IPerlProc * piPerl)1713 PerlProcGetuid(struct IPerlProc* piPerl)
1714 {
1715     PERL_UNUSED_ARG(piPerl);
1716     return getuid();
1717 }
1718 
1719 uid_t
PerlProcGeteuid(struct IPerlProc * piPerl)1720 PerlProcGeteuid(struct IPerlProc* piPerl)
1721 {
1722     PERL_UNUSED_ARG(piPerl);
1723     return geteuid();
1724 }
1725 
1726 gid_t
PerlProcGetgid(struct IPerlProc * piPerl)1727 PerlProcGetgid(struct IPerlProc* piPerl)
1728 {
1729     PERL_UNUSED_ARG(piPerl);
1730     return getgid();
1731 }
1732 
1733 gid_t
PerlProcGetegid(struct IPerlProc * piPerl)1734 PerlProcGetegid(struct IPerlProc* piPerl)
1735 {
1736     PERL_UNUSED_ARG(piPerl);
1737     return getegid();
1738 }
1739 
1740 char *
PerlProcGetlogin(struct IPerlProc * piPerl)1741 PerlProcGetlogin(struct IPerlProc* piPerl)
1742 {
1743     PERL_UNUSED_ARG(piPerl);
1744     return g_getlogin();
1745 }
1746 
1747 int
PerlProcKill(struct IPerlProc * piPerl,int pid,int sig)1748 PerlProcKill(struct IPerlProc* piPerl, int pid, int sig)
1749 {
1750     PERL_UNUSED_ARG(piPerl);
1751     return win32_kill(pid, sig);
1752 }
1753 
1754 int
PerlProcKillpg(struct IPerlProc * piPerl,int pid,int sig)1755 PerlProcKillpg(struct IPerlProc* piPerl, int pid, int sig)
1756 {
1757     PERL_UNUSED_ARG(piPerl);
1758     return win32_kill(pid, -sig);
1759 }
1760 
1761 int
PerlProcPauseProc(struct IPerlProc * piPerl)1762 PerlProcPauseProc(struct IPerlProc* piPerl)
1763 {
1764     PERL_UNUSED_ARG(piPerl);
1765     return win32_pause();
1766 }
1767 
1768 PerlIO*
PerlProcPopen(struct IPerlProc * piPerl,const char * command,const char * mode)1769 PerlProcPopen(struct IPerlProc* piPerl, const char *command, const char *mode)
1770 {
1771     dTHX;
1772     PERL_FLUSHALL_FOR_CHILD;
1773     PERL_UNUSED_ARG(piPerl);
1774     return win32_popen(command, mode);
1775 }
1776 
1777 PerlIO*
PerlProcPopenList(struct IPerlProc * piPerl,const char * mode,IV narg,SV ** args)1778 PerlProcPopenList(struct IPerlProc* piPerl, const char *mode, IV narg, SV **args)
1779 {
1780     dTHX;
1781     PERL_FLUSHALL_FOR_CHILD;
1782     PERL_UNUSED_ARG(piPerl);
1783     return win32_popenlist(mode, narg, args);
1784 }
1785 
1786 int
PerlProcPclose(struct IPerlProc * piPerl,PerlIO * stream)1787 PerlProcPclose(struct IPerlProc* piPerl, PerlIO *stream)
1788 {
1789     PERL_UNUSED_ARG(piPerl);
1790     return win32_pclose(stream);
1791 }
1792 
1793 int
PerlProcPipe(struct IPerlProc * piPerl,int * phandles)1794 PerlProcPipe(struct IPerlProc* piPerl, int *phandles)
1795 {
1796     PERL_UNUSED_ARG(piPerl);
1797     return win32_pipe(phandles, 512, O_BINARY);
1798 }
1799 
1800 int
PerlProcSetuid(struct IPerlProc * piPerl,uid_t u)1801 PerlProcSetuid(struct IPerlProc* piPerl, uid_t u)
1802 {
1803     PERL_UNUSED_ARG(piPerl);
1804     return setuid(u);
1805 }
1806 
1807 int
PerlProcSetgid(struct IPerlProc * piPerl,gid_t g)1808 PerlProcSetgid(struct IPerlProc* piPerl, gid_t g)
1809 {
1810     PERL_UNUSED_ARG(piPerl);
1811     return setgid(g);
1812 }
1813 
1814 int
PerlProcSleep(struct IPerlProc * piPerl,unsigned int s)1815 PerlProcSleep(struct IPerlProc* piPerl, unsigned int s)
1816 {
1817     PERL_UNUSED_ARG(piPerl);
1818     return win32_sleep(s);
1819 }
1820 
1821 int
PerlProcTimes(struct IPerlProc * piPerl,struct tms * timebuf)1822 PerlProcTimes(struct IPerlProc* piPerl, struct tms *timebuf)
1823 {
1824     PERL_UNUSED_ARG(piPerl);
1825     return win32_times(timebuf);
1826 }
1827 
1828 int
PerlProcWait(struct IPerlProc * piPerl,int * status)1829 PerlProcWait(struct IPerlProc* piPerl, int *status)
1830 {
1831     PERL_UNUSED_ARG(piPerl);
1832     return win32_wait(status);
1833 }
1834 
1835 int
PerlProcWaitpid(struct IPerlProc * piPerl,int pid,int * status,int flags)1836 PerlProcWaitpid(struct IPerlProc* piPerl, int pid, int *status, int flags)
1837 {
1838     PERL_UNUSED_ARG(piPerl);
1839     return win32_waitpid(pid, status, flags);
1840 }
1841 
1842 Sighandler_t
PerlProcSignal(struct IPerlProc * piPerl,int sig,Sighandler_t subcode)1843 PerlProcSignal(struct IPerlProc* piPerl, int sig, Sighandler_t subcode)
1844 {
1845     PERL_UNUSED_ARG(piPerl);
1846     return win32_signal(sig, subcode);
1847 }
1848 
1849 int
PerlProcGetTimeOfDay(struct IPerlProc * piPerl,struct timeval * t,void * z)1850 PerlProcGetTimeOfDay(struct IPerlProc* piPerl, struct timeval *t, void *z)
1851 {
1852     PERL_UNUSED_ARG(piPerl);
1853     return win32_gettimeofday(t, z);
1854 }
1855 
1856 #ifdef USE_ITHREADS
1857 PERL_STACK_REALIGN
1858 static THREAD_RET_TYPE
win32_start_child(LPVOID arg)1859 win32_start_child(LPVOID arg)
1860 {
1861     PerlInterpreter *my_perl = (PerlInterpreter*)arg;
1862     int status;
1863     HWND parent_message_hwnd;
1864 #ifdef PERL_SYNC_FORK
1865     static long sync_fork_id = 0;
1866     long id = ++sync_fork_id;
1867 #endif
1868 
1869 
1870     PERL_SET_THX(my_perl);
1871     win32_checkTLS(my_perl);
1872 
1873 #ifdef PERL_SYNC_FORK
1874     w32_pseudo_id = id;
1875 #else
1876     w32_pseudo_id = GetCurrentThreadId();
1877 #endif
1878 #ifdef PERL_USES_PL_PIDSTATUS
1879     hv_clear(PL_pidstatus);
1880 #endif
1881 
1882     /* create message window and tell parent about it */
1883     parent_message_hwnd = w32_message_hwnd;
1884     w32_message_hwnd = win32_create_message_window();
1885     if (parent_message_hwnd != NULL)
1886         PostMessage(parent_message_hwnd, WM_USER_MESSAGE, w32_pseudo_id, (LPARAM)w32_message_hwnd);
1887 
1888     /* push a zero on the stack (we are the child) */
1889     {
1890         dSP;
1891         dTARGET;
1892         PUSHi(0);
1893         PUTBACK;
1894     }
1895 
1896     /* continue from next op */
1897     PL_op = PL_op->op_next;
1898 
1899     {
1900         dJMPENV;
1901         volatile int oldscope = 1; /* We are responsible for all scopes */
1902 
1903 restart:
1904         JMPENV_PUSH(status);
1905         switch (status) {
1906         case 0:
1907             CALLRUNOPS(aTHX);
1908             /* We may have additional unclosed scopes if fork() was called
1909              * from within a BEGIN block.  See perlfork.pod for more details.
1910              * We cannot clean up these other scopes because they belong to a
1911              * different interpreter, but we also cannot leave PL_scopestack_ix
1912              * dangling because that can trigger an assertion in perl_destruct().
1913              */
1914             if (PL_scopestack_ix > oldscope) {
1915                 PL_scopestack[oldscope-1] = PL_scopestack[PL_scopestack_ix-1];
1916                 PL_scopestack_ix = oldscope;
1917             }
1918             status = 0;
1919             break;
1920         case 2:
1921             while (PL_scopestack_ix > oldscope)
1922                 LEAVE;
1923             FREETMPS;
1924             PL_curstash = PL_defstash;
1925             if (PL_curstash != PL_defstash) {
1926                 SvREFCNT_dec(PL_curstash);
1927                 PL_curstash = (HV *)SvREFCNT_inc(PL_defstash);
1928             }
1929             if (PL_endav && !PL_minus_c) {
1930                 PERL_SET_PHASE(PERL_PHASE_END);
1931                 call_list(oldscope, PL_endav);
1932             }
1933             status = STATUS_EXIT;
1934             break;
1935         case 3:
1936             if (PL_restartop) {
1937                 POPSTACK_TO(PL_mainstack);
1938                 PL_op = PL_restartop;
1939                 PL_restartop = (OP*)NULL;
1940                 goto restart;
1941             }
1942             PerlIO_printf(Perl_error_log, "panic: restartop\n");
1943             FREETMPS;
1944             status = 1;
1945             break;
1946         }
1947         JMPENV_POP;
1948 
1949         /* XXX hack to avoid perl_destruct() freeing optree */
1950         win32_checkTLS(my_perl);
1951         PL_main_root = (OP*)NULL;
1952     }
1953 
1954     win32_checkTLS(my_perl);
1955     /* close the std handles to avoid fd leaks */
1956     {
1957         do_close(PL_stdingv, FALSE);
1958         do_close(gv_fetchpv("STDOUT", TRUE, SVt_PVIO), FALSE); /* PL_stdoutgv - ISAGN */
1959         do_close(PL_stderrgv, FALSE);
1960     }
1961 
1962     /* destroy everything (waits for any pseudo-forked children) */
1963     win32_checkTLS(my_perl);
1964     perl_destruct(my_perl);
1965     win32_checkTLS(my_perl);
1966     perl_free(my_perl);
1967 
1968 #ifdef PERL_SYNC_FORK
1969     return id;
1970 #else
1971     return (DWORD)status;
1972 #endif
1973 }
1974 #endif /* USE_ITHREADS */
1975 
1976 int
PerlProcFork(struct IPerlProc * piPerl)1977 PerlProcFork(struct IPerlProc* piPerl)
1978 {
1979     PERL_UNUSED_ARG(piPerl);
1980 #ifdef USE_ITHREADS
1981     dTHX;
1982     DWORD id;
1983     HANDLE handle;
1984     CPerlHost *h;
1985 
1986     if (w32_num_pseudo_children >= MAXIMUM_WAIT_OBJECTS) {
1987         errno = EAGAIN;
1988         return -1;
1989     }
1990     h = new CPerlHost(*(CPerlHost*)w32_internal_host);
1991     PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHX,
1992                                                  CLONEf_COPY_STACKS,
1993                                                  h->m_pHostperlMem,
1994                                                  h->m_pHostperlMemShared,
1995                                                  h->m_pHostperlMemParse,
1996                                                  h->m_pHostperlEnv,
1997                                                  h->m_pHostperlStdIO,
1998                                                  h->m_pHostperlLIO,
1999                                                  h->m_pHostperlDir,
2000                                                  h->m_pHostperlSock,
2001                                                  h->m_pHostperlProc
2002                                                  );
2003     new_perl->Isys_intern.internal_host = h;
2004     h->host_perl = new_perl;
2005 #  ifdef PERL_SYNC_FORK
2006     id = win32_start_child((LPVOID)new_perl);
2007     PERL_SET_THX(aTHX);
2008 #  else
2009     if (w32_message_hwnd == INVALID_HANDLE_VALUE)
2010         w32_message_hwnd = win32_create_message_window();
2011     new_perl->Isys_intern.message_hwnd = w32_message_hwnd;
2012     w32_pseudo_child_message_hwnds[w32_num_pseudo_children] =
2013         (w32_message_hwnd == NULL) ? (HWND)NULL : (HWND)INVALID_HANDLE_VALUE;
2014 #    ifdef USE_RTL_THREAD_API
2015     handle = (HANDLE)_beginthreadex((void*)NULL, 0, win32_start_child,
2016                                     (void*)new_perl, 0, (unsigned*)&id);
2017 #    else
2018     handle = CreateThread(NULL, 0, win32_start_child,
2019                           (LPVOID)new_perl, 0, &id);
2020 #    endif
2021     PERL_SET_THX(aTHX);	/* XXX perl_clone*() set TLS */
2022     if (!handle) {
2023         errno = EAGAIN;
2024         return -1;
2025     }
2026     w32_pseudo_child_handles[w32_num_pseudo_children] = handle;
2027     w32_pseudo_child_pids[w32_num_pseudo_children] = id;
2028     w32_pseudo_child_sigterm[w32_num_pseudo_children] = 0;
2029     ++w32_num_pseudo_children;
2030 #  endif
2031     return -(int)id;
2032 #else
2033     win32_croak_not_implemented("fork()");
2034     return -1;
2035 #endif /* USE_ITHREADS */
2036 }
2037 
2038 int
PerlProcGetpid(struct IPerlProc * piPerl)2039 PerlProcGetpid(struct IPerlProc* piPerl)
2040 {
2041     PERL_UNUSED_ARG(piPerl);
2042     return win32_getpid();
2043 }
2044 
2045 void*
PerlProcDynaLoader(struct IPerlProc * piPerl,const char * filename)2046 PerlProcDynaLoader(struct IPerlProc* piPerl, const char* filename)
2047 {
2048     PERL_UNUSED_ARG(piPerl);
2049     return win32_dynaload(filename);
2050 }
2051 
2052 void
PerlProcGetOSError(struct IPerlProc * piPerl,SV * sv,DWORD dwErr)2053 PerlProcGetOSError(struct IPerlProc* piPerl, SV* sv, DWORD dwErr)
2054 {
2055     PERL_UNUSED_ARG(piPerl);
2056     win32_str_os_error(sv, dwErr);
2057 }
2058 
2059 int
PerlProcSpawnvp(struct IPerlProc * piPerl,int mode,const char * cmdname,const char * const * argv)2060 PerlProcSpawnvp(struct IPerlProc* piPerl, int mode, const char *cmdname, const char *const *argv)
2061 {
2062     PERL_UNUSED_ARG(piPerl);
2063     return win32_spawnvp(mode, cmdname, argv);
2064 }
2065 
2066 int
PerlProcLastHost(struct IPerlProc * piPerl)2067 PerlProcLastHost(struct IPerlProc* piPerl)
2068 {
2069  /* this dTHX is unused in an optimized build since CPerlHost::num_hosts
2070     is a static */
2071     dTHX;
2072     CPerlHost *h = (CPerlHost*)w32_internal_host;
2073     PERL_UNUSED_ARG(piPerl);
2074     return h->LastHost();
2075 }
2076 
2077 const struct IPerlProc perlProc =
2078 {
2079     PerlProcAbort,
2080     PerlProcCrypt,
2081     PerlProcExit,
2082     PerlProc_Exit,
2083     PerlProcExecl,
2084     PerlProcExecv,
2085     PerlProcExecvp,
2086     PerlProcGetuid,
2087     PerlProcGeteuid,
2088     PerlProcGetgid,
2089     PerlProcGetegid,
2090     PerlProcGetlogin,
2091     PerlProcKill,
2092     PerlProcKillpg,
2093     PerlProcPauseProc,
2094     PerlProcPopen,
2095     PerlProcPclose,
2096     PerlProcPipe,
2097     PerlProcSetuid,
2098     PerlProcSetgid,
2099     PerlProcSleep,
2100     PerlProcTimes,
2101     PerlProcWait,
2102     PerlProcWaitpid,
2103     PerlProcSignal,
2104     PerlProcFork,
2105     PerlProcGetpid,
2106     PerlProcDynaLoader,
2107     PerlProcGetOSError,
2108     PerlProcSpawnvp,
2109     PerlProcLastHost,
2110     PerlProcPopenList,
2111     PerlProcGetTimeOfDay
2112 };
2113 
2114 
2115 /*
2116  * CPerlHost
2117  */
2118 
CPerlHost(void)2119 CPerlHost::CPerlHost(void)
2120 {
2121     /* Construct a host from scratch */
2122     InterlockedIncrement(&num_hosts);
2123     m_pvDir = new VDir();
2124     m_pVMem = new VMem();
2125     m_pVMemShared = new VMem();
2126     m_pVMemParse =  new VMem();
2127 
2128     m_pvDir->Init(NULL, m_pVMem);
2129 
2130     m_dwEnvCount = 0;
2131     m_lppEnvList = NULL;
2132     m_bTopLevel = TRUE;
2133 
2134     CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2135     CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2136     CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2137     CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2138     CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2139     CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2140     CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2141     CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2142     CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2143 
2144     m_pHostperlMem	    = &m_hostperlMem;
2145     m_pHostperlMemShared    = &m_hostperlMemShared;
2146     m_pHostperlMemParse	    = &m_hostperlMemParse;
2147     m_pHostperlEnv	    = &m_hostperlEnv;
2148     m_pHostperlStdIO	    = &m_hostperlStdIO;
2149     m_pHostperlLIO	    = &m_hostperlLIO;
2150     m_pHostperlDir	    = &m_hostperlDir;
2151     m_pHostperlSock	    = &m_hostperlSock;
2152     m_pHostperlProc	    = &m_hostperlProc;
2153 }
2154 
2155 #define SETUPEXCHANGE(xptr, iptr, table) \
2156     STMT_START {				\
2157         if (xptr) {				\
2158             iptr = *xptr;			\
2159             *xptr = &table;			\
2160         }					\
2161         else {					\
2162             iptr = &table;			\
2163         }					\
2164     } STMT_END
2165 
CPerlHost(struct IPerlMem ** ppMem,struct IPerlMem ** ppMemShared,struct IPerlMem ** ppMemParse,struct IPerlEnv ** ppEnv,struct IPerlStdIO ** ppStdIO,struct IPerlLIO ** ppLIO,struct IPerlDir ** ppDir,struct IPerlSock ** ppSock,struct IPerlProc ** ppProc)2166 CPerlHost::CPerlHost(struct IPerlMem** ppMem, struct IPerlMem** ppMemShared,
2167                  struct IPerlMem** ppMemParse, struct IPerlEnv** ppEnv,
2168                  struct IPerlStdIO** ppStdIO, struct IPerlLIO** ppLIO,
2169                  struct IPerlDir** ppDir, struct IPerlSock** ppSock,
2170                  struct IPerlProc** ppProc)
2171 {
2172     InterlockedIncrement(&num_hosts);
2173     m_pvDir = new VDir(0);
2174     m_pVMem = new VMem();
2175     m_pVMemShared = new VMem();
2176     m_pVMemParse =  new VMem();
2177 
2178     m_pvDir->Init(NULL, m_pVMem);
2179 
2180     m_dwEnvCount = 0;
2181     m_lppEnvList = NULL;
2182     m_bTopLevel = FALSE;
2183 
2184     CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2185     CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2186     CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2187     CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2188     CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2189     CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2190     CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2191     CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2192     CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2193 
2194     SETUPEXCHANGE(ppMem,	m_pHostperlMem,		m_hostperlMem);
2195     SETUPEXCHANGE(ppMemShared,	m_pHostperlMemShared,	m_hostperlMemShared);
2196     SETUPEXCHANGE(ppMemParse,	m_pHostperlMemParse,	m_hostperlMemParse);
2197     SETUPEXCHANGE(ppEnv,	m_pHostperlEnv,		m_hostperlEnv);
2198     SETUPEXCHANGE(ppStdIO,	m_pHostperlStdIO,	m_hostperlStdIO);
2199     SETUPEXCHANGE(ppLIO,	m_pHostperlLIO,		m_hostperlLIO);
2200     SETUPEXCHANGE(ppDir,	m_pHostperlDir,		m_hostperlDir);
2201     SETUPEXCHANGE(ppSock,	m_pHostperlSock,	m_hostperlSock);
2202     SETUPEXCHANGE(ppProc,	m_pHostperlProc,	m_hostperlProc);
2203 }
2204 #undef SETUPEXCHANGE
2205 
CPerlHost(CPerlHost & host)2206 CPerlHost::CPerlHost(CPerlHost& host)
2207 {
2208     /* Construct a host from another host */
2209     InterlockedIncrement(&num_hosts);
2210     m_pVMem = new VMem();
2211     m_pVMemShared = host.GetMemShared();
2212     m_pVMemParse =  host.GetMemParse();
2213 
2214     /* duplicate directory info */
2215     m_pvDir = new VDir(0);
2216     m_pvDir->Init(host.GetDir(), m_pVMem);
2217 
2218     CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
2219     CopyMemory(&m_hostperlMemShared, &perlMemShared, sizeof(perlMemShared));
2220     CopyMemory(&m_hostperlMemParse, &perlMemParse, sizeof(perlMemParse));
2221     CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
2222     CopyMemory(&m_hostperlStdIO, &perlStdIO, sizeof(perlStdIO));
2223     CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
2224     CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
2225     CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
2226     CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
2227     m_pHostperlMem	    = &m_hostperlMem;
2228     m_pHostperlMemShared    = &m_hostperlMemShared;
2229     m_pHostperlMemParse	    = &m_hostperlMemParse;
2230     m_pHostperlEnv	    = &m_hostperlEnv;
2231     m_pHostperlStdIO	    = &m_hostperlStdIO;
2232     m_pHostperlLIO	    = &m_hostperlLIO;
2233     m_pHostperlDir	    = &m_hostperlDir;
2234     m_pHostperlSock	    = &m_hostperlSock;
2235     m_pHostperlProc	    = &m_hostperlProc;
2236 
2237     m_dwEnvCount = 0;
2238     m_lppEnvList = NULL;
2239     m_bTopLevel = FALSE;
2240 
2241     /* duplicate environment info */
2242     LPSTR lpPtr;
2243     DWORD dwIndex = 0;
2244     while((lpPtr = host.GetIndex(dwIndex)))
2245         Add(lpPtr);
2246 }
2247 
~CPerlHost(void)2248 CPerlHost::~CPerlHost(void)
2249 {
2250     Reset();
2251     InterlockedDecrement(&num_hosts);
2252     delete m_pvDir;
2253     m_pVMemParse->Release();
2254     m_pVMemShared->Release();
2255     m_pVMem->Release();
2256 }
2257 
2258 LPSTR
Find(LPCSTR lpStr)2259 CPerlHost::Find(LPCSTR lpStr)
2260 {
2261     LPSTR lpPtr;
2262     LPSTR* lppPtr = Lookup(lpStr);
2263     if(lppPtr != NULL) {
2264         for(lpPtr = *lppPtr; *lpPtr != '\0' && *lpPtr != '='; ++lpPtr)
2265             ;
2266 
2267         if(*lpPtr == '=')
2268             ++lpPtr;
2269 
2270         return lpPtr;
2271     }
2272     return NULL;
2273 }
2274 
2275 int
lookup(const void * arg1,const void * arg2)2276 lookup(const void *arg1, const void *arg2)
2277 {   // Compare strings
2278     char*ptr1, *ptr2;
2279     char c1,c2;
2280 
2281     ptr1 = *(char**)arg1;
2282     ptr2 = *(char**)arg2;
2283     for(;;) {
2284         c1 = *ptr1++;
2285         c2 = *ptr2++;
2286         if(c1 == '\0' || c1 == '=') {
2287             if(c2 == '\0' || c2 == '=')
2288                 break;
2289 
2290             return -1; // string 1 < string 2
2291         }
2292         else if(c2 == '\0' || c2 == '=')
2293             return 1; // string 1 > string 2
2294         else if(c1 != c2) {
2295             c1 = toupper(c1);
2296             c2 = toupper(c2);
2297             if(c1 != c2) {
2298                 if(c1 < c2)
2299                     return -1; // string 1 < string 2
2300 
2301                 return 1; // string 1 > string 2
2302             }
2303         }
2304     }
2305     return 0;
2306 }
2307 
2308 LPSTR*
Lookup(LPCSTR lpStr)2309 CPerlHost::Lookup(LPCSTR lpStr)
2310 {
2311     if (!lpStr)
2312         return NULL;
2313     return (LPSTR*)bsearch(&lpStr, m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), lookup);
2314 }
2315 
2316 int
compare(const void * arg1,const void * arg2)2317 compare(const void *arg1, const void *arg2)
2318 {   // Compare strings
2319     char*ptr1, *ptr2;
2320     char c1,c2;
2321 
2322     ptr1 = *(char**)arg1;
2323     ptr2 = *(char**)arg2;
2324     for(;;) {
2325         c1 = *ptr1++;
2326         c2 = *ptr2++;
2327         if(c1 == '\0' || c1 == '=') {
2328             if(c1 == c2)
2329                 break;
2330 
2331             return -1; // string 1 < string 2
2332         }
2333         else if(c2 == '\0' || c2 == '=')
2334             return 1; // string 1 > string 2
2335         else if(c1 != c2) {
2336             c1 = toupper(c1);
2337             c2 = toupper(c2);
2338             if(c1 != c2) {
2339                 if(c1 < c2)
2340                     return -1; // string 1 < string 2
2341 
2342                 return 1; // string 1 > string 2
2343             }
2344         }
2345     }
2346     return 0;
2347 }
2348 
2349 void
Add(LPCSTR lpStr)2350 CPerlHost::Add(LPCSTR lpStr)
2351 {
2352     LPSTR *lpPtr;
2353     STRLEN length = strlen(lpStr)+1;
2354 
2355     // replacing ?
2356     lpPtr = Lookup(lpStr);
2357     if (lpPtr != NULL) {
2358         // must allocate things via host memory allocation functions
2359         // rather than perl's Renew() et al, as the perl interpreter
2360         // may either not be initialized enough when we allocate these,
2361         // or may already be dead when we go to free these
2362         *lpPtr = (char*)Realloc(*lpPtr, length * sizeof(char));
2363         strcpy(*lpPtr, lpStr);
2364     }
2365     else {
2366         m_lppEnvList = (LPSTR*)Realloc(m_lppEnvList, (m_dwEnvCount+1) * sizeof(LPSTR));
2367         if (m_lppEnvList) {
2368             m_lppEnvList[m_dwEnvCount] = (char*)Malloc(length * sizeof(char));
2369             if (m_lppEnvList[m_dwEnvCount] != NULL) {
2370                 strcpy(m_lppEnvList[m_dwEnvCount], lpStr);
2371                 ++m_dwEnvCount;
2372                 qsort(m_lppEnvList, m_dwEnvCount, sizeof(LPSTR), compare);
2373             }
2374         }
2375     }
2376 }
2377 
2378 DWORD
CalculateEnvironmentSpace(void)2379 CPerlHost::CalculateEnvironmentSpace(void)
2380 {
2381     DWORD index;
2382     DWORD dwSize = 0;
2383     for(index = 0; index < m_dwEnvCount; ++index)
2384         dwSize += strlen(m_lppEnvList[index]) + 1;
2385 
2386     return dwSize;
2387 }
2388 
2389 void
FreeLocalEnvironmentStrings(LPSTR lpStr)2390 CPerlHost::FreeLocalEnvironmentStrings(LPSTR lpStr)
2391 {
2392     Safefree(lpStr);
2393 }
2394 
2395 char*
GetChildDir(void)2396 CPerlHost::GetChildDir(void)
2397 {
2398     char* ptr;
2399     size_t length;
2400 
2401     Newx(ptr, MAX_PATH+1, char);
2402     m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr);
2403     length = strlen(ptr);
2404     if (length > 3) {
2405         if ((ptr[length-1] == '\\') || (ptr[length-1] == '/'))
2406             ptr[length-1] = 0;
2407     }
2408     return ptr;
2409 }
2410 
2411 void
FreeChildDir(char * pStr)2412 CPerlHost::FreeChildDir(char* pStr)
2413 {
2414     Safefree(pStr);
2415 }
2416 
2417 LPSTR
CreateLocalEnvironmentStrings(VDir & vDir)2418 CPerlHost::CreateLocalEnvironmentStrings(VDir &vDir)
2419 {
2420     LPSTR lpStr, lpPtr, lpEnvPtr, lpTmp, lpLocalEnv, lpAllocPtr;
2421     DWORD dwSize, dwEnvIndex;
2422     int nLength, compVal;
2423 
2424     // get the process environment strings
2425     lpAllocPtr = lpTmp = (LPSTR)win32_getenvironmentstrings();
2426 
2427     // step over current directory stuff
2428     while(*lpTmp == '=')
2429         lpTmp += strlen(lpTmp) + 1;
2430 
2431     // save the start of the environment strings
2432     lpEnvPtr = lpTmp;
2433     for(dwSize = 1; *lpTmp != '\0'; lpTmp += strlen(lpTmp) + 1) {
2434         // calculate the size of the environment strings
2435         dwSize += strlen(lpTmp) + 1;
2436     }
2437 
2438     // add the size of current directories
2439     dwSize += vDir.CalculateEnvironmentSpace();
2440 
2441     // add the additional space used by changes made to the environment
2442     dwSize += CalculateEnvironmentSpace();
2443 
2444     Newx(lpStr, dwSize, char);
2445     lpPtr = lpStr;
2446     if(lpStr != NULL) {
2447         // build the local environment
2448         lpStr = vDir.BuildEnvironmentSpace(lpStr);
2449 
2450         dwEnvIndex = 0;
2451         lpLocalEnv = GetIndex(dwEnvIndex);
2452         while(*lpEnvPtr != '\0') {
2453             if(!lpLocalEnv) {
2454                 // all environment overrides have been added
2455                 // so copy string into place
2456                 strcpy(lpStr, lpEnvPtr);
2457                 nLength = strlen(lpEnvPtr) + 1;
2458                 lpStr += nLength;
2459                 lpEnvPtr += nLength;
2460             }
2461             else {
2462                 // determine which string to copy next
2463                 compVal = compare(&lpEnvPtr, &lpLocalEnv);
2464                 if(compVal < 0) {
2465                     strcpy(lpStr, lpEnvPtr);
2466                     nLength = strlen(lpEnvPtr) + 1;
2467                     lpStr += nLength;
2468                     lpEnvPtr += nLength;
2469                 }
2470                 else {
2471                     char *ptr = strchr(lpLocalEnv, '=');
2472                     if(ptr && ptr[1]) {
2473                         strcpy(lpStr, lpLocalEnv);
2474                         lpStr += strlen(lpLocalEnv) + 1;
2475                     }
2476                     lpLocalEnv = GetIndex(dwEnvIndex);
2477                     if(compVal == 0) {
2478                         // this string was replaced
2479                         lpEnvPtr += strlen(lpEnvPtr) + 1;
2480                     }
2481                 }
2482             }
2483         }
2484 
2485         while(lpLocalEnv) {
2486             // still have environment overrides to add
2487             // so copy the strings into place if not an override
2488             char *ptr = strchr(lpLocalEnv, '=');
2489             if(ptr && ptr[1]) {
2490                 strcpy(lpStr, lpLocalEnv);
2491                 lpStr += strlen(lpLocalEnv) + 1;
2492             }
2493             lpLocalEnv = GetIndex(dwEnvIndex);
2494         }
2495 
2496         // add final NULL
2497         *lpStr = '\0';
2498     }
2499 
2500     // release the process environment strings
2501     win32_freeenvironmentstrings(lpAllocPtr);
2502 
2503     return lpPtr;
2504 }
2505 
2506 void
Reset(void)2507 CPerlHost::Reset(void)
2508 {
2509     if(m_lppEnvList != NULL) {
2510         for(DWORD index = 0; index < m_dwEnvCount; ++index) {
2511             Free(m_lppEnvList[index]);
2512             m_lppEnvList[index] = NULL;
2513         }
2514     }
2515     m_dwEnvCount = 0;
2516     Free(m_lppEnvList);
2517     m_lppEnvList = NULL;
2518 }
2519 
2520 void
Clearenv(void)2521 CPerlHost::Clearenv(void)
2522 {
2523     char ch;
2524     LPSTR lpPtr, lpStr, lpEnvPtr;
2525     if (m_lppEnvList != NULL) {
2526         /* set every entry to an empty string */
2527         for(DWORD index = 0; index < m_dwEnvCount; ++index) {
2528             char* ptr = strchr(m_lppEnvList[index], '=');
2529             if(ptr) {
2530                 *++ptr = 0;
2531             }
2532         }
2533     }
2534 
2535     /* get the process environment strings */
2536     lpStr = lpEnvPtr = (LPSTR)win32_getenvironmentstrings();
2537 
2538     /* step over current directory stuff */
2539     while(*lpStr == '=')
2540         lpStr += strlen(lpStr) + 1;
2541 
2542     while(*lpStr) {
2543         lpPtr = strchr(lpStr, '=');
2544         if(lpPtr) {
2545             ch = *++lpPtr;
2546             *lpPtr = 0;
2547             Add(lpStr);
2548             if (m_bTopLevel)
2549                 (void)win32_putenv(lpStr);
2550             *lpPtr = ch;
2551         }
2552         lpStr += strlen(lpStr) + 1;
2553     }
2554 
2555     win32_freeenvironmentstrings(lpEnvPtr);
2556 }
2557 
2558 
2559 char*
Getenv(const char * varname)2560 CPerlHost::Getenv(const char *varname)
2561 {
2562     if (!m_bTopLevel) {
2563         char *pEnv = Find(varname);
2564         if (pEnv && *pEnv)
2565             return pEnv;
2566     }
2567     return win32_getenv(varname);
2568 }
2569 
2570 int
Putenv(const char * envstring)2571 CPerlHost::Putenv(const char *envstring)
2572 {
2573     Add(envstring);
2574     if (m_bTopLevel)
2575         return win32_putenv(envstring);
2576 
2577     return 0;
2578 }
2579 
2580 int
Chdir(const char * dirname)2581 CPerlHost::Chdir(const char *dirname)
2582 {
2583     int ret;
2584     if (!dirname) {
2585         errno = ENOENT;
2586         return -1;
2587     }
2588     ret = m_pvDir->SetCurrentDirectoryA((char*)dirname);
2589     if(ret < 0) {
2590         errno = ENOENT;
2591     }
2592     return ret;
2593 }
2594 
2595 #endif /* ___PerlHost_H___ */
2596