From 891d29f011ec6e0fd4a4c0369f42699bbf7d0310 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 9 May 2024 21:31:22 +0800 Subject: [PATCH] Pause the console pauser before exiting, when there's some wrong in program execution. --- tools/consolepauser/main.windows.cpp | 80 ++++++++++++++++------------ 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/tools/consolepauser/main.windows.cpp b/tools/consolepauser/main.windows.cpp index 1f6eef17..5022831d 100644 --- a/tools/consolepauser/main.windows.cpp +++ b/tools/consolepauser/main.windows.cpp @@ -23,6 +23,7 @@ using std::string; #include #include #include +#include #ifndef WINBOOL #define WINBOOL BOOL @@ -36,6 +37,14 @@ using std::string; #define MAX_COMMAND_LENGTH 32768 #define MAX_ERROR_LENGTH 2048 +#define EXIT_WRONG_ARGUMENTS -1 +#define EXIT_COMMAND_TOO_LONG -2 +#define EXIT_CREATE_JOB_OBJ_FAILED -3 +#define EXIT_SET_JOB_OBJ_INFO_FAILED -4 +#define EXIT_CREATE_PROCESS_FAILED -5 +#define EXIT_ASSGIN_PROCESS_JOB_FAILED -6 + + enum RunProgramFlag { RPF_PAUSE_CONSOLE = 0x0001, RPF_REDIRECT_INPUT = 0x0002, @@ -44,6 +53,8 @@ enum RunProgramFlag { HANDLE hJob; +bool pauseBeforeExit = false; + LONGLONG GetClockTick() { LARGE_INTEGER dummy; QueryPerformanceCounter(&dummy); @@ -75,35 +86,37 @@ string GetErrorMessage() { } void PauseExit(int exitcode, bool reInp) { - HANDLE hInp=NULL; - if (reInp) { - SECURITY_ATTRIBUTES sa; - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; + if (pauseBeforeExit) { + HANDLE hInp=NULL; + if (reInp) { + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; - HANDLE hInp = CreateFileA("CONIN$", GENERIC_WRITE | GENERIC_READ, - FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL); - //si.hStdInput = hInp; - SetStdHandle(STD_INPUT_HANDLE,hInp); - freopen("CONIN$","r",stdin); - } - FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); - fflush(stdin); - printf("\n"); - printf("Press ANY key to exit..."); - getch(); - if (reInp) { - CloseHandle(hInp); + HANDLE hInp = CreateFileA("CONIN$", GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL); + //si.hStdInput = hInp; + SetStdHandle(STD_INPUT_HANDLE,hInp); + freopen("CONIN$","r",stdin); + } + FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); + fflush(stdin); + printf("\n"); + printf("Press ANY key to exit..."); + getch(); + if (reInp) { + CloseHandle(hInp); + } } exit(exitcode); } -string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit, bool &enableVisualTerminalSeq) { +string GetCommand(int argc,char** argv,bool &reInp, bool &enableVisualTerminalSeq) { string result; int flags = atoi(argv[1]); reInp = flags & RPF_REDIRECT_INPUT; - pauseAfterExit = flags & RPF_PAUSE_CONSOLE; + pauseBeforeExit = flags & RPF_PAUSE_CONSOLE; enableVisualTerminalSeq = flags & RPF_ENABLE_VIRTUAL_TERMINAL_PROCESSING; for(int i = 3;i < argc;i++) { // Quote the argument in case the path name contains spaces @@ -118,7 +131,7 @@ string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit, bool &e if(result.length() > MAX_COMMAND_LENGTH) { printf("\n--------------------------------"); printf("\nError: Length of command line string is over %d characters\n",MAX_COMMAND_LENGTH); - PauseExit(EXIT_FAILURE,reInp); + PauseExit(EXIT_COMMAND_TOO_LONG,reInp); } return result; @@ -139,12 +152,12 @@ DWORD ExecuteCommand(string& command,bool reInp, LONGLONG &peakMemory, LONGLONG printf("\n--------------------------------"); printf("\nFailed to execute \"%s\":",command.c_str()); printf("\nError %lu: %s\n",GetLastError(),GetErrorMessage().c_str()); - PauseExit(EXIT_FAILURE,reInp); + PauseExit(EXIT_CREATE_PROCESS_FAILED,reInp); } WINBOOL bSuccess = AssignProcessToJobObject( hJob, pi.hProcess ); if ( bSuccess == FALSE ) { printf( "AssignProcessToJobObject failed: error %lu\n", GetLastError() ); - return 0; + PauseExit(EXIT_ASSGIN_PROCESS_JOB_FAILED); } WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish @@ -190,7 +203,7 @@ int main(int argc, char** argv) { printf("\n--------------------------------"); printf("\nUsage: consolepauser.exe <0|1> \n"); printf("\n 1 means the STDIN is redirected by Red Panda C++; 0 means not\n"); - PauseExit(EXIT_SUCCESS,false); + PauseExit(EXIT_WRONG_ARGUMENTS,false); } // Make us look like the paused program @@ -203,11 +216,16 @@ int main(int argc, char** argv) { sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = FALSE; + bool reInp; + bool enableVisualTerminalSeq; + // Then build the to-run application command + string command = GetCommand(argc, argv, reInp, enableVisualTerminalSeq); + hJob= CreateJobObject( &sa, NULL ); if ( hJob == NULL ) { printf( "CreateJobObject failed: error %lu\n", GetLastError() ); - return 0; + PauseExit(EXIT_CREATE_JOB_OBJ_FAILED,reInp); } JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; @@ -216,14 +234,9 @@ int main(int argc, char** argv) { WINBOOL bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &info, sizeof( info ) ); if ( bSuccess == FALSE ) { printf( "SetInformationJobObject failed: error %lu\n", GetLastError() ); - return 0; + PauseExit(EXIT_SET_JOB_OBJ_INFO_FAILED,reInp); } - bool reInp; - bool pauseAfterExit; - bool enableVisualTerminalSeq; - // Then build the to-run application command - string command = GetCommand(argc,argv,reInp, pauseAfterExit, enableVisualTerminalSeq); HANDLE hOutput = NULL; if (reInp) { SECURITY_ATTRIBUTES sa; @@ -287,8 +300,7 @@ int main(int argc, char** argv) { // Done? Print return value of executed program printf("\n--------------------------------"); printf("\nProcess exited after %.4g seconds with return value %lu (%.4g ms cpu time, %lld KB mem used).\n",seconds,returnvalue, execSeconds, peakMemory); - if (pauseAfterExit) - PauseExit(returnvalue,reInp); + PauseExit(returnvalue,reInp); return 0; }