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