VirtualBox

Changeset 21377 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Jul 8, 2009 1:00:22 AM (16 years ago)
Author:
vboxsync
Message:

iprt/log.h,DBGFLog.cpp,VBoxGuest-linux.c: Added RTLogDestinations, RTLogGetDestinations, RTLogGetFlags and RTLogGetGroupSettings.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/log/log.cpp

    r21375 r21377  
    134134#endif /* IN_RING0 */
    135135
     136/**
     137 * Logger flags instructions.
     138 */
     139static struct
     140{
     141    const char *pszInstr;               /**< The name  */
     142    size_t      cchInstr;               /**< The size of the name. */
     143    uint32_t    fFlag;                  /**< The flag value. */
     144    bool        fInverted;              /**< Inverse meaning? */
     145}
     146const s_aLogFlags[] =
     147{
     148    { "disabled",     sizeof("disabled"    ) - 1,   RTLOGFLAGS_DISABLED,            false },
     149    { "enabled",      sizeof("enabled"     ) - 1,   RTLOGFLAGS_DISABLED,            true  },
     150    { "buffered",     sizeof("buffered"    ) - 1,   RTLOGFLAGS_BUFFERED,            false },
     151    { "unbuffered",   sizeof("unbuffered"  ) - 1,   RTLOGFLAGS_BUFFERED,            true  },
     152    { "usecrlf",      sizeof("usecrlf"     ) - 1,   RTLOGFLAGS_USECRLF,             false },
     153    { "uself",        sizeof("uself"       ) - 1,   RTLOGFLAGS_USECRLF,             true  },
     154    { "append",       sizeof("append"      ) - 1,   RTLOGFLAGS_APPEND,              false },
     155    { "overwrite",    sizeof("overwrite"   ) - 1,   RTLOGFLAGS_APPEND,              true  },
     156    { "rel",          sizeof("rel"         ) - 1,   RTLOGFLAGS_REL_TS,              false },
     157    { "abs",          sizeof("abs"         ) - 1,   RTLOGFLAGS_REL_TS,              true  },
     158    { "dec",          sizeof("dec"         ) - 1,   RTLOGFLAGS_DECIMAL_TS,          false },
     159    { "hex",          sizeof("hex"         ) - 1,   RTLOGFLAGS_DECIMAL_TS,          true  },
     160    { "lockcnts",     sizeof("lockcnts"    ) - 1,   RTLOGFLAGS_PREFIX_LOCK_COUNTS,  false },
     161    { "cpuid",        sizeof("cpuid"       ) - 1,   RTLOGFLAGS_PREFIX_CPUID,        false },
     162    { "pid",          sizeof("pid"         ) - 1,   RTLOGFLAGS_PREFIX_PID,          false },
     163    { "flagno",       sizeof("flagno"      ) - 1,   RTLOGFLAGS_PREFIX_FLAG_NO,      false },
     164    { "flag",         sizeof("flag"        ) - 1,   RTLOGFLAGS_PREFIX_FLAG,         false },
     165    { "groupno",      sizeof("groupno"     ) - 1,   RTLOGFLAGS_PREFIX_GROUP_NO,     false },
     166    { "group",        sizeof("group"       ) - 1,   RTLOGFLAGS_PREFIX_GROUP,        false },
     167    { "tid",          sizeof("tid"         ) - 1,   RTLOGFLAGS_PREFIX_TID,          false },
     168    { "thread",       sizeof("thread"      ) - 1,   RTLOGFLAGS_PREFIX_THREAD,       false },
     169    { "custom",       sizeof("custom"      ) - 1,   RTLOGFLAGS_PREFIX_CUSTOM,       false },
     170    { "timeprog",     sizeof("timeprog"    ) - 1,   RTLOGFLAGS_PREFIX_TIME_PROG,    false },
     171    { "time",         sizeof("time"        ) - 1,   RTLOGFLAGS_PREFIX_TIME,         false },
     172    { "msprog",       sizeof("msprog"      ) - 1,   RTLOGFLAGS_PREFIX_MS_PROG,      false },
     173    { "tsc",          sizeof("tsc"         ) - 1,   RTLOGFLAGS_PREFIX_TSC,          false }, /* before ts! */
     174    { "ts",           sizeof("ts"          ) - 1,   RTLOGFLAGS_PREFIX_TS,           false },
     175};
     176
     177/**
     178 * Logger destination instructions.
     179 */
     180static struct
     181{
     182    const char *pszInstr;               /**< The name. */
     183    size_t      cchInstr;               /**< The size of the name. */
     184    uint32_t    fFlag;                  /**< The corresponding destination flag. */
     185} const s_aLogDst[] =
     186{
     187    { "file",     sizeof("file"    ) - 1,  RTLOGDEST_FILE }, /* Must be 1st! */
     188    { "dir",      sizeof("dir"     ) - 1,  RTLOGDEST_FILE }, /* Must be 2nd! */
     189    { "stdout",   sizeof("stdout"  ) - 1,  RTLOGDEST_STDOUT },
     190    { "stderr",   sizeof("stderr"  ) - 1,  RTLOGDEST_STDERR },
     191    { "debugger", sizeof("debugger") - 1,  RTLOGDEST_DEBUGGER },
     192    { "com",      sizeof("com"     ) - 1,  RTLOGDEST_COM },
     193    { "user",     sizeof("user"    ) - 1,  RTLOGDEST_USER },
     194};
     195
    136196
    137197/**
     
    291351                const char *pszVar = RTEnvGet(pszEnvVar);
    292352                if (pszVar)
    293                 {
    294                     while (*pszVar)
    295                     {
    296                         /* skip blanks. */
    297                         while (RT_C_IS_SPACE(*pszVar))
    298                             pszVar++;
    299                         if (!*pszVar)
    300                             break;
    301 
    302                         /* parse instruction. */
    303                         static struct
    304                         {
    305                             const char *pszInstr;
    306                             unsigned    fFlag;
    307                         } const aDest[] =
    308                         {
    309                             { "file",       RTLOGDEST_FILE }, /* Must be 1st! */
    310                             { "dir",        RTLOGDEST_FILE }, /* Must be 2nd! */
    311                             { "stdout",     RTLOGDEST_STDOUT },
    312                             { "stderr",     RTLOGDEST_STDERR },
    313                             { "debugger",   RTLOGDEST_DEBUGGER },
    314                             { "com",        RTLOGDEST_COM },
    315                             { "user",       RTLOGDEST_USER },
    316                         };
    317 
    318                         /* check no prefix. */
    319                         bool fNo = false;
    320                         if (pszVar[0] == 'n' && pszVar[1] == 'o')
    321                         {
    322                             fNo = true;
    323                             pszVar += 2;
    324                         }
    325 
    326                         /* instruction. */
    327                         unsigned i;
    328                         for (i = 0; i < RT_ELEMENTS(aDest); i++)
    329                         {
    330                             size_t cchInstr = strlen(aDest[i].pszInstr);
    331                             if (!strncmp(pszVar, aDest[i].pszInstr, cchInstr))
    332                             {
    333                                 if (!fNo)
    334                                     pLogger->fDestFlags |= aDest[i].fFlag;
    335                                 else
    336                                     pLogger->fDestFlags &= ~aDest[i].fFlag;
    337                                 pszVar += cchInstr;
    338 
    339                                 /* check for value. */
    340                                 while (RT_C_IS_SPACE(*pszVar))
    341                                     pszVar++;
    342                                 if (*pszVar == '=' || *pszVar == ':')
    343                                 {
    344                                     pszVar++;
    345                                     const char *pszEnd = strchr(pszVar, ';');
    346                                     if (!pszEnd)
    347                                         pszEnd = strchr(pszVar, '\0');
    348 
    349                                     /* log file name */
    350                                     size_t cch = pszEnd - pszVar;
    351                                     if (i == 0 /* file */ && !fNo)
    352                                     {
    353                                         memcpy(pLogger->pszFilename, pszVar, cch);
    354                                         pLogger->pszFilename[cch] = '\0';
    355                                     }
    356                                     /* log directory */
    357                                     else if (i == 1 /* dir */ && !fNo)
    358                                     {
    359                                         char szTmp[RTPATH_MAX];
    360                                         const char *pszFile = RTPathFilename(pLogger->pszFilename);
    361                                         if (pszFile)
    362                                             strcpy(szTmp, pszFile);
    363                                         else
    364                                             pszFile = ""; /* you've screwed up, sir. */
    365 
    366                                         memcpy(pLogger->pszFilename, pszVar, cch);
    367                                         pLogger->pszFilename[cch] = '\0';
    368                                         RTPathStripTrailingSlash(pLogger->pszFilename);
    369 
    370                                         cch = strlen(pLogger->pszFilename);
    371                                         pLogger->pszFilename[cch++] = '/';
    372                                         strcpy(&pLogger->pszFilename[cch], szTmp);
    373                                     }
    374                                     else
    375                                         AssertMsgFailed(("Invalid %s_DEST! %s%s doesn't take a value!\n", pszEnvVarBase, fNo ? "no" : "", aDest[i].pszInstr));
    376                                     pszVar = pszEnd + (*pszEnd != '\0');
    377                                 }
    378                                 break;
    379                             }
    380                         }
    381                         /* unknown instruction? */
    382                         if (i >= RT_ELEMENTS(aDest))
    383                         {
    384                             AssertMsgFailed(("Invalid %s_DEST! unknown instruction %.20s\n", pszEnvVarBase, pszVar));
    385                             pszVar++;
    386                         }
    387 
    388                         /* skip blanks and delimiters. */
    389                         while (RT_C_IS_SPACE(*pszVar) || *pszVar == ';')
    390                             pszVar++;
    391                     } /* while more environment variable value left */
    392                 }
     353                    RTLogDestinations(pLogger, pszVar);
    393354
    394355                /*
     
    12641225}
    12651226
     1227/**
     1228 * Helper for RTLogGetGroupSettings.
     1229 */
     1230static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, char **ppszBuf, size_t *pcchBuf, bool *pfNotFirst)
     1231{
     1232#define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)
     1233#define APPEND_SZ(sz)       APPEND_PSZ(sz, sizeof(sz) - 1)
     1234#define APPEND_CH(ch)       do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0)
     1235
     1236    /*
     1237     * Add the name.
     1238     */
     1239    size_t cchName = strlen(pszName);
     1240    if (cchName + 1 + *pfNotFirst > *pcchBuf)
     1241        return VERR_BUFFER_OVERFLOW;
     1242    if (*pfNotFirst)
     1243        APPEND_CH(' ');
     1244    else
     1245        *pfNotFirst = true;
     1246    APPEND_PSZ(pszName, cchName);
     1247
     1248    /*
     1249     * Only generate mnemonics for the simple+common bits.
     1250     */
     1251    if (fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1))
     1252        /* nothing */;
     1253    else if (    fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_LEVEL_2 |  RTLOGGRPFLAGS_FLOW)
     1254             &&  *pcchBuf >= sizeof(".e.l.f"))
     1255        APPEND_SZ(".e.l.f");
     1256    else if (    fGroup == (RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1 | RTLOGGRPFLAGS_FLOW)
     1257             &&  *pcchBuf >= sizeof(".e.f"))
     1258        APPEND_SZ(".e.f");
     1259    else if (*pcchBuf >= 1 + 10 + 1)
     1260    {
     1261        size_t cch;
     1262        APPEND_CH('=');
     1263        cch = RTStrFormatNumber(*ppszBuf, fGroup, 16, 0, 0, RTSTR_F_SPECIAL | RTSTR_F_32BIT);
     1264        *ppszBuf += cch;
     1265        *pcchBuf -= cch;
     1266    }
     1267    else
     1268        return VERR_BUFFER_OVERFLOW;
     1269
     1270#undef APPEND_PSZ
     1271#undef APPEND_SZ
     1272#undef APPEND_CH
     1273    return VINF_SUCCESS;
     1274}
     1275
     1276
     1277/**
     1278 * Get the current log group settings as a string.
     1279 *
     1280 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
     1281 * @param   pLogger             Logger instance (NULL for default logger).
     1282 * @param   pszBuf              The output buffer.
     1283 * @param   cchBuf              The size of the output buffer. Must be greater
     1284 *                              than zero.
     1285 */
     1286RTDECL(int) RTLogGetGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
     1287{
     1288    bool        fNotFirst = false;
     1289    int         rc        = VINF_SUCCESS;
     1290    uint32_t    cGroups;
     1291    uint32_t    fGroup;
     1292    uint32_t    i;
     1293
     1294    Assert(cchBuf);
     1295
     1296    /*
     1297     * Resolve defaults.
     1298     */
     1299    if (!pLogger)
     1300    {
     1301        pLogger = RTLogDefaultInstance();
     1302        if (!pLogger)
     1303        {
     1304            *pszBuf = '\0';
     1305            return VINF_SUCCESS;
     1306        }
     1307    }
     1308
     1309    cGroups = pLogger->cGroups;
     1310
     1311    /*
     1312     * Check if all are the same.
     1313     */
     1314    fGroup = pLogger->afGroups[0];
     1315    for (i = 1; i < cGroups; i++)
     1316        if (pLogger->afGroups[i] != fGroup)
     1317            break;
     1318    if (i >= cGroups)
     1319        rc = rtLogGetGroupSettingsAddOne("all", fGroup, &pszBuf, &cchBuf, &fNotFirst);
     1320    else
     1321    {
     1322
     1323        /*
     1324         * Iterate all the groups and print all that are enabled.
     1325         */
     1326        for (i = 0; i < cGroups; i++)
     1327        {
     1328            fGroup = pLogger->afGroups[i];
     1329            if (fGroup)
     1330            {
     1331                const char *pszName = pLogger->papszGroups[i];
     1332                if (pszName)
     1333                {
     1334                    rc = rtLogGetGroupSettingsAddOne(pszName, fGroup, &pszBuf, &cchBuf, &fNotFirst);
     1335                    if (rc)
     1336                        break;
     1337                }
     1338            }
     1339        }
     1340    }
     1341
     1342    *pszBuf = '\0';
     1343    return rc;
     1344}
     1345RT_EXPORT_SYMBOL(RTLogGetGroupSettings);
    12661346#endif /* !IN_RC */
    12671347
     
    12951375    while (*pszVar)
    12961376    {
    1297         /* parse instruction. */
    1298         static struct
    1299         {
    1300             const char *pszInstr;
    1301             size_t      cchInstr;
    1302             unsigned    fFlag;
    1303             bool        fInverted;
    1304         } const aDest[] =
    1305         {
    1306             { "disabled",     sizeof("disabled"    ) - 1,   RTLOGFLAGS_DISABLED,            false },
    1307             { "enabled",      sizeof("enabled"     ) - 1,   RTLOGFLAGS_DISABLED,            true  },
    1308             { "buffered",     sizeof("buffered"    ) - 1,   RTLOGFLAGS_BUFFERED,            false },
    1309             { "unbuffered",   sizeof("unbuffered"  ) - 1,   RTLOGFLAGS_BUFFERED,            true  },
    1310             { "usecrlf",      sizeof("usecrlf"     ) - 1,   RTLOGFLAGS_USECRLF,             true },
    1311             { "uself",        sizeof("uself"       ) - 1,   RTLOGFLAGS_USECRLF,             false  },
    1312             { "append",       sizeof("append"      ) - 1,   RTLOGFLAGS_APPEND,              false  },
    1313             { "overwrite",    sizeof("overwrite"   ) - 1,   RTLOGFLAGS_APPEND,              true  },
    1314             { "rel",          sizeof("rel"         ) - 1,   RTLOGFLAGS_REL_TS,              false },
    1315             { "abs",          sizeof("abs"         ) - 1,   RTLOGFLAGS_REL_TS,              true  },
    1316             { "dec",          sizeof("dec"         ) - 1,   RTLOGFLAGS_DECIMAL_TS,          false },
    1317             { "hex",          sizeof("hex"         ) - 1,   RTLOGFLAGS_DECIMAL_TS,          true  },
    1318             { "lockcnts",     sizeof("lockcnts"    ) - 1,   RTLOGFLAGS_PREFIX_LOCK_COUNTS,  false },
    1319             { "cpuid",        sizeof("cpuid"       ) - 1,   RTLOGFLAGS_PREFIX_CPUID,        false },
    1320             { "pid",          sizeof("pid"         ) - 1,   RTLOGFLAGS_PREFIX_PID,          false },
    1321             { "flagno",       sizeof("flagno"      ) - 1,   RTLOGFLAGS_PREFIX_FLAG_NO,      false },
    1322             { "flag",         sizeof("flag"        ) - 1,   RTLOGFLAGS_PREFIX_FLAG,         false },
    1323             { "groupno",      sizeof("groupno"     ) - 1,   RTLOGFLAGS_PREFIX_GROUP_NO,     false },
    1324             { "group",        sizeof("group"       ) - 1,   RTLOGFLAGS_PREFIX_GROUP,        false },
    1325             { "tid",          sizeof("tid"         ) - 1,   RTLOGFLAGS_PREFIX_TID,          false },
    1326             { "thread",       sizeof("thread"      ) - 1,   RTLOGFLAGS_PREFIX_THREAD,       false },
    1327             { "custom",       sizeof("custom"      ) - 1,   RTLOGFLAGS_PREFIX_CUSTOM,       false },
    1328             { "timeprog",     sizeof("timeprog"    ) - 1,   RTLOGFLAGS_PREFIX_TIME_PROG,    false },
    1329             { "time",         sizeof("time"        ) - 1,   RTLOGFLAGS_PREFIX_TIME,         false },
    1330             { "msprog",       sizeof("msprog"      ) - 1,   RTLOGFLAGS_PREFIX_MS_PROG,      false },
    1331             { "tsc",          sizeof("tsc"         ) - 1,   RTLOGFLAGS_PREFIX_TSC,          false }, /* before ts! */
    1332             { "ts",           sizeof("ts"          ) - 1,   RTLOGFLAGS_PREFIX_TS,           false },
    1333         };
    1334 
    13351377        /* check no prefix. */
    13361378        bool fNo = false;
     
    13661408
    13671409        /* instruction. */
    1368         for (i = 0; i < RT_ELEMENTS(aDest); i++)
    1369         {
    1370             if (!strncmp(pszVar, aDest[i].pszInstr, aDest[i].cchInstr))
    1371             {
    1372                 if (fNo == aDest[i].fInverted)
    1373                     pLogger->fFlags |= aDest[i].fFlag;
     1410        for (i = 0; i < RT_ELEMENTS(s_aLogFlags); i++)
     1411        {
     1412            if (!strncmp(pszVar, s_aLogFlags[i].pszInstr, s_aLogFlags[i].cchInstr))
     1413            {
     1414                if (fNo == s_aLogFlags[i].fInverted)
     1415                    pLogger->fFlags |= s_aLogFlags[i].fFlag;
    13741416                else
    1375                     pLogger->fFlags &= ~aDest[i].fFlag;
    1376                 pszVar += aDest[i].cchInstr;
     1417                    pLogger->fFlags &= ~s_aLogFlags[i].fFlag;
     1418                pszVar += s_aLogFlags[i].cchInstr;
    13771419                break;
    13781420            }
     
    13801422
    13811423        /* unknown instruction? */
    1382         if (i >= RT_ELEMENTS(aDest))
     1424        if (i >= RT_ELEMENTS(s_aLogFlags))
    13831425        {
    13841426            AssertMsgFailed(("Invalid flags! unknown instruction %.20s\n", pszVar));
     
    13941436}
    13951437RT_EXPORT_SYMBOL(RTLogFlags);
     1438
     1439
     1440#ifndef IN_RC
     1441/**
     1442 * Get the current log flags as a string.
     1443 *
     1444 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
     1445 * @param   pLogger             Logger instance (NULL for default logger).
     1446 * @param   pszBuf              The output buffer.
     1447 * @param   cchBuf              The size of the output buffer. Must be greater
     1448 *                              than zero.
     1449 */
     1450RTDECL(int) RTLogGetFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
     1451{
     1452    bool        fNotFirst = false;
     1453    int         rc        = VINF_SUCCESS;
     1454    uint32_t    fFlags;
     1455    unsigned    i;
     1456
     1457    Assert(cchBuf);
     1458
     1459    /*
     1460     * Resolve defaults.
     1461     */
     1462    if (!pLogger)
     1463    {
     1464        pLogger = RTLogDefaultInstance();
     1465        if (!pLogger)
     1466        {
     1467            *pszBuf = '\0';
     1468            return VINF_SUCCESS;
     1469        }
     1470    }
     1471
     1472    /*
     1473     * Add the flags in the list.
     1474     */
     1475    fFlags = pLogger->fFlags;
     1476    for (i = 0; i < RT_ELEMENTS(s_aLogFlags); i++)
     1477        if (    !s_aLogFlags[i].fInverted
     1478            ?   (s_aLogFlags[i].fFlag & fFlags)
     1479            :   !(s_aLogFlags[i].fFlag & fFlags))
     1480        {
     1481            size_t cchInstr = s_aLogFlags[i].cchInstr;
     1482            if (cchInstr + fNotFirst + 1 > cchBuf)
     1483            {
     1484                rc = VERR_BUFFER_OVERFLOW;
     1485                break;
     1486            }
     1487            if (fNotFirst)
     1488            {
     1489                *pszBuf++ = ' ';
     1490                cchBuf--;
     1491            }
     1492            memcpy(pszBuf, s_aLogFlags[i].pszInstr, cchInstr);
     1493            pszBuf += cchInstr;
     1494            cchBuf -= cchInstr;
     1495            fNotFirst = true;
     1496        }
     1497    *pszBuf = '\0';
     1498    return rc;
     1499}
     1500RT_EXPORT_SYMBOL(RTLogGetFlags);
     1501
     1502
     1503/**
     1504 * Updates the logger desination using the specified string.
     1505 *
     1506 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
     1507 * @param   pLogger             Logger instance (NULL for default logger).
     1508 * @param   pszVar              The value to parse.
     1509 */
     1510RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszVar)
     1511{
     1512    /*
     1513     * Resolve defaults.
     1514     */
     1515    if (!pLogger)
     1516    {
     1517        pLogger = RTLogDefaultInstance();
     1518        if (!pLogger)
     1519            return VINF_SUCCESS;
     1520    }
     1521
     1522    /*
     1523     * Do the parsing.
     1524     */
     1525    while (*pszVar)
     1526    {
     1527        /* skip blanks. */
     1528        while (RT_C_IS_SPACE(*pszVar))
     1529            pszVar++;
     1530        if (!*pszVar)
     1531            break;
     1532
     1533        /* check no prefix. */
     1534        bool fNo = false;
     1535        if (pszVar[0] == 'n' && pszVar[1] == 'o')
     1536        {
     1537            fNo = true;
     1538            pszVar += 2;
     1539        }
     1540
     1541        /* instruction. */
     1542        unsigned i;
     1543        for (i = 0; i < RT_ELEMENTS(s_aLogDst); i++)
     1544        {
     1545            size_t cchInstr = strlen(s_aLogDst[i].pszInstr);
     1546            if (!strncmp(pszVar, s_aLogDst[i].pszInstr, cchInstr))
     1547            {
     1548                if (!fNo)
     1549                    pLogger->fDestFlags |= s_aLogDst[i].fFlag;
     1550                else
     1551                    pLogger->fDestFlags &= ~s_aLogDst[i].fFlag;
     1552                pszVar += cchInstr;
     1553
     1554                /* check for value. */
     1555                while (RT_C_IS_SPACE(*pszVar))
     1556                    pszVar++;
     1557                if (*pszVar == '=' || *pszVar == ':')
     1558                {
     1559                    pszVar++;
     1560                    const char *pszEnd = strchr(pszVar, ';');
     1561                    if (!pszEnd)
     1562                        pszEnd = strchr(pszVar, '\0');
     1563#ifndef IN_RING0
     1564                    size_t cch = pszEnd - pszVar;
     1565
     1566                    /* log file name */
     1567                    if (i == 0 /* file */ && !fNo)
     1568                    {
     1569                        AssertReturn(cch < RTPATH_MAX, VERR_OUT_OF_RANGE);
     1570                        memcpy(pLogger->pszFilename, pszVar, cch);
     1571                        pLogger->pszFilename[cch] = '\0';
     1572                    }
     1573                    /* log directory */
     1574                    else if (i == 1 /* dir */ && !fNo)
     1575                    {
     1576                        char        szTmp[RTPATH_MAX];
     1577                        const char *pszFile = RTPathFilename(pLogger->pszFilename);
     1578                        size_t      cchFile = pszFile ? strlen(pszFile) : 0;
     1579                        AssertReturn(cchFile + cch + 1 < RTPATH_MAX, VERR_OUT_OF_RANGE);
     1580                        memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1);
     1581
     1582                        memcpy(pLogger->pszFilename, pszVar, cch);
     1583                        pLogger->pszFilename[cch] = '\0';
     1584                        RTPathStripTrailingSlash(pLogger->pszFilename);
     1585
     1586                        cch = strlen(pLogger->pszFilename);
     1587                        pLogger->pszFilename[cch++] = '/';
     1588                        memcpy(&pLogger->pszFilename[cch], szTmp, cchFile);
     1589                    }
     1590                    else
     1591                        AssertMsgFailedReturn(("Invalid destination value! %s%s doesn't take a value!\n",
     1592                                               fNo ? "no" : "", s_aLogDst[i].pszInstr),
     1593                                              VERR_INVALID_PARAMETER);
     1594#endif
     1595                    pszVar = pszEnd + (*pszEnd != '\0');
     1596                }
     1597                break;
     1598            }
     1599        }
     1600
     1601        /* assert known instruction */
     1602        AssertMsgReturn(i < RT_ELEMENTS(s_aLogDst),
     1603                        ("Invalid destination value! unknown instruction %.20s\n", pszVar),
     1604                        VERR_INVALID_PARAMETER);
     1605
     1606        /* skip blanks and delimiters. */
     1607        while (RT_C_IS_SPACE(*pszVar) || *pszVar == ';')
     1608            pszVar++;
     1609    } /* while more environment variable value left */
     1610
     1611    return VINF_SUCCESS;
     1612}
     1613RT_EXPORT_SYMBOL(RTLogDestinations);
     1614
     1615
     1616/**
     1617 * Get the current log destinations as a string.
     1618 *
     1619 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
     1620 * @param   pLogger             Logger instance (NULL for default logger).
     1621 * @param   pszBuf              The output buffer.
     1622 * @param   cchBuf              The size of the output buffer. Must be greater
     1623 *                              than 0.
     1624 */
     1625RTDECL(int) RTLogGetDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf)
     1626{
     1627    bool        fNotFirst = false;
     1628    int         rc        = VINF_SUCCESS;
     1629    uint32_t    fDestFlags;
     1630    unsigned    i;
     1631
     1632    Assert(cchBuf);
     1633
     1634    /*
     1635     * Resolve defaults.
     1636     */
     1637    if (!pLogger)
     1638    {
     1639        pLogger = RTLogDefaultInstance();
     1640        if (!pLogger)
     1641        {
     1642            *pszBuf = '\0';
     1643            return VINF_SUCCESS;
     1644        }
     1645    }
     1646#define APPEND_PSZ(psz,cch) do { memcpy(pszBuf, (psz), (cch)); pszBuf += (cch); cchBuf -= (cch); } while (0)
     1647#define APPEND_SZ(sz)       APPEND_PSZ(sz, sizeof(sz) - 1)
     1648#define APPEND_CH(ch)       do { *pszBuf++ = (ch); cchBuf--; } while (0)
     1649
     1650    /*
     1651     * Add the flags in the list.
     1652     */
     1653    fDestFlags = pLogger->fDestFlags;
     1654    for (i = 2; i < RT_ELEMENTS(s_aLogDst); i++)
     1655        if (s_aLogDst[i].fFlag & fDestFlags)
     1656        {
     1657            size_t cchInstr = s_aLogDst[i].cchInstr;
     1658            if (cchInstr + fNotFirst + 1 > cchBuf)
     1659            {
     1660                rc = VERR_BUFFER_OVERFLOW;
     1661                break;
     1662            }
     1663            if (fNotFirst)
     1664                APPEND_CH(' ');
     1665            fNotFirst = true;
     1666            APPEND_PSZ(s_aLogDst[i].pszInstr, cchInstr);
     1667        }
     1668
     1669    /*
     1670     * Add the filename.
     1671     */
     1672    if (    (fDestFlags & RTLOGDEST_FILE)
     1673        &&  VALID_PTR(pLogger->pszFilename)
     1674        &&  RT_SUCCESS(rc))
     1675    {
     1676        size_t cchFilename = strlen(pLogger->pszFilename);
     1677        if (cchFilename + sizeof("file=") - 1 + fNotFirst + 1 <= cchBuf)
     1678        {
     1679            if (fNotFirst)
     1680                APPEND_SZ(" file=");
     1681            else
     1682                APPEND_SZ("file=");
     1683            APPEND_PSZ(pLogger->pszFilename, cchFilename);
     1684        }
     1685        else
     1686            rc = VERR_BUFFER_OVERFLOW;
     1687    }
     1688
     1689#undef APPEND_PSZ
     1690#undef APPEND_SZ
     1691#undef APPEND_CH
     1692
     1693    *pszBuf = '\0';
     1694    return rc;
     1695}
     1696RT_EXPORT_SYMBOL(RTLogGetDestinations);
     1697#endif /* !IN_RC */
    13961698
    13971699
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette