Pause the console pauser before exiting, when there's some wrong in program execution.

This commit is contained in:
Roy Qu 2024-05-09 21:31:22 +08:00
parent 1a59e3190b
commit 891d29f011
1 changed files with 46 additions and 34 deletions

View File

@ -23,6 +23,7 @@ using std::string;
#include <psapi.h>
#include <processthreadsapi.h>
#include <conio.h>
#include <stdbool.h>
#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,6 +86,7 @@ string GetErrorMessage() {
}
void PauseExit(int exitcode, bool reInp) {
if (pauseBeforeExit) {
HANDLE hInp=NULL;
if (reInp) {
SECURITY_ATTRIBUTES sa;
@ -96,14 +108,15 @@ void PauseExit(int exitcode, bool reInp) {
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> <shared_memory_id> <filename> <parameters>\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,7 +300,6 @@ 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);
return 0;
}