static int tstRTCreateProcEx6Child(int argc, char **argv)
{
    int rc = RTR3InitExeNoArguments(0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    int cErrors = 0;
    char szValue[_16K];

    /*
     * Check for the environment variable we've set in the parent process.
     */
    if (argc >= 3 && strcmp(argv[2], "inherit") == 0)
    {
        if (!RTEnvExistEx(RTENV_DEFAULT, "testcase-child-6"))
        {
            RTStrmPrintf(g_pStdErr, "child6: Env.var. 'testcase-child-6' was not inherited from parent\n");
            cErrors++;
        }
    }
    else if (argc >= 3 && strstr(argv[2], "change-record") != NULL)
    {
        rc = RTEnvGetEx(RTENV_DEFAULT, "testcase-child-6", szValue, sizeof(szValue), NULL);
        if (RT_SUCCESS(rc) && strcmp(szValue, "changed"))
        {
            RTStrmPrintf(g_pStdErr, "child6: Env.var. 'testcase-child-6'='%s', expected 'changed'.\n", szValue);
            cErrors++;
        }
        else if (RT_FAILURE(rc))
        {
            RTStrmPrintf(g_pStdErr, "child6: RTEnvGetEx(,'testcase-child-6',,) -> %Rrc\n", rc);
            cErrors++;
        }
    }
    else
    {
        if (RTEnvExistEx(RTENV_DEFAULT, "testcase-child-6"))
        {
            RTStrmPrintf(g_pStdErr, "child6: Env.var. 'testcase-child-6' was inherited from parent\n");
            cErrors++;
        }
    }

    /*
     * Check the user name if present we didn't inherit from parent.
     */
    if (   argc >= 4
        && argv[3][0] != '\0'
        && strstr(argv[2], "noinherit") != NULL)
    {
        static struct
        {
            const char *pszVarNm;
            bool fReq;
        } const s_aVars[] =
        {
#ifdef RT_OS_WINDOWS
            { "USERNAME", true },
#else
            { "LOGNAME",  true },
            { "USER",    false },
#endif
        };
        for (unsigned i = 0; i < RT_ELEMENTS(s_aVars); i++)
        {
            rc = RTEnvGetEx(RTENV_DEFAULT, s_aVars[i].pszVarNm, szValue, sizeof(szValue), NULL);
            if (RT_SUCCESS(rc))
            {
                if (strcmp(szValue, argv[3]))
                {
                    RTStrmPrintf(g_pStdErr, "child6: env.var. '%s'='%s', expected '%s'\n",
                                 s_aVars[i].pszVarNm, szValue, argv[3]);
                    cErrors++;
                }
            }
            else if (rc != VERR_ENV_VAR_NOT_FOUND || s_aVars[i].fReq)
            {
                RTStrmPrintf(g_pStdErr, "child6: RTGetEnv('%s') -> %Rrc\n", s_aVars[i].pszVarNm, rc);
                cErrors++;
            }
        }
    }

#if 1
    /* For manual testing. */
    if (strcmp(argv[2],"noinherit") == 0)
    //if (strcmp(argv[2],"noinherit-change-record") == 0)
    {
        RTENV hEnv;
        rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
        if (RT_SUCCESS(rc))
        {
            uint32_t cVars = RTEnvCountEx(hEnv);
            for (uint32_t i = 0; i < cVars; i++)
            {
                char szVarNm[_1K];
                rc = RTEnvGetByIndexEx(hEnv, i, szVarNm, sizeof(szVarNm), szValue, sizeof(szValue));
                if (RT_SUCCESS(rc))
                    RTStrmPrintf(g_pStdErr, "child6: #%u: %s=%s\n", i, szVarNm, szValue);
                else
                {
                    RTStrmPrintf(g_pStdErr, "child6: #%u: %Rrc\n", i, rc);
                    cErrors++;
                }
            }
            RTEnvDestroy(hEnv);
        }
        else
        {
            RTStrmPrintf(g_pStdErr, "child6: RTEnvClone failed: %Rrc\n", rc);
            cErrors++;
        }
    }
#endif

    return cErrors == 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
Example #2
0
/**
 * Generates a kind of report of the hardware, software and whatever else we
 * think might be useful to know about the testbox.
 */
static RTEXITCODE handlerReport(int argc, char **argv)
{
    NOREF(argc); NOREF(argv);

#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    /*
     * For now, a simple CPUID dump.  Need to figure out how to share code
     * like this with other bits, putting it in IPRT.
     */
    RTPrintf("CPUID Dump\n"
             "Leaf      eax      ebx      ecx      edx\n"
             "---------------------------------------------\n");
    static uint32_t const s_auRanges[] =
    {
        UINT32_C(0x00000000),
        UINT32_C(0x80000000),
        UINT32_C(0x80860000),
        UINT32_C(0xc0000000),
        UINT32_C(0x40000000),
    };
    for (uint32_t iRange = 0; iRange < RT_ELEMENTS(s_auRanges); iRange++)
    {
        uint32_t const uFirst = s_auRanges[iRange];

        uint32_t uEax, uEbx, uEcx, uEdx;
        ASMCpuIdExSlow(uFirst, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
        if (uEax >= uFirst && uEax < uFirst + 100)
        {
            uint32_t const cLeafs = RT_MIN(uEax - uFirst + 1, 32);
            for (uint32_t iLeaf = 0; iLeaf < cLeafs; iLeaf++)
            {
                uint32_t uLeaf = uFirst + iLeaf;
                ASMCpuIdExSlow(uLeaf, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);

                /* Clear APIC IDs to avoid submitting new reports all the time. */
                if (uLeaf == 1)
                    uEbx &= UINT32_C(0x00ffffff);
                if (uLeaf == 0xb)
                    uEdx  = 0;
                if (uLeaf == 0x8000001e)
                    uEax  = 0;

                /* Clear some other node/cpu/core/thread ids. */
                if (uLeaf == 0x8000001e)
                {
                    uEbx &= UINT32_C(0xffffff00);
                    uEcx &= UINT32_C(0xffffff00);
                }

                RTPrintf("%08x: %08x %08x %08x %08x\n", uLeaf, uEax, uEbx, uEcx, uEdx);
            }
        }
    }
    RTPrintf("\n");

    /*
     * DMI info.
     */
    RTPrintf("DMI Info\n"
             "--------\n");
    static const struct { const char *pszName; RTSYSDMISTR enmDmiStr; } s_aDmiStrings[] =
    {
        { "Product Name",           RTSYSDMISTR_PRODUCT_NAME },
        { "Product version",        RTSYSDMISTR_PRODUCT_VERSION },
        { "Product UUID",           RTSYSDMISTR_PRODUCT_UUID },
        { "Product Serial",         RTSYSDMISTR_PRODUCT_SERIAL },
        { "System Manufacturer",    RTSYSDMISTR_MANUFACTURER },
    };
    for (uint32_t iDmiString = 0; iDmiString < RT_ELEMENTS(s_aDmiStrings); iDmiString++)
    {
        char szTmp[4096];
        RT_ZERO(szTmp);
        int rc = RTSystemQueryDmiString(s_aDmiStrings[iDmiString].enmDmiStr, szTmp, sizeof(szTmp) - 1);
        if (RT_SUCCESS(rc))
            RTPrintf("%25s: %s\n", s_aDmiStrings[iDmiString].pszName, RTStrStrip(szTmp));
        else
            RTPrintf("%25s: %s [rc=%Rrc]\n", s_aDmiStrings[iDmiString].pszName, RTStrStrip(szTmp), rc);
    }
    RTPrintf("\n");

#else
#endif

    /*
     * Dump the environment.
     */
    RTPrintf("Environment\n"
             "-----------\n");
    RTENV hEnv;
    int rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
    if (RT_SUCCESS(rc))
    {
        uint32_t cVars = RTEnvCountEx(hEnv);
        for (uint32_t iVar = 0; iVar < cVars; iVar++)
        {
            char szVar[1024];
            char szValue[16384];
            rc = RTEnvGetByIndexEx(hEnv, iVar, szVar, sizeof(szVar), szValue, sizeof(szValue));

            /* zap the value of variables that are subject to change. */
            if (   (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW)
                && (   !strcmp(szVar, "TESTBOX_SCRIPT_REV")
                    || !strcmp(szVar, "TESTBOX_ID")
                    || !strcmp(szVar, "TESTBOX_SCRATCH_SIZE")
                    || !strcmp(szVar, "TESTBOX_TIMEOUT")
                    || !strcmp(szVar, "TESTBOX_TIMEOUT_ABS")
                    || !strcmp(szVar, "TESTBOX_TEST_SET_ID")
                   )
               )
               strcpy(szValue, "<volatile>");

            if (RT_SUCCESS(rc))
                RTPrintf("%25s=%s\n", szVar, szValue);
            else if (rc == VERR_BUFFER_OVERFLOW)
                RTPrintf("%25s=%s [VERR_BUFFER_OVERFLOW]\n", szVar, szValue);
            else
                RTPrintf("rc=%Rrc\n", rc);
        }
        RTEnvDestroy(hEnv);
    }

    /** @todo enumerate volumes and whatnot.  */

    int cch = RTPrintf("\n");
    return cch > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
static void tstRTCreateProcEx6(const char *pszAsUser, const char *pszPassword)
{
    RTTestISub("Profile environment");

    const char *apszArgs[5] =
    {
        g_szExecName,
        "--testcase-child-6",
        "inherit",
        pszAsUser,
        NULL
    };

    RTTESTI_CHECK_RC_RETV(RTEnvSetEx(RTENV_DEFAULT, "testcase-child-6", "true"), VINF_SUCCESS);

    /* Use the process environment first. */
    RTPROCESS hProc;
    RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/,
                                         NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);
    RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
    RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);

    if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
        RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);

    /* Use the process environment first with a little change. */
    apszArgs[2] = "change-record";
    RTENV hEnvChange;
    RTTESTI_CHECK_RC_RETV(RTEnvCreateChangeRecord(&hEnvChange), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTEnvSetEx(hEnvChange, "testcase-child-6", "changed"), VINF_SUCCESS);
    int rc;
    RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, hEnvChange, RTPROC_FLAGS_ENV_CHANGE_RECORD,
                                         NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);
    if (RT_SUCCESS(rc))
    {
        ProcStatus.enmReason = RTPROCEXITREASON_ABEND;
        ProcStatus.iStatus   = -1;
        RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);

        if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
            RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
    }


    /* Use profile environment this time. */
    apszArgs[2] = "noinherit";
    RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, RTPROC_FLAGS_PROFILE,
                                         NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);
    if (RT_SUCCESS(rc))
    {
        ProcStatus.enmReason = RTPROCEXITREASON_ABEND;
        ProcStatus.iStatus   = -1;
        RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);

        if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
            RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
    }

    /* Use profile environment this time. */
    apszArgs[2] = "noinherit-change-record";
    RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, hEnvChange,
                                         RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_ENV_CHANGE_RECORD,
                                         NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS);
    if (RT_SUCCESS(rc))
    {
        ProcStatus.enmReason = RTPROCEXITREASON_ABEND;
        ProcStatus.iStatus   = -1;
        RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);

        if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
            RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
    }


    RTTESTI_CHECK_RC(RTEnvDestroy(hEnvChange), VINF_SUCCESS);

    /*
     * Restore the environment and check that the PROFILE flag didn't mess with
     * the process environment.  (Note! The bug may be elsewhere as well.)
     */
    RTTESTI_CHECK_RC(RTEnvUnsetEx(RTENV_DEFAULT, "testcase-child-6"), VINF_SUCCESS);

    RTENV hEnvCur;
    RTTESTI_CHECK_RC_RETV(RTEnvClone(&hEnvCur, RTENV_DEFAULT), VINF_SUCCESS);
    uint32_t cCurrent = RTEnvCountEx(hEnvCur);
    uint32_t cInitial = RTEnvCountEx(g_hEnvInitial);
    RTTESTI_CHECK_MSG(cCurrent == cInitial, ("cCurrent=%u cInitial=%u\n", cCurrent, cInitial));
    uint32_t    cVars1;
    RTENV       hEnv1,    hEnv2;
    const char *pszEnv1, *pszEnv2;
    if (cCurrent >= cInitial)
    {
        hEnv1   = hEnvCur;
        pszEnv1 = "current";
        cVars1  = cCurrent;
        hEnv2   = g_hEnvInitial;
        pszEnv2 = "initial";
    }
    else
    {
        hEnv2   = hEnvCur;
        pszEnv2 = "current";
        hEnv1   = g_hEnvInitial;
        pszEnv1 = "initial";
        cVars1  = cInitial;
    }
    for (uint32_t i = 0; i < cVars1; i++)
    {
        char szValue1[_16K];
        char szVarNm[_1K];
        rc = RTEnvGetByIndexEx(hEnv1, i, szVarNm, sizeof(szVarNm), szValue1, sizeof(szValue1));
        if (RT_SUCCESS(rc))
        {
            char szValue2[_16K];
            rc = RTEnvGetEx(hEnv2, szVarNm, szValue2, sizeof(szValue2), NULL);
            if (RT_SUCCESS(rc))
            {
                if (strcmp(szValue1, szValue2) != 0)
                {
                    RTTestIFailed("Variable '%s' differs", szVarNm);
                    RTTestIFailureDetails("%s: '%s'\n"
                                          "%s: '%s'\n",
                                          pszEnv1, szValue1,
                                          pszEnv2, szValue2);
                }
            }
            else
                RTTestIFailed("RTEnvGetEx(%s,%s,,) failed: %Rrc", pszEnv2, szVarNm, rc);

        }
        else
            RTTestIFailed("RTEnvGetByIndexEx(%s,%u,,,,) failed: %Rrc", pszEnv1, i, rc);
    }
}