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