Ticket #85: P_SESSION.diff
File P_SESSION.diff, 17.5 KB (added by , 15 years ago) |
---|
-
src/emx/src/lib/sys/__spawnve.c
11 11 #define INCL_DOSPROCESS 12 12 #define INCL_FSMACROS 13 13 #define INCL_DOSERRORS 14 #define INCL_DOSSESMGR 14 15 #include <os2emx.h> 15 16 #include "b_fs.h" 16 17 #include "b_signal.h" … … 190 191 case P_WAIT: 191 192 case P_NOWAIT: 192 193 case P_OVERLAY: 194 case P_SESSION: 193 195 break; 194 196 default: 195 197 errno = EINVAL; … … 221 223 pszPgmName = &szNativePath[0]; 222 224 223 225 /* 224 * cmd.exe and 4os2.exe needs different argument handling, and 225 * starting with kLIBC 0.6.4 we can pass argv directly to LIBC 226 * cmd.exe and 4os2.exe needs different argument handling, and 227 * starting with kLIBC 0.6.4 we can pass argv directly to LIBC 226 228 * programs. 227 229 * (1 == cmd or 4os2 shell, 0 == anything else) 228 230 */ … … 401 403 pEmbryo->pInherit = doInherit(); 402 404 if (pEmbryo->pInherit) 403 405 { 406 STARTDATA StartData; 407 ULONG idSession; 404 408 RESULTCODES resc; 405 409 char szObj[40]; 406 410 … … 408 412 * Create the process. 409 413 */ 410 414 FS_SAVE_LOAD(); 411 LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 412 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)pszArgsBuf, (PCSZ)np->env_off, &resc, (PCSZ)pszPgmName); 415 if ((ulMode & 0xff) == P_SESSION) 416 { 417 pEmbryo->pid = -2; /* magic value for spmRegisterSelf() */ 418 419 StartData.Length = sizeof(StartData); 420 StartData.Related = SSF_RELATED_CHILD; /* @todo P_UNRELATED */ 421 StartData.FgBg = SSF_FGBG_FORE; /* @todo P_FOREGROUND | P_BACKGROUND */ 422 StartData.TraceOpt = SSF_TRACEOPT_NONE; 423 StartData.PgmTitle = NULL; 424 StartData.PgmName = pszPgmName; 425 StartData.PgmInputs = pszArgsBuf + strlen(pszArgsBuf) + 1; 426 StartData.TermQ = 0; 427 StartData.Environment = (PSZ)np->env_off; 428 StartData.InheritOpt = SSF_INHERTOPT_PARENT; 429 StartData.SessionType = SSF_TYPE_DEFAULT; /* @todo P_PM, P_DEFAULT, P_FULLSCREEN, P_WINDOWED */ 430 StartData.IconFile = NULL; 431 StartData.PgmHandle = 0; 432 StartData.PgmControl = 0; /* @todo P_MINIMIZE, P_MAXIMIZE, P_NOCLOSE */ 433 StartData.InitXPos = 0; 434 StartData.InitYPos = 0; 435 StartData.InitXSize = 0; 436 StartData.InitYSize = 0; 437 StartData.Reserved = 0; 438 StartData.ObjectBuffer = (PSZ)&szObj; 439 StartData.ObjectBuffLen = sizeof(szObj); 440 LIBCLOG_MSG("Calling DosStartSession pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 441 rc = DosStartSession(&StartData, &idSession, &resc.codeTerminate); 442 } 443 else 444 { 445 LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 446 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)pszArgsBuf, (PCSZ)np->env_off, &resc, (PCSZ)pszPgmName); 447 } 413 448 int cTries = 3; 414 449 while ( ( rc == ERROR_INVALID_EXE_SIGNATURE 415 450 || rc == ERROR_BAD_EXE_FORMAT) … … 570 605 /* 571 606 * Try execute it. 572 607 */ 573 LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 574 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)pszArgsBuf, (PCSZ)np->env_off, &resc, (PCSZ)pszPgmName); 608 if ((ulMode & 0xff) == P_SESSION) 609 { 610 StartData.PgmName = pszPgmName; 611 StartData.PgmInputs = pszArgsBuf + strlen(pszArgsBuf) + 1; 612 LIBCLOG_MSG("Calling DosStartSession pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 613 rc = DosStartSession(&StartData, &idSession, &resc.codeTerminate); 614 } 615 else 616 { 617 LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pszPgmName, pszArgsBuf, pszArgsBuf + strlen(pszArgsBuf) + 1); 618 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)pszArgsBuf, (PCSZ)np->env_off, &resc, (PCSZ)pszPgmName); 619 } 575 620 } /* while */ 576 621 FS_RESTORE(); 577 622 if (!rc) 578 623 { 579 __atomic_cmpxchg32((volatile uint32_t *)(void *)&pEmbryo->pid, (uint32_t)resc.codeTerminate, ~0);624 __atomic_cmpxchg32((volatile uint32_t *)(void *)&pEmbryo->pid, (uint32_t)resc.codeTerminate, (ulMode & 0xff) == P_SESSION ? ~1 : ~0); 580 625 LIBCLOG_MSG("Spawned pid=%04lx (%ld)\n", resc.codeTerminate, resc.codeTerminate); 581 626 582 627 /* … … 618 663 * Return the pid. 619 664 */ 620 665 case P_NOWAIT: 666 case P_SESSION: 621 667 LIBCLOG_RETURN_INT((int)resc.codeTerminate); 622 668 623 669 /* -
src/emx/src/lib/sys/tcpipver.c
280 280 _smutex_release(&gsmtxSockets); 281 281 } 282 282 283 if ( rc)283 if (!rc) 284 284 LIBCLOG_RETURN_INT(rc); 285 285 LIBCLOG_ERROR_RETURN_INT(rc); 286 286 } -
src/emx/src/lib/sys/sharedpm.c
105 105 static unsigned gcNesting; 106 106 /** Pointer to termination handlers. */ 107 107 static void (*gapfnExitList[4])(void); 108 /** Maximum time to wait for a child to become alive. */ 109 static ULONG gulMaxChildWait; 110 /** Maximum time to wait for a LIBC child to finish initialization. */ 111 static ULONG gulMaxLibcChildWait; 108 112 109 113 110 114 /******************************************************************************* … … 398 402 { 399 403 LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify); 400 404 APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify); 401 LIBC_ASSERTM(!rc2 , "rc2=%ld!\n", rc2); rc2 = rc2;405 LIBC_ASSERTM(!rc2 || rc2 == ERROR_ALREADY_POSTED, "rc2=%ld!\n", rc2); rc2 = rc2; 402 406 } 403 407 FS_RESTORE(); 404 408 } … … 493 497 LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify); 494 498 APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify); 495 499 spmReleaseMutex(&RegRec); 496 LIBC_ASSERTM(!rc2 , "rc2=%ld!\n", rc2); rc2 = rc2;500 LIBC_ASSERTM(!rc2 || rc2 == ERROR_ALREADY_POSTED, "rc2=%ld!\n", rc2); rc2 = rc2; 497 501 } 498 502 } 499 503 LIBCLOG_RETURN_VOID(); … … 628 632 629 633 630 634 /** 631 * Wait for a embryo to become a live process and complete 635 * Wait for a embryo to become a live process and complete 632 636 * inheriting (file handles / sockets issues). 633 637 * 634 638 * @returns non-zero if the process has started. … … 643 647 int fAlive = 0; 644 648 APIRET rc = 0; 645 649 ULONG ulStart = 0; 650 646 651 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStart, sizeof(ulStart)); 647 652 648 /* 649 * Wait for the process to become ready, 8 ms max.650 * However, if it becomes alive in that period we know it's a libc651 * process and will wait a bit more (130 ms) for it to finishing652 * initializationand inheritance.653 /* 654 * Wait for the process to become ready, gulMaxChildWait ms max. However, if 655 * it becomes alive in that period we know it's a libc process and will wait 656 * a bit more (gulMaxLibcChildWait ms) for it to finishing initialization 657 * and inheritance. 653 658 */ 654 for (cLoops = 0; ; cLoops++) 659 for (cLoops = 0; ; cLoops++) 655 660 { 656 /* 657 * Reset the notification event sem. 661 /* 662 * Reset the notification event sem. 658 663 */ 659 664 spmRequestMutex(&RegRec); 660 665 fAlive = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE 661 || ( pEmbryo->pInherit == NULL 666 || ( pEmbryo->pInherit == NULL 662 667 && pEmbryo->pInheritLocked == NULL 663 668 && pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE); 664 669 if (!fAlive) … … 667 672 if (fAlive) 668 673 break; /* done */ 669 674 670 /* 671 * Calc the time we should sleep. 675 /* 676 * Calc the time we should sleep. 672 677 */ 673 678 ULONG ulNow = 0; 674 679 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulNow, sizeof(ulNow)); 675 680 ULONG ulSleep = ulNow - ulStart; 676 if (ulSleep < 8)681 if (ulSleep < gulMaxChildWait) 677 682 { 678 ulSleep = 8 - ulSleep; 683 ulSleep = gulMaxChildWait - ulSleep; 684 if (ulSleep > 8) 685 ulSleep = 8; /* reset race protection */ 679 686 LIBCLOG_MSG("wait %lu ms (cLoops=%d rc=%ld)\n", ulSleep, cLoops, rc); 680 687 } 681 688 else if (pEmbryo->enmState != __LIBC_PROCSTATE_ALIVE) 682 689 break; /* giving up */ 683 else if (ulSleep < 130)690 else if (ulSleep < gulMaxLibcChildWait) 684 691 { 685 ulSleep = 130- ulSleep;692 ulSleep = gulMaxLibcChildWait - ulSleep; 686 693 if (ulSleep > 8) 687 694 ulSleep = 8; /* reset race protection */ 688 695 LIBCLOG_MSG("libc child - wait %lu ms (cLoops=%d rc=%ld)\n", ulSleep, cLoops, rc); 689 696 } 690 else 697 else 691 698 break; /* giving up */ 692 699 693 /* 694 * Recheck before going to sleep on the event sem. 700 /* 701 * Recheck before going to sleep on the event sem. 695 702 */ 696 703 fAlive = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE 697 || ( pEmbryo->pInherit == NULL 704 || ( pEmbryo->pInherit == NULL 698 705 && pEmbryo->pInheritLocked == NULL 699 706 && pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE); 700 707 if (fAlive) 701 708 break; /* done */ 702 709 703 if ( gpSPMHdr->hevNotify 710 if ( gpSPMHdr->hevNotify 704 711 && (rc == NO_ERROR || rc == ERROR_TIMEOUT || rc == ERROR_SEM_TIMEOUT)) 705 712 rc = DosWaitEventSem(gpSPMHdr->hevNotify, ulSleep); 706 713 else … … 2322 2329 #endif /* unused */ 2323 2330 2324 2331 /** 2332 * Gets a long long value from an environment variable (DosScanEnv version). 2333 * 2334 * @return 0 on success. 2335 * @return -1 on failure. 2336 * 2337 * @param pszEnvVar The name of the environment variable. 2338 * @param pll Where to store the result. 2339 * @remark This is a LIBC extension. 2340 */ 2341 static int spmGetEnvLongLong(const char *pszEnvVar, long long *pll) 2342 { 2343 const char *pszValue; 2344 int rc = DosScanEnv(pszEnvVar, (PSZ*)&pszValue); 2345 if (rc == NO_ERROR) 2346 { 2347 char *pszType; 2348 long long ll = strtoll(pszValue, &pszType, 0); 2349 if ( pszType != pszValue 2350 && (!pszType[0] || !pszType[1])) 2351 { 2352 switch (pszType[0]) 2353 { 2354 case 't': case 'T': ll *= 1024LL*1024LL*1024LL*1024LL; break; 2355 case 'g': case 'G': ll *= 1024*1024*1024; break; 2356 case 'm': case 'M': ll *= 1024*1024; break; 2357 case 'k': case 'K': ll *= 1024; break; 2358 case '\0': break; 2359 default: 2360 return -1; 2361 } 2362 *pll = ll; 2363 return 0; 2364 } 2365 } 2366 return -1; 2367 } 2368 2369 /** 2370 * Gets a long value from an environment variable (DosScanEnv version). 2371 * 2372 * @return 0 on success. 2373 * @return -1 on failure. 2374 * 2375 * @param pszEnvVar The name of the environment variable. 2376 * @param pl Where to store the result. 2377 * @remark This is a LIBC extension. 2378 */ 2379 static int spmGetEnvLong(const char *pszEnvVar, long *pl) 2380 { 2381 long long ll; 2382 if (!spmGetEnvLongLong(pszEnvVar, &ll)) 2383 { 2384 *pl = (long)ll; 2385 return 0; 2386 } 2387 return -1; 2388 } 2389 2390 /** 2325 2391 * Open and if needed creates the LIBC shared memory. 2326 2392 * 2327 2393 * This is called lazily by the mutex request function. … … 2360 2426 LIBCLOG_RETURN_INT(-EINVAL); 2361 2427 2362 2428 /* 2429 * Get the configuration from the environment. 2430 */ 2431 if ( spmGetEnvLong("LIBC_spm.maxchildwait", (long*)&gulMaxChildWait) 2432 || gulMaxChildWait > 30000 /* sanity */) 2433 gulMaxChildWait = 8; 2434 if ( spmGetEnvLong("LIBC_spm.maxlibcchildwait", (long*)&gulMaxLibcChildWait) 2435 || gulMaxLibcChildWait > 30000 /* sanity */) 2436 gulMaxLibcChildWait = 130; 2437 /* enforce a sane relation */ 2438 if (gulMaxLibcChildWait < gulMaxChildWait + 130 - 8) 2439 gulMaxLibcChildWait = gulMaxChildWait + 130 - 8; 2440 LIBCLOG_MSG("gulMaxChildWait=%lu\n", gulMaxChildWait); 2441 LIBCLOG_MSG("gulMaxLibcChildWait=%lu\n", gulMaxLibcChildWait); 2442 2443 /* 2363 2444 * Get current process id and parent process id 2364 2445 * and install the exception handler. 2365 2446 */ … … 2485 2566 2486 2567 LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify); 2487 2568 APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify); 2488 LIBC_ASSERTM(!rc2 , "rc2=%ld!\n", rc2); rc2 = rc2;2569 LIBC_ASSERTM(!rc2 || rc2 == ERROR_ALREADY_POSTED, "rc2=%ld!\n", rc2); rc2 = rc2; 2489 2570 } 2490 2571 2491 2572 /* … … 2666 2747 pTerm->pNext = NULL; 2667 2748 *pParent->ppChildNotifyTail = pTerm; 2668 2749 pParent->ppChildNotifyTail = &pTerm->pNext; 2669 2750 2670 2751 LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify); 2671 2752 APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify); 2672 LIBC_ASSERTM(!rc2 , "rc2=%ld!\n", rc2); rc2 = rc2;2753 LIBC_ASSERTM(!rc2 || rc2 == ERROR_ALREADY_POSTED, "rc2=%ld!\n", rc2); rc2 = rc2; 2673 2754 } 2674 2755 else 2675 2756 spmFreeChildNotify(pTerm); … … 2869 2950 if (!pProcessBest) 2870 2951 pProcessBest = pProcess; 2871 2952 } 2872 LIBCLOG_MSG("Walking by embryo %p (pidParent=%04x cReferences=%d)\n", 2873 (void *)pProcess, pProcess->pidParent, pProcess->cReferences); 2953 else 2954 { 2955 /* 2956 * pid -2 means that daddy gave us for adoption by the shell process 2957 * through a new session, spin around until it fills this with PID 2958 */ 2959 if (pProcess->pid == -2) 2960 { 2961 LIBCLOG_MSG("Embryo %p is born in a new session (pidParent=%04x), spinning until PID is known\n", 2962 (void *)pProcess, pProcess->pidParent); 2963 int cTries = 100; /* @todo count ms instead and make configurable throuhg a LIBC_spm. variable */ 2964 while (pProcess->pid == -2 && cTries--) 2965 DosSleep(0); 2966 if (pProcess->pid == pid) 2967 { 2968 pProcessBest = pProcess; 2969 break; 2970 } 2971 } 2972 } 2874 2973 2974 LIBCLOG_MSG("Walking by embryo %p (pid=%04x pidParent=%04x cReferences=%d)\n", 2975 (void *)pProcess, pProcess->pid, pProcess->pidParent, pProcess->cReferences); 2976 2875 2977 /* cure insanity... no fix for paranoia? */ 2876 2978 if ( pProcess->pNext == gpSPMHdr->apHeads[__LIBC_PROCSTATE_EMBRYO] 2877 2979 || pProcess->pNext == pProcess) … … 3293 3395 /* post notification sem. */ 3294 3396 LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify); 3295 3397 APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify); 3296 LIBC_ASSERTM(!rc2 , "rc2=%ld!\n", rc2); rc2 = rc2;3398 LIBC_ASSERTM(!rc2 || rc2 == ERROR_ALREADY_POSTED, "rc2=%ld!\n", rc2); rc2 = rc2; 3297 3399 } 3298 3400 else 3299 3401 { … … 3495 3597 (void *)pProcess->pNext, (void *)pProcess->pPrev); 3496 3598 spmFreeProcess(pProcess); 3497 3599 pProcess = pProcessNext; 3498 3600 3499 3601 /* Wake up the embryo waiters (paranoia). */ 3500 3602 LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify); 3501 3603 APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify); 3502 LIBC_ASSERTM(!rc2 , "rc2=%ld!\n", rc2); rc2 = rc2;3604 LIBC_ASSERTM(!rc2 || rc2 == ERROR_ALREADY_POSTED, "rc2=%ld!\n", rc2); rc2 = rc2; 3503 3605 continue; 3504 3606 } 3505 3607 … … 3591 3693 (void *)pProcess->pNext, (void *)pProcess->pPrev); 3592 3694 spmFreeProcess(pProcess); 3593 3695 pProcess = pProcessNext; 3594 3696 3595 3697 /* Wake up the embryo waiters (paranoia). */ 3596 3698 LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify); 3597 3699 APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify); 3598 LIBC_ASSERTM(!rc2 , "rc2=%ld!\n", rc2); rc2 = rc2;3700 LIBC_ASSERTM(!rc2 || rc2 == ERROR_ALREADY_POSTED, "rc2=%ld!\n", rc2); rc2 = rc2; 3599 3701 continue; 3600 3702 } 3601 3703