diff options
-rw-r--r-- | Source/kwsys/testProcess.c | 115 |
1 files changed, 83 insertions, 32 deletions
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c index 36222b9..f87f1e0 100644 --- a/Source/kwsys/testProcess.c +++ b/Source/kwsys/testProcess.c @@ -32,7 +32,7 @@ int runChild(const char* cmd[], int state, int exception, int value, int share, int output, int delay, double timeout, int poll, - int repeat); + int repeat, int disown); int test1(int argc, const char* argv[]) { @@ -84,14 +84,6 @@ int test4(int argc, const char* argv[]) return 0; } -/* Quick hack to test grandchild killing. */ -/*#define TEST5_GRANDCHILD_KILL*/ -#ifdef TEST5_GRANDCHILD_KILL -# define TEST5_TIMEOUT 10 -#else -# define TEST5_TIMEOUT 30 -#endif - int test5(int argc, const char* argv[]) { int r; @@ -99,18 +91,14 @@ int test5(int argc, const char* argv[]) (void)argc; cmd[0] = argv[0]; cmd[1] = "run"; -#ifdef TEST5_GRANDCHILD_KILL - cmd[2] = "3"; -#else cmd[2] = "4"; -#endif cmd[3] = 0; fprintf(stdout, "Output on stdout before recursive test.\n"); fprintf(stderr, "Output on stderr before recursive test.\n"); fflush(stdout); fflush(stderr); r = runChild(cmd, kwsysProcess_State_Exception, - kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1); + kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0); fprintf(stdout, "Output on stdout after recursive test.\n"); fprintf(stderr, "Output on stderr after recursive test.\n"); fflush(stdout); @@ -163,10 +151,56 @@ int test7(int argc, const char* argv[]) return 0; } +int test8(int argc, const char* argv[]) +{ + /* Create a disowned grandchild to test handling of processes + that exit before their children. */ + int r; + const char* cmd[4]; + (void)argc; + cmd[0] = argv[0]; + cmd[1] = "run"; + cmd[2] = "108"; + cmd[3] = 0; + fprintf(stdout, "Output on stdout before grandchild test.\n"); + fprintf(stderr, "Output on stderr before grandchild test.\n"); + fflush(stdout); + fflush(stderr); + r = runChild(cmd, kwsysProcess_State_Disowned, kwsysProcess_Exception_None, + 1, 1, 1, 0, 10, 0, 1, 1); + fprintf(stdout, "Output on stdout after grandchild test.\n"); + fprintf(stderr, "Output on stderr after grandchild test.\n"); + fflush(stdout); + fflush(stderr); + return r; +} + +int test8_grandchild(int argc, const char* argv[]) +{ + (void)argc; (void)argv; + fprintf(stdout, "Output on stdout from grandchild before sleep.\n"); + fprintf(stderr, "Output on stderr from grandchild before sleep.\n"); + fflush(stdout); + fflush(stderr); + /* TODO: Instead of closing pipes here leave them open to make sure + the grandparent can stop listening when the parent exits. This + part of the test cannot be enabled until the feature is + implemented. */ + fclose(stdout); + fclose(stderr); +#if defined(_WIN32) + Sleep(15000); +#else + sleep(15); +#endif + return 0; +} + + int runChild2(kwsysProcess* kp, const char* cmd[], int state, int exception, int value, int share, int output, int delay, double timeout, - int poll) + int poll, int disown) { int result = 0; char* data = 0; @@ -183,6 +217,10 @@ int runChild2(kwsysProcess* kp, kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDOUT, 1); kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDERR, 1); } + if(disown) + { + kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1); + } kwsysProcess_Execute(kp); if(poll) @@ -190,7 +228,7 @@ int runChild2(kwsysProcess* kp, pUserTimeout = &userTimeout; } - if(!share) + if(!share && !disown) { int p; while((p = kwsysProcess_WaitForData(kp, &data, &length, pUserTimeout))) @@ -235,8 +273,15 @@ int runChild2(kwsysProcess* kp, } } } - - kwsysProcess_WaitForExit(kp, 0); + + if(disown) + { + kwsysProcess_Disown(kp); + } + else + { + kwsysProcess_WaitForExit(kp, 0); + } switch (kwsysProcess_GetState(kp)) { @@ -258,6 +303,8 @@ int runChild2(kwsysProcess* kp, kwsysProcess_GetExceptionString(kp)); result = ((exception != kwsysProcess_GetExitException(kp)) || (value != kwsysProcess_GetExitValue(kp))); break; + case kwsysProcess_State_Disowned: + printf("Child was disowned.\n"); break; case kwsysProcess_State_Error: printf("Error in administrating child process: [%s]\n", kwsysProcess_GetErrorString(kp)); break; @@ -301,7 +348,7 @@ int runChild2(kwsysProcess* kp, int runChild(const char* cmd[], int state, int exception, int value, int share, int output, int delay, double timeout, - int poll, int repeat) + int poll, int repeat, int disown) { int result = 1; kwsysProcess* kp = kwsysProcess_New(); @@ -313,7 +360,7 @@ int runChild(const char* cmd[], int state, int exception, int value, while(repeat-- > 0) { result = runChild2(kp, cmd, state, exception, value, share, - output, delay, timeout, poll); + output, delay, timeout, poll, disown); } kwsysProcess_Delete(kp); return result; @@ -347,7 +394,7 @@ int main(int argc, const char* argv[]) n = atoi(argv[2]); } /* Check arguments. */ - if(n >= 1 && n <= 7 && argc == 3) + if(((n >= 1 && n <= 8) || n == 108) && argc == 3) { /* This is the child process for a requested test number. */ switch (n) @@ -359,14 +406,16 @@ int main(int argc, const char* argv[]) case 5: return test5(argc, argv); case 6: test6(argc, argv); return 0; case 7: return test7(argc, argv); + case 8: return test8(argc, argv); + case 108: return test8_grandchild(argc, argv); } fprintf(stderr, "Invalid test number %d.\n", n); return 1; } - else if(n >= 1 && n <= 7) + else if(n >= 1 && n <= 8) { /* This is the parent process for a requested test number. */ - int states[7] = + int states[8] = { kwsysProcess_State_Exited, kwsysProcess_State_Exited, @@ -374,9 +423,10 @@ int main(int argc, const char* argv[]) kwsysProcess_State_Exception, kwsysProcess_State_Exited, kwsysProcess_State_Expired, + kwsysProcess_State_Exited, kwsysProcess_State_Exited }; - int exceptions[7] = + int exceptions[8] = { kwsysProcess_Exception_None, kwsysProcess_Exception_None, @@ -384,14 +434,15 @@ int main(int argc, const char* argv[]) kwsysProcess_Exception_Fault, kwsysProcess_Exception_None, kwsysProcess_Exception_None, + kwsysProcess_Exception_None, kwsysProcess_Exception_None }; - int values[7] = {0, 123, 1, 1, 0, 0, 0}; - int outputs[7] = {1, 1, 1, 1, 1, 0, 1}; - int delays[7] = {0, 0, 0, 0, 0, 1, 0}; - double timeouts[7] = {10, 10, 10, 10, TEST5_TIMEOUT, 10, -1}; - int polls[7] = {0, 0, 0, 0, 0, 0, 1}; - int repeat[7] = {2, 1, 1, 1, 1, 1, 1}; + int values[8] = {0, 123, 1, 1, 0, 0, 0, 0}; + int outputs[8] = {1, 1, 1, 1, 1, 0, 1, 1}; + int delays[8] = {0, 0, 0, 0, 0, 1, 0, 0}; + double timeouts[8] = {10, 10, 10, 10, 30, 10, -1, 10}; + int polls[8] = {0, 0, 0, 0, 0, 0, 1, 0}; + int repeat[8] = {2, 1, 1, 1, 1, 1, 1, 1}; int r; const char* cmd[4]; #ifdef _WIN32 @@ -425,7 +476,7 @@ int main(int argc, const char* argv[]) fflush(stderr); r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], 0, outputs[n-1], delays[n-1], timeouts[n-1], - polls[n-1], repeat[n-1]); + polls[n-1], repeat[n-1], 0); fprintf(stdout, "Output on stdout after test %d.\n", n); fprintf(stderr, "Output on stderr after test %d.\n", n); fflush(stdout); @@ -444,7 +495,7 @@ int main(int argc, const char* argv[]) int exception = kwsysProcess_Exception_None; int value = 0; double timeout = 0; - int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1); + int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0); return r; } else |