Pause the console pauser before exiting, when there's some wrong in program execution.
This commit is contained in:
parent
1a59e3190b
commit
891d29f011
|
@ -23,6 +23,7 @@ using std::string;
|
||||||
#include <psapi.h>
|
#include <psapi.h>
|
||||||
#include <processthreadsapi.h>
|
#include <processthreadsapi.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifndef WINBOOL
|
#ifndef WINBOOL
|
||||||
#define WINBOOL BOOL
|
#define WINBOOL BOOL
|
||||||
|
@ -36,6 +37,14 @@ using std::string;
|
||||||
#define MAX_COMMAND_LENGTH 32768
|
#define MAX_COMMAND_LENGTH 32768
|
||||||
#define MAX_ERROR_LENGTH 2048
|
#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 {
|
enum RunProgramFlag {
|
||||||
RPF_PAUSE_CONSOLE = 0x0001,
|
RPF_PAUSE_CONSOLE = 0x0001,
|
||||||
RPF_REDIRECT_INPUT = 0x0002,
|
RPF_REDIRECT_INPUT = 0x0002,
|
||||||
|
@ -44,6 +53,8 @@ enum RunProgramFlag {
|
||||||
|
|
||||||
HANDLE hJob;
|
HANDLE hJob;
|
||||||
|
|
||||||
|
bool pauseBeforeExit = false;
|
||||||
|
|
||||||
LONGLONG GetClockTick() {
|
LONGLONG GetClockTick() {
|
||||||
LARGE_INTEGER dummy;
|
LARGE_INTEGER dummy;
|
||||||
QueryPerformanceCounter(&dummy);
|
QueryPerformanceCounter(&dummy);
|
||||||
|
@ -75,35 +86,37 @@ string GetErrorMessage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PauseExit(int exitcode, bool reInp) {
|
void PauseExit(int exitcode, bool reInp) {
|
||||||
HANDLE hInp=NULL;
|
if (pauseBeforeExit) {
|
||||||
if (reInp) {
|
HANDLE hInp=NULL;
|
||||||
SECURITY_ATTRIBUTES sa;
|
if (reInp) {
|
||||||
sa.nLength = sizeof(sa);
|
SECURITY_ATTRIBUTES sa;
|
||||||
sa.lpSecurityDescriptor = NULL;
|
sa.nLength = sizeof(sa);
|
||||||
sa.bInheritHandle = TRUE;
|
sa.lpSecurityDescriptor = NULL;
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
|
||||||
HANDLE hInp = CreateFileA("CONIN$", GENERIC_WRITE | GENERIC_READ,
|
HANDLE hInp = CreateFileA("CONIN$", GENERIC_WRITE | GENERIC_READ,
|
||||||
FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
|
FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
|
||||||
//si.hStdInput = hInp;
|
//si.hStdInput = hInp;
|
||||||
SetStdHandle(STD_INPUT_HANDLE,hInp);
|
SetStdHandle(STD_INPUT_HANDLE,hInp);
|
||||||
freopen("CONIN$","r",stdin);
|
freopen("CONIN$","r",stdin);
|
||||||
}
|
}
|
||||||
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
|
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
|
||||||
fflush(stdin);
|
fflush(stdin);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Press ANY key to exit...");
|
printf("Press ANY key to exit...");
|
||||||
getch();
|
getch();
|
||||||
if (reInp) {
|
if (reInp) {
|
||||||
CloseHandle(hInp);
|
CloseHandle(hInp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exit(exitcode);
|
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;
|
string result;
|
||||||
int flags = atoi(argv[1]);
|
int flags = atoi(argv[1]);
|
||||||
reInp = flags & RPF_REDIRECT_INPUT;
|
reInp = flags & RPF_REDIRECT_INPUT;
|
||||||
pauseAfterExit = flags & RPF_PAUSE_CONSOLE;
|
pauseBeforeExit = flags & RPF_PAUSE_CONSOLE;
|
||||||
enableVisualTerminalSeq = flags & RPF_ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
enableVisualTerminalSeq = flags & RPF_ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
for(int i = 3;i < argc;i++) {
|
for(int i = 3;i < argc;i++) {
|
||||||
// Quote the argument in case the path name contains spaces
|
// 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) {
|
if(result.length() > MAX_COMMAND_LENGTH) {
|
||||||
printf("\n--------------------------------");
|
printf("\n--------------------------------");
|
||||||
printf("\nError: Length of command line string is over %d characters\n",MAX_COMMAND_LENGTH);
|
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;
|
return result;
|
||||||
|
@ -139,12 +152,12 @@ DWORD ExecuteCommand(string& command,bool reInp, LONGLONG &peakMemory, LONGLONG
|
||||||
printf("\n--------------------------------");
|
printf("\n--------------------------------");
|
||||||
printf("\nFailed to execute \"%s\":",command.c_str());
|
printf("\nFailed to execute \"%s\":",command.c_str());
|
||||||
printf("\nError %lu: %s\n",GetLastError(),GetErrorMessage().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 );
|
WINBOOL bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
|
||||||
if ( bSuccess == FALSE ) {
|
if ( bSuccess == FALSE ) {
|
||||||
printf( "AssignProcessToJobObject failed: error %lu\n", GetLastError() );
|
printf( "AssignProcessToJobObject failed: error %lu\n", GetLastError() );
|
||||||
return 0;
|
PauseExit(EXIT_ASSGIN_PROCESS_JOB_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish
|
WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish
|
||||||
|
@ -190,7 +203,7 @@ int main(int argc, char** argv) {
|
||||||
printf("\n--------------------------------");
|
printf("\n--------------------------------");
|
||||||
printf("\nUsage: consolepauser.exe <0|1> <shared_memory_id> <filename> <parameters>\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");
|
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
|
// Make us look like the paused program
|
||||||
|
@ -203,11 +216,16 @@ int main(int argc, char** argv) {
|
||||||
sa.lpSecurityDescriptor = NULL;
|
sa.lpSecurityDescriptor = NULL;
|
||||||
sa.bInheritHandle = FALSE;
|
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 );
|
hJob= CreateJobObject( &sa, NULL );
|
||||||
|
|
||||||
if ( hJob == NULL ) {
|
if ( hJob == NULL ) {
|
||||||
printf( "CreateJobObject failed: error %lu\n", GetLastError() );
|
printf( "CreateJobObject failed: error %lu\n", GetLastError() );
|
||||||
return 0;
|
PauseExit(EXIT_CREATE_JOB_OBJ_FAILED,reInp);
|
||||||
}
|
}
|
||||||
|
|
||||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
|
||||||
|
@ -216,14 +234,9 @@ int main(int argc, char** argv) {
|
||||||
WINBOOL bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &info, sizeof( info ) );
|
WINBOOL bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &info, sizeof( info ) );
|
||||||
if ( bSuccess == FALSE ) {
|
if ( bSuccess == FALSE ) {
|
||||||
printf( "SetInformationJobObject failed: error %lu\n", GetLastError() );
|
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;
|
HANDLE hOutput = NULL;
|
||||||
if (reInp) {
|
if (reInp) {
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
@ -287,8 +300,7 @@ int main(int argc, char** argv) {
|
||||||
// Done? Print return value of executed program
|
// Done? Print return value of executed program
|
||||||
printf("\n--------------------------------");
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue