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