summaryrefslogtreecommitdiffstats
path: root/Source/kwsys
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2003-12-30 21:23:16 (GMT)
committerBrad King <brad.king@kitware.com>2003-12-30 21:23:16 (GMT)
commit1c8f885f9dc2fe73dcc3651eaead86d566030c2b (patch)
treea4012d7690af6d19ffed617e02acf8367b027a2f /Source/kwsys
parentf48941f261bee3a6ae49fdc9cda177908ba76af6 (diff)
downloadCMake-1c8f885f9dc2fe73dcc3651eaead86d566030c2b.zip
CMake-1c8f885f9dc2fe73dcc3651eaead86d566030c2b.tar.gz
CMake-1c8f885f9dc2fe73dcc3651eaead86d566030c2b.tar.bz2
ENH: Added GetExceptionString method to provide an error description when GetState returns Exception.
Diffstat (limited to 'Source/kwsys')
-rw-r--r--Source/kwsys/Process.h.in8
-rw-r--r--Source/kwsys/ProcessUNIX.c169
-rw-r--r--Source/kwsys/ProcessWin32.c126
-rw-r--r--Source/kwsys/test1.cxx9
4 files changed, 257 insertions, 55 deletions
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index 83e3060..001b853 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -56,6 +56,7 @@
#define kwsysProcess_GetExitCode kwsys(Process_GetExitCode)
#define kwsysProcess_GetExitValue kwsys(Process_GetExitValue)
#define kwsysProcess_GetErrorString kwsys(Process_GetErrorString)
+#define kwsysProcess_GetExceptionString kwsys(Process_GetExceptionString)
#define kwsysProcess_Execute kwsys(Process_Execute)
#define kwsysProcess_WaitForData kwsys(Process_WaitForData)
#define kwsysProcess_Pipes_e kwsys(Process_Pipes_e)
@@ -225,6 +226,12 @@ kwsysEXPORT int kwsysProcess_GetExitValue(kwsysProcess* cp);
kwsysEXPORT const char* kwsysProcess_GetErrorString(kwsysProcess* cp);
/**
+ * When GetState returns "Exception", this method returns a string
+ * describing the problem. Otherwise, it returns NULL.
+ */
+kwsysEXPORT const char* kwsysProcess_GetExceptionString(kwsysProcess* cp);
+
+/**
* Start executing the child process.
*/
kwsysEXPORT void kwsysProcess_Execute(kwsysProcess* cp);
@@ -335,6 +342,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
# undef kwsysProcess_GetExitCode
# undef kwsysProcess_GetExitValue
# undef kwsysProcess_GetErrorString
+# undef kwsysProcess_GetExceptionString
# undef kwsysProcess_Execute
# undef kwsysProcess_WaitForData
# undef kwsysProcess_Pipes_e
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 2abc8e1..96d1afb 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -95,6 +95,7 @@ static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
+static void kwsysProcessSetExitException(kwsysProcess* cp, int sig);
static void kwsysProcessChildErrorExit(int errorPipe);
static void kwsysProcessRestoreDefaultSignalHandlers();
@@ -161,6 +162,9 @@ struct kwsysProcess_s
/* Buffer for error message in case of failure. */
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
+ /* Description for the ExitException. */
+ char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
+
/* The exit codes of each child process in the pipeline. */
int* CommandExitCodes;
@@ -481,13 +485,27 @@ const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
{
if(!cp)
{
- return "Process management structure could not be allocated.";
+ return "Process management structure could not be allocated";
}
else if(cp->State == kwsysProcess_State_Error)
{
return cp->ErrorMessage;
}
- return 0;
+ return "Success";
+}
+
+/*--------------------------------------------------------------------------*/
+const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
+{
+ if(!cp)
+ {
+ return "GetExceptionString called with NULL process management structure";
+ }
+ else if(cp->State == kwsysProcess_State_Exception)
+ {
+ return cp->ExitExceptionString;
+ }
+ return "No exception";
}
/*--------------------------------------------------------------------------*/
@@ -941,26 +959,8 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
{
/* The child received an unhandled signal. */
cp->State = kwsysProcess_State_Exception;
- switch ((int)WTERMSIG(status))
- {
-#ifdef SIGSEGV
- case SIGSEGV: cp->ExitException = kwsysProcess_Exception_Fault; break;
-#endif
-#ifdef SIGBUS
- case SIGBUS: cp->ExitException = kwsysProcess_Exception_Fault; break;
-#endif
-#ifdef SIGFPE
- case SIGFPE: cp->ExitException = kwsysProcess_Exception_Numerical; break;
-#endif
-#ifdef SIGILL
- case SIGILL: cp->ExitException = kwsysProcess_Exception_Illegal; break;
-#endif
-#ifdef SIGINT
- case SIGINT: cp->ExitException = kwsysProcess_Exception_Interrupt; break;
-#endif
- default: cp->ExitException = kwsysProcess_Exception_Other; break;
- }
cp->ExitCode = status;
+ kwsysProcessSetExitException(cp, (int)WTERMSIG(status));
}
else
{
@@ -1019,6 +1019,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->ExitCode = 1;
cp->ExitValue = 1;
cp->ErrorMessage[0] = 0;
+ strcpy(cp->ExitExceptionString, "No exception");
if(cp->ForkPIDs)
{
@@ -1462,6 +1463,132 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc
}
/*--------------------------------------------------------------------------*/
+#define KWSYSPE_CASE(type, str) \
+ cp->ExitException = kwsysProcess_Exception_##type; \
+ strcpy(cp->ExitExceptionString, str)
+static void kwsysProcessSetExitException(kwsysProcess* cp, int sig)
+{
+ switch (sig)
+ {
+#ifdef SIGSEGV
+ case SIGSEGV: KWSYSPE_CASE(Fault, "Segmentation fault"); break;
+#endif
+#ifdef SIGBUS
+ case SIGBUS: KWSYSPE_CASE(Fault, "Bus error"); break;
+#endif
+#ifdef SIGFPE
+ case SIGFPE: KWSYSPE_CASE(Numerical, "Floating-point exception"); break;
+#endif
+#ifdef SIGILL
+ case SIGILL: KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
+#endif
+#ifdef SIGINT
+ case SIGINT: KWSYSPE_CASE(Interrupt, "User interrupt"); break;
+#endif
+#ifdef SIGABRT
+ case SIGABRT: KWSYSPE_CASE(Other, "Child aborted"); break;
+#endif
+#ifdef SIGKILL
+ case SIGKILL: KWSYSPE_CASE(Other, "Child killed"); break;
+#endif
+#ifdef SIGTERM
+ case SIGTERM: KWSYSPE_CASE(Other, "Child terminated"); break;
+#endif
+#ifdef SIGHUP
+ case SIGHUP: KWSYSPE_CASE(Other, "SIGHUP"); break;
+#endif
+#ifdef SIGQUIT
+ case SIGQUIT: KWSYSPE_CASE(Other, "SIGQUIT"); break;
+#endif
+#ifdef SIGTRAP
+ case SIGTRAP: KWSYSPE_CASE(Other, "SIGTRAP"); break;
+#endif
+#ifdef SIGIOT
+# if !defined(SIGABRT) || SIGIOT != SIGABRT
+ case SIGIOT: KWSYSPE_CASE(Other, "SIGIOT"); break;
+# endif
+#endif
+#ifdef SIGUSR1
+ case SIGUSR1: KWSYSPE_CASE(Other, "SIGUSR1"); break;
+#endif
+#ifdef SIGUSR2
+ case SIGUSR2: KWSYSPE_CASE(Other, "SIGUSR2"); break;
+#endif
+#ifdef SIGPIPE
+ case SIGPIPE: KWSYSPE_CASE(Other, "SIGPIPE"); break;
+#endif
+#ifdef SIGALRM
+ case SIGALRM: KWSYSPE_CASE(Other, "SIGALRM"); break;
+#endif
+#ifdef SIGSTKFLT
+ case SIGSTKFLT: KWSYSPE_CASE(Other, "SIGSTKFLT"); break;
+#endif
+#ifdef SIGCHLD
+ case SIGCHLD: KWSYSPE_CASE(Other, "SIGCHLD"); break;
+#elif defined(SIGCLD)
+ case SIGCLD: KWSYSPE_CASE(Other, "SIGCLD"); break;
+#endif
+#ifdef SIGCONT
+ case SIGCONT: KWSYSPE_CASE(Other, "SIGCONT"); break;
+#endif
+#ifdef SIGSTOP
+ case SIGSTOP: KWSYSPE_CASE(Other, "SIGSTOP"); break;
+#endif
+#ifdef SIGTSTP
+ case SIGTSTP: KWSYSPE_CASE(Other, "SIGTSTP"); break;
+#endif
+#ifdef SIGTTIN
+ case SIGTTIN: KWSYSPE_CASE(Other, "SIGTTIN"); break;
+#endif
+#ifdef SIGTTOU
+ case SIGTTOU: KWSYSPE_CASE(Other, "SIGTTOU"); break;
+#endif
+#ifdef SIGURG
+ case SIGURG: KWSYSPE_CASE(Other, "SIGURG"); break;
+#endif
+#ifdef SIGXCPU
+ case SIGXCPU: KWSYSPE_CASE(Other, "SIGXCPU"); break;
+#endif
+#ifdef SIGXFSZ
+ case SIGXFSZ: KWSYSPE_CASE(Other, "SIGXFSZ"); break;
+#endif
+#ifdef SIGVTALRM
+ case SIGVTALRM: KWSYSPE_CASE(Other, "SIGVTALRM"); break;
+#endif
+#ifdef SIGPROF
+ case SIGPROF: KWSYSPE_CASE(Other, "SIGPROF"); break;
+#endif
+#ifdef SIGWINCH
+ case SIGWINCH: KWSYSPE_CASE(Other, "SIGWINCH"); break;
+#endif
+#ifdef SIGPOLL
+ case SIGPOLL: KWSYSPE_CASE(Other, "SIGPOLL"); break;
+#endif
+#ifdef SIGIO
+# if !defined(SIGPOLL) || SIGIO != SIGPOLL
+ case SIGIO: KWSYSPE_CASE(Other, "SIGIO"); break;
+# endif
+#endif
+#ifdef SIGPWR
+ case SIGPWR: KWSYSPE_CASE(Other, "SIGPWR"); break;
+#endif
+#ifdef SIGSYS
+ case SIGSYS: KWSYSPE_CASE(Other, "SIGSYS"); break;
+#endif
+#ifdef SIGUNUSED
+# if !defined(SIGSYS) || SIGUNUSED != SIGSYS
+ case SIGUNUSED: KWSYSPE_CASE(Other, "SIGUNUSED"); break;
+# endif
+#endif
+ default:
+ cp->ExitException = kwsysProcess_Exception_Other;
+ sprintf(cp->ExitExceptionString, "Signal %d", sig);
+ break;
+ }
+}
+#undef KWSYSPE_CASE
+
+/*--------------------------------------------------------------------------*/
/* When the child process encounters an error before its program is
invoked, this is called to report the error to the parent and
exit. */
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index c710fac..8556a96 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -92,6 +92,7 @@ static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
+static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
/*--------------------------------------------------------------------------*/
@@ -234,6 +235,9 @@ struct kwsysProcess_s
/* Buffer for error messages (possibly from Win9x child). */
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
+ /* Description for the ExitException. */
+ char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
+
/* Windows process information data. */
PROCESS_INFORMATION* ProcessInformation;
@@ -905,13 +909,27 @@ const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
{
if(!cp)
{
- return "Process management structure could not be allocated.";
+ return "Process management structure could not be allocated";
}
else if(cp->State == kwsysProcess_State_Error)
{
return cp->ErrorMessage;
}
- return 0;
+ return "Success";
+}
+
+/*--------------------------------------------------------------------------*/
+const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
+{
+ if(!cp)
+ {
+ return "GetExceptionString called with NULL process management structure";
+ }
+ else if(cp->State == kwsysProcess_State_Exception)
+ {
+ return cp->ExitExceptionString;
+ }
+ return "No exception";
}
/*--------------------------------------------------------------------------*/
@@ -1312,39 +1330,8 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
{
/* Child terminated due to exceptional behavior. */
cp->State = kwsysProcess_State_Exception;
- switch (cp->ExitCode)
- {
- case CONTROL_C_EXIT:
- cp->ExitException = kwsysProcess_Exception_Interrupt; break;
-
- case EXCEPTION_FLT_DENORMAL_OPERAND:
- case EXCEPTION_FLT_DIVIDE_BY_ZERO:
- case EXCEPTION_FLT_INEXACT_RESULT:
- case EXCEPTION_FLT_INVALID_OPERATION:
- case EXCEPTION_FLT_OVERFLOW:
- case EXCEPTION_FLT_STACK_CHECK:
- case EXCEPTION_FLT_UNDERFLOW:
- case EXCEPTION_INT_DIVIDE_BY_ZERO:
- case EXCEPTION_INT_OVERFLOW:
- cp->ExitException = kwsysProcess_Exception_Numerical; break;
-
- case EXCEPTION_ACCESS_VIOLATION:
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- case EXCEPTION_DATATYPE_MISALIGNMENT:
- case EXCEPTION_INVALID_DISPOSITION:
- case EXCEPTION_IN_PAGE_ERROR:
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- case EXCEPTION_STACK_OVERFLOW:
- cp->ExitException = kwsysProcess_Exception_Fault; break;
-
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- case EXCEPTION_PRIV_INSTRUCTION:
- cp->ExitException = kwsysProcess_Exception_Illegal; break;
-
- default:
- cp->ExitException = kwsysProcess_Exception_Other; break;
- }
cp->ExitValue = 1;
+ kwsysProcessSetExitException(cp, cp->ExitCode);
}
else
{
@@ -1493,6 +1480,7 @@ int kwsysProcessInitialize(kwsysProcess* cp)
/* Reset error data. */
cp->ErrorMessage[0] = 0;
+ strcpy(cp->ExitExceptionString, "No exception");
/* Allocate process information for each process. */
cp->ProcessInformation =
@@ -2070,3 +2058,73 @@ kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime
out.QuadPart = in1.QuadPart - in2.QuadPart;
return out;
}
+
+/*--------------------------------------------------------------------------*/
+#define KWSYSPE_CASE(type, str) \
+ cp->ExitException = kwsysProcess_Exception_##type; \
+ strcpy(cp->ExitExceptionString, str)
+static void kwsysProcessSetExitException(kwsysProcess* cp, int code)
+{
+ switch (code)
+ {
+ case STATUS_CONTROL_C_EXIT:
+ KWSYSPE_CASE(Interrupt, "User interrupt"); break;
+
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (denormal operand)"); break;
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ KWSYSPE_CASE(Numerical, "Divide-by-zero"); break;
+ case STATUS_FLOAT_INEXACT_RESULT:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (inexact result)"); break;
+ case STATUS_FLOAT_INVALID_OPERATION:
+ KWSYSPE_CASE(Numerical, "Invalid floating-point operation"); break;
+ case STATUS_FLOAT_OVERFLOW:
+ KWSYSPE_CASE(Numerical, "Floating-point overflow"); break;
+ case STATUS_FLOAT_STACK_CHECK:
+ KWSYSPE_CASE(Numerical, "Floating-point stack check failed"); break;
+ case STATUS_FLOAT_UNDERFLOW:
+ KWSYSPE_CASE(Numerical, "Floating-point underflow"); break;
+#ifdef STATUS_FLOAT_MULTIPLE_FAULTS
+ case STATUS_FLOAT_MULTIPLE_FAULTS:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (multiple faults)"); break;
+#endif
+#ifdef STATUS_FLOAT_MULTIPLE_TRAPS
+ case STATUS_FLOAT_MULTIPLE_TRAPS:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (multiple traps)"); break;
+#endif
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ KWSYSPE_CASE(Numerical, "Integer divide-by-zero"); break;
+ case STATUS_INTEGER_OVERFLOW:
+ KWSYSPE_CASE(Numerical, "Integer overflow"); break;
+
+ case STATUS_DATATYPE_MISALIGNMENT:
+ KWSYSPE_CASE(Fault, "Datatype misalignment"); break;
+ case STATUS_ACCESS_VIOLATION:
+ KWSYSPE_CASE(Fault, "Access violation"); break;
+ case STATUS_IN_PAGE_ERROR:
+ KWSYSPE_CASE(Fault, "In-page error"); break;
+ case STATUS_INVALID_HANDLE:
+ KWSYSPE_CASE(Fault, "Invalid hanlde"); break;
+ case STATUS_NONCONTINUABLE_EXCEPTION:
+ KWSYSPE_CASE(Fault, "Noncontinuable exception"); break;
+ case STATUS_INVALID_DISPOSITION:
+ KWSYSPE_CASE(Fault, "Invalid disposition"); break;
+ case STATUS_ARRAY_BOUNDS_EXCEEDED:
+ KWSYSPE_CASE(Fault, "Array bounds exceeded"); break;
+ case STATUS_STACK_OVERFLOW:
+ KWSYSPE_CASE(Fault, "Stack overflow"); break;
+
+ case STATUS_ILLEGAL_INSTRUCTION:
+ KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
+ case STATUS_PRIVILEGED_INSTRUCTION:
+ KWSYSPE_CASE(Illegal, "Privileged instruction"); break;
+
+ case STATUS_NO_MEMORY:
+ default:
+ cp->ExitException = kwsysProcess_Exception_Other;
+ sprintf(cp->ExitExceptionString, "Exit code 0x%x\n", code);
+ break;
+ }
+}
+#undef KWSYSPE_CASE
+
diff --git a/Source/kwsys/test1.cxx b/Source/kwsys/test1.cxx
index 4c1def5..840253f 100644
--- a/Source/kwsys/test1.cxx
+++ b/Source/kwsys/test1.cxx
@@ -28,6 +28,15 @@ int main()
{
kwsys_ios::cout.write(data, length);
}
+ kwsysProcess_WaitForExit(kp, 0);
+ if(kwsysProcess_GetState(kp) == kwsysProcess_State_Error)
+ {
+ kwsys_ios::cout << kwsysProcess_GetErrorString(kp) << kwsys_ios::endl;
+ }
+ else if(kwsysProcess_GetState(kp) == kwsysProcess_State_Exception)
+ {
+ kwsys_ios::cout << kwsysProcess_GetExceptionString(kp) << kwsys_ios::endl;
+ }
kwsysProcess_Delete(kp);
kwsys_ios::cout << kwsys_ios::endl;
return 0;