1/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ 3#ifndef @KWSYS_NAMESPACE@_Process_h 4#define @KWSYS_NAMESPACE@_Process_h 5 6#include <@KWSYS_NAMESPACE@/Configure.h> 7 8/* Redefine all public interface symbol names to be in the proper 9 namespace. These macros are used internally to kwsys only, and are 10 not visible to user code. Use kwsysHeaderDump.pl to reproduce 11 these macros after making changes to the interface. */ 12#if !defined(KWSYS_NAMESPACE) 13# define kwsys_ns(x) @KWSYS_NAMESPACE@##x 14# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT 15#endif 16#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS 17# define kwsysProcess kwsys_ns(Process) 18# define kwsysProcess_s kwsys_ns(Process_s) 19# define kwsysProcess_New kwsys_ns(Process_New) 20# define kwsysProcess_Delete kwsys_ns(Process_Delete) 21# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand) 22# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand) 23# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout) 24# define kwsysProcess_SetWorkingDirectory \ 25 kwsys_ns(Process_SetWorkingDirectory) 26# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile) 27# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative) 28# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared) 29# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach) 30# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow) 31# define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput) 32# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim) 33# define kwsysProcess_Option_CreateProcessGroup \ 34 kwsys_ns(Process_Option_CreateProcessGroup) 35# define kwsysProcess_GetOption kwsys_ns(Process_GetOption) 36# define kwsysProcess_SetOption kwsys_ns(Process_SetOption) 37# define kwsysProcess_Option_e kwsys_ns(Process_Option_e) 38# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting) 39# define kwsysProcess_State_Error kwsys_ns(Process_State_Error) 40# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception) 41# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing) 42# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited) 43# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired) 44# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed) 45# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned) 46# define kwsysProcess_State_e kwsys_ns(Process_State_e) 47# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None) 48# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault) 49# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal) 50# define kwsysProcess_Exception_Interrupt \ 51 kwsys_ns(Process_Exception_Interrupt) 52# define kwsysProcess_Exception_Numerical \ 53 kwsys_ns(Process_Exception_Numerical) 54# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other) 55# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e) 56# define kwsysProcess_GetState kwsys_ns(Process_GetState) 57# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException) 58# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode) 59# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue) 60# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString) 61# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString) 62# define kwsysProcess_GetStateByIndex kwsys_ns(Process_GetStateByIndex) 63# define kwsysProcess_GetExitExceptionByIndex \ 64 kwsys_ns(Process_GetExitExceptionByIndex) 65# define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex) 66# define kwsysProcess_GetExitValueByIndex \ 67 kwsys_ns(Process_GetExitValueByIndex) 68# define kwsysProcess_GetExceptionStringByIndex \ 69 kwsys_ns(Process_GetExceptionStringByIndex) 70# define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex) 71# define kwsysProcess_Execute kwsys_ns(Process_Execute) 72# define kwsysProcess_Disown kwsys_ns(Process_Disown) 73# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData) 74# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e) 75# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None) 76# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN) 77# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT) 78# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR) 79# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout) 80# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle) 81# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit) 82# define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt) 83# define kwsysProcess_Kill kwsys_ns(Process_Kill) 84# define kwsysProcess_KillPID kwsys_ns(Process_KillPID) 85# define kwsysProcess_ResetStartTime kwsys_ns(Process_ResetStartTime) 86#endif 87 88#if defined(__cplusplus) 89extern "C" { 90#endif 91 92/** 93 * Process control data structure. 94 */ 95typedef struct kwsysProcess_s kwsysProcess; 96 97/* Platform-specific pipe handle type. */ 98#if defined(_WIN32) && !defined(__CYGWIN__) 99typedef void* kwsysProcess_Pipe_Handle; 100#else 101typedef int kwsysProcess_Pipe_Handle; 102#endif 103 104/** 105 * Create a new Process instance. 106 */ 107kwsysEXPORT kwsysProcess* kwsysProcess_New(void); 108 109/** 110 * Delete an existing Process instance. If the instance is currently 111 * executing a process, this blocks until the process terminates. 112 */ 113kwsysEXPORT void kwsysProcess_Delete(kwsysProcess* cp); 114 115/** 116 * Set the command line to be executed. Argument is an array of 117 * pointers to the command and each argument. The array must end with 118 * a NULL pointer. Any previous command lines are removed. Returns 119 * 1 for success and 0 otherwise. 120 */ 121kwsysEXPORT int kwsysProcess_SetCommand(kwsysProcess* cp, 122 char const* const* command); 123 124/** 125 * Add a command line to be executed. Argument is an array of 126 * pointers to the command and each argument. The array must end with 127 * a NULL pointer. If this is not the first command added, its 128 * standard input will be connected to the standard output of the 129 * previous command. Returns 1 for success and 0 otherwise. 130 */ 131kwsysEXPORT int kwsysProcess_AddCommand(kwsysProcess* cp, 132 char const* const* command); 133 134/** 135 * Set the timeout in seconds for the child process. The timeout 136 * period begins when the child is executed. If the child has not 137 * terminated when the timeout expires, it will be killed. A 138 * non-positive (<= 0) value will disable the timeout. 139 */ 140kwsysEXPORT void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout); 141 142/** 143 * Set the working directory for the child process. The working 144 * directory can be absolute or relative to the current directory. 145 * Returns 1 for success and 0 for failure. 146 */ 147kwsysEXPORT int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, 148 const char* dir); 149 150/** 151 * Set the name of a file to be attached to the given pipe. Returns 1 152 * for success and 0 for failure. 153 */ 154kwsysEXPORT int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, 155 const char* file); 156 157/** 158 * Set whether the given pipe in the child is shared with the parent 159 * process. The default is no for Pipe_STDOUT and Pipe_STDERR and yes 160 * for Pipe_STDIN. 161 */ 162kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, 163 int shared); 164 165/** 166 * Specify a platform-specific native pipe for use as one of the child 167 * interface pipes. The native pipe is specified by an array of two 168 * descriptors or handles. The first entry in the array (index 0) 169 * should be the read end of the pipe. The second entry in the array 170 * (index 1) should be the write end of the pipe. If a null pointer 171 * is given the option will be disabled. 172 * 173 * For Pipe_STDIN the native pipe is connected to the first child in 174 * the pipeline as its stdin. After the children are created the 175 * write end of the pipe will be closed in the child process and the 176 * read end will be closed in the parent process. 177 * 178 * For Pipe_STDOUT and Pipe_STDERR the pipe is connected to the last 179 * child as its stdout or stderr. After the children are created the 180 * write end of the pipe will be closed in the parent process and the 181 * read end will be closed in the child process. 182 */ 183kwsysEXPORT void kwsysProcess_SetPipeNative( 184 kwsysProcess* cp, int pipe, const kwsysProcess_Pipe_Handle p[2]); 185 186/** 187 * Get/Set a possibly platform-specific option. Possible options are: 188 * 189 * kwsysProcess_Option_Detach = Whether to detach the process. 190 * 0 = No (default) 191 * 1 = Yes 192 * 193 * kwsysProcess_Option_HideWindow = Whether to hide window on Windows. 194 * 0 = No (default) 195 * 1 = Yes 196 * 197 * kwsysProcess_Option_MergeOutput = Whether to merge stdout/stderr. 198 * No content will be returned as stderr. 199 * Any actual stderr will be on stdout. 200 * 0 = No (default) 201 * 1 = Yes 202 * 203 * kwsysProcess_Option_Verbatim = Whether SetCommand and AddCommand 204 * should treat the first argument 205 * as a verbatim command line 206 * and ignore the rest of the arguments. 207 * 0 = No (default) 208 * 1 = Yes 209 * 210 * kwsysProcess_Option_CreateProcessGroup = Whether to place the process in a 211 * new process group. This is 212 * useful if you want to send Ctrl+C 213 * to the process. On UNIX, also 214 * places the process in a new 215 * session. 216 * 0 = No (default) 217 * 1 = Yes 218 */ 219kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId); 220kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, 221 int value); 222enum kwsysProcess_Option_e 223{ 224 kwsysProcess_Option_HideWindow, 225 kwsysProcess_Option_Detach, 226 kwsysProcess_Option_MergeOutput, 227 kwsysProcess_Option_Verbatim, 228 kwsysProcess_Option_CreateProcessGroup 229}; 230 231/** 232 * Get the current state of the Process instance. Possible states are: 233 * 234 * kwsysProcess_State_Starting = Execute has not yet been called. 235 * kwsysProcess_State_Error = Error administrating the child process. 236 * kwsysProcess_State_Exception = Child process exited abnormally. 237 * kwsysProcess_State_Executing = Child process is currently running. 238 * kwsysProcess_State_Exited = Child process exited normally. 239 * kwsysProcess_State_Expired = Child process's timeout expired. 240 * kwsysProcess_State_Killed = Child process terminated by Kill method. 241 * kwsysProcess_State_Disowned = Child is no longer managed by this object. 242 */ 243kwsysEXPORT int kwsysProcess_GetState(kwsysProcess* cp); 244enum kwsysProcess_State_e 245{ 246 kwsysProcess_State_Starting, 247 kwsysProcess_State_Error, 248 kwsysProcess_State_Exception, 249 kwsysProcess_State_Executing, 250 kwsysProcess_State_Exited, 251 kwsysProcess_State_Expired, 252 kwsysProcess_State_Killed, 253 kwsysProcess_State_Disowned 254}; 255 256/** 257 * When GetState returns "Exception", this method returns a 258 * platform-independent description of the exceptional behavior that 259 * caused the child to terminate abnormally. Possible exceptions are: 260 * 261 * kwsysProcess_Exception_None = No exceptional behavior occurred. 262 * kwsysProcess_Exception_Fault = Child crashed with a memory fault. 263 * kwsysProcess_Exception_Illegal = Child crashed with an illegal 264 * instruction. 265 * kwsysProcess_Exception_Interrupt = Child was interrupted by user 266 * (Cntl-C/Break). 267 * kwsysProcess_Exception_Numerical = Child crashed with a numerical 268 * exception. 269 * kwsysProcess_Exception_Other = Child terminated for another reason. 270 */ 271kwsysEXPORT int kwsysProcess_GetExitException(kwsysProcess* cp); 272enum kwsysProcess_Exception_e 273{ 274 kwsysProcess_Exception_None, 275 kwsysProcess_Exception_Fault, 276 kwsysProcess_Exception_Illegal, 277 kwsysProcess_Exception_Interrupt, 278 kwsysProcess_Exception_Numerical, 279 kwsysProcess_Exception_Other 280}; 281 282/** 283 * When GetState returns "Exited" or "Exception", this method returns 284 * the platform-specific raw exit code of the process. UNIX platforms 285 * should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access 286 * this value. Windows users should compare the value to the various 287 * EXCEPTION_* values. 288 * 289 * If GetState returns "Exited", use GetExitValue to get the 290 * platform-independent child return value. 291 */ 292kwsysEXPORT int kwsysProcess_GetExitCode(kwsysProcess* cp); 293 294/** 295 * When GetState returns "Exited", this method returns the child's 296 * platform-independent exit code (such as the value returned by the 297 * child's main). 298 */ 299kwsysEXPORT int kwsysProcess_GetExitValue(kwsysProcess* cp); 300 301/** 302 * When GetState returns "Error", this method returns a string 303 * describing the problem. Otherwise, it returns NULL. 304 */ 305kwsysEXPORT const char* kwsysProcess_GetErrorString(kwsysProcess* cp); 306 307/** 308 * When GetState returns "Exception", this method returns a string 309 * describing the problem. Otherwise, it returns NULL. 310 */ 311kwsysEXPORT const char* kwsysProcess_GetExceptionString(kwsysProcess* cp); 312 313/** 314 * Get the current state of the Process instance. Possible states are: 315 * 316 * kwsysProcess_StateByIndex_Starting = Execute has not yet been called. 317 * kwsysProcess_StateByIndex_Exception = Child process exited abnormally. 318 * kwsysProcess_StateByIndex_Exited = Child process exited normally. 319 * kwsysProcess_StateByIndex_Error = Error getting the child return code. 320 */ 321kwsysEXPORT int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx); 322enum kwsysProcess_StateByIndex_e 323{ 324 kwsysProcess_StateByIndex_Starting = kwsysProcess_State_Starting, 325 kwsysProcess_StateByIndex_Exception = kwsysProcess_State_Exception, 326 kwsysProcess_StateByIndex_Exited = kwsysProcess_State_Exited, 327 kwsysProcess_StateByIndex_Error = kwsysProcess_State_Error 328}; 329 330/** 331 * When GetState returns "Exception", this method returns a 332 * platform-independent description of the exceptional behavior that 333 * caused the child to terminate abnormally. Possible exceptions are: 334 * 335 * kwsysProcess_Exception_None = No exceptional behavior occurred. 336 * kwsysProcess_Exception_Fault = Child crashed with a memory fault. 337 * kwsysProcess_Exception_Illegal = Child crashed with an illegal 338 * instruction. 339 * kwsysProcess_Exception_Interrupt = Child was interrupted by user 340 * (Cntl-C/Break). 341 * kwsysProcess_Exception_Numerical = Child crashed with a numerical 342 * exception. 343 * kwsysProcess_Exception_Other = Child terminated for another reason. 344 */ 345kwsysEXPORT int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, 346 int idx); 347 348/** 349 * When GetState returns "Exited" or "Exception", this method returns 350 * the platform-specific raw exit code of the process. UNIX platforms 351 * should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access 352 * this value. Windows users should compare the value to the various 353 * EXCEPTION_* values. 354 * 355 * If GetState returns "Exited", use GetExitValue to get the 356 * platform-independent child return value. 357 */ 358kwsysEXPORT int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx); 359 360/** 361 * When GetState returns "Exited", this method returns the child's 362 * platform-independent exit code (such as the value returned by the 363 * child's main). 364 */ 365kwsysEXPORT int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx); 366 367/** 368 * When GetState returns "Exception", this method returns a string 369 * describing the problem. Otherwise, it returns NULL. 370 */ 371kwsysEXPORT const char* kwsysProcess_GetExceptionStringByIndex( 372 kwsysProcess* cp, int idx); 373 374/** 375 * Start executing the child process. 376 */ 377kwsysEXPORT void kwsysProcess_Execute(kwsysProcess* cp); 378 379/** 380 * Stop management of a detached child process. This closes any pipes 381 * being read. If the child was not created with the 382 * kwsysProcess_Option_Detach option, this method does nothing. This 383 * is because disowning a non-detached process will cause the child 384 * exit signal to be left unhandled until this process exits. 385 */ 386kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp); 387 388/** 389 * Block until data are available on a pipe, a timeout expires, or the 390 * child process terminates. Arguments are as follows: 391 * 392 * data = If data are read, the pointer to which this points is 393 * set to point to the data. 394 * length = If data are read, the integer to which this points is 395 * set to the length of the data read. 396 * timeout = Specifies the maximum time this call may block. Upon 397 * return after reading data, the time elapsed is subtracted 398 * from the timeout value. If this timeout expires, the 399 * value is set to 0. A NULL pointer passed for this argument 400 * indicates no timeout for the call. A negative or zero 401 * value passed for this argument may be used for polling 402 * and will always return immediately. 403 * 404 * Return value will be one of: 405 * 406 * Pipe_None = No more data will be available from the child process, 407 * ( == 0) or no process has been executed. WaitForExit should 408 * be called to wait for the process to terminate. 409 * Pipe_STDOUT = Data have been read from the child's stdout pipe. 410 * Pipe_STDERR = Data have been read from the child's stderr pipe. 411 * Pipe_Timeout = No data available within timeout specified for the 412 * call. Time elapsed has been subtracted from timeout 413 * argument. 414 */ 415kwsysEXPORT int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, 416 int* length, double* timeout); 417enum kwsysProcess_Pipes_e 418{ 419 kwsysProcess_Pipe_None, 420 kwsysProcess_Pipe_STDIN, 421 kwsysProcess_Pipe_STDOUT, 422 kwsysProcess_Pipe_STDERR, 423 kwsysProcess_Pipe_Timeout = 255 424}; 425 426/** 427 * Block until the child process terminates or the given timeout 428 * expires. If no process is running, returns immediately. The 429 * argument is: 430 * 431 * timeout = Specifies the maximum time this call may block. Upon 432 * returning due to child termination, the elapsed time 433 * is subtracted from the given value. A NULL pointer 434 * passed for this argument indicates no timeout for the 435 * call. 436 * 437 * Return value will be one of: 438 * 439 * 0 = Child did not terminate within timeout specified for 440 * the call. Time elapsed has been subtracted from timeout 441 * argument. 442 * 1 = Child has terminated or was not running. 443 */ 444kwsysEXPORT int kwsysProcess_WaitForExit(kwsysProcess* cp, double* timeout); 445 446/** 447 * Interrupt the process group for the child process that is currently 448 * running by sending it the appropriate operating-system specific signal. 449 * The caller should call WaitForExit after this returns to wait for the 450 * child to terminate. 451 * 452 * WARNING: If you didn't specify kwsysProcess_Option_CreateProcessGroup, 453 * you will interrupt your own process group. 454 */ 455kwsysEXPORT void kwsysProcess_Interrupt(kwsysProcess* cp); 456 457/** 458 * Forcefully terminate the child process that is currently running. 459 * The caller should call WaitForExit after this returns to wait for 460 * the child to terminate. 461 */ 462kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp); 463 464/** 465 * Same as kwsysProcess_Kill using process ID to locate process to 466 * terminate. 467 * @see kwsysProcess_Kill(kwsysProcess* cp) 468 */ 469kwsysEXPORT void kwsysProcess_KillPID(unsigned long); 470 471/** 472 * Reset the start time of the child process to the current time. 473 */ 474kwsysEXPORT void kwsysProcess_ResetStartTime(kwsysProcess* cp); 475 476#if defined(__cplusplus) 477} /* extern "C" */ 478#endif 479 480/* If we are building a kwsys .c or .cxx file, let it use these macros. 481 Otherwise, undefine them to keep the namespace clean. */ 482#if !defined(KWSYS_NAMESPACE) 483# undef kwsys_ns 484# undef kwsysEXPORT 485# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS 486# undef kwsysProcess 487# undef kwsysProcess_s 488# undef kwsysProcess_New 489# undef kwsysProcess_Delete 490# undef kwsysProcess_SetCommand 491# undef kwsysProcess_AddCommand 492# undef kwsysProcess_SetTimeout 493# undef kwsysProcess_SetWorkingDirectory 494# undef kwsysProcess_SetPipeFile 495# undef kwsysProcess_SetPipeNative 496# undef kwsysProcess_SetPipeShared 497# undef kwsysProcess_Option_Detach 498# undef kwsysProcess_Option_HideWindow 499# undef kwsysProcess_Option_MergeOutput 500# undef kwsysProcess_Option_Verbatim 501# undef kwsysProcess_Option_CreateProcessGroup 502# undef kwsysProcess_GetOption 503# undef kwsysProcess_SetOption 504# undef kwsysProcess_Option_e 505# undef kwsysProcess_State_Starting 506# undef kwsysProcess_State_Error 507# undef kwsysProcess_State_Exception 508# undef kwsysProcess_State_Executing 509# undef kwsysProcess_State_Exited 510# undef kwsysProcess_State_Expired 511# undef kwsysProcess_State_Killed 512# undef kwsysProcess_State_Disowned 513# undef kwsysProcess_GetState 514# undef kwsysProcess_State_e 515# undef kwsysProcess_Exception_None 516# undef kwsysProcess_Exception_Fault 517# undef kwsysProcess_Exception_Illegal 518# undef kwsysProcess_Exception_Interrupt 519# undef kwsysProcess_Exception_Numerical 520# undef kwsysProcess_Exception_Other 521# undef kwsysProcess_GetExitException 522# undef kwsysProcess_Exception_e 523# undef kwsysProcess_GetExitCode 524# undef kwsysProcess_GetExitValue 525# undef kwsysProcess_GetErrorString 526# undef kwsysProcess_GetExceptionString 527# undef kwsysProcess_Execute 528# undef kwsysProcess_Disown 529# undef kwsysProcess_WaitForData 530# undef kwsysProcess_Pipes_e 531# undef kwsysProcess_Pipe_None 532# undef kwsysProcess_Pipe_STDIN 533# undef kwsysProcess_Pipe_STDOUT 534# undef kwsysProcess_Pipe_STDERR 535# undef kwsysProcess_Pipe_Timeout 536# undef kwsysProcess_Pipe_Handle 537# undef kwsysProcess_WaitForExit 538# undef kwsysProcess_Interrupt 539# undef kwsysProcess_Kill 540# undef kwsysProcess_ResetStartTime 541# endif 542#endif 543 544#endif 545