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