testProcess.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*=========================================================================
  2. Program: KWSys - Kitware System Library
  3. Module: $RCSfile$
  4. Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
  5. See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  8. PURPOSE. See the above copyright notices for more information.
  9. =========================================================================*/
  10. #include <kwsys/Process.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #if defined(_WIN32)
  14. # include <windows.h>
  15. #else
  16. # include <unistd.h>
  17. #endif
  18. int runChild(const char* cmd[], int state, int exception, int value,
  19. int share, double timeout);
  20. int test1(int argc, const char* argv[])
  21. {
  22. (void)argc; (void)argv;
  23. fprintf(stdout, "Output on stdout from test returning 0.\n");
  24. fprintf(stderr, "Output on stderr from test returning 0.\n");
  25. return 0;
  26. }
  27. int test2(int argc, const char* argv[])
  28. {
  29. (void)argc; (void)argv;
  30. fprintf(stdout, "Output on stdout from test returning 123.\n");
  31. fprintf(stderr, "Output on stderr from test returning 123.\n");
  32. return 123;
  33. }
  34. int test3(int argc, const char* argv[])
  35. {
  36. (void)argc; (void)argv;
  37. fprintf(stdout, "Output before sleep on stdout from timeout test.\n");
  38. fprintf(stderr, "Output before sleep on stderr from timeout test.\n");
  39. fflush(stdout);
  40. fflush(stderr);
  41. #if defined(_WIN32)
  42. Sleep(5000);
  43. #else
  44. sleep(5);
  45. #endif
  46. fprintf(stdout, "Output after sleep on stdout from timeout test.\n");
  47. fprintf(stderr, "Output after sleep on stderr from timeout test.\n");
  48. return 0;
  49. }
  50. int test4(int argc, const char* argv[])
  51. {
  52. (void)argc; (void)argv;
  53. fprintf(stdout, "Output before crash on stdout from crash test.\n");
  54. fprintf(stderr, "Output before crash on stderr from crash test.\n");
  55. fflush(stdout);
  56. fflush(stderr);
  57. *(int*)0 = 0;
  58. fprintf(stdout, "Output after crash on stdout from crash test.\n");
  59. fprintf(stderr, "Output after crash on stderr from crash test.\n");
  60. return 0;
  61. }
  62. int test5(int argc, const char* argv[])
  63. {
  64. int r;
  65. const char* cmd[4];
  66. (void)argc;
  67. cmd[0] = argv[0];
  68. cmd[1] = "run";
  69. cmd[2] = "4";
  70. cmd[3] = 0;
  71. fprintf(stdout, "Output on stdout before recursive test.\n");
  72. fprintf(stderr, "Output on stderr before recursive test.\n");
  73. fflush(stdout);
  74. fflush(stderr);
  75. r = runChild(cmd, kwsysProcess_State_Exception,
  76. kwsysProcess_Exception_Fault, 1, 1, 2);
  77. fprintf(stdout, "Output on stdout after recursive test.\n");
  78. fprintf(stderr, "Output on stderr after recursive test.\n");
  79. fflush(stdout);
  80. fflush(stderr);
  81. return r;
  82. }
  83. int runChild(const char* cmd[], int state, int exception, int value,
  84. int share, double timeout)
  85. {
  86. int result = 0;
  87. char* data = 0;
  88. int length = 0;
  89. kwsysProcess* kp = kwsysProcess_New();
  90. if(!kp)
  91. {
  92. fprintf(stderr, "kwsysProcess_New returned NULL!\n");
  93. return 1;
  94. }
  95. kwsysProcess_SetCommand(kp, cmd);
  96. kwsysProcess_SetTimeout(kp, timeout);
  97. if(share)
  98. {
  99. kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDOUT, 1);
  100. kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDERR, 1);
  101. }
  102. kwsysProcess_Execute(kp);
  103. if(!share)
  104. {
  105. while(kwsysProcess_WaitForData(kp, &data, &length, 0))
  106. {
  107. fwrite(data, 1, length, stdout);
  108. fflush(stdout);
  109. }
  110. }
  111. kwsysProcess_WaitForExit(kp, 0);
  112. switch (kwsysProcess_GetState(kp))
  113. {
  114. case kwsysProcess_State_Starting:
  115. printf("No process has been executed.\n"); break;
  116. case kwsysProcess_State_Executing:
  117. printf("The process is still executing.\n"); break;
  118. case kwsysProcess_State_Expired:
  119. printf("Child was killed when timeout expired.\n"); break;
  120. case kwsysProcess_State_Exited:
  121. printf("Child exited with value = %d\n",
  122. kwsysProcess_GetExitValue(kp));
  123. result = ((exception != kwsysProcess_GetExitException(kp)) ||
  124. (value != kwsysProcess_GetExitValue(kp))); break;
  125. case kwsysProcess_State_Killed:
  126. printf("Child was killed by parent.\n"); break;
  127. case kwsysProcess_State_Exception:
  128. printf("Child terminated abnormally: %s\n",
  129. kwsysProcess_GetExceptionString(kp));
  130. result = ((exception != kwsysProcess_GetExitException(kp)) ||
  131. (value != kwsysProcess_GetExitValue(kp))); break;
  132. case kwsysProcess_State_Error:
  133. printf("Error in administrating child process: [%s]\n",
  134. kwsysProcess_GetErrorString(kp)); break;
  135. };
  136. if(result)
  137. {
  138. if(exception != kwsysProcess_GetExitException(kp))
  139. {
  140. fprintf(stderr, "Mismatch in exit exception. Should have been %d.\n",
  141. exception);
  142. }
  143. if(value != kwsysProcess_GetExitValue(kp))
  144. {
  145. fprintf(stderr, "Mismatch in exit value. Should have been %d.\n",
  146. value);
  147. }
  148. }
  149. if(kwsysProcess_GetState(kp) != state)
  150. {
  151. fprintf(stderr, "Mismatch in state. Should have been %d.\n", state);
  152. result = 1;
  153. }
  154. kwsysProcess_Delete(kp);
  155. return result;
  156. }
  157. int main(int argc, const char* argv[])
  158. {
  159. int n = 0;
  160. #if 0
  161. {
  162. HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
  163. DuplicateHandle(GetCurrentProcess(), out,
  164. GetCurrentProcess(), &out, 0, FALSE,
  165. DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
  166. SetStdHandle(STD_OUTPUT_HANDLE, out);
  167. }
  168. {
  169. HANDLE out = GetStdHandle(STD_ERROR_HANDLE);
  170. DuplicateHandle(GetCurrentProcess(), out,
  171. GetCurrentProcess(), &out, 0, FALSE,
  172. DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
  173. SetStdHandle(STD_ERROR_HANDLE, out);
  174. }
  175. #endif
  176. if(argc == 2)
  177. {
  178. n = atoi(argv[1]);
  179. }
  180. else if(argc == 3)
  181. {
  182. n = atoi(argv[2]);
  183. }
  184. /* Check arguments. */
  185. if(n < 1 || n > 5 || (argc == 3 && strcmp(argv[1], "run") != 0))
  186. {
  187. fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
  188. return 1;
  189. }
  190. if(argc == 3)
  191. {
  192. switch (n)
  193. {
  194. case 1: return test1(argc, argv);
  195. case 2: return test2(argc, argv);
  196. case 3: return test3(argc, argv);
  197. case 4: return test4(argc, argv);
  198. case 5: return test5(argc, argv);
  199. }
  200. fprintf(stderr, "Invalid test number %d.\n", n);
  201. return 1;
  202. }
  203. if(n >= 0 && n <= 5)
  204. {
  205. int states[5] =
  206. {
  207. kwsysProcess_State_Exited,
  208. kwsysProcess_State_Exited,
  209. kwsysProcess_State_Expired,
  210. kwsysProcess_State_Exception,
  211. kwsysProcess_State_Exited
  212. };
  213. int exceptions[5] =
  214. {
  215. kwsysProcess_Exception_None,
  216. kwsysProcess_Exception_None,
  217. kwsysProcess_Exception_None,
  218. kwsysProcess_Exception_Fault,
  219. kwsysProcess_Exception_None
  220. };
  221. int values[5] = {0, 123, 1, 1, 0};
  222. int r;
  223. const char* cmd[4];
  224. cmd[0] = argv[0];
  225. cmd[1] = "run";
  226. cmd[2] = argv[1];
  227. cmd[3] = 0;
  228. fprintf(stdout, "Output on stdout before test %d.\n", n);
  229. fprintf(stderr, "Output on stderr before test %d.\n", n);
  230. fflush(stdout);
  231. fflush(stderr);
  232. r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], 0, 3);
  233. fprintf(stdout, "Output on stdout after test %d.\n", n);
  234. fprintf(stderr, "Output on stderr after test %d.\n", n);
  235. fflush(stdout);
  236. fflush(stderr);
  237. return r;
  238. }
  239. else
  240. {
  241. fprintf(stderr, "Test number out of range\n");
  242. return 1;
  243. }
  244. }