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