Ticket #85: P_SESSION.diff

File P_SESSION.diff, 17.5 KB (added by Dmitry A. Kuminov, 15 years ago)

Incomplete patch to libc-0.6 for P_SESSION

  • src/emx/src/lib/sys/__spawnve.c

     
    1111#define INCL_DOSPROCESS
    1212#define INCL_FSMACROS
    1313#define INCL_DOSERRORS
     14#define INCL_DOSSESMGR
    1415#include <os2emx.h>
    1516#include "b_fs.h"
    1617#include "b_signal.h"
     
    190191        case P_WAIT:
    191192        case P_NOWAIT:
    192193        case P_OVERLAY:
     194        case P_SESSION:
    193195            break;
    194196        default:
    195197            errno = EINVAL;
     
    221223    pszPgmName = &szNativePath[0];
    222224
    223225    /*
    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
    226228     * programs.
    227229     * (1 == cmd or 4os2 shell, 0 == anything else)
    228230     */
     
    401403        pEmbryo->pInherit = doInherit();
    402404        if (pEmbryo->pInherit)
    403405        {
     406            STARTDATA   StartData;
     407            ULONG       idSession;
    404408            RESULTCODES resc;
    405409            char        szObj[40];
    406410
     
    408412             * Create the process.
    409413             */
    410414            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            }
    413448            int cTries = 3;
    414449            while (     (   rc == ERROR_INVALID_EXE_SIGNATURE
    415450                         || rc == ERROR_BAD_EXE_FORMAT)
     
    570605                /*
    571606                 * Try execute it.
    572607                 */
    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                }
    575620            } /* while */
    576621            FS_RESTORE();
    577622            if (!rc)
    578623            {
    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);
    580625                LIBCLOG_MSG("Spawned pid=%04lx (%ld)\n", resc.codeTerminate, resc.codeTerminate);
    581626
    582627                /*
     
    618663                     * Return the pid.
    619664                     */
    620665                    case P_NOWAIT:
     666                    case P_SESSION:
    621667                        LIBCLOG_RETURN_INT((int)resc.codeTerminate);
    622668
    623669                    /*
  • src/emx/src/lib/sys/tcpipver.c

     
    280280        _smutex_release(&gsmtxSockets);
    281281    }
    282282
    283     if (rc)
     283    if (!rc)
    284284        LIBCLOG_RETURN_INT(rc);
    285285    LIBCLOG_ERROR_RETURN_INT(rc);
    286286}
  • src/emx/src/lib/sys/sharedpm.c

     
    105105static unsigned                 gcNesting;
    106106/** Pointer to termination handlers. */
    107107static void                   (*gapfnExitList[4])(void);
     108/** Maximum time to wait for a child to become alive. */
     109static ULONG                   gulMaxChildWait;
     110/** Maximum time to wait for a LIBC child to finish initialization. */
     111static ULONG                   gulMaxLibcChildWait;
    108112
    109113
    110114/*******************************************************************************
     
    398402            {
    399403                LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
    400404                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;
    402406            }
    403407            FS_RESTORE();
    404408        }
     
    493497            LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
    494498            APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
    495499            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;
    497501        }
    498502    }
    499503    LIBCLOG_RETURN_VOID();
     
    628632
    629633
    630634/**
    631  * Wait for a embryo to become a live process and complete 
     635 * Wait for a embryo to become a live process and complete
    632636 * inheriting (file handles / sockets issues).
    633637 *
    634638 * @returns non-zero if the process has started.
     
    643647    int                     fAlive = 0;
    644648    APIRET                  rc = 0;
    645649    ULONG                   ulStart = 0;
     650
    646651    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStart, sizeof(ulStart));
    647652
    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 libc
    651      * process and will wait a bit more (130 ms) for it to finishing
    652      * initialization and 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.
    653658     */
    654     for (cLoops = 0; ; cLoops++) 
     659    for (cLoops = 0; ; cLoops++)
    655660    {
    656         /* 
    657          * Reset the notification event sem. 
     661        /*
     662         * Reset the notification event sem.
    658663         */
    659664        spmRequestMutex(&RegRec);
    660665        fAlive = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
    661               || (   pEmbryo->pInherit == NULL 
     666              || (   pEmbryo->pInherit == NULL
    662667                  && pEmbryo->pInheritLocked == NULL
    663668                  && pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE);
    664669        if (!fAlive)
     
    667672        if (fAlive)
    668673            break; /* done */
    669674
    670         /* 
    671          * Calc the time we should sleep. 
     675        /*
     676         * Calc the time we should sleep.
    672677         */
    673678        ULONG ulNow = 0;
    674679        DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulNow, sizeof(ulNow));
    675680        ULONG ulSleep = ulNow - ulStart;
    676         if (ulSleep < 8)
     681        if (ulSleep < gulMaxChildWait)
    677682        {
    678             ulSleep = 8 - ulSleep;
     683            ulSleep = gulMaxChildWait - ulSleep;
     684            if (ulSleep > 8)
     685                ulSleep = 8; /* reset race protection */
    679686            LIBCLOG_MSG("wait %lu ms (cLoops=%d rc=%ld)\n", ulSleep, cLoops, rc);
    680687        }
    681688        else if (pEmbryo->enmState != __LIBC_PROCSTATE_ALIVE)
    682689            break; /* giving up */
    683         else if (ulSleep < 130)
     690        else if (ulSleep < gulMaxLibcChildWait)
    684691        {
    685             ulSleep = 130 - ulSleep;
     692            ulSleep = gulMaxLibcChildWait - ulSleep;
    686693            if (ulSleep > 8)
    687694                ulSleep = 8; /* reset race protection */
    688695            LIBCLOG_MSG("libc child - wait %lu ms (cLoops=%d rc=%ld)\n", ulSleep, cLoops, rc);
    689696        }
    690         else 
     697        else
    691698            break; /* giving up */
    692699
    693         /* 
    694          * Recheck before going to sleep on the event sem. 
     700        /*
     701         * Recheck before going to sleep on the event sem.
    695702         */
    696703        fAlive = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
    697               || (   pEmbryo->pInherit == NULL 
     704              || (   pEmbryo->pInherit == NULL
    698705                  && pEmbryo->pInheritLocked == NULL
    699706                  && pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE);
    700707        if (fAlive)
    701708            break; /* done */
    702709
    703         if (    gpSPMHdr->hevNotify 
     710        if (    gpSPMHdr->hevNotify
    704711            &&  (rc == NO_ERROR || rc == ERROR_TIMEOUT || rc == ERROR_SEM_TIMEOUT))
    705712            rc = DosWaitEventSem(gpSPMHdr->hevNotify, ulSleep);
    706713        else
     
    23222329#endif /* unused */
    23232330
    23242331/**
     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 */
     2341static 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 */
     2379static 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/**
    23252391 * Open and if needed creates the LIBC shared memory.
    23262392 *
    23272393 * This is called lazily by the mutex request function.
     
    23602426        LIBCLOG_RETURN_INT(-EINVAL);
    23612427
    23622428    /*
     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    /*
    23632444     * Get current process id and parent process id
    23642445     * and install the exception handler.
    23652446     */
     
    24852566
    24862567                LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
    24872568                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;
    24892570            }
    24902571
    24912572            /*
     
    26662747                    pTerm->pNext = NULL;
    26672748                    *pParent->ppChildNotifyTail = pTerm;
    26682749                    pParent->ppChildNotifyTail = &pTerm->pNext;
    2669                    
     2750
    26702751                    LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
    26712752                    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;
    26732754                }
    26742755                else
    26752756                    spmFreeChildNotify(pTerm);
     
    28692950            if (!pProcessBest)
    28702951                pProcessBest = pProcess;
    28712952        }
    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        }
    28742973
     2974        LIBCLOG_MSG("Walking by embryo %p (pid=%04x pidParent=%04x cReferences=%d)\n",
     2975                    (void *)pProcess, pProcess->pid, pProcess->pidParent, pProcess->cReferences);
     2976
    28752977        /* cure insanity... no fix for paranoia? */
    28762978        if (    pProcess->pNext == gpSPMHdr->apHeads[__LIBC_PROCSTATE_EMBRYO]
    28772979            ||  pProcess->pNext == pProcess)
     
    32933395                /* post notification sem. */
    32943396                LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
    32953397                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;
    32973399            }
    32983400            else
    32993401            {
     
    34953597                                (void *)pProcess->pNext, (void *)pProcess->pPrev);
    34963598                    spmFreeProcess(pProcess);
    34973599                    pProcess = pProcessNext;
    3498                    
     3600
    34993601                    /* Wake up the embryo waiters (paranoia). */
    35003602                    LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
    35013603                    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;
    35033605                    continue;
    35043606                }
    35053607
     
    35913693                                    (void *)pProcess->pNext, (void *)pProcess->pPrev);
    35923694                        spmFreeProcess(pProcess);
    35933695                        pProcess = pProcessNext;
    3594                        
     3696
    35953697                        /* Wake up the embryo waiters (paranoia). */
    35963698                        LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
    35973699                        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;
    35993701                        continue;
    36003702                    }
    36013703