Commit b7eba998 authored by Adam Weisi's avatar Adam Weisi Committed by Brad King
Browse files

Process: Add APIs to get results of individual processes

When running a pipeline of child processes, provide clients a way
to get individual results.
parent 7d56ef24
......@@ -56,6 +56,14 @@
#define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
#define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
#define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
#define kwsysProcess_GetStateByIndex kwsys_ns(Process_GetStateByIndex)
#define kwsysProcess_GetExitExceptionByIndex \
kwsys_ns(Process_GetExitExceptionByIndex)
#define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex)
#define kwsysProcess_GetExitValueByIndex kwsys_ns(Process_GetExitValueByIndex)
#define kwsysProcess_GetExceptionStringByIndex \
kwsys_ns(Process_GetExceptionStringByIndex)
#define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex)
#define kwsysProcess_Execute kwsys_ns(Process_Execute)
#define kwsysProcess_Disown kwsys_ns(Process_Disown)
#define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
......@@ -297,6 +305,67 @@ kwsysEXPORT const char* kwsysProcess_GetErrorString(kwsysProcess* cp);
*/
kwsysEXPORT const char* kwsysProcess_GetExceptionString(kwsysProcess* cp);
/**
* Get the current state of the Process instance. Possible states are:
*
* kwsysProcess_StateByIndex_Starting = Execute has not yet been called.
* kwsysProcess_StateByIndex_Exception = Child process exited abnormally.
* kwsysProcess_StateByIndex_Exited = Child process exited normally.
* kwsysProcess_StateByIndex_Error = Error getting the child return code.
*/
kwsysEXPORT int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx);
enum kwsysProcess_StateByIndex_e
{
kwsysProcess_StateByIndex_Starting = kwsysProcess_State_Starting,
kwsysProcess_StateByIndex_Exception = kwsysProcess_State_Exception,
kwsysProcess_StateByIndex_Exited = kwsysProcess_State_Exited,
kwsysProcess_StateByIndex_Error = kwsysProcess_State_Error
};
/**
* When GetState returns "Exception", this method returns a
* platform-independent description of the exceptional behavior that
* caused the child to terminate abnormally. Possible exceptions are:
*
* kwsysProcess_Exception_None = No exceptional behavior occurred.
* kwsysProcess_Exception_Fault = Child crashed with a memory fault.
* kwsysProcess_Exception_Illegal = Child crashed with an illegal
* instruction.
* kwsysProcess_Exception_Interrupt = Child was interrupted by user
* (Cntl-C/Break).
* kwsysProcess_Exception_Numerical = Child crashed with a numerical
* exception.
* kwsysProcess_Exception_Other = Child terminated for another reason.
*/
kwsysEXPORT int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp,
int idx);
/**
* When GetState returns "Exited" or "Exception", this method returns
* the platform-specific raw exit code of the process. UNIX platforms
* should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access
* this value. Windows users should compare the value to the various
* EXCEPTION_* values.
*
* If GetState returns "Exited", use GetExitValue to get the
* platform-independent child return value.
*/
kwsysEXPORT int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx);
/**
* When GetState returns "Exited", this method returns the child's
* platform-independent exit code (such as the value returned by the
* child's main).
*/
kwsysEXPORT int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx);
/**
* When GetState returns "Exception", this method returns a string
* describing the problem. Otherwise, it returns NULL.
*/
kwsysEXPORT const char* kwsysProcess_GetExceptionStringByIndex(
kwsysProcess* cp, int idx);
/**
* Start executing the child process.
*/
......
......@@ -703,6 +703,48 @@ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
return "No exception";
}
/* the index should be in array bound. */
#define KWSYSPE_IDX_CHK(RET) \
if (!cp || idx >= cp->NumberOfCommands || idx < 0) { \
return RET; \
}
int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(kwsysProcess_State_Error)
return cp->ProcessResults[idx].State;
}
int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(kwsysProcess_Exception_Other)
return cp->ProcessResults[idx].ExitException;
}
int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(-1)
return cp->ProcessResults[idx].ExitValue;
}
int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(-1)
return cp->CommandExitCodes[idx];
}
const char* kwsysProcess_GetExceptionStringByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK("GetExceptionString called with NULL process management "
"structure or index out of bound")
if (cp->ProcessResults[idx].State == kwsysProcess_StateByIndex_Exception) {
return cp->ProcessResults[idx].ExitExceptionString;
}
return "No exception";
}
#undef KWSYSPE_IDX_CHK
void kwsysProcess_Execute(kwsysProcess* cp)
{
int i;
......@@ -1324,7 +1366,7 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
cp->ProcessResults[prPipe].ExitCode = cp->CommandExitCodes[prPipe];
if (WIFEXITED(cp->ProcessResults[prPipe].ExitCode)) {
/* The child exited normally. */
cp->ProcessResults[prPipe].State = kwsysProcess_State_Exited;
cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Exited;
cp->ProcessResults[prPipe].ExitException = kwsysProcess_Exception_None;
cp->ProcessResults[prPipe].ExitValue =
(int)WEXITSTATUS(cp->ProcessResults[prPipe].ExitCode);
......@@ -1337,7 +1379,7 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
/* Error getting the child return code. */
strcpy(cp->ProcessResults[prPipe].ExitExceptionString,
"Error getting child return code.");
cp->ProcessResults[prPipe].State = kwsysProcess_State_Error;
cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Error;
}
}
/* support legacy state status value */
......@@ -1503,7 +1545,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
sizeof(kwsysProcessResults) * (size_t)(cp->NumberOfCommands));
for (i = 0; i < cp->NumberOfCommands; i++) {
cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None;
cp->ProcessResults[i].State = kwsysProcess_State_Starting;
cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Starting;
cp->ProcessResults[i].ExitCode = 1;
cp->ProcessResults[i].ExitValue = 1;
strcpy(cp->ProcessResults[i].ExitExceptionString, "No exception");
......
......@@ -892,6 +892,49 @@ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
return "No exception";
}
/* the index should be in array bound. */
#define KWSYSPE_IDX_CHK(RET) \
if (!cp || idx >= cp->NumberOfCommands || idx < 0) { \
KWSYSPE_DEBUG((stderr, "array index out of bound\n")); \
return RET; \
}
int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(kwsysProcess_State_Error)
return cp->ProcessResults[idx].State;
}
int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(kwsysProcess_Exception_Other)
return cp->ProcessResults[idx].ExitException;
}
int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(-1)
return cp->ProcessResults[idx].ExitValue;
}
int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK(-1)
return cp->CommandExitCodes[idx];
}
const char* kwsysProcess_GetExceptionStringByIndex(kwsysProcess* cp, int idx)
{
KWSYSPE_IDX_CHK("GetExceptionString called with NULL process management "
"structure or index out of bound")
if (cp->ProcessResults[idx].State == kwsysProcess_StateByIndex_Exception) {
return cp->ProcessResults[idx].ExitExceptionString;
}
return "No exception";
}
#undef KWSYSPE_IDX_CHK
void kwsysProcess_Execute(kwsysProcess* cp)
{
int i;
......@@ -1337,13 +1380,13 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
cp->ProcessResults[i].ExitCode = cp->CommandExitCodes[i];
if ((cp->ProcessResults[i].ExitCode & 0xF0000000) == 0xC0000000) {
/* Child terminated due to exceptional behavior. */
cp->ProcessResults[i].State = kwsysProcess_State_Exception;
cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exception;
cp->ProcessResults[i].ExitValue = 1;
kwsysProcessSetExitExceptionByIndex(cp, cp->ProcessResults[i].ExitCode,
i);
} else {
/* Child exited without exception. */
cp->ProcessResults[i].State = kwsysProcess_State_Exited;
cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exited;
cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None;
cp->ProcessResults[i].ExitValue = cp->ProcessResults[i].ExitCode;
}
......@@ -1549,7 +1592,7 @@ int kwsysProcessInitialize(kwsysProcess* cp)
sizeof(kwsysProcessResults) * cp->NumberOfCommands);
for (i = 0; i < cp->NumberOfCommands; i++) {
cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None;
cp->ProcessResults[i].State = kwsysProcess_State_Starting;
cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Starting;
cp->ProcessResults[i].ExitCode = 1;
cp->ProcessResults[i].ExitValue = 1;
strcpy(cp->ProcessResults[i].ExitExceptionString, "No exception");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment