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