Changeset 2796


Ignore:
Timestamp:
Aug 28, 2006, 3:19:56 AM (19 years ago)
Author:
bird
Message:

Fixed log problem in fork() child. Fixes #119.

Location:
branches/libc-0.6/src/emx
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/ChangeLog.LIBC

    r2795 r2796  
    552006-08-27: knut st. osmundsen <bird-gccos2-spam@anduin.net>
    66    - libc:
     7        o Fixed log problem in fork() child. Fixes #119.
    78        o Corrected DosSetFHState mask. Fixes #118.
    89        o Implemented the new length modifiers for *scanf. Adjusted the length
  • branches/libc-0.6/src/emx/src/lib/sys/logstrict.c

    r2654 r2796  
    6262#include <machine/param.h>
    6363#include <InnoTekLIBC/thread.h>
     64#include <InnoTekLIBC/fork.h>
    6465
    6566#define INCL_BASE
     
    9899*******************************************************************************/
    99100/** Hex digits. */
    100 static const char gszHexDigits[17] = "0123456789abcdef";
     101static const char       gszHexDigits[17] = "0123456789abcdef";
    101102/** Uppercase hex digits. */
    102 static const char gszHexDigitsUpper[17] = "0123456789ABCDEF";
     103static const char       gszHexDigitsUpper[17] = "0123456789ABCDEF";
     104/** Pointer to default logger instance. */
     105static __LIBC_PLOGINST  gpDefault;
    103106
    104107
     
    116119static int      __libc_logVSNPrintf(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args);
    117120static int      __libc_logSNPrintf(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...) __printflike(3, 4);
     121int __libc_logForkParent(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    118122
    119123
     
    247251            while (i-- > 0)
    248252                DosClose(ah[i]);
     253
     254            ULONG fulFlags = ~0U;
     255            if (DosQueryFHState(pInst->hFile, &fulFlags) == NO_ERROR)
     256            {
     257                fulFlags |= OPEN_FLAGS_NOINHERIT;
     258                fulFlags &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
     259                DosSetFHState(pInst->hFile, fulFlags);
     260            }
    249261        }
    250262    }
     
    263275        int         cch;
    264276
     277        /* The current time+date and basic process attributes. */
    265278        DosGetInfoBlocks(&pTib, &pPib);
    266279        DosGetDateTime(&dt);
    267 
    268280        cch = __libc_logSNPrintf(pszMsg, CCHTMPMSGBUFFER,
    269281                                 "Opened log at %04d-%02d-%02d %02d:%02d:%02d.%02d\n"
    270                                  "Process ID: %#x (%d) Parent PID: %#x (%d)\n",
     282                                 "Process ID: %#x (%d) Parent PID: %#x (%d) Type: %d\n",
    271283                                 dt.year, dt.month, dt.day, dt.hours, dt.minutes, dt.seconds, dt.hundredths,
    272                                  (int)pPib->pib_ulpid, (unsigned)pPib->pib_ulpid, (int)pPib->pib_ulppid, (unsigned)pPib->pib_ulppid);
     284                                 (int)pPib->pib_ulpid, (unsigned)pPib->pib_ulpid, (int)pPib->pib_ulppid, (unsigned)pPib->pib_ulppid,
     285                                 (int)pPib->pib_ultype);
    273286        DosWrite(pInst->hFile, pszMsg, cch, &cb);
    274287
     288        /* The executable module. */
    275289        cch = __libc_logSNPrintf(pszMsg, CCHTMPMSGBUFFER,
    276290                                 "Exe hmte  : %#x (",
    277291                                 (unsigned)pPib->pib_hmte);
    278292        DosWrite(pInst->hFile, pszMsg, cch, &cb);
    279         if (DosQueryModuleName(pPib->pib_hmte, CCHTMPMSGBUFFER, pszMsg))
     293        if (DosQueryModuleName(pPib->pib_hmte, CCHTMPMSGBUFFER - 4, pszMsg))
    280294            pszMsg[0] = '\0';
    281295        cch = strlen(pszMsg);
     
    284298        DosWrite(pInst->hFile, pszMsg, cch, &cb);
    285299
     300        /* The raw arguments. */
    286301        cch = __libc_logSNPrintf(pszMsg, CCHTMPMSGBUFFER,
    287302                                 "First arg : %s\n"
     
    292307        cch = strlen(psz);
    293308        DosWrite(pInst->hFile, psz, cch, &cb);
    294 
    295         char    szMod[CCHMAXPATH];
     309        DosWrite(pInst->hFile, "\n", 1, &cb);
     310
     311        /* The current drive and directory. */
     312        ULONG ulDisk = 0;
     313        ULONG fLogical = 0;
     314        if (!DosQueryCurrentDisk(&ulDisk, &fLogical))
     315        {
     316            cch = __libc_logSNPrintf(pszMsg, CCHTMPMSGBUFFER,
     317                                     "Cur dir   : %c:\\",
     318                                     (char)ulDisk + ('A' - 1));
     319            DosWrite(pInst->hFile, pszMsg, cch, &cb);
     320
     321            ULONG cchDir = CCHTMPMSGBUFFER - 4;
     322            if (DosQueryCurrentDir(ulDisk, (PSZ)pszMsg, &cchDir))
     323                pszMsg[0] = '\0';
     324            cch = strlen(pszMsg);
     325            pszMsg[cch++] = '\n';
     326            DosWrite(pInst->hFile, pszMsg, cch, &cb);
     327        }
     328
     329        /* The CRT module. */
     330        char    szMod[128];
    296331        ULONG   iObj = ~0;
    297332        ULONG   offObj = ~0;
    298333        HMODULE hmod = ~0;
    299334        if (DosQueryModFromEIP(&hmod, &iObj, sizeof(szMod), &szMod[0], &offObj, (uintptr_t)__libc_logInit))
     335        {
    300336            szMod[0] = '\0';
     337            hmod = NULLHANDLE;
     338        }
    301339        cch = __libc_logSNPrintf(pszMsg, CCHTMPMSGBUFFER,
    302                                  "\n"
    303                                  "CRT Module: %s hmod=%#lx\n"
     340                                 "CRT Module: %s hmod=%#lx (",
     341                                 szMod, hmod);
     342        DosWrite(pInst->hFile, pszMsg, cch, &cb);
     343
     344        if (    hmod == NULLHANDLE
     345            ||  DosQueryModuleName(hmod, CCHTMPMSGBUFFER - 4, pszMsg))
     346            pszMsg[0] = '\0';
     347        cch = strlen(pszMsg);
     348        pszMsg[cch++] = ')';
     349        pszMsg[cch++] = '\n';
     350        DosWrite(pInst->hFile, pszMsg, cch, &cb);
     351
     352        cch = __libc_logSNPrintf(pszMsg, CCHTMPMSGBUFFER,
    304353                                 "__libc_logInit: addr %p iObj=%ld offObj=%#lx\n",
    305                                  szMod, hmod, (void *)__libc_logInit, iObj, offObj);
     354                                 (void *)__libc_logInit, iObj, offObj);
    306355        DosWrite(pInst->hFile, pszMsg, cch, &cb);
    307356
    308 
     357        /* column headers */
    309358        cch = __libc_logSNPrintf(pszMsg, CCHTMPMSGBUFFER,
    310359                                 "   Millsecond Timestamp.\n"
     
    436485static void *__libc_logDefault(void)
    437486{
    438     /** Pointer to default logger instance. */
    439     static __LIBC_PLOGINST  pDefault;
    440487    /** Set if we've already tried to init the log, but failed. */
    441488    static int              fAlreadyTried;
    442489
    443     if (pDefault)
    444         return pDefault;
     490    if (gpDefault)
     491        return gpDefault;
    445492    else if (!fAlreadyTried)
    446493    {
     
    501548        __libc_logSNPrintf(szFilename, sizeof(szFilename), "libc_%04x.log", getPid());
    502549        if (__libc_logInit(&DefInst, 0, &DefGrps, szFilename))
    503             pDefault = &DefInst;
     550            gpDefault = &DefInst;
    504551
    505552        /*
     
    509556    }
    510557
    511     return pDefault;
     558    return gpDefault;
    512559}
    513560
     
    22102257}
    22112258
     2259
     2260/**
     2261 * Procedure invoked by the parent for aligning the log file handle
     2262 * and semaphore handle with the parent ones.
     2263 *
     2264 * @returns 0 on success.
     2265 * @returns -errno on failure.
     2266 * @param pForkHandle   The fork handle
     2267 * @param pvArg         Pointer to a __LIBC_LOGINST containing the parent handles.
     2268 * @param cbArg         sizeof(__LIBC_LOGINST).
     2269 */
     2270static int __libc_logForkChildRelocate(__LIBC_PFORKHANDLE pForkHandle, void *pvArg, size_t cbArg)
     2271{
     2272    const __LIBC_LOGINST *pParent = (const __LIBC_LOGINST *)pvArg;
     2273
     2274    /*
     2275     * Make sure there is a log handle.
     2276     */
     2277    __LIBC_PLOGINST pChild = gpDefault;
     2278    if (!pChild)
     2279    {
     2280        pChild = __libc_logDefault();
     2281        if (!pChild)
     2282            return 0;
     2283    }
     2284
     2285    /*
     2286     * The file handle.
     2287     */
     2288    if (    pParent->hFile != pChild->hFile
     2289        &&  pParent->hFile >= 0
     2290        &&  pChild->hFile  >= 0)
     2291    {
     2292        HFILE hNew = pParent->hFile;
     2293        APIRET rc = DosDupHandle(pChild->hFile, &hNew);
     2294        if (rc == ERROR_TOO_MANY_OPEN_FILES)
     2295        {
     2296            DosSetMaxFH(pParent->hFile + 1);
     2297            hNew = pParent->hFile;
     2298            rc = DosDupHandle(pChild->hFile, &hNew);
     2299        }
     2300        if (rc == NO_ERROR)
     2301        {
     2302            /* mark it non-inherit */
     2303            ULONG fulFlags = ~0U;
     2304            rc = DosQueryFHState(hNew, &fulFlags);
     2305            if (rc == NO_ERROR)
     2306            {
     2307                fulFlags |= OPEN_FLAGS_NOINHERIT;
     2308                fulFlags &= OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT; /* Turn off non-participating bits. */
     2309                rc = DosSetFHState(hNew, fulFlags);
     2310            }
     2311            if (rc == NO_ERROR)
     2312                __libc_LogMsg(0, pChild, 0xffff, __FUNCTION__,
     2313                              "Successfully relocated the log handle from %ld to %ld\n", pChild->hFile, hNew);
     2314            else
     2315                __libc_LogError(0, pChild, 0xffff, __FUNCTION__, __FILE__, __LINE__,
     2316                                "Failed to modify the inherit flag of %ld. rc=%ld. fulFlags=%lx\n", hNew, rc, fulFlags);
     2317
     2318            /* replace. */
     2319            DosClose(pChild->hFile);
     2320            pChild->hFile = hNew;
     2321
     2322        }
     2323        else
     2324            __libc_LogError(0, pChild, 0xffff, __FUNCTION__, __FILE__, __LINE__,
     2325                            "DosDupHandle(%ld, %ld) -> %ld\n", pChild->hFile, pParent->hFile, rc);
     2326    }
     2327
     2328    /*
     2329     * The mutex handle.
     2330     */
     2331    if (    pParent->hmtx != pChild->hmtx
     2332        &&  pParent->hmtx != NULLHANDLE
     2333        &&  pChild->hmtx  != NULLHANDLE)
     2334    {
     2335        APIRET rc = NO_ERROR;
     2336        if ((pParent->hmtx & 0xffff) < 0x3000) /* I'm so sorry, but if it's higher than 0x3000 we can't run the risk of exhausting the stack. */
     2337        {
     2338            /*
     2339             * Mutex handles are allocated in ascending order, so we'll have to allocate
     2340             * mutexes until we get or pass the desired handle.
     2341             */
     2342            struct __LIBC_LOGFORKMTXRELOC
     2343            {
     2344                struct __LIBC_LOGFORKMTXRELOC *pNext;
     2345                int         iCur;
     2346                HMTX        ahmtx[128];
     2347            }  *pHead = NULL,
     2348               *pNew;
     2349            for (;;)
     2350            {
     2351                HMTX hmtx;
     2352                rc = DosCreateMutexSem(NULL, &hmtx, 0, FALSE);
     2353                if (rc != NO_ERROR)
     2354                    break;
     2355                if (hmtx == pParent->hmtx)
     2356                {
     2357                    __libc_LogMsg(0, pChild, 0xffff, __FUNCTION__,
     2358                                  "Successfully relocated the log mutex from %ld to %ld\n", pChild->hmtx, hmtx);
     2359                    DosCloseMutexSem(pChild->hmtx);
     2360                    pChild->hmtx = hmtx;
     2361                    break;
     2362                }
     2363                if (hmtx > pParent->hmtx)
     2364                    break;
     2365
     2366                /* record it */
     2367                if (    pHead == NULL
     2368                    ||  pHead->iCur >= sizeof(pNew->ahmtx) / sizeof(pNew->ahmtx[0]))
     2369                {
     2370                    pNew = alloca(sizeof(*pNew));
     2371                    if (!pNew)
     2372                    {
     2373                        DosCloseMutexSem(hmtx);
     2374                        break;
     2375                    }
     2376                    pNew->iCur = 0;
     2377                    pNew->pNext = pHead;
     2378                    pHead = pNew;
     2379                }
     2380                pHead->ahmtx[pHead->iCur++] = hmtx;
     2381            }
     2382
     2383            /* Cleanup */
     2384            while (pHead)
     2385            {
     2386                while (pHead->iCur-- > 0)
     2387                    DosCloseMutexSem(pHead->ahmtx[pHead->iCur]);
     2388                pHead = pHead->pNext;
     2389            }
     2390        }
     2391        if (pChild->hmtx != pParent->hmtx)
     2392            __libc_LogError(0, pChild, 0xffff, __FUNCTION__, __FILE__, __LINE__,
     2393                            "Failed to relocate the mutex.  parent=%#lx child=%#lx rc=%ld\n", pParent->hmtx, pChild->hmtx, rc);
     2394    }
     2395
     2396    /* We don't fail the fork() even if the log relocation fails. */
     2397    return 0;
     2398}
     2399
     2400
     2401/**
     2402 * Fork callback which will make sure the child log handles are reallocated
     2403 * so they are identical to the ones used in the parent.
     2404 *
     2405 * @returns 0 on success.
     2406 * @returns -errno on failure.
     2407 * @param   pForkHandle     Pointer to fork handle.
     2408 * @param   enmOperation    Fork operation.
     2409 */
     2410int __libc_logForkParent(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation)
     2411{
     2412    if (    enmOperation == __LIBC_FORK_OP_EXEC_PARENT
     2413        &&  gpDefault)
     2414        return pForkHandle->pfnInvoke(pForkHandle, __libc_logForkChildRelocate, gpDefault, sizeof(*gpDefault));
     2415    return 0;
     2416}
     2417
     2418_FORK_PARENT1(0xfffffff0, __libc_logForkParent)
     2419
Note: See TracChangeset for help on using the changeset viewer.