- Timestamp:
- Aug 31, 2006, 2:31:27 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/libc-0.6/src/emx/src/lib/sys/libcfork.c
r2803 r2804 42 42 #include <string.h> 43 43 #include <errno.h> 44 #include <setjmp.h> 44 45 #include <emx/syscalls.h> 45 46 #include <386/builtin.h> … … 91 92 volatile int fDoneCompletion; 92 93 } __LIBC_FORKXCPTREGREC, *__LIBC_PFORKXCPTREGREC; 94 95 /** 96 * Exception registration record used for the module registration 97 * and deregistration APIs. 98 */ 99 typedef struct __LIBC_FORKXCPTREGREC2 100 { 101 /** The OS/2 exception record. */ 102 EXCEPTIONREGISTRATIONRECORD Core; 103 /** Our jump buffer. */ 104 jmp_buf JmpBuf; 105 } __LIBC_FORKXCPTREGREC2, *__LIBC_PFORKXCPTREGREC2; 106 107 93 108 94 109 /** … … 235 250 PCONTEXTRECORD pCtx, 236 251 PVOID pvWhatEver); 252 static ULONG _System forkBthExceptionHandlerRegDereg(PEXCEPTIONREPORTRECORD pXcptRepRec, 253 PEXCEPTIONREGISTRATIONRECORD pXcptRegRec, 254 PCONTEXTRECORD pCtx, 255 PVOID pvWhatEver); 256 237 257 238 258 /******************************************************************************* … … 336 356 forkLogModuleByAddr(pModule->pvDataSegBase); 337 357 #endif 338 int rc;339 __LIBC_PSPMPROCESS pProcess;340 __LIBC_PFORKHANDLE pForkHandle;341 PTIB pTib;342 PPIB pPib;343 EXCEPTIONREGISTRATIONRECORDXcptRegRec;358 int rc; 359 __LIBC_PSPMPROCESS pProcess; 360 __LIBC_PFORKHANDLE pForkHandle; 361 PTIB pTib; 362 PPIB pPib; 363 __LIBC_FORKXCPTREGREC2 XcptRegRec; 344 364 345 365 /* … … 347 367 */ 348 368 DosGetInfoBlocks(&pTib, &pPib); 349 XcptRegRec.ExceptionHandler = forkChlExceptionHandler; 350 XcptRegRec.prev_structure = pTib->tib_pexchain; 351 pTib->tib_pexchain = &XcptRegRec; 369 XcptRegRec.Core.ExceptionHandler = forkBthExceptionHandlerRegDereg; 370 XcptRegRec.Core.prev_structure = pTib->tib_pexchain; 371 if (!setjmp(XcptRegRec.JmpBuf)) 372 { 373 pTib->tib_pexchain = &XcptRegRec; 352 374 353 375 #ifdef TIMEBOMB 354 __libc_Timebomb();376 __libc_Timebomb(); 355 377 #endif 356 378 357 /*358 * Find the SPM process.359 */360 pProcess = __libc_spmSelf();361 if (!pProcess)362 {363 static char szMsg[] = "LIBC Error: Couldn't register process in shared memory!\r\n";364 ULONG ul;365 LIBC_ASSERTM_FAILED("couldn't register process!\n");366 367 DosWrite(2, szMsg, sizeof(szMsg), &ul);368 while (fExecutable)369 {370 LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n");371 DosExit(EXIT_PROCESS, /*fixme*/0xffff);372 }373 pTib->tib_pexchain = XcptRegRec.prev_structure;374 LIBCLOG_RETURN_INT(-1);375 }376 377 /*378 * Register the module.379 * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.)380 */381 if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED)382 LIBCLOG_MSG("__LIBC_FORKMODULE_FLAGS_DEREGISTERED!\n");383 pModule->fFlags &= ~__LIBC_FORKMODULE_FLAGS_DEREGISTERED;384 pModule->pNext = NULL;385 if (pProcess->pvModuleHead)386 *(__LIBC_PFORKMODULE*)pProcess->ppvModuleTail = pModule;387 else388 pProcess->pvModuleHead = pModule;389 pProcess->ppvModuleTail = (void **)&pModule->pNext;379 /* 380 * Find the SPM process. 381 */ 382 pProcess = __libc_spmSelf(); 383 if (!pProcess) 384 { 385 static char szMsg[] = "LIBC Error: Couldn't register process in shared memory!\r\n"; 386 ULONG ul; 387 LIBC_ASSERTM_FAILED("couldn't register process!\n"); 388 389 DosWrite(2, szMsg, sizeof(szMsg), &ul); 390 while (fExecutable) 391 { 392 LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n"); 393 DosExit(EXIT_PROCESS, /*fixme*/0xffff); 394 } 395 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 396 LIBCLOG_RETURN_INT(-1); 397 } 398 399 /* 400 * Register the module. 401 * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.) 402 */ 403 if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED) 404 LIBCLOG_MSG("__LIBC_FORKMODULE_FLAGS_DEREGISTERED!\n"); 405 pModule->fFlags &= ~__LIBC_FORKMODULE_FLAGS_DEREGISTERED; 406 pModule->pNext = NULL; 407 if (pProcess->pvModuleHead) 408 *(__LIBC_PFORKMODULE*)pProcess->ppvModuleTail = pModule; 409 else 410 pProcess->pvModuleHead = pModule; 411 pProcess->ppvModuleTail = (void **)&pModule->pNext; 390 412 391 413 392 414 #if 0 393 /* 394 * Debug checks. 395 */ 396 static char sz[] = "forking\0forking\0"; 397 PPIB pPib; 398 PTIB pTib; 399 DosGetInfoBlocks(&pTib, &pPib); 400 if (!memcmp(pPib->pib_pchcmd, sz, sizeof(sz))) 401 { 402 LIBC_ASSERTM(pProcess->pvForkHandle, "fork arguments, no fork handle!!! process %p\n", pProcess); 415 /* 416 * Debug checks. 417 */ 418 static char sz[] = "forking\0forking\0"; 419 PPIB pPib; 420 PTIB pTib; 421 DosGetInfoBlocks(&pTib, &pPib); 422 if (!memcmp(pPib->pib_pchcmd, sz, sizeof(sz))) 423 { 424 LIBC_ASSERTM(pProcess->pvForkHandle, "fork arguments, no fork handle!!! process %p\n", pProcess); 425 if (!pProcess->pvForkHandle) 426 __libc_SpmCheck(0, 1); 427 } 428 else 429 { 430 LIBC_ASSERTM(!pProcess->pvForkHandle, "no fork arguments, fork handle!!! process %p handle %p\n", pProcess, pProcess->pvForkHandle); 431 if (pProcess->pvForkHandle) 432 __libc_SpmCheck(0, 1); 433 } 434 #endif 435 436 /* 437 * Are we forking? 438 */ 439 #ifdef TIMEBOMB 440 forkTimebomb(); 441 #endif 403 442 if (!pProcess->pvForkHandle) 404 __libc_SpmCheck(0, 1); 405 } 406 else 407 { 408 LIBC_ASSERTM(!pProcess->pvForkHandle, "no fork arguments, fork handle!!! process %p handle %p\n", pProcess, pProcess->pvForkHandle); 409 if (pProcess->pvForkHandle) 410 __libc_SpmCheck(0, 1); 411 } 412 #endif 413 414 /* 415 * Are we forking? 416 */ 417 #ifdef TIMEBOMB 418 forkTimebomb(); 419 #endif 420 if (!pProcess->pvForkHandle) 421 { 422 pTib->tib_pexchain = XcptRegRec.prev_structure; 423 LIBCLOG_RETURN_INT(0); 424 } 425 /* we are! */ 426 427 /* 428 * Open the fork handle. 429 */ 430 pForkHandle = forkChlOpenHandle(pProcess->pvForkHandle); 431 if (!pForkHandle) 432 { 433 while (fExecutable) 434 { 435 LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n"); 436 DosExit(EXIT_PROCESS, /*fixme*/0xffff); 437 } 438 pTib->tib_pexchain = XcptRegRec.prev_structure; 439 LIBCLOG_RETURN_INT(-1); 440 } 441 g_pForkHandle = pForkHandle; 442 443 /* 444 * Let pfnDoFork() process the module. 445 */ 446 rc = pForkHandle->pfnDoFork(pForkHandle, pModule, fExecutable); 447 if (rc < 0) 448 { 449 while (fExecutable) 450 { 451 LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n"); 452 DosExit(EXIT_PROCESS, /*fixme*/0xffff); 453 } 454 pTib->tib_pexchain = XcptRegRec.prev_structure; 455 LIBCLOG_RETURN_INT(-1); 456 } 457 458 /* 459 * Done. 460 */ 461 LIBC_ASSERT(!fExecutable); 462 pTib->tib_pexchain = XcptRegRec.prev_structure; 463 LIBCLOG_RETURN_INT(1); 443 { 444 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 445 LIBCLOG_RETURN_INT(0); 446 } 447 /* we are! */ 448 449 /* 450 * Open the fork handle. 451 */ 452 pForkHandle = forkChlOpenHandle(pProcess->pvForkHandle); 453 if (!pForkHandle) 454 { 455 while (fExecutable) 456 { 457 LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n"); 458 DosExit(EXIT_PROCESS, /*fixme*/0xffff); 459 } 460 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 461 LIBCLOG_RETURN_INT(-1); 462 } 463 g_pForkHandle = pForkHandle; 464 465 /* 466 * Let pfnDoFork() process the module. 467 */ 468 XcptRegRec.Core.ExceptionHandler = forkChlExceptionHandler; 469 rc = pForkHandle->pfnDoFork(pForkHandle, pModule, fExecutable); 470 if (rc < 0) 471 { 472 while (fExecutable) 473 { 474 LIBCLOG_MSG("Calling DosExit(EXIT_PROCESS, 0xffff)...\n"); 475 DosExit(EXIT_PROCESS, /*fixme*/0xffff); 476 } 477 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 478 LIBCLOG_RETURN_INT(-1); 479 } 480 481 /* 482 * Done. 483 */ 484 LIBC_ASSERT(!fExecutable); 485 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 486 LIBCLOG_RETURN_INT(1); 487 } 488 489 /* Exception! */ 490 LIBCLOG_RETURN_INT(-1); 464 491 } 465 492 … … 482 509 forkLogModuleByAddr(pModule->pvDataSegBase); 483 510 #endif 484 485 /* 486 * Don't deregister modules which has already been deregistered. 487 * Don't deregister if we're in shutting down the process (waste of time and 488 * SPM might already be shut down). 489 */ 490 if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED) 491 LIBCLOG_RETURN_MSG_VOID( "ret void (__LIBC_FORKMODULE_FLAGS_DEREGISTERD)\n"); 492 if (!__libc_GpFIBLIS) 493 LIBCLOG_RETURN_MSG_VOID( "ret void (__libc_GpFIBLIS)\n"); 494 if (fibIsInExit()) 495 LIBCLOG_RETURN_MSG_VOID( "ret void (fibIsInExit)\n"); 496 497 /* 498 * Find the SPM process. 499 */ 500 __LIBC_PSPMPROCESS pProcess = __libc_spmSelf(); 501 if (!pProcess) 502 { 503 LIBC_ASSERTM_FAILED("can't find the process! weird!\n"); 511 PTIB pTib; 512 PPIB pPib; 513 __LIBC_FORKXCPTREGREC2 XcptRegRec; 514 515 /* 516 * Install an exceptionhandler. 517 */ 518 DosGetInfoBlocks(&pTib, &pPib); 519 XcptRegRec.Core.ExceptionHandler = forkBthExceptionHandlerRegDereg; 520 XcptRegRec.Core.prev_structure = pTib->tib_pexchain; 521 if (!setjmp(XcptRegRec.JmpBuf)) 522 { 523 pTib->tib_pexchain = &XcptRegRec; 524 525 /* 526 * Don't deregister modules which has already been deregistered. 527 * Don't deregister if we're in shutting down the process (waste of time and 528 * SPM might already be shut down). 529 */ 530 if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED) 531 { 532 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 533 LIBCLOG_RETURN_MSG_VOID( "ret void (__LIBC_FORKMODULE_FLAGS_DEREGISTERD)\n"); 534 } 535 if (!__libc_GpFIBLIS) 536 { 537 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 538 LIBCLOG_RETURN_MSG_VOID( "ret void (__libc_GpFIBLIS)\n"); 539 } 540 if (fibIsInExit()) 541 { 542 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 543 LIBCLOG_RETURN_MSG_VOID( "ret void (fibIsInExit)\n"); 544 } 545 546 /* 547 * Find the SPM process. 548 */ 549 __LIBC_PSPMPROCESS pProcess = __libc_spmSelf(); 550 if (!pProcess) 551 { 552 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 553 LIBC_ASSERTM_FAILED("can't find the process! weird!\n"); 554 LIBCLOG_RETURN_VOID(); 555 } 556 557 /* 558 * Deregister the module. 559 * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.) 560 */ 561 if ((__LIBC_PFORKMODULE)pProcess->pvModuleHead == pModule) 562 { 563 pProcess->pvModuleHead = pModule->pNext; 564 if (!pModule->pNext) 565 pProcess->ppvModuleTail = &pProcess->pvModuleHead; 566 } 567 else 568 { 569 __LIBC_PFORKMODULE pPrev = (__LIBC_PFORKMODULE)pProcess->pvModuleHead; 570 while (pPrev && pPrev->pNext != pModule) 571 pPrev = pPrev->pNext; 572 if (!pPrev) 573 { 574 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 575 LIBC_ASSERTM_FAILED("can't find the module! weird!\n"); 576 LIBCLOG_RETURN_VOID(); 577 } 578 579 pPrev->pNext = pModule->pNext; 580 if (!pModule->pNext) 581 pProcess->ppvModuleTail = (void **)&pPrev->pNext; 582 } 583 584 pModule->pNext = NULL; 585 pModule->fFlags |= __LIBC_FORKMODULE_FLAGS_DEREGISTERED; 586 587 pTib->tib_pexchain = XcptRegRec.Core.prev_structure; 504 588 LIBCLOG_RETURN_VOID(); 505 589 } 506 590 507 /* 508 * Deregister the module. 509 * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.) 510 */ 511 if ((__LIBC_PFORKMODULE)pProcess->pvModuleHead == pModule) 512 { 513 pProcess->pvModuleHead = pModule->pNext; 514 if (!pModule->pNext) 515 pProcess->ppvModuleTail = &pProcess->pvModuleHead; 516 } 517 else 518 { 519 __LIBC_PFORKMODULE pPrev = (__LIBC_PFORKMODULE)pProcess->pvModuleHead; 520 while (pPrev && pPrev->pNext != pModule) 521 pPrev = pPrev->pNext; 522 if (!pPrev) 523 { 524 LIBC_ASSERTM_FAILED("can't find the module! weird!\n"); 525 LIBCLOG_RETURN_VOID(); 526 } 527 528 pPrev->pNext = pModule->pNext; 529 if (!pModule->pNext) 530 pProcess->ppvModuleTail = (void **)&pPrev->pNext; 531 } 532 533 pModule->pNext = NULL; 534 pModule->fFlags |= __LIBC_FORKMODULE_FLAGS_DEREGISTERED; 535 591 /* Exception! */ 536 592 LIBCLOG_RETURN_VOID(); 537 593 } … … 728 784 * @param pvForkRet Return address for the child. 729 785 * @param pvStackRet ESP for the child when returning from fork. 730 * @param pXc tpRegRec Pointer to the exception registration record (fDoneCompletion).786 * @param pXcptRegRec Pointer to the exception registration record (fDoneCompletion). 731 787 */ 732 788 static int forkParDo(void *pvForkRet, void *pvStackRet, __LIBC_PFORKXCPTREGREC pXcptRegRec) … … 3349 3405 } 3350 3406 3407 3408 /** 3409 * Exception handler for the module registration/deregistration. 3410 * 3411 * @returns XCPT_CONTINUE_SEARCH or XCPT_CONTINUE_EXECUTION. 3412 * @param pXcptRepRec Report record. 3413 * @param pXcptRegRec Registration record. 3414 * @param pCtx Context record. 3415 * @param pvWhatEver Not quite sure what this is... 3416 */ 3417 static ULONG _System forkBthExceptionHandlerRegDereg(PEXCEPTIONREPORTRECORD pXcptRepRec, 3418 PEXCEPTIONREGISTRATIONRECORD pXcptRegRec, 3419 PCONTEXTRECORD pCtx, 3420 PVOID pvWhatEver) 3421 { 3422 __asm__ ("cld"); /* usual paranoia. */ 3423 3424 if (pXcptRepRec->fHandlerFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) 3425 return XCPT_CONTINUE_SEARCH; 3426 3427 LIBCLOG_MSG2("forkBthExceptionHandlerRegDereg: ExceptionNum=%#lx ExceptionAddress=%p eip=%#lx ExceptionInfo={%#08lx,%#08lx,%#08lx,%#08lx} fHandlerFlags=%#lx\n", 3428 pXcptRepRec->ExceptionNum, pXcptRepRec->ExceptionAddress, pCtx->ctx_RegEip, 3429 pXcptRepRec->ExceptionInfo[0], pXcptRepRec->ExceptionInfo[1], 3430 pXcptRepRec->ExceptionInfo[2], pXcptRepRec->ExceptionInfo[3], 3431 pXcptRepRec->fHandlerFlags); 3432 3433 switch (pXcptRepRec->ExceptionNum) 3434 { 3435 /* 3436 * It's ok to get signaled, terminated or similar. 3437 */ 3438 case XCPT_SIGNAL: 3439 case XCPT_ASYNC_PROCESS_TERMINATE: 3440 case XCPT_PROCESS_TERMINATE: 3441 default: 3442 return XCPT_CONTINUE_SEARCH; 3443 3444 /* 3445 * Most otherthings should be considered fatal and 3446 * cause module initialization to fail. 3447 */ 3448 case XCPT_ACCESS_VIOLATION: 3449 case XCPT_DATATYPE_MISALIGNMENT: 3450 case XCPT_INTEGER_OVERFLOW: 3451 case XCPT_INTEGER_DIVIDE_BY_ZERO: 3452 case XCPT_FLOAT_DIVIDE_BY_ZERO: 3453 case XCPT_FLOAT_OVERFLOW: 3454 case XCPT_FLOAT_UNDERFLOW: 3455 case XCPT_FLOAT_DENORMAL_OPERAND: 3456 case XCPT_FLOAT_INEXACT_RESULT: 3457 case XCPT_FLOAT_INVALID_OPERATION: 3458 case XCPT_FLOAT_STACK_CHECK: 3459 case XCPT_ARRAY_BOUNDS_EXCEEDED: 3460 case XCPT_ILLEGAL_INSTRUCTION: 3461 case XCPT_INVALID_LOCK_SEQUENCE: 3462 case XCPT_PRIVILEGED_INSTRUCTION: 3463 case XCPT_SINGLE_STEP: 3464 case XCPT_BREAKPOINT: 3465 { 3466 __LIBC_PFORKXCPTREGREC2 pRegRec = (__LIBC_PFORKXCPTREGREC2)pXcptRegRec; 3467 PPIB pPib; 3468 PTIB pTib; 3469 3470 DosGetInfoBlocks(&pTib, &pPib); 3471 pTib->tib_pexchain = pRegRec->Core.prev_structure; 3472 3473 #if 0 /* can't do this in libc06x because of compatability issues */ 3474 longjmp(pRegRec->JmpBuf, -1); 3475 #endif 3476 return XCPT_CONTINUE_SEARCH; 3477 } 3478 } 3479 3480 } 3481
Note:
See TracChangeset
for help on using the changeset viewer.