#define WIN32_LEAN_AND_MEAN #include #include #include #include int __cdecl wmain(int argc, wchar_t** argv) { static const wchar_t* format = L"\nreal\t%ldm%.3fs\nuser\t%ldm%.3fs\nsys\t%ldm%.3fs\n"; if(argc > 1) { FILE* out = stdout; int argsToShift = 1; if((argv[1][0] == L'-') && (towlower(argv[1][1]) == L'p')) { out = stderr; ++argsToShift; } int argCount = 0; // construct argv for the new process LPWSTR* argVector = CommandLineToArgvW(GetCommandLine(), &argCount); memmove(argVector, &argVector[argsToShift], sizeof(WCHAR*) * (argc - argsToShift)); argVector[argc - argsToShift] = NULL; // spawn it HANDLE hProcess = (HANDLE)_wspawnv(P_NOWAIT, argVector[0], argVector); LocalFree(argVector); if(hProcess == INVALID_HANDLE_VALUE) { #ifdef _DEBUG fwprintf(stderr, L"Couldn't launch process. errno = %d\n", errno); #endif return 126; } // wait for it to exit WaitForSingleObject(hProcess, INFINITE); DWORD exitCode = 0; GetExitCodeProcess(hProcess, &exitCode); FILETIME creation, exit, kernel, user; // see how long it ran for BOOL result = GetProcessTimes(hProcess, &creation, &exit, &kernel, &user); CloseHandle(hProcess); if(result) { // calculate the difference between creation and exit ULARGE_INTEGER ulCreation = {creation.dwLowDateTime, creation.dwHighDateTime}; ULARGE_INTEGER ulExit = {exit.dwLowDateTime, exit.dwHighDateTime}; ULONGLONG total = ulExit.QuadPart - ulCreation.QuadPart; ulCreation.QuadPart = total; FILETIME elapsed = {ulCreation.LowPart, ulCreation.HighPart}; // convert it to a systemtime SYSTEMTIME sysTimeElapsed = {0}; FileTimeToSystemTime(&elapsed, &sysTimeElapsed); double elapsedSeconds = sysTimeElapsed.wSecond + ((sysTimeElapsed.wMilliseconds) / 1000.); // convert user time to systemtime SYSTEMTIME userSysTime = {0}; FileTimeToSystemTime(&user, &userSysTime); double userSeconds = userSysTime.wSecond + ((userSysTime.wMilliseconds) / 1000.); // convert kernel time SYSTEMTIME kernelSysTime = {0}; FileTimeToSystemTime(&kernel, &kernelSysTime); double kernelSeconds = kernelSysTime.wSecond + ((kernelSysTime.wMilliseconds) / 1000.); // print the results fwprintf( out, format, sysTimeElapsed.wMinute, elapsedSeconds, userSysTime.wMinute, userSeconds, kernelSysTime.wMinute, kernelSeconds ); } else { #ifdef _DEBUG fwprintf(stderr, L"Failed to get process times, error %lu\n", GetLastError()); #endif } return exitCode; } else { const wchar_t* usage = L"Usage: time [-p] utility args\n" L"-p\t\tOptional, send output to stderr instead of stdout\n" L"utility\t\tThe command to time\n" L"args\t\tArguments to 'utility'\n"; fputws(usage, stderr); return 1; } return 0; }