int main(int argc, char **argv) { /* * Init IPRT. */ int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Locate a native DTrace command binary. */ bool fIsNativeDTrace = false; char szDTraceCmd[RTPATH_MAX]; szDTraceCmd[0] = '\0'; #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) /* * 1. Try native first on platforms where it's applicable. */ static const char * const s_apszNativeDTrace[] = { "/usr/sbin/dtrace", "/sbin/dtrace", "/usr/bin/dtrace", "/bin/dtrace", "/usr/local/sbin/dtrace", "/usr/local/bin/dtrace" }; if (!RTEnvExist("VBOX_DTRACE_NO_NATIVE")) for (uint32_t i = 0; i < RT_ELEMENTS(s_apszNativeDTrace); i++) if (RTFileExists(s_apszNativeDTrace[i])) { fIsNativeDTrace = true; strcpy(szDTraceCmd, s_apszNativeDTrace[i]); # ifdef RT_OS_LINUX /** @todo Warn if the dtrace modules haven't been loaded or vboxdrv isn't * compiled against them. */ # endif break; } if (szDTraceCmd[0] == '\0') #endif { /* * 2. VBoxDTrace extension pack installed? * * Note! We cannot use the COM API here because this program is usually * run thru sudo or directly as root, even if the target * VirtualBox process is running as regular user. This is due to * the privileges required to run dtrace scripts on a host. */ rc = RTPathAppPrivateArch(szDTraceCmd, sizeof(szDTraceCmd)); if (RT_SUCCESS(rc)) rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd), VBOX_EXTPACK_INSTALL_DIR RTPATH_SLASH_STR VBOX_EXTPACK_VBOXDTRACE_MANGLED_NAME); if (RT_SUCCESS(rc)) rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd), RTBldCfgTargetDotArch()); if (RT_SUCCESS(rc)) rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd), "VBoxDTraceCmd"); if (RT_SUCCESS(rc)) rc = RTStrCat(szDTraceCmd, sizeof(szDTraceCmd), RTLdrGetSuff()); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing extension pack path: %Rrc", rc); if (!RTFileExists(szDTraceCmd)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unable to find a DTrace implementation. VBoxDTrace Extension Pack installed?"); fIsNativeDTrace = false; } /* * Construct a new command line that includes our libary. */ char szDTraceLibDir[RTPATH_MAX]; rc = RTPathAppPrivateNoArch(szDTraceLibDir, sizeof(szDTraceLibDir)); if (RT_SUCCESS(rc)) rc = RTPathAppend(szDTraceLibDir, sizeof(szDTraceLibDir), "dtrace" RTPATH_SLASH_STR "lib"); if (RT_SUCCESS(rc)) rc = RTPathAppend(szDTraceLibDir, sizeof(szDTraceLibDir), RTBldCfgTargetArch()); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing dtrace library path for VBox: %Rrc", rc); char **papszArgs = (char **)RTMemAlloc((argc + 3) * sizeof(char *)); if (!papszArgs) return RTMsgErrorExit(RTEXITCODE_FAILURE, "No memory for argument list."); int cArgs = 1; papszArgs[0] = fIsNativeDTrace ? szDTraceCmd : argv[0]; if (argc > 1) { papszArgs[cArgs++] = (char *)"-L"; papszArgs[cArgs++] = szDTraceLibDir; } for (int i = 1; i < argc; i++) papszArgs[cArgs++] = argv[i]; papszArgs[cArgs] = NULL; Assert(cArgs <= argc + 3); /* * The native DTrace we execute as a sub-process and wait for. */ RTEXITCODE rcExit; if (fIsNativeDTrace) { RTPROCESS hProc; rc = RTProcCreate(szDTraceCmd, papszArgs, RTENV_DEFAULT, 0, &hProc); if (RT_SUCCESS(rc)) { RTPROCSTATUS Status; rc = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &Status); if (RT_SUCCESS(rc)) { if (Status.enmReason == RTPROCEXITREASON_NORMAL) rcExit = (RTEXITCODE)Status.iStatus; else rcExit = RTEXITCODE_FAILURE; } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error waiting for child process: %Rrc", rc); } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error executing '%s': %Rrc", szDTraceCmd, rc); } /* * While the VBoxDTrace we load and call the main function of. */ else { RTERRINFOSTATIC ErrInfo; RTLDRMOD hMod; rc = SUPR3HardenedLdrLoadPlugIn(szDTraceCmd, &hMod, RTErrInfoInitStatic(&ErrInfo)); if (RT_SUCCESS(rc)) { PFNVBOXDTRACEMAIN pfnVBoxDTraceMain; rc = RTLdrGetSymbol(hMod, "VBoxDTraceMain", (void **)&pfnVBoxDTraceMain); if (RT_SUCCESS(rc)) rcExit = (RTEXITCODE)pfnVBoxDTraceMain(cArgs, papszArgs); else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error locating 'VBoxDTraceMain' in '%s': %Rrc", szDTraceCmd, rc); } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading '%s': %Rrc (%s)", szDTraceCmd, rc, ErrInfo.szMsg); } return rcExit; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse arguments. */ static RTGETOPTDEF const s_aOptions[] = { { "--manifest", 'm', RTGETOPT_REQ_STRING }, { "--java", 'j', RTGETOPT_REQ_NOTHING }, { "--chdir", 'C', RTGETOPT_REQ_STRING }, { "--attribute", 'a', RTGETOPT_REQ_STRING }, { "--verify", 'v', RTGETOPT_REQ_NOTHING }, }; bool fVerify = false; bool fStdFormat = true; const char *pszManifest = NULL; const char *pszChDir = NULL; uint32_t fAttr = RTMANIFEST_ATTR_UNKNOWN; RTGETOPTSTATE GetState; rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc", rc); RTGETOPTUNION ValueUnion; while ( (rc = RTGetOpt(&GetState, &ValueUnion)) != 0 && rc != VINF_GETOPT_NOT_OPTION) { switch (rc) { case 'a': { static struct { const char *pszAttr; uint32_t fAttr; } s_aAttributes[] = { { "size", RTMANIFEST_ATTR_SIZE }, { "md5", RTMANIFEST_ATTR_MD5 }, { "sha1", RTMANIFEST_ATTR_SHA1 }, { "sha256", RTMANIFEST_ATTR_SHA256 }, { "sha512", RTMANIFEST_ATTR_SHA512 } }; uint32_t fThisAttr = RTMANIFEST_ATTR_UNKNOWN; for (unsigned i = 0; i < RT_ELEMENTS(s_aAttributes); i++) if (!RTStrICmp(s_aAttributes[i].pszAttr, ValueUnion.psz)) { fThisAttr = s_aAttributes[i].fAttr; break; } if (fThisAttr == RTMANIFEST_ATTR_UNKNOWN) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown attribute type '%s'", ValueUnion.psz); if (fAttr == RTMANIFEST_ATTR_UNKNOWN) fAttr = fThisAttr; else fAttr |= fThisAttr; break; } case 'j': fStdFormat = false; break; case 'm': if (pszManifest) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one manifest can be specified"); pszManifest = ValueUnion.psz; break; case 'v': fVerify = true; break; case 'C': if (pszChDir) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one directory change can be specified"); pszChDir = ValueUnion.psz; break; case 'h': RTPrintf("Usage: %s [--manifest <file>] [--chdir <dir>] [--attribute <attrib-name> [..]] <files>\n" " or %s --verify [--manifest <file>] [--chdir <dir>]\n" "\n" "attrib-name: size, md5, sha1, sha256 or sha512\n" , RTProcShortName(), RTProcShortName()); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Take action. */ RTEXITCODE rcExit; if (!fVerify) { if (rc != VINF_GETOPT_NOT_OPTION) RTMsgWarning("No files specified, the manifest will be empty."); if (fAttr == RTMANIFEST_ATTR_UNKNOWN) fAttr = RTMANIFEST_ATTR_SIZE | RTMANIFEST_ATTR_MD5 | RTMANIFEST_ATTR_SHA1 | RTMANIFEST_ATTR_SHA256 | RTMANIFEST_ATTR_SHA512; rcExit = rtManifestDoCreate(pszManifest, fStdFormat, pszChDir, fAttr, &GetState, &ValueUnion, rc); } else { if (rc == VINF_GETOPT_NOT_OPTION) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No files should be specified when verifying a manifest (--verfiy), " "only a manifest via the --manifest option"); if (fAttr != RTMANIFEST_ATTR_UNKNOWN) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --attribute (-a) option does not combine with --verify (-v)"); rcExit = rtManifestDoVerify(pszManifest, fStdFormat, pszChDir); } return rcExit; }
/** * The main loop for the VBoxClient daemon. */ int main(int argc, char *argv[]) { /* Initialise our runtime before all else. */ int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); int rcClipboard; const char *pszFileName = RTPathFilename(argv[0]); bool fDaemonise = true; /* Have any fatal errors occurred yet? */ bool fSuccess = true; /* Do we know which service we wish to run? */ bool fHaveService = false; if (NULL == pszFileName) pszFileName = "VBoxClient"; /* Initialise our global clean-up critical section */ rc = RTCritSectInit(&g_critSect); if (RT_FAILURE(rc)) { /* Of course, this should never happen. */ RTPrintf("%s: Failed to initialise the global critical section, rc=%Rrc\n", pszFileName, rc); return 1; } /* Parse our option(s) */ /** @todo Use RTGetOpt() if the arguments become more complex. */ for (int i = 1; i < argc; ++i) { if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--nodaemon")) fDaemonise = false; else if (!strcmp(argv[i], "--clipboard")) { if (g_pService == NULL) g_pService = VBoxClient::GetClipboardService(); else fSuccess = false; } else if (!strcmp(argv[i], "--display")) { if (g_pService == NULL) g_pService = VBoxClient::GetDisplayService(); else fSuccess = false; } else if (!strcmp(argv[i], "--seamless")) { if (g_pService == NULL) g_pService = VBoxClient::GetSeamlessService(); else fSuccess = false; } else if (!strcmp(argv[i], "--checkhostversion")) { if (g_pService == NULL) g_pService = VBoxClient::GetHostVersionService(); else fSuccess = false; } #ifdef VBOX_WITH_DRAG_AND_DROP else if (!strcmp(argv[i], "--draganddrop")) { if (g_pService == NULL) g_pService = VBoxClient::GetDragAndDropService(); else fSuccess = false; } #endif /* VBOX_WITH_DRAG_AND_DROP */ else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { vboxClientUsage(pszFileName); return 0; } else { RTPrintf("%s: unrecognized option `%s'\n", pszFileName, argv[i]); RTPrintf("Try `%s --help' for more information\n", pszFileName); return 1; } } if (!fSuccess || !g_pService) { vboxClientUsage(pszFileName); return 1; } /* Get the path for the pidfiles */ rc = RTPathUserHome(g_szPidFile, sizeof(g_szPidFile)); if (RT_FAILURE(rc)) { RTPrintf("VBoxClient: failed to get home directory, rc=%Rrc. Exiting.\n", rc); LogRel(("VBoxClient: failed to get home directory, rc=%Rrc. Exiting.\n", rc)); return 1; } rc = RTPathAppend(g_szPidFile, sizeof(g_szPidFile), g_pService->getPidFilePath()); if (RT_FAILURE(rc)) { RTPrintf("VBoxClient: RTPathAppend failed with rc=%Rrc. Exiting.\n", rc); LogRel(("VBoxClient: RTPathAppend failed with rc=%Rrc. Exiting.\n", rc)); return 1; } /* Initialise the guest library. */ if (RT_FAILURE(VbglR3InitUser())) { RTPrintf("Failed to connect to the VirtualBox kernel service\n"); LogRel(("Failed to connect to the VirtualBox kernel service\n")); return 1; } if (fDaemonise) { rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */); if (RT_FAILURE(rc)) { RTPrintf("VBoxClient: failed to daemonize. Exiting.\n"); LogRel(("VBoxClient: failed to daemonize. Exiting.\n")); # ifdef DEBUG RTPrintf("Error %Rrc\n", rc); # endif return 1; } } if (g_szPidFile[0] && RT_FAILURE(VbglR3PidFile(g_szPidFile, &g_hPidFile))) { RTPrintf("Failed to create a pidfile. Exiting.\n"); LogRel(("Failed to create a pidfile. Exiting.\n")); VbglR3Term(); return 1; } /* Set signal handlers to clean up on exit. */ vboxClientSetSignalHandlers(); /* Set an X11 error handler, so that we don't die when we get unavoidable errors. */ XSetErrorHandler(vboxClientXLibErrorHandler); /* Set an X11 I/O error handler, so that we can shutdown properly on fatal errors. */ XSetIOErrorHandler(vboxClientXLibIOErrorHandler); g_pService->run(fDaemonise); VBoxClient::CleanUp(); return 1; /* We should never get here. */ }
int main(int argc, char **argv) { bool fSys = true; bool fGip = false; #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) fGip = true; #endif /* * Init. */ int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); if (argc == 2 && !strcmp(argv[1], "child")) { RTThreadSleep(300); return 0; } RTTEST hTest; rc = RTTestCreate("tstSupSem", &hTest); if (RT_FAILURE(rc)) { RTPrintf("tstSupSem: fatal error: RTTestCreate failed with rc=%Rrc\n", rc); return 1; } g_hTest = hTest; PSUPDRVSESSION pSession; rc = SUPR3Init(&pSession); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); } g_pSession = pSession; RTTestBanner(hTest); /* * Basic API checks. */ RTTestSub(hTest, "Single Release Event (SRE) API"); SUPSEMEVENT hEvent = NIL_SUPSEMEVENT; RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 20), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,1000),VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VERR_INVALID_HANDLE); RTTESTI_CHECK_RC(SUPSemEventClose(pSession, NIL_SUPSEMEVENT), VINF_SUCCESS); RTTestSub(hTest, "Multiple Release Event (MRE) API"); SUPSEMEVENTMULTI hEventMulti = NIL_SUPSEMEVENT; RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiReset(pSession, hEventMulti), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20), VERR_TIMEOUT); RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 20), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000), VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED); RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VERR_INVALID_HANDLE); RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, NIL_SUPSEMEVENTMULTI), VINF_SUCCESS); #if !defined(RT_OS_OS2) && !defined(RT_OS_WINDOWS) RTTestSub(hTest, "SRE Interruptibility"); RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); g_cMillies = RT_INDEFINITE_WAIT; RTTHREAD hThread = NIL_RTTHREAD; RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS); RTThreadSleep(120); RTThreadPoke(hThread); int rcThread = VINF_SUCCESS; RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS); RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED); RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); g_cMillies = 120*1000; hThread = NIL_RTTHREAD; RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS); RTThreadSleep(120); RTThreadPoke(hThread); rcThread = VINF_SUCCESS; RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS); RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED); RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestSub(hTest, "MRE Interruptibility"); RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS); g_cMillies = RT_INDEFINITE_WAIT; hThread = NIL_RTTHREAD; RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntMRE"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS); RTThreadSleep(120); RTThreadPoke(hThread); rcThread = VINF_SUCCESS; RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS); RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED); RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED); RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti), VINF_SUCCESS); g_cMillies = 120*1000; hThread = NIL_RTTHREAD; RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEventMulti, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntMRE"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadUserWait(hThread, 60*1000), VINF_SUCCESS); RTThreadSleep(120); RTThreadPoke(hThread); rcThread = VINF_SUCCESS; RTTESTI_CHECK_RC(RTThreadWait(hThread, 60*1000, &rcThread), VINF_SUCCESS); RTTESTI_CHECK_RC(rcThread, VERR_INTERRUPTED); RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti), VINF_OBJECT_DESTROYED); /* * Fork test. * Spawn a thread waiting for an event, then spawn a new child process (of * ourselves) and make sure that this does not alter the intended behaviour * of our event semaphore implementation (see @bugref{5090}). */ RTTestSub(hTest, "SRE Process Spawn"); hThread = NIL_RTTHREAD; g_cMillies = 120*1000; RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleSRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS); const char *apszArgs[3] = { argv[0], "child", NULL }; RTPROCESS Process = NIL_RTPROCESS; RTThreadSleep(250); RTTESTI_CHECK_RC(RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, 0, &Process), VINF_SUCCESS); RTThreadSleep(250); RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent), VINF_SUCCESS); rcThread = VERR_GENERAL_FAILURE; RTTESTI_CHECK_RC(RTThreadWait(hThread, 120*1000, &rcThread), VINF_SUCCESS); RTTESTI_CHECK_RC(rcThread, VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestSub(hTest, "MRE Process Spawn"); hThread = NIL_RTTHREAD; g_cMillies = 120*1000; RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstSupSemInterruptibleMRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS); RTTHREAD hThread2 = NIL_RTTHREAD; RTTESTI_CHECK_RC(RTThreadCreate(&hThread2, tstSupSemInterruptibleMRE, (void *)hEvent, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "IntSRE"), VINF_SUCCESS); Process = NIL_RTPROCESS; RTThreadSleep(250); RTTESTI_CHECK_RC(RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, 0, &Process), VINF_SUCCESS); RTThreadSleep(250); RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEvent), VINF_SUCCESS); rcThread = VERR_GENERAL_FAILURE; RTTESTI_CHECK_RC(RTThreadWait(hThread, 120*1000, &rcThread), VINF_SUCCESS); RTTESTI_CHECK_RC(rcThread, VINF_SUCCESS); int rcThread2 = VERR_GENERAL_FAILURE; RTTESTI_CHECK_RC(RTThreadWait(hThread2, 120*1000, &rcThread2), VINF_SUCCESS); RTTESTI_CHECK_RC(rcThread2, VINF_SUCCESS); RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED); #endif /* !OS2 && !WINDOWS */ { #define LOOP_COUNT 20 static unsigned const s_acMsIntervals[] = { 0, 1, 2, 3, 4, 8, 10, 16, 32 }; if (RTTestErrorCount(hTest) == 0) { RTTestSub(hTest, "SRE Timeout Accuracy (ms)"); RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); uint32_t cInterrupted = 0; for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++) { uint64_t cMs = s_acMsIntervals[i]; uint64_t cNsMinSys = UINT64_MAX; uint64_t cNsMin = UINT64_MAX; uint64_t cNsTotalSys= 0; uint64_t cNsTotal = 0; unsigned cLoops = 0; while (cLoops < LOOP_COUNT) { uint64_t u64StartSys = RTTimeSystemNanoTS(); uint64_t u64Start = RTTimeNanoTS(); int rcX = SUPSemEventWaitNoResume(pSession, hEvent, cMs); uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys; uint64_t cNsElapsed = RTTimeNanoTS() - u64Start; if (rcX == VERR_INTERRUPTED) { cInterrupted++; continue; /* retry */ } if (rcX != VERR_TIMEOUT) RTTestFailed(hTest, "%Rrc cLoops=%u cMs=%u", rcX, cLoops, cMs); if (cNsElapsedSys < cNsMinSys) cNsMinSys = cNsElapsedSys; if (cNsElapsed < cNsMin) cNsMin = cNsElapsed; cNsTotalSys += cNsElapsedSys; cNsTotal += cNsElapsed; cLoops++; } if (fSys) { RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs); RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs); } if (fGip) { RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs); RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=gip)", cMs); } } RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned"); } if (RTTestErrorCount(hTest) == 0) { RTTestSub(hTest, "MRE Timeout Accuracy (ms)"); RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS); uint32_t cInterrupted = 0; for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++) { uint64_t cMs = s_acMsIntervals[i]; uint64_t cNsMinSys = UINT64_MAX; uint64_t cNsMin = UINT64_MAX; uint64_t cNsTotalSys= 0; uint64_t cNsTotal = 0; unsigned cLoops = 0; while (cLoops < LOOP_COUNT) { uint64_t u64StartSys = RTTimeSystemNanoTS(); uint64_t u64Start = RTTimeNanoTS(); int rcX = SUPSemEventMultiWaitNoResume(pSession, hEvent, cMs); uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys; uint64_t cNsElapsed = RTTimeNanoTS() - u64Start; if (rcX == VERR_INTERRUPTED) { cInterrupted++; continue; /* retry */ } if (rcX != VERR_TIMEOUT) RTTestFailed(hTest, "%Rrc cLoops=%u cMs=%u", rcX, cLoops, cMs); if (cNsElapsedSys < cNsMinSys) cNsMinSys = cNsElapsedSys; if (cNsElapsed < cNsMin) cNsMin = cNsElapsed; cNsTotalSys += cNsElapsedSys; cNsTotal += cNsElapsed; cLoops++; } if (fSys) { RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs); RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs); } if (fGip) { RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs); RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%u ms avg (clock=gip)", cMs); } } RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned"); } } { static uint32_t const s_acNsIntervals[] = { 0, 1000, 5000, 15000, 30000, 50000, 100000, 250000, 500000, 750000, 900000, 1500000, 2200000 }; if (RTTestErrorCount(hTest) == 0) { RTTestSub(hTest, "SUPSemEventWaitNsRelIntr Accuracy"); RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "SRE resolution"); RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); uint32_t cInterrupted = 0; for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++) { uint64_t cNs = s_acNsIntervals[i]; uint64_t cNsMinSys = UINT64_MAX; uint64_t cNsMin = UINT64_MAX; uint64_t cNsTotalSys= 0; uint64_t cNsTotal = 0; unsigned cLoops = 0; while (cLoops < LOOP_COUNT) { uint64_t u64StartSys = RTTimeSystemNanoTS(); uint64_t u64Start = RTTimeNanoTS(); int rcX = SUPSemEventWaitNsRelIntr(pSession, hEvent, cNs); uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys; uint64_t cNsElapsed = RTTimeNanoTS() - u64Start; if (rcX == VERR_INTERRUPTED) { cInterrupted++; continue; /* retry */ } if (rcX != VERR_TIMEOUT) RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs); if (cNsElapsedSys < cNsMinSys) cNsMinSys = cNsElapsedSys; if (cNsElapsed < cNsMin) cNsMin = cNsElapsed; cNsTotalSys += cNsElapsedSys; cNsTotal += cNsElapsed; cLoops++; } if (fSys) { RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs); RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs); } if (fGip) { RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs); RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs); } } RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned"); } if (RTTestErrorCount(hTest) == 0) { RTTestSub(hTest, "SUPSemEventMultiWaitNsRelIntr Accuracy"); RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution"); RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS); uint32_t cInterrupted = 0; for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++) { uint64_t cNs = s_acNsIntervals[i]; uint64_t cNsMinSys = UINT64_MAX; uint64_t cNsMin = UINT64_MAX; uint64_t cNsTotalSys= 0; uint64_t cNsTotal = 0; unsigned cLoops = 0; while (cLoops < LOOP_COUNT) { uint64_t u64StartSys = RTTimeSystemNanoTS(); uint64_t u64Start = RTTimeNanoTS(); int rcX = SUPSemEventMultiWaitNsRelIntr(pSession, hEvent, cNs); uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys; uint64_t cNsElapsed = RTTimeNanoTS() - u64Start; if (rcX == VERR_INTERRUPTED) { cInterrupted++; continue; /* retry */ } if (rcX != VERR_TIMEOUT) RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs); if (cNsElapsedSys < cNsMinSys) cNsMinSys = cNsElapsedSys; if (cNsElapsed < cNsMin) cNsMin = cNsElapsed; cNsTotalSys += cNsElapsedSys; cNsTotal += cNsElapsed; cLoops++; } if (fSys) { RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs); RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs); } if (fGip) { RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs); RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs); } } RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned"); } if (RTTestErrorCount(hTest) == 0) { RTTestSub(hTest, "SUPSemEventWaitNsAbsIntr Accuracy"); RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution"); RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS); uint32_t cInterrupted = 0; for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++) { uint64_t cNs = s_acNsIntervals[i]; uint64_t cNsMinSys = UINT64_MAX; uint64_t cNsMin = UINT64_MAX; uint64_t cNsTotalSys= 0; uint64_t cNsTotal = 0; unsigned cLoops = 0; while (cLoops < LOOP_COUNT) { uint64_t u64StartSys = RTTimeSystemNanoTS(); uint64_t u64Start = RTTimeNanoTS(); uint64_t uAbsDeadline = (fGip ? u64Start : u64StartSys) + cNs; int rcX = SUPSemEventWaitNsAbsIntr(pSession, hEvent, uAbsDeadline); uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys; uint64_t cNsElapsed = RTTimeNanoTS() - u64Start; if (rcX == VERR_INTERRUPTED) { cInterrupted++; continue; /* retry */ } if (rcX != VERR_TIMEOUT) RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs); if (cNsElapsedSys < cNsMinSys) cNsMinSys = cNsElapsedSys; if (cNsElapsed < cNsMin) cNsMin = cNsElapsed; cNsTotalSys += cNsElapsedSys; cNsTotal += cNsElapsed; cLoops++; } if (fSys) { RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs); RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs); } if (fGip) { RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs); RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs); } } RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned"); } if (RTTestErrorCount(hTest) == 0) { RTTestSub(hTest, "SUPSemEventMultiWaitNsAbsIntr Accuracy"); RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution"); RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS); uint32_t cInterrupted = 0; for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++) { uint64_t cNs = s_acNsIntervals[i]; uint64_t cNsMinSys = UINT64_MAX; uint64_t cNsMin = UINT64_MAX; uint64_t cNsTotalSys= 0; uint64_t cNsTotal = 0; unsigned cLoops = 0; while (cLoops < LOOP_COUNT) { uint64_t u64StartSys = RTTimeSystemNanoTS(); uint64_t u64Start = RTTimeNanoTS(); uint64_t uAbsDeadline = (fGip ? u64Start : u64StartSys) + cNs; int rcX = SUPSemEventMultiWaitNsAbsIntr(pSession, hEvent, uAbsDeadline); uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys; uint64_t cNsElapsed = RTTimeNanoTS() - u64Start; if (rcX == VERR_INTERRUPTED) { cInterrupted++; continue; /* retry */ } if (rcX != VERR_TIMEOUT) RTTestFailed(hTest, "%Rrc cLoops=%u cNs=%u", rcX, cLoops, cNs); if (cNsElapsedSys < cNsMinSys) cNsMinSys = cNsElapsedSys; if (cNsElapsed < cNsMin) cNsMin = cNsElapsed; cNsTotalSys += cNsElapsedSys; cNsTotal += cNsElapsed; cLoops++; } if (fSys) { RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%'u ns min (clock=sys)", cNs); RTTestValueF(hTest, cNsTotalSys / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs); } if (fGip) { RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%'u ns min (clock=gip)", cNs); RTTestValueF(hTest, cNsTotal / cLoops, RTTESTUNIT_NS, "%'u ns avg (clock=gip)", cNs); } } RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED); RTTestValueF(hTest, cInterrupted, RTTESTUNIT_OCCURRENCES, "VERR_INTERRUPTED returned"); } } /* * Done. */ return RTTestSummaryAndDestroy(hTest); }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse arguments up to the command and pass it on to the command handlers. */ typedef enum { VCUACTION_ADD_TRUSTED_PUBLISHER = 1000, VCUACTION_REMOVE_TRUSTED_PUBLISHER, VCUACTION_DISPLAY_ALL, VCUACTION_END } VCUACTION; static const RTGETOPTDEF s_aOptions[] = { { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, { "add-trusted-publisher", VCUACTION_ADD_TRUSTED_PUBLISHER, RTGETOPT_REQ_NOTHING }, { "remove-trusted-publisher", VCUACTION_REMOVE_TRUSTED_PUBLISHER, RTGETOPT_REQ_NOTHING }, { "display-all", VCUACTION_DISPLAY_ALL, RTGETOPT_REQ_NOTHING }, }; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'v': g_cVerbosityLevel++; break; case 'q': if (g_cVerbosityLevel > 0) g_cVerbosityLevel--; break; case 'h': showUsage(argv[0]); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; case VCUACTION_ADD_TRUSTED_PUBLISHER: return cmdAddTrustedPublisher(argc - GetState.iNext + 1, argv + GetState.iNext - 1); case VCUACTION_REMOVE_TRUSTED_PUBLISHER: return cmdRemoveTrustedPublisher(argc - GetState.iNext + 1, argv + GetState.iNext - 1); case VCUACTION_DISPLAY_ALL: return cmdDisplayAll(argc - GetState.iNext + 1, argv + GetState.iNext - 1); default: return RTGetOptPrintError(rc, &ValueUnion); } } RTMsgError("Missing command..."); showUsage(argv[0]); return RTEXITCODE_SYNTAX; }
int main(int argc, char *argv[]) { int rc; int c; bool fDemonize = true; static char *szLogFileName = NULL; /* Parse command line */ while((c = getopt(argc, argv, "fvl:")) != -1) { switch(c) { case 'f': fDemonize = false; break; case 'v': g_cVerbosity++; break; case 'l': szLogFileName = RTStrDup(optarg); break; default : usage(argv[0]); } } /* No more arguments allowed */ if ((argc - optind) != 0) usage(argv[0]); if (fDemonize) { rc = RTProcDaemonizeUsingFork(true /* fNoChDir */, false /* fNoClose */, NULL); if (RT_FAILURE(rc)) { RTPrintf("failed to run into background\n"); return 1; } } rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) { RTPrintf("RTR3InitExe() failed: (%Rrc)\n", rc); return RTMsgInitFailure(rc); } rc = VbglR3Init(); if (RT_SUCCESS(rc)) { rc = vbclInitLogger(szLogFileName); if (RT_SUCCESS(rc)) { rc = vbclStartServices(); if (RT_SUCCESS(rc)) { vbclWait(); vbclStopServices(); } else { RTPrintf("failed to start services: (%Rrc)\n", rc); } vbclTermLogger(szLogFileName); } else { RTPrintf("failed to start logger: (%Rrc)\n", rc); } VbglR3Term(); } else { RTPrintf("failed to initialize guest library: (%Rrc)\n", rc); } return 0; }
RT_C_DECLS_END int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse arguments. */ bool fVerbose = true; uint32_t u32NewRes = 0; uint32_t cSecsSleep = UINT32_MAX; static const RTGETOPTDEF s_aOptions[] = { { "--resolution", 'r', RTGETOPT_REQ_UINT32 }, { "--sleep", 's', RTGETOPT_REQ_UINT32 }, { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, }; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'r': u32NewRes = ValueUnion.u32; if (u32NewRes > 16*10000 /* 16 ms */ || u32NewRes < 1000 /* 100 microsec */) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "syntax error: the new timer resolution (%RU32) is out of range\n", u32NewRes); break; case 's': cSecsSleep = ValueUnion.u32; break; case 'q': fVerbose = false; break; case 'v': fVerbose = true; break; case 'h': RTPrintf("Usage: ntsetfreq [-q|--quiet] [-v|--verbose] [-r|--resolution <100ns>] [-s|--sleep <1s>]\n"); return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Query the current resolution. */ ULONG Cur = ~0; ULONG Min = ~0; ULONG Max = ~0; LONG Status; if (fVerbose || !u32NewRes) { Status = NtQueryTimerResolution(&Min, &Max, &Cur); if (Status >= 0) RTMsgInfo("cur: %u (%u.%02u Hz) min: %u (%u.%02u Hz) max: %u (%u.%02u Hz)\n", Cur, 10000000 / Cur, (10000000 / (Cur * 100)) % 100, Min, 10000000 / Min, (10000000 / (Min * 100)) % 100, Max, 10000000 / Max, (10000000 / (Max * 100)) % 100); else RTMsgError("NTQueryTimerResolution failed with status %#x\n", Status); } if (u32NewRes) { Status = NtSetTimerResolution(u32NewRes, TRUE, &Cur); if (Status < 0) RTMsgError("NTSetTimerResolution(%RU32,,) failed with status %#x\n", u32NewRes, Status); else if (fVerbose) { Cur = Min = Max = ~0; Status = NtQueryTimerResolution(&Min, &Max, &Cur); if (Status >= 0) RTMsgInfo("new: %u (%u.%02u Hz) requested %RU32 (%u.%02u Hz)\n", Cur, 10000000 / Cur, (10000000 / (Cur * 100)) % 100, u32NewRes, 10000000 / u32NewRes, (10000000 / (u32NewRes * 100)) % 100); else RTMsgError("NTSetTimerResolution succeeded but the NTQueryTimerResolution call failed with status %#x (ignored)\n", Status); Status = 0; } } if (u32NewRes && Status >= 0) { if (cSecsSleep == UINT32_MAX) for (;;) RTThreadSleep(RT_INDEFINITE_WAIT); else while (cSecsSleep-- > 0) RTThreadSleep(1000); } return Status >= 0 ? 0 : 1; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Create an empty address space that we can load modules and stuff into * as we parse the parameters. */ RTDBGAS hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTUINTPTR_MAX, ""); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDBgAsCreate -> %Rrc", rc); /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--input", 'i', RTGETOPT_REQ_STRING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, }; PRTSTREAM pInput = g_pStdIn; PRTSTREAM pOutput = g_pStdOut; unsigned cVerbosityLevel = 0; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'i': rc = RTStrmOpen(ValueUnion.psz, "r", &pInput); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open '%s' for reading: %Rrc", ValueUnion.psz, rc); break; case 'v': cVerbosityLevel++; break; case 'h': RTPrintf("Usage: %s [options] <module> <address> [<module> <address> [..]]\n" "\n" "Options:\n" " -i,--input=file\n" " Specify a input file instead of standard input.\n" " -v, --verbose\n" " Display the address space before doing the filtering.\n" " -h, -?, --help\n" " Display this help text and exit successfully.\n" " -V, --version\n" " Display the revision and exit successfully.\n" , RTPathFilename(argv[0])); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("$Revision: 83687 $\n"); return RTEXITCODE_SUCCESS; case VINF_GETOPT_NOT_OPTION: { /* <module> <address> */ const char *pszModule = ValueUnion.psz; rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX); if (RT_FAILURE(rc)) return RTGetOptPrintError(rc, &ValueUnion); uint64_t u64Address = ValueUnion.u64; RTDBGMOD hMod; rc = RTDbgModCreateFromImage(&hMod, pszModule, NULL, 0 /*fFlags*/); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreateFromImage(,%s,,) -> %Rrc", pszModule, rc); rc = RTDbgAsModuleLink(hDbgAs, hMod, u64Address, 0 /* fFlags */); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgAsModuleLink(,%s,%llx,) -> %Rrc", pszModule, u64Address, rc); break; } default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Display the address space. */ if (cVerbosityLevel) { RTPrintf("*** Address Space Dump ***\n"); uint32_t cModules = RTDbgAsModuleCount(hDbgAs); for (uint32_t iModule = 0; iModule < cModules; iModule++) { RTDBGMOD hDbgMod = RTDbgAsModuleByIndex(hDbgAs, iModule); RTPrintf("Module #%u: %s\n", iModule, RTDbgModName(hDbgMod)); RTDBGASMAPINFO aMappings[128]; uint32_t cMappings = RT_ELEMENTS(aMappings); rc = RTDbgAsModuleQueryMapByIndex(hDbgAs, iModule, &aMappings[0], &cMappings, 0 /*fFlags*/); if (RT_SUCCESS(rc)) { for (uint32_t iMapping = 0; iMapping < cMappings; iMapping++) { if (aMappings[iMapping].iSeg == NIL_RTDBGSEGIDX) RTPrintf(" mapping #%u: %RTptr-%RTptr\n", iMapping, aMappings[iMapping].Address, aMappings[iMapping].Address + RTDbgModImageSize(hDbgMod) - 1); else { RTDBGSEGMENT SegInfo; rc = RTDbgModSegmentByIndex(hDbgMod, aMappings[iMapping].iSeg, &SegInfo); if (RT_SUCCESS(rc)) RTPrintf(" mapping #%u: %RTptr-%RTptr (segment #%u - '%s')", iMapping, aMappings[iMapping].Address, aMappings[iMapping].Address + SegInfo.cb, SegInfo.iSeg, SegInfo.szName); else RTPrintf(" mapping #%u: %RTptr-???????? (segment #%u)", iMapping, aMappings[iMapping].Address); } if (cVerbosityLevel > 1) { uint32_t cSymbols = RTDbgModSymbolCount(hDbgMod); RTPrintf(" %u symbols\n", cSymbols); for (uint32_t iSymbol = 0; iSymbol < cSymbols; iSymbol++) { RTDBGSYMBOL SymInfo; rc = RTDbgModSymbolByOrdinal(hDbgMod, iSymbol, &SymInfo); if (RT_SUCCESS(rc)) RTPrintf(" #%04u at %08x:%RTptr %05llx %s\n", SymInfo.iOrdinal, SymInfo.iSeg, SymInfo.offSeg, (uint64_t)SymInfo.cb, SymInfo.szName); } } } } else RTMsgError("RTDbgAsModuleQueryMapByIndex failed: %Rrc", rc); RTDbgModRelease(hDbgMod); } RTPrintf("*** End of Address Space Dump ***\n"); } /* * Read text from standard input and see if there is anything we can translate. */ for (;;) { /* Get a line. */ char szLine[_64K]; rc = RTStrmGetLine(pInput, szLine, sizeof(szLine)); if (rc == VERR_EOF) break; if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrmGetLine() -> %Rrc\n", rc); /* * Search the line for potential addresses and replace them with * symbols+offset. */ const char *pszStart = szLine; const char *psz = szLine; char ch; while ((ch = *psz) != '\0') { size_t cchAddress; uint64_t u64Address; if ( ( ch == '0' && (psz[1] == 'x' || psz[1] == 'X') && TryParseAddress(psz, &cchAddress, &u64Address)) || ( RT_C_IS_XDIGIT(ch) && TryParseAddress(psz, &cchAddress, &u64Address)) ) { /* Print. */ psz += cchAddress; if (pszStart != psz) RTStrmWrite(pOutput, pszStart, psz - pszStart); pszStart = psz; /* Try get the module. */ RTUINTPTR uAddr; RTDBGSEGIDX iSeg; RTDBGMOD hDbgMod; rc = RTDbgAsModuleByAddr(hDbgAs, u64Address, &hDbgMod, &uAddr, &iSeg); if (RT_SUCCESS(rc)) { if (iSeg != UINT32_MAX) RTStrmPrintf(pOutput, "=[%s:%u", RTDbgModName(hDbgMod), iSeg); else RTStrmPrintf(pOutput, "=[%s", RTDbgModName(hDbgMod), iSeg); /* * Do we have symbols? */ RTDBGSYMBOL Symbol; RTINTPTR offSym; rc = RTDbgAsSymbolByAddr(hDbgAs, u64Address, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, &offSym, &Symbol, NULL); if (RT_SUCCESS(rc)) { if (!offSym) RTStrmPrintf(pOutput, "!%s", Symbol.szName); else if (offSym > 0) RTStrmPrintf(pOutput, "!%s+%#llx", Symbol.szName, offSym); else RTStrmPrintf(pOutput, "!%s-%#llx", Symbol.szName, -offSym); } else RTStrmPrintf(pOutput, "+%#llx", u64Address - uAddr); /* * Do we have line numbers? */ RTDBGLINE Line; RTINTPTR offLine; rc = RTDbgAsLineByAddr(hDbgAs, u64Address, &offLine, &Line); if (RT_SUCCESS(rc)) RTStrmPrintf(pOutput, " %Rbn(%u)", Line.szFilename, Line.uLineNo); RTStrmPrintf(pOutput, "]"); RTDbgModRelease(hDbgMod); } } else psz++; } if (pszStart != psz) RTStrmWrite(pOutput, pszStart, psz - pszStart); RTStrmPutCh(pOutput, '\n'); } return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse the command line. */ static const RTGETOPTDEF s_aOptions[] = { { "--ascii", 'a', RTGETOPT_REQ_NOTHING }, { "--stdout", 'c', RTGETOPT_REQ_NOTHING }, { "--to-stdout", 'c', RTGETOPT_REQ_NOTHING }, { "--decompress", 'd', RTGETOPT_REQ_NOTHING }, { "--uncompress", 'd', RTGETOPT_REQ_NOTHING }, { "--force", 'f', RTGETOPT_REQ_NOTHING }, { "--list", 'l', RTGETOPT_REQ_NOTHING }, { "--no-name", 'n', RTGETOPT_REQ_NOTHING }, { "--name", 'N', RTGETOPT_REQ_NOTHING }, { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, { "--recursive", 'r', RTGETOPT_REQ_NOTHING }, { "--suffix", 'S', RTGETOPT_REQ_STRING }, { "--test", 't', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { "--fast", '1', RTGETOPT_REQ_NOTHING }, { "-1", '1', RTGETOPT_REQ_NOTHING }, { "-2", '2', RTGETOPT_REQ_NOTHING }, { "-3", '3', RTGETOPT_REQ_NOTHING }, { "-4", '4', RTGETOPT_REQ_NOTHING }, { "-5", '5', RTGETOPT_REQ_NOTHING }, { "-6", '6', RTGETOPT_REQ_NOTHING }, { "-7", '7', RTGETOPT_REQ_NOTHING }, { "-8", '8', RTGETOPT_REQ_NOTHING }, { "-9", '9', RTGETOPT_REQ_NOTHING }, { "--best", '9', RTGETOPT_REQ_NOTHING } }; bool fAscii = false; bool fStdOut = false; bool fDecompress = false; bool fForce = false; bool fList = false; bool fName = true; bool fQuiet = false; bool fRecursive = false; const char *pszSuff = ".gz"; bool fTest = false; unsigned uLevel = 6; RTEXITCODE rcExit = RTEXITCODE_SUCCESS; unsigned cProcessed = 0; RTVFSIOSTREAM hVfsStdOut= NIL_RTVFSIOSTREAM; RTGETOPTSTATE GetState; rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); for (;;) { RTGETOPTUNION ValueUnion; rc = RTGetOpt(&GetState, &ValueUnion); switch (rc) { case 0: { /* * If we've processed any files we're done. Otherwise take * input from stdin and write the output to stdout. */ if (cProcessed > 0) return rcExit; #if 0 rc = RTVfsFileFromRTFile(1, RTFILE_O_WRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, true /*fLeaveOpen*/, &hVfsOut); if (!fForce && isStdHandleATty(fDecompress ? 0 : 1)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Yeah, right. I'm not %s any compressed data %s the terminal without --force.\n", fDecompress ? "reading" : "writing", fDecompress ? "from" : "to"); #else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "reading from standard input has not yet been implemented"); #endif return rcExit; } case VINF_GETOPT_NOT_OPTION: { if (!*pszSuff && !fStdOut) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --suffix option specified an empty string"); if (!fStdOut && RTVfsChainIsSpec(ValueUnion.psz)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Must use standard out with VFS chain specifications"); RTEXITCODE rcExit2; if (fList) rcExit2 = gzipListFile(ValueUnion.psz, fForce); else if (fTest) rcExit2 = gzipTestFile(ValueUnion.psz, fForce); else if (fDecompress) rcExit2 = gzipDecompressFile(ValueUnion.psz, fStdOut, fForce, &hVfsStdOut); else rcExit2 = gzipCompressFile(ValueUnion.psz, fStdOut, fForce, &hVfsStdOut); if (rcExit2 != RTEXITCODE_SUCCESS) rcExit = rcExit2; cProcessed++; break; } case 'a': fAscii = true; break; case 'c': fStdOut = true; break; case 'd': fDecompress = true; break; case 'f': fForce = true; break; case 'l': fList = true; break; case 'n': fName = false; break; case 'N': fName = true; break; case 'q': fQuiet = true; break; case 'r': fRecursive = true; break; case 'S': pszSuff = ValueUnion.psz; break; case 't': fTest = true; break; case 'v': fQuiet = false; break; case '1': uLevel = 1; break; case '2': uLevel = 2; break; case '3': uLevel = 3; break; case '4': uLevel = 4; break; case '5': uLevel = 5; break; case '6': uLevel = 6; break; case '7': uLevel = 7; break; case '8': uLevel = 8; break; case '9': uLevel = 9; break; case 'h': RTPrintf("Usage: to be written\nOption dump:\n"); for (unsigned i = 0; i < RT_ELEMENTS(s_aOptions); i++) RTPrintf(" -%c,%s\n", s_aOptions[i].iShort, s_aOptions[i].pszLong); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(rc, &ValueUnion); } } }
/** * The main loop for the VBoxClient daemon. * @todo Clean up for readability. */ int main(int argc, char *argv[]) { bool fDaemonise = true, fRespawn = true; int rc; const char *pcszFileName, *pcszStage; /* Initialise our runtime before all else. */ rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* This should never be called twice in one process - in fact one Display * object should probably never be used from multiple threads anyway. */ if (!XInitThreads()) VBClFatalError(("Failed to initialize X11 threads\n")); /* Get our file name for error output. */ pcszFileName = RTPathFilename(argv[0]); if (!pcszFileName) pcszFileName = "VBoxClient"; /* Parse our option(s) */ /** @todo Use RTGetOpt() if the arguments become more complex. */ for (int i = 1; i < argc; ++i) { rc = VERR_INVALID_PARAMETER; if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--nodaemon")) { /* If the user is running in "no daemon" mode anyway, send critical * logging to stdout as well. */ PRTLOGGER pReleaseLog = RTLogRelDefaultInstance(); if (pReleaseLog) rc = RTLogDestinations(pReleaseLog, "stdout"); if (pReleaseLog && RT_FAILURE(rc)) RTPrintf("%s: failed to redivert error output, rc=%Rrc\n", pcszFileName, rc); fDaemonise = false; } else if (!strcmp(argv[i], "--no-respawn")) { fRespawn = false; } else if (!strcmp(argv[i], "--clipboard")) { if (g_pService) break; g_pService = VBClGetClipboardService(); } else if (!strcmp(argv[i], "--display")) { if (g_pService) break; g_pService = VBClGetDisplayService(); } else if (!strcmp(argv[i], "--seamless")) { if (g_pService) break; g_pService = VBClGetSeamlessService(); } else if (!strcmp(argv[i], "--checkhostversion")) { if (g_pService) break; g_pService = VBClGetHostVersionService(); } #ifdef VBOX_WITH_DRAG_AND_DROP else if (!strcmp(argv[i], "--draganddrop")) { if (g_pService) break; g_pService = VBClGetDragAndDropService(); } #endif /* VBOX_WITH_DRAG_AND_DROP */ else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { vboxClientUsage(pcszFileName); return 0; } else { RTPrintf("%s: unrecognized option `%s'\n", pcszFileName, argv[i]); RTPrintf("Try `%s --help' for more information\n", pcszFileName); return 1; } rc = VINF_SUCCESS; } if (RT_FAILURE(rc) || !g_pService) { vboxClientUsage(pcszFileName); return 1; } rc = RTCritSectInit(&g_critSect); if (RT_FAILURE(rc)) VBClFatalError(("Initialising critical section: %Rrc\n", rc)); rc = RTPathUserHome(g_szPidFile, sizeof(g_szPidFile)); if (RT_FAILURE(rc)) VBClFatalError(("Getting home directory for pid-file: %Rrc\n", rc)); rc = RTPathAppend(g_szPidFile, sizeof(g_szPidFile), (*g_pService)->getPidFilePath()); if (RT_FAILURE(rc)) VBClFatalError(("Creating pid-file path: %Rrc\n", rc)); if (fDaemonise) rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */, fRespawn, &cRespawn); if (RT_FAILURE(rc)) VBClFatalError(("Daemonizing: %Rrc\n", rc)); if (g_szPidFile[0]) rc = VbglR3PidFile(g_szPidFile, &g_hPidFile); if (rc == VERR_FILE_LOCK_VIOLATION) /* Already running. */ return 0; if (RT_FAILURE(rc)) VBClFatalError(("Creating pid-file: %Rrc\n", rc)); /* Set signal handlers to clean up on exit. */ vboxClientSetSignalHandlers(); #ifndef VBOXCLIENT_WITHOUT_X11 /* Set an X11 error handler, so that we don't die when we get unavoidable * errors. */ XSetErrorHandler(vboxClientXLibErrorHandler); /* Set an X11 I/O error handler, so that we can shutdown properly on * fatal errors. */ XSetIOErrorHandler(vboxClientXLibIOErrorHandler); #endif rc = (*g_pService)->init(g_pService); if (RT_FAILURE(rc)) VBClFatalError(("Initialising service: %Rrc\n", rc)); rc = (*g_pService)->run(g_pService, fDaemonise); if (RT_FAILURE(rc)) VBClFatalError(("Service main loop failed: %Rrc\n", rc)); VBClCleanUp(); return 0; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); static const RTGETOPTDEF s_aOptions[] = { { "--samples-per-sec", 's', RTGETOPT_REQ_UINT32 }, { "--period-in-samples", 'p', RTGETOPT_REQ_UINT32 }, { "--bufsize-in-samples", 'b', RTGETOPT_REQ_UINT32 }, { "--total-duration-in-secs", 'd', RTGETOPT_REQ_UINT32 } }; RTGETOPTSTATE State; RTGetOptInit(&State, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); RTGETOPTUNION ValueUnion; int chOpt; while ((chOpt = RTGetOpt(&State, &ValueUnion)) != 0) { switch (chOpt) { case 's': g_cSamplesPerSec = ValueUnion.u32; break; case 'p': g_cSamplesPerPeriod = ValueUnion.u32; break; case 'b': g_cSamplesInBuffer = ValueUnion.u32; break; case 'd': g_rdSecDuration = ValueUnion.u32; break; case 'h': RTPrintf("usage: ntPlayToneWaveX.exe\n" "[-s|--samples-per-sec]\n" "[-p|--period-in-samples]\n" "[-b|--bufsize-in-samples]\n" "[-d|--total-duration-in-secs]\n" "\n" "Plays sine tone using ancient waveX API\n"); return 0; default: return RTGetOptPrintError(chOpt, &ValueUnion); } } WAVEFORMATEX waveFormatEx = { 0 }; MMRESULT mmresult; waveFormatEx.wFormatTag = WAVE_FORMAT_PCM; waveFormatEx.nChannels = 2; waveFormatEx.nSamplesPerSec = g_cSamplesPerSec; waveFormatEx.wBitsPerSample = 16; waveFormatEx.nBlockAlign = g_cbSample = waveFormatEx.nChannels * waveFormatEx.wBitsPerSample / 8; waveFormatEx.nAvgBytesPerSec = waveFormatEx.nBlockAlign * waveFormatEx.nSamplesPerSec; waveFormatEx.cbSize = 0; g_hWavEvent = CreateEvent(NULL, FALSE, FALSE, NULL); mmresult = waveOutOpen(&g_hWaveOut, WAVE_MAPPER, &waveFormatEx, (DWORD_PTR)g_hWavEvent, NULL, CALLBACK_EVENT); if (mmresult != MMSYSERR_NOERROR) { RTMsgError("waveOutOpen failed with 0x%X\n", mmresult); return -1; } uint32_t ui32SamplesToPlayTotal = (uint32_t)(g_rdSecDuration * g_cSamplesPerSec); uint32_t ui32SamplesToPlay = ui32SamplesToPlayTotal; uint32_t ui32SamplesPlayed = 0; uint32_t ui32SamplesForWavBuf; WAVEHDR waveHdr1 = {0}, waveHdr2 = {0}, *pWaveHdr, *pWaveHdrPlaying, *pWaveHdrWaiting; uint32_t i, k; DWORD res; int16_t *i16Samples1 = (int16_t *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, g_cSamplesInBuffer * g_cbSample); int16_t *i16Samples2 = (int16_t *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, g_cSamplesInBuffer * g_cbSample); k = 0; // This is discrete time really!!! for (i = 0; i < g_cSamplesInBuffer; i++, k++) { i16Samples1[2 * i] = (uint16_t)(10000.0 * sin(2.0 * M_PI * k / g_cSamplesPerPeriod)); i16Samples1[2 * i + 1] = i16Samples1[2 * i]; } ui32SamplesForWavBuf = min(ui32SamplesToPlay, g_cSamplesInBuffer); waveHdr1.lpData = (LPSTR)i16Samples1; waveHdr1.dwBufferLength = ui32SamplesForWavBuf * g_cbSample; waveHdr1.dwFlags = 0; waveHdr1.dwLoops = 0; ui32SamplesToPlay -= ui32SamplesForWavBuf; ui32SamplesPlayed += ui32SamplesForWavBuf; pWaveHdrPlaying = &waveHdr1; mmresult = waveOutPrepareHeader(g_hWaveOut, pWaveHdrPlaying, sizeof(WAVEHDR)); mmresult = waveOutWrite(g_hWaveOut, pWaveHdrPlaying, sizeof(WAVEHDR)); //RTMsgInfo("waveOutWrite completes with %d\n", mmresult); res = WaitForSingleObject(g_hWavEvent, INFINITE); //RTMsgInfo("WaitForSingleObject completes with %d\n\n", res); waveHdr2.lpData = (LPSTR)i16Samples2; waveHdr2.dwBufferLength = 0; waveHdr2.dwFlags = 0; waveHdr2.dwLoops = 0; pWaveHdrWaiting = &waveHdr2; while (ui32SamplesToPlay > 0) { int16_t *i16Samples = (int16_t *)pWaveHdrWaiting->lpData; for (i = 0; i < g_cSamplesInBuffer; i++, k++) { i16Samples[2 * i] = (uint16_t)(10000.0 * sin(2.0 * M_PI * k / g_cSamplesPerPeriod)); i16Samples[2 * i + 1] = i16Samples[2 * i]; } ui32SamplesForWavBuf = min(ui32SamplesToPlay, g_cSamplesInBuffer); pWaveHdrWaiting->dwBufferLength = ui32SamplesForWavBuf * g_cbSample; pWaveHdrWaiting->dwFlags = 0; pWaveHdrWaiting->dwLoops = 0; ui32SamplesToPlay -= ui32SamplesForWavBuf; ui32SamplesPlayed += ui32SamplesForWavBuf; mmresult = waveOutPrepareHeader(g_hWaveOut, pWaveHdrWaiting, sizeof(WAVEHDR)); mmresult = waveOutWrite(g_hWaveOut, pWaveHdrWaiting, sizeof(WAVEHDR)); //RTMsgInfo("waveOutWrite completes with %d\n", mmresult); res = WaitForSingleObject(g_hWavEvent, INFINITE); //RTMsgInfo("WaitForSingleObject completes with %d\n\n", res); mmresult = waveOutUnprepareHeader(g_hWaveOut, pWaveHdrPlaying, sizeof(WAVEHDR)); //RTMsgInfo("waveOutUnprepareHeader completes with %d\n", mmresult); pWaveHdr = pWaveHdrWaiting; pWaveHdrWaiting = pWaveHdrPlaying; pWaveHdrPlaying = pWaveHdr; } while (mmresult = waveOutUnprepareHeader(g_hWaveOut, pWaveHdrPlaying, sizeof(WAVEHDR))) { //Expecting WAVERR_STILLPLAYING //RTMsgInfo("waveOutUnprepareHeader failed with 0x%X\n", mmresult); Sleep(100); } if (mmresult == MMSYSERR_NOERROR) { waveOutClose(g_hWaveOut); } HeapFree(GetProcessHeap(), 0, i16Samples1); HeapFree(GetProcessHeap(), 0, i16Samples2); }
int main(int cArgs, char **apszArgs) { int rc = RTR3InitExe(cArgs, &apszArgs, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); enum { OPTION_FORMAT = 1, OPTION_COMMAND, OPTION_ARGUMENTS, OPTION_DESCRIPTION, OPTION_SERVICE_NAME, OPTION_ONE_SHOT, OPTION_STOP_COMMAND, OPTION_STOP_ARGUMENTS, OPTION_STATUS_COMMAND, OPTION_STATUS_ARGUMENTS }; static const RTGETOPTDEF s_aOptions[] = { { "--format", OPTION_FORMAT, RTGETOPT_REQ_STRING }, { "--command", OPTION_COMMAND, RTGETOPT_REQ_STRING }, { "--arguments", OPTION_ARGUMENTS, RTGETOPT_REQ_STRING }, { "--description", OPTION_DESCRIPTION, RTGETOPT_REQ_STRING }, { "--service-name", OPTION_SERVICE_NAME, RTGETOPT_REQ_STRING }, { "--one-shot", OPTION_ONE_SHOT, RTGETOPT_REQ_NOTHING }, { "--stop-command", OPTION_STOP_COMMAND, RTGETOPT_REQ_STRING }, { "--stop-arguments", OPTION_STOP_ARGUMENTS, RTGETOPT_REQ_STRING }, { "--status-command", OPTION_STATUS_COMMAND, RTGETOPT_REQ_STRING }, { "--status-arguments", OPTION_STATUS_ARGUMENTS, RTGETOPT_REQ_STRING } }; int ch; struct SERVICEPARAMETERS Parameters = { FORMAT_NONE }; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, cArgs, apszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'h': showUsage(apszArgs[0]); return RTEXITCODE_SUCCESS; break; case 'V': showLogo(); return RTEXITCODE_SUCCESS; break; case OPTION_FORMAT: if (errorIfSet("--format", Parameters.enmFormat != FORMAT_NONE)) return(RTEXITCODE_SYNTAX); Parameters.enmFormat = getFormat("--format", ValueUnion.psz); if (Parameters.enmFormat == FORMAT_NONE) return(RTEXITCODE_SYNTAX); break; case OPTION_COMMAND: if (errorIfSet("--command", Parameters.pcszCommand)) return(RTEXITCODE_SYNTAX); Parameters.pcszCommand = ValueUnion.psz; if (!checkAbsoluteFilePath("--command", Parameters.pcszCommand)) return(RTEXITCODE_SYNTAX); break; case OPTION_ARGUMENTS: if (errorIfSet("--arguments", Parameters.pcszArguments)) return(RTEXITCODE_SYNTAX); /* Quoting will be checked while writing out the string. */ Parameters.pcszArguments = ValueUnion.psz; break; case OPTION_DESCRIPTION: if (errorIfSet("--description", Parameters.pcszDescription)) return(RTEXITCODE_SYNTAX); Parameters.pcszDescription = ValueUnion.psz; if (!checkPrintable("--description", Parameters.pcszDescription)) return(RTEXITCODE_SYNTAX); break; case OPTION_SERVICE_NAME: if (errorIfSet("--service-name", Parameters.pcszServiceName)) return(RTEXITCODE_SYNTAX); Parameters.pcszServiceName = ValueUnion.psz; if (!checkGraphic("--service-name", Parameters.pcszServiceName)) return(RTEXITCODE_SYNTAX); break; case OPTION_ONE_SHOT: Parameters.fOneShot = true; break; case OPTION_STOP_COMMAND: if (errorIfSet("--stop-command", Parameters.pcszStopCommand)) return(RTEXITCODE_SYNTAX); Parameters.pcszStopCommand = ValueUnion.psz; if (!checkAbsoluteFilePath("--stop-command", Parameters.pcszStopCommand)) return(RTEXITCODE_SYNTAX); break; case OPTION_STOP_ARGUMENTS: if (errorIfSet("--stop-arguments", Parameters.pcszStopArguments)) return(RTEXITCODE_SYNTAX); /* Quoting will be checked while writing out the string. */ Parameters.pcszStopArguments = ValueUnion.psz; break; case OPTION_STATUS_COMMAND: if (errorIfSet("--status-command", Parameters.pcszStatusCommand)) return(RTEXITCODE_SYNTAX); Parameters.pcszStatusCommand = ValueUnion.psz; if (!checkAbsoluteFilePath("--status-command", Parameters.pcszStatusCommand)) return(RTEXITCODE_SYNTAX); break; case OPTION_STATUS_ARGUMENTS: if (errorIfSet("--status-arguments", Parameters.pcszStatusArguments)) return(RTEXITCODE_SYNTAX); /* Quoting will be checked while writing out the string. */ Parameters.pcszStatusArguments = ValueUnion.psz; break; default: return RTGetOptPrintError(ch, &ValueUnion); } } if (Parameters.enmFormat == FORMAT_NONE) { RTStrmPrintf(g_pStdErr, "--format must be specified.\n"); return(RTEXITCODE_SYNTAX); } if (Parameters.pcszArguments && !Parameters.pcszCommand) { RTStrmPrintf(g_pStdErr, "--arguments requires --command to be specified.\n"); return(RTEXITCODE_SYNTAX); } if (Parameters.pcszStopArguments && !Parameters.pcszStopCommand) { RTStrmPrintf(g_pStdErr, "--stop-arguments requires --stop-command to be specified.\n"); return(RTEXITCODE_SYNTAX); } if (Parameters.pcszStatusArguments && !Parameters.pcszStatusCommand) { RTStrmPrintf(g_pStdErr, "--status-arguments requires --status-command to be specified.\n"); return(RTEXITCODE_SYNTAX); } return createServiceFile(&Parameters) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; }
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; }
int main(int argc, char **argv) { RTEXITCODE rcExit; /* * Init globals and such. */ int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); g_pszProgName = RTPathFilename(argv[0]); #ifdef DEBUG rc = RTCritSectInit(&g_csLog); AssertRC(rc); #endif #ifdef VBOXSERVICE_TOOLBOX /* * Run toolbox code before all other stuff since these things are simpler * shell/file/text utility like programs that just happens to be inside * VBoxService and shouldn't be subject to /dev/vboxguest, pid-files and * global mutex restrictions. */ if (VBoxServiceToolboxMain(argc, argv, &rcExit)) return rcExit; #endif /* * Connect to the kernel part before daemonizing so we can fail and * complain if there is some kind of problem. We need to initialize the * guest lib *before* we do the pre-init just in case one of services needs * do to some initial stuff with it. */ VBoxServiceVerbose(2, "Calling VbgR3Init()\n"); rc = VbglR3Init(); if (RT_FAILURE(rc)) { if (rc == VERR_ACCESS_DENIED) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Insufficient privileges to start %s! Please start with Administrator/root privileges!\n", g_pszProgName); return RTMsgErrorExit(RTEXITCODE_FAILURE, "VbglR3Init failed with rc=%Rrc\n", rc); } #ifdef RT_OS_WINDOWS /* * Check if we're the specially spawned VBoxService.exe process that * handles page fusion. This saves an extra executable. */ if ( argc == 2 && !strcmp(argv[1], "--pagefusionfork")) return VBoxServicePageSharingInitFork(); #endif char szLogFile[RTPATH_MAX + 128] = ""; /* * Parse the arguments. * * Note! This code predates RTGetOpt, thus the manual parsing. */ bool fDaemonize = true; bool fDaemonized = false; for (int i = 1; i < argc; i++) { const char *psz = argv[i]; if (*psz != '-') return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown argument '%s'\n", psz); psz++; /* translate long argument to short */ if (*psz == '-') { psz++; size_t cch = strlen(psz); #define MATCHES(strconst) ( cch == sizeof(strconst) - 1 \ && !memcmp(psz, strconst, sizeof(strconst) - 1) ) if (MATCHES("foreground")) psz = "f"; else if (MATCHES("verbose")) psz = "v"; else if (MATCHES("version")) psz = "V"; else if (MATCHES("help")) psz = "h"; else if (MATCHES("interval")) psz = "i"; #ifdef RT_OS_WINDOWS else if (MATCHES("register")) psz = "r"; else if (MATCHES("unregister")) psz = "u"; #endif else if (MATCHES("logfile")) psz = "l"; else if (MATCHES("daemonized")) { fDaemonized = true; continue; } else { bool fFound = false; if (cch > sizeof("enable-") && !memcmp(psz, "enable-", sizeof("enable-") - 1)) for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++) if ((fFound = !RTStrICmp(psz + sizeof("enable-") - 1, g_aServices[j].pDesc->pszName))) g_aServices[j].fEnabled = true; if (cch > sizeof("disable-") && !memcmp(psz, "disable-", sizeof("disable-") - 1)) for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++) if ((fFound = !RTStrICmp(psz + sizeof("disable-") - 1, g_aServices[j].pDesc->pszName))) g_aServices[j].fEnabled = false; if (cch > sizeof("only-") && !memcmp(psz, "only-", sizeof("only-") - 1)) for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) { g_aServices[j].fEnabled = !RTStrICmp(psz + sizeof("only-") - 1, g_aServices[j].pDesc->pszName); if (g_aServices[j].fEnabled) fFound = true; } if (!fFound) { rcExit = vboxServiceLazyPreInit(); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++) { rc = g_aServices[j].pDesc->pfnOption(NULL, argc, argv, &i); fFound = rc == VINF_SUCCESS; if (fFound) break; if (rc != -1) return rc; } } if (!fFound) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%s'\n", argv[i]); continue; } #undef MATCHES } /* handle the string of short options. */ do { switch (*psz) { case 'i': rc = VBoxServiceArgUInt32(argc, argv, psz + 1, &i, &g_DefaultInterval, 1, (UINT32_MAX / 1000) - 1); if (rc) return rc; psz = NULL; break; case 'f': fDaemonize = false; break; case 'v': g_cVerbosity++; break; case 'V': RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); return RTEXITCODE_SUCCESS; case 'h': case '?': return vboxServiceUsage(); #ifdef RT_OS_WINDOWS case 'r': return VBoxServiceWinInstall(); case 'u': return VBoxServiceWinUninstall(); #endif case 'l': { rc = VBoxServiceArgString(argc, argv, psz + 1, &i, szLogFile, sizeof(szLogFile)); if (rc) return rc; psz = NULL; break; } default: { rcExit = vboxServiceLazyPreInit(); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; bool fFound = false; for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) { rc = g_aServices[j].pDesc->pfnOption(&psz, argc, argv, &i); fFound = rc == VINF_SUCCESS; if (fFound) break; if (rc != -1) return rc; } if (!fFound) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%c' (%s)\n", *psz, argv[i]); break; } } } while (psz && *++psz); } /* Check that at least one service is enabled. */ if (vboxServiceCountEnabledServices() == 0) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "At least one service must be enabled\n"); rc = VBoxServiceLogCreate(strlen(szLogFile) ? szLogFile : NULL); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log (%s, %Rrc)", strlen(szLogFile) ? szLogFile : "<None>", rc); /* Call pre-init if we didn't do it already. */ rcExit = vboxServiceLazyPreInit(); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; #ifdef RT_OS_WINDOWS /* * Make sure only one instance of VBoxService runs at a time. Create a * global mutex for that. * * Note! The \\Global\ namespace was introduced with Win2K, thus the * version check. * Note! If the mutex exists CreateMutex will open it and set last error to * ERROR_ALREADY_EXISTS. */ OSVERSIONINFOEX OSInfoEx; RT_ZERO(OSInfoEx); OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); SetLastError(NO_ERROR); HANDLE hMutexAppRunning; if ( GetVersionEx((LPOSVERSIONINFO)&OSInfoEx) && OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT && OSInfoEx.dwMajorVersion >= 5 /* NT 5.0 a.k.a W2K */) hMutexAppRunning = CreateMutex(NULL, FALSE, "Global\\" VBOXSERVICE_NAME); else hMutexAppRunning = CreateMutex(NULL, FALSE, VBOXSERVICE_NAME); if (hMutexAppRunning == NULL) { DWORD dwErr = GetLastError(); if ( dwErr == ERROR_ALREADY_EXISTS || dwErr == ERROR_ACCESS_DENIED) { VBoxServiceError("%s is already running! Terminating.", g_pszProgName); return RTEXITCODE_FAILURE; } VBoxServiceError("CreateMutex failed with last error %u! Terminating", GetLastError()); return RTEXITCODE_FAILURE; } #else /* !RT_OS_WINDOWS */ /** @todo Add PID file creation here? */ #endif /* !RT_OS_WINDOWS */ VBoxServiceVerbose(0, "%s r%s started. Verbose level = %d\n", RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity); /* * Daemonize if requested. */ if (fDaemonize && !fDaemonized) { #ifdef RT_OS_WINDOWS VBoxServiceVerbose(2, "Starting service dispatcher ...\n"); rcExit = VBoxServiceWinEnterCtrlDispatcher(); #else VBoxServiceVerbose(1, "Daemonizing...\n"); rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */); if (RT_FAILURE(rc)) return VBoxServiceError("Daemon failed: %Rrc\n", rc); /* in-child */ #endif } #ifdef RT_OS_WINDOWS else #endif { /* * Windows: We're running the service as a console application now. Start the * services, enter the main thread's run loop and stop them again * when it returns. * * POSIX: This is used for both daemons and console runs. Start all services * and return immediately. */ #ifdef RT_OS_WINDOWS # ifndef RT_OS_NT4 /* Install console control handler. */ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)VBoxServiceConsoleControlHandler, TRUE /* Add handler */)) { VBoxServiceError("Unable to add console control handler, error=%ld\n", GetLastError()); /* Just skip this error, not critical. */ } # endif /* !RT_OS_NT4 */ #endif /* RT_OS_WINDOWS */ rc = VBoxServiceStartServices(); rcExit = RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; if (RT_SUCCESS(rc)) VBoxServiceMainWait(); #ifdef RT_OS_WINDOWS # ifndef RT_OS_NT4 /* Uninstall console control handler. */ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */)) { VBoxServiceError("Unable to remove console control handler, error=%ld\n", GetLastError()); /* Just skip this error, not critical. */ } # endif /* !RT_OS_NT4 */ #else /* !RT_OS_WINDOWS */ /* On Windows - since we're running as a console application - we already stopped all services * through the console control handler. So only do the stopping of services here on other platforms * where the break/shutdown/whatever signal was just received. */ VBoxServiceStopServices(); #endif /* RT_OS_WINDOWS */ } VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminated); #ifdef RT_OS_WINDOWS /* * Cleanup mutex. */ CloseHandle(hMutexAppRunning); #endif VBoxServiceVerbose(0, "Ended.\n"); #ifdef DEBUG RTCritSectDelete(&g_csLog); //RTMemTrackerDumpAllToStdOut(); #endif VBoxServiceLogDestroy(); return rcExit; }
int main() { /* * Init. */ int rc = RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); RTTEST hTest; rc = RTTestCreate("tstRTTime", &hTest); if (RT_FAILURE(rc)) return RTEXITCODE_FAILURE; RTTestBanner(hTest); /* * RTNanoTimeTS() shall never return something which * is less or equal to the return of the previous call. */ RTTimeSystemNanoTS(); RTTimeNanoTS(); RTThreadYield(); uint64_t u64RTStartTS = RTTimeNanoTS(); uint64_t u64OSStartTS = RTTimeSystemNanoTS(); uint32_t i; uint64_t u64Prev = RTTimeNanoTS(); for (i = 0; i < 100*_1M; i++) { uint64_t u64 = RTTimeNanoTS(); if (u64 <= u64Prev) { /** @todo wrapping detection. */ RTTestFailed(hTest, "i=%#010x u64=%#llx u64Prev=%#llx (1)\n", i, u64, u64Prev); if (RTTestErrorCount(hTest) >= 256) break; RTThreadYield(); u64 = RTTimeNanoTS(); } else if (u64 - u64Prev > 1000000000 /* 1sec */) { RTTestFailed(hTest, "i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev); if (RTTestErrorCount(hTest) >= 256) break; RTThreadYield(); u64 = RTTimeNanoTS(); } if (!(i & (_1M*2 - 1))) { RTTestPrintf(hTest, RTTESTLVL_INFO, "i=%#010x u64=%#llx u64Prev=%#llx delta=%lld\n", i, u64, u64Prev, u64 - u64Prev); RTThreadYield(); u64 = RTTimeNanoTS(); } u64Prev = u64; } RTTimeSystemNanoTS(); RTTimeNanoTS(); RTThreadYield(); uint64_t u64RTElapsedTS = RTTimeNanoTS(); uint64_t u64OSElapsedTS = RTTimeSystemNanoTS(); u64RTElapsedTS -= u64RTStartTS; u64OSElapsedTS -= u64OSStartTS; int64_t i64Diff = u64OSElapsedTS >= u64RTElapsedTS ? u64OSElapsedTS - u64RTElapsedTS : u64RTElapsedTS - u64OSElapsedTS; if (i64Diff > (int64_t)(u64OSElapsedTS / 1000)) RTTestFailed(hTest, "total time differs too much! u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n", u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS); else { RTTestValue(hTest, "Total time delta", u64OSElapsedTS - u64RTElapsedTS, RTTESTUNIT_NS); RTTestPrintf(hTest, RTTESTLVL_INFO, "total time difference: u64OSElapsedTS=%#llx u64RTElapsedTS=%#llx delta=%lld\n", u64OSElapsedTS, u64RTElapsedTS, u64OSElapsedTS - u64RTElapsedTS); } #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) /** @todo This isn't really x86 or AMD64 specific... */ RTTestValue(hTest, "RTTimeDbgSteps", RTTimeDbgSteps(), RTTESTUNIT_OCCURRENCES); RTTestValue(hTest, "RTTimeDbgSteps pp", ((uint64_t)RTTimeDbgSteps() * 1000) / i, RTTESTUNIT_PP1K); RTTestValue(hTest, "RTTimeDbgExpired", RTTimeDbgExpired(), RTTESTUNIT_OCCURRENCES); RTTestValue(hTest, "RTTimeDbgExpired pp", ((uint64_t)RTTimeDbgExpired() * 1000) / i, RTTESTUNIT_PP1K); RTTestValue(hTest, "RTTimeDbgBad", RTTimeDbgBad(), RTTESTUNIT_OCCURRENCES); RTTestValue(hTest, "RTTimeDbgBad pp", ((uint64_t)RTTimeDbgBad() * 1000) / i, RTTESTUNIT_PP1K); RTTestValue(hTest, "RTTimeDbgRaces", RTTimeDbgRaces(), RTTESTUNIT_OCCURRENCES); RTTestValue(hTest, "RTTimeDbgRaces pp", ((uint64_t)RTTimeDbgRaces() * 1000) / i, RTTESTUNIT_PP1K); #endif return RTTestSummaryAndDestroy(hTest); }
int main(int argc, char *argv[]) { /* * Initialize IPRT and convert argv to UTF-8. */ int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse arguments and read input files. */ if (argc < 4) { usage(stderr, argv[0]); return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Insufficient arguments."); } g_products.reserve(20000); g_vendors.reserve(3500); const char *pszOutFile = NULL; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-o") == 0) { pszOutFile = argv[++i]; continue; } if ( strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0 || strcmp(argv[i], "--help") == 0) { usage(stdout, argv[0]); return RTEXITCODE_SUCCESS; } PRTSTREAM pInStrm; rc = RTStrmOpen(argv[i], "r", &pInStrm); if (RT_FAILURE(rc)) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Failed to open file '%s' for reading: %Rrc", argv[i], rc); rc = ParseUsbIds(pInStrm, argv[i]); RTStrmClose(pInStrm); if (rc != 0) { RTMsgError("Failed parsing USB devices file '%s'", argv[i]); return rc; } } /* * Due to USBIDDBVENDOR::iProduct, there is currently a max of 64KB products. * (Not a problem as we've only have less that 54K products currently.) */ if (g_products.size() > _64K) return RTMsgErrorExit((RTEXITCODE)ERROR_TOO_MANY_PRODUCTS, "More than 64K products is not supported: %u products", g_products.size()); /* * Sort the IDs and fill in the iProduct and cProduct members. */ sort(g_products.begin(), g_products.end()); sort(g_vendors.begin(), g_vendors.end()); size_t iProduct = 0; for (size_t iVendor = 0; iVendor < g_vendors.size(); iVendor++) { size_t const idVendor = g_vendors[iVendor].vendorID; g_vendors[iVendor].iProduct = iProduct; if ( iProduct < g_products.size() && g_products[iProduct].vendorID <= idVendor) { if (g_products[iProduct].vendorID == idVendor) do iProduct++; while ( iProduct < g_products.size() && g_products[iProduct].vendorID == idVendor); else return RTMsgErrorExit((RTEXITCODE)ERROR_IN_PARSE_LINE, "product without vendor after sorting. impossible!"); } g_vendors[iVendor].cProducts = iProduct - g_vendors[iVendor].iProduct; } /* * Verify that all IDs are unique. */ ProductsSet::iterator ita = adjacent_find(g_products.begin(), g_products.end()); if (ita != g_products.end()) return RTMsgErrorExit((RTEXITCODE)ERROR_DUPLICATE_ENTRY, "Duplicate alias detected: idProduct=%#06x", ita->productID); /* * Build the string table. * Do string compression and create the string table. */ BLDPROGSTRTAB StrTab; if (!BldProgStrTab_Init(&StrTab, g_products.size() + g_vendors.size())) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Out of memory!"); for (ProductsSet::iterator it = g_products.begin(); it != g_products.end(); ++it) { it->StrRef.pszString = (char *)it->str.c_str(); BldProgStrTab_AddString(&StrTab, &it->StrRef); } for (VendorsSet::iterator it = g_vendors.begin(); it != g_vendors.end(); ++it) { it->StrRef.pszString = (char *)it->str.c_str(); BldProgStrTab_AddString(&StrTab, &it->StrRef); } if (!BldProgStrTab_CompileIt(&StrTab, g_fVerbose)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "BldProgStrTab_CompileIt failed!\n"); /* * Print stats. Making a little extra effort to get it all on one line. */ size_t const cbVendorEntry = sizeof(USBIdDatabase::s_aVendors[0]) + sizeof(USBIdDatabase::s_aVendorNames[0]); size_t const cbProductEntry = sizeof(USBIdDatabase::s_aProducts[0]) + sizeof(USBIdDatabase::s_aProductNames[0]); size_t cbOldRaw = (g_products.size() + g_vendors.size()) * sizeof(const char *) * 2 + g_cbRawStrings; size_t cbRaw = g_vendors.size() * cbVendorEntry + g_products.size() * cbProductEntry + g_cbRawStrings; size_t cbActual = g_vendors.size() * cbVendorEntry + g_products.size() * cbProductEntry + StrTab.cchStrTab; #ifdef USB_ID_DATABASE_WITH_COMPRESSION cbActual += sizeof(StrTab.aCompDict); #endif char szMsg1[32]; RTStrPrintf(szMsg1, sizeof(szMsg1),"Total %zu bytes", cbActual); char szMsg2[64]; RTStrPrintf(szMsg2, sizeof(szMsg2)," old version %zu bytes + relocs (%zu%% save)", cbOldRaw, (cbOldRaw - cbActual) * 100 / cbOldRaw); if (cbActual < cbRaw) RTMsgInfo("%s - saving %zu%% (%zu bytes);%s", szMsg1, (cbRaw - cbActual) * 100 / cbRaw, cbRaw - cbActual, szMsg2); else RTMsgInfo("%s - wasting %zu bytes;%s", szMsg1, cbActual - cbRaw, szMsg2); /* * Produce the source file. */ if (!pszOutFile) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Output file is not specified."); FILE *pOut = fopen(pszOutFile, "w"); if (!pOut) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Error opening '%s' for writing", pszOutFile); WriteSourceFile(pOut, argv[0], &StrTab); if (ferror(pOut)) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Error writing '%s'!", pszOutFile); if (fclose(pOut) != 0) return RTMsgErrorExit((RTEXITCODE)ERROR_OPEN_FILE, "Error closing '%s'!", pszOutFile); return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { /* * Init. */ int rc = RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Process arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--keep", 'k', RTGETOPT_REQ_NOTHING }, { "--no-keep", 'n', RTGETOPT_REQ_NOTHING }, }; bool fKeepLoaded = false; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case VINF_GETOPT_NOT_OPTION: { void *pvImageBase; RTERRINFOSTATIC ErrInfo; RTErrInfoInitStatic(&ErrInfo); rc = SUPR3LoadModule(ValueUnion.psz, RTPathFilename(ValueUnion.psz), &pvImageBase, &ErrInfo.Core); if (RT_FAILURE(rc)) { RTMsgError("%Rrc when attempting to load '%s': %s\n", rc, ValueUnion.psz, ErrInfo.Core.pszMsg); return 1; } RTPrintf("Loaded '%s' at %p\n", ValueUnion.psz, pvImageBase); if (!fKeepLoaded) { rc = SUPR3FreeModule(pvImageBase); if (RT_FAILURE(rc)) { RTMsgError("%Rrc when attempting to load '%s'\n", rc, ValueUnion.psz); return 1; } } break; } case 'k': fKeepLoaded = true; break; case 'n': fKeepLoaded = false; break; case 'h': RTPrintf("%s [mod1 [mod2...]]\n", argv[0]); return 1; case 'V': RTPrintf("$Revision$\n"); return 0; default: return RTGetOptPrintError(ch, &ValueUnion); } } return 0; }
int main() { /* * Init runtime */ unsigned cErrors = 0; int rc = RTR3InitExeNoArguments(0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Check that the clock is reliable. */ RTPrintf("tstTimer: TESTING - RTTimeNanoTS() for 2sec\n"); uint64_t uTSMillies = RTTimeMilliTS(); uint64_t uTSBegin = RTTimeNanoTS(); uint64_t uTSLast = uTSBegin; uint64_t uTSDiff; uint64_t cIterations = 0; do { uint64_t uTS = RTTimeNanoTS(); if (uTS < uTSLast) { RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. uTS=%RU64 uTSLast=%RU64\n", uTS, uTSLast); cErrors++; } if (++cIterations > (2*1000*1000*1000)) { RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. cIterations=%RU64 uTS=%RU64 uTSBegin=%RU64\n", cIterations, uTS, uTSBegin); return 1; } uTSLast = uTS; uTSDiff = uTSLast - uTSBegin; } while (uTSDiff < (2*1000*1000*1000)); uTSMillies = RTTimeMilliTS() - uTSMillies; if (uTSMillies >= 2500 || uTSMillies <= 1500) { RTPrintf("tstTimer: FAILURE - uTSMillies=%RI64 uTSBegin=%RU64 uTSLast=%RU64 uTSDiff=%RU64\n", uTSMillies, uTSBegin, uTSLast, uTSDiff); cErrors++; } if (!cErrors) RTPrintf("tstTimer: OK - RTTimeNanoTS()\n"); /* * Tests. */ static struct { unsigned uMicroInterval; unsigned uMilliesWait; unsigned cLower; unsigned cUpper; } aTests[] = { { 32000, 2000, 0, 0 }, { 20000, 2000, 0, 0 }, { 10000, 2000, 0, 0 }, { 8000, 2000, 0, 0 }, { 2000, 2000, 0, 0 }, { 1000, 2000, 0, 0 }, { 500, 5000, 0, 0 }, { 200, 5000, 0, 0 }, { 100, 5000, 0, 0 } }; unsigned i = 0; for (i = 0; i < RT_ELEMENTS(aTests); i++) { aTests[i].cLower = (aTests[i].uMilliesWait*1000 - aTests[i].uMilliesWait*100) / aTests[i].uMicroInterval; aTests[i].cUpper = (aTests[i].uMilliesWait*1000 + aTests[i].uMilliesWait*100) / aTests[i].uMicroInterval; gu64Norm = aTests[i].uMicroInterval*1000; RTPrintf("\n" "tstTimer: TESTING - %d us interval, %d ms wait, expects %d-%d ticks.\n", aTests[i].uMicroInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper); /* * Start timer which ticks every 10ms. */ gcTicks = 0; PRTTIMER pTimer; gu64Max = 0; gu64Min = UINT64_MAX; gu64Prev = 0; RT_ZERO(cFrequency); #ifdef RT_OS_WINDOWS if (aTests[i].uMicroInterval < 1000) continue; rc = RTTimerCreate(&pTimer, aTests[i].uMicroInterval / 1000, TimerCallback, NULL); #else rc = RTTimerCreateEx(&pTimer, aTests[i].uMicroInterval * (uint64_t)1000, 0, TimerCallback, NULL); #endif if (RT_FAILURE(rc)) { RTPrintf("tstTimer: FAILURE - RTTimerCreateEx(,%u*1M,,,) -> %Rrc\n", aTests[i].uMicroInterval, rc); cErrors++; continue; } /* * Start the timer and active waiting for the requested test period. */ uTSBegin = RTTimeNanoTS(); #ifndef RT_OS_WINDOWS rc = RTTimerStart(pTimer, 0); if (RT_FAILURE(rc)) { RTPrintf("tstTimer: FAILURE - RTTimerStart(,0) -> %Rrc\n", rc); cErrors++; } #endif while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000) /* nothing */; /* destroy the timer */ uint64_t uTSEnd = RTTimeNanoTS(); uTSDiff = uTSEnd - uTSBegin; rc = RTTimerDestroy(pTimer); if (RT_FAILURE(rc)) { RTPrintf("tstTimer: FAILURE - RTTimerDestroy() -> %d gcTicks=%d\n", rc, gcTicks); cErrors++; } RTPrintf("tstTimer: uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd); unsigned cTicks = gcTicks; RTThreadSleep(aTests[i].uMicroInterval/1000 * 3); if (gcTicks != cTicks) { RTPrintf("tstTimer: FAILURE - RTTimerDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d\n", gcTicks, cTicks); cErrors++; continue; } /* * Check the number of ticks. */ if (gcTicks < aTests[i].cLower) { RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); cErrors++; } else if (gcTicks > aTests[i].cUpper) { RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower); cErrors++; } else RTPrintf("tstTimer: OK - gcTicks=%d", gcTicks); RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max); for (int j = 0; j < (int)RT_ELEMENTS(cFrequency); j++) { uint32_t len = cFrequency[j] * 70 / gcTicks; uint32_t deviation = j - RT_ELEMENTS(cFrequency) / 2; uint64_t u64FreqPercent = (uint64_t)cFrequency[j] * 10000 / gcTicks; uint64_t u64FreqPercentFrac = u64FreqPercent % 100; u64FreqPercent = u64FreqPercent / 100; RTPrintf("%+4d%c %6u %3llu.%02llu%% ", deviation, deviation == 0 ? ' ' : '%', cFrequency[j], u64FreqPercent, u64FreqPercentFrac); for (unsigned k = 0; k < len; k++) RTPrintf("*"); RTPrintf("\n"); } } /* * Summary. */ if (!cErrors) RTPrintf("tstTimer: SUCCESS\n"); else RTPrintf("tstTimer: FAILURE %d errors\n", cErrors); return !!cErrors; }
static int tstRTCreateProcEx5Child(int argc, char **argv) { int rc = RTR3InitExeNoArguments(0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); #ifdef RT_OS_WINDOWS char szUser[_1K]; DWORD cbLen = sizeof(szUser); /** @todo Does not yet handle ERROR_MORE_DATA for user names longer than 32767. */ if (!GetUserName(szUser, &cbLen)) { RTPrintf("GetUserName failed with last error=%ld\n", GetLastError()); return RTEXITCODE_FAILURE; } # if 0 /* Does not work on NT4 (yet). */ DWORD cbSid = 0; DWORD cbDomain = 0; SID_NAME_USE sidUse; /* First try to figure out how much space for SID + domain name we need. */ BOOL bRet = LookupAccountName(NULL /* current system*/, szUser, NULL, &cbSid, NULL, &cbDomain, &sidUse); if (!bRet) { DWORD dwErr = GetLastError(); if (dwErr != ERROR_INSUFFICIENT_BUFFER) { RTPrintf("LookupAccountName(1) failed with last error=%ld\n", dwErr); return RTEXITCODE_FAILURE; } } /* Now try getting the real SID + domain name. */ SID *pSid = (SID *)RTMemAlloc(cbSid); AssertPtr(pSid); char *pszDomain = (char *)RTMemAlloc(cbDomain); /* Size in TCHAR! */ AssertPtr(pszDomain); if (!LookupAccountName(NULL /* Current system */, szUser, pSid, &cbSid, pszDomain, &cbDomain, &sidUse)) { RTPrintf("LookupAccountName(2) failed with last error=%ld\n", GetLastError()); return RTEXITCODE_FAILURE; } RTMemFree(pSid); RTMemFree(pszDomain); # endif #else /** @todo Lookup UID/effective UID, maybe GID? */ #endif return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * The first argument is a command. Figure out which and call its handler. */ static const struct { const char *pszCommand; RTEXITCODE (*pfnHandler)(int argc, char **argv); bool fNoArgs; } s_aHandlers[] = { { "cpuvendor", handlerCpuVendor, true }, { "cpuname", handlerCpuName, true }, { "cpurevision", handlerCpuRevision, true }, { "cpuhwvirt", handlerCpuHwVirt, true }, { "nestedpaging", handlerCpuNestedPaging, true }, { "longmode", handlerCpuLongMode, true }, { "memsize", handlerMemSize, true }, { "report", handlerReport, true } }; if (argc < 2) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "expected command as the first argument"); for (unsigned i = 0; i < RT_ELEMENTS(s_aHandlers); i++) { if (!strcmp(argv[1], s_aHandlers[i].pszCommand)) { if ( s_aHandlers[i].fNoArgs && argc != 2) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "the command '%s' does not take any arguments", argv[1]); return s_aHandlers[i].pfnHandler(argc - 1, argv + 1); } } /* * Help or version query? */ for (int i = 1; i < argc; i++) if ( !strcmp(argv[i], "--help") || !strcmp(argv[i], "-h") || !strcmp(argv[i], "-?") || !strcmp(argv[i], "help") ) { RTPrintf("usage: %s <cmd> [cmd specific args]\n" "\n" "commands:\n", argv[0]); for (unsigned j = 0; j < RT_ELEMENTS(s_aHandlers); j++) RTPrintf(" %s\n", s_aHandlers[j].pszCommand); return RTEXITCODE_FAILURE; } else if ( !strcmp(argv[i], "--version") || !strcmp(argv[i], "-V") ) { RTPrintf("%sr%u", RTBldCfgVersion(), RTBldCfgRevision()); return argc == 2 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; } /* * Syntax error. */ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "unknown command '%s'", argv[1]); }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse the command line. */ static const RTGETOPTDEF s_aOptions[] = { { "--halt", 'H', RTGETOPT_REQ_NOTHING }, { "--poweroff", 'p', RTGETOPT_REQ_NOTHING }, { "--reboot", 'r', RTGETOPT_REQ_NOTHING }, { "--force", 'f', RTGETOPT_REQ_NOTHING }, { "--delay", 'd', RTGETOPT_REQ_UINT32 }, { "--message", 'm', RTGETOPT_REQ_STRING } }; const char *pszMsg = "RTShutdown"; RTMSINTERVAL cMsDelay = 0; uint32_t fFlags = RTSYSTEM_SHUTDOWN_POWER_OFF | RTSYSTEM_SHUTDOWN_PLANNED; RTGETOPTSTATE GetState; rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); for (;;) { RTGETOPTUNION ValueUnion; rc = RTGetOpt(&GetState, &ValueUnion); if (rc == 0) break; switch (rc) { case 'H': fFlags = (fFlags & ~RTSYSTEM_SHUTDOWN_ACTION_MASK) | RTSYSTEM_SHUTDOWN_HALT; break; case 'p': fFlags = (fFlags & ~RTSYSTEM_SHUTDOWN_ACTION_MASK) | RTSYSTEM_SHUTDOWN_POWER_OFF_HALT; break; case 'r': fFlags = (fFlags & ~RTSYSTEM_SHUTDOWN_ACTION_MASK) | RTSYSTEM_SHUTDOWN_REBOOT; break; case 'f': fFlags |= RTSYSTEM_SHUTDOWN_FORCE; break; case 'd': cMsDelay = ValueUnion.u32; break; case 'm': pszMsg = ValueUnion.psz; break; case 'h': RTPrintf("Usage: RTShutdown [-H|-p|-r] [-f] [-d <milliseconds>] [-m <msg>]\n"); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Do the deed. */ rc = RTSystemShutdown(cMsDelay, fFlags, pszMsg); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTSystemShutdown(%u, %#x, \"%s\") returned %Rrc\n", cMsDelay, fFlags, pszMsg, rc); return RTEXITCODE_SUCCESS; }