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