Commits

hoffman  committed 8232b72

Merge changes from the main tree, fix a bug in the process kill code

  • Participants
  • Parent commits bed61da
  • Branches CMake-2-0
  • Tags CMake-2-0-0, CMake-2-0-1

Comments (0)

Files changed (7)

File GCC_XML/KWSys/Base64.h.in

    namespace.  These macros are used internally to kwsys only, and are
    not visible to user code.  Use kwsysHeaderDump.pl to reproduce
    these macros after making changes to the interface.  */
-#define kw_sys(x) @KWSYS_NAMESPACE@##x
+#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
 #define kwsysEXPORT          @KWSYS_NAMESPACE@_EXPORT
-#define kwsysBase64          kw_sys(Base64)
-#define kwsysBase64_Decode   kw_sys(Base64_Decode)
-#define kwsysBase64_Decode3  kw_sys(Base64_Decode3)
-#define kwsysBase64_Encode   kw_sys(Base64_Encode)
-#define kwsysBase64_Encode1  kw_sys(Base64_Encode1)
-#define kwsysBase64_Encode2  kw_sys(Base64_Encode2)
-#define kwsysBase64_Encode3  kw_sys(Base64_Encode3)
+#define kwsysBase64          kwsys_ns(Base64)
+#define kwsysBase64_Decode   kwsys_ns(Base64_Decode)
+#define kwsysBase64_Decode3  kwsys_ns(Base64_Decode3)
+#define kwsysBase64_Encode   kwsys_ns(Base64_Encode)
+#define kwsysBase64_Encode1  kwsys_ns(Base64_Encode1)
+#define kwsysBase64_Encode2  kwsys_ns(Base64_Encode2)
+#define kwsysBase64_Encode3  kwsys_ns(Base64_Encode3)
 
 #if defined(__cplusplus)
 extern "C"
 /* If we are building Base64.c, let it use these macros.  Otherwise,
    undefine them to keep the namespace clean.  */
 #if !defined(KWSYS_IN_BASE64_C)
-# undef kwsys
+# undef kwsys_ns
 # undef kwsysEXPORT
 # undef kwsysBase64
 # undef kwsysBase64_Decode

File GCC_XML/KWSys/CMakeLists.txt

     SET_SOURCE_FILES_PROPERTIES(
       ${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
       PROPERTIES GENERATED 1)
-    SET(KWSYS_H_FILES ${KWSYS_H_FILES} ProcessWin32Kill)
-    SET(KWSYS_SRCS ${KWSYS_SRCS} ProcessWin32Kill.c)
   ELSE(NOT UNIX)
     # Use the UNIX implementation.
     SET(KWSYS_SRCS ${KWSYS_SRCS} ProcessUNIX.c)

File GCC_XML/KWSys/Process.h.in

    namespace.  These macros are used internally to kwsys only, and are
    not visible to user code.  Use kwsysHeaderDump.pl to reproduce
    these macros after making changes to the interface.  */
-#define kw_sys(x) @KWSYS_NAMESPACE@##x
+#define kwsys_ns(x) @KWSYS_NAMESPACE@##x
 #define kwsysEXPORT                      @KWSYS_NAMESPACE@_EXPORT
-#define kwsysProcess                     kw_sys(Process)
-#define kwsysProcess_s                   kw_sys(Process_s)
-#define kwsysProcess_New                 kw_sys(Process_New)
-#define kwsysProcess_Delete              kw_sys(Process_Delete)
-#define kwsysProcess_SetCommand          kw_sys(Process_SetCommand)
-#define kwsysProcess_AddCommand          kw_sys(Process_AddCommand)
-#define kwsysProcess_SetTimeout          kw_sys(Process_SetTimeout)
-#define kwsysProcess_SetWorkingDirectory kw_sys(Process_SetWorkingDirectory)
-#define kwsysProcess_SetPipeFile         kw_sys(Process_SetPipeFile)
-#define kwsysProcess_SetPipeShared       kw_sys(Process_SetPipeShared)
-#define kwsysProcess_Option_HideWindow   kw_sys(Process_Option_HideWindow)
-#define kwsysProcess_GetOption           kw_sys(Process_GetOption)
-#define kwsysProcess_SetOption           kw_sys(Process_SetOption)
-#define kwsysProcess_Option_e            kw_sys(Process_Option_e)
-#define kwsysProcess_State_Starting      kw_sys(Process_State_Starting)
-#define kwsysProcess_State_Error         kw_sys(Process_State_Error)
-#define kwsysProcess_State_Exception     kw_sys(Process_State_Exception)
-#define kwsysProcess_State_Executing     kw_sys(Process_State_Executing)
-#define kwsysProcess_State_Exited        kw_sys(Process_State_Exited)
-#define kwsysProcess_State_Expired       kw_sys(Process_State_Expired)
-#define kwsysProcess_State_Killed        kw_sys(Process_State_Killed)
-#define kwsysProcess_GetState            kw_sys(Process_GetState)
-#define kwsysProcess_State_e             kw_sys(Process_State_e)
-#define kwsysProcess_Exception_None      kw_sys(Process_Exception_None)
-#define kwsysProcess_Exception_Fault     kw_sys(Process_Exception_Fault)
-#define kwsysProcess_Exception_Illegal   kw_sys(Process_Exception_Illegal)
-#define kwsysProcess_Exception_Interrupt kw_sys(Process_Exception_Interrupt)
-#define kwsysProcess_Exception_Numerical kw_sys(Process_Exception_Numerical)
-#define kwsysProcess_Exception_Other     kw_sys(Process_Exception_Other)
-#define kwsysProcess_GetExitException    kw_sys(Process_GetExitException)
-#define kwsysProcess_Exception_e         kw_sys(Process_Exception_e)
-#define kwsysProcess_GetExitCode         kw_sys(Process_GetExitCode)
-#define kwsysProcess_GetExitValue        kw_sys(Process_GetExitValue)
-#define kwsysProcess_GetErrorString      kw_sys(Process_GetErrorString)
-#define kwsysProcess_GetExceptionString  kw_sys(Process_GetExceptionString)
-#define kwsysProcess_Execute             kw_sys(Process_Execute)
-#define kwsysProcess_WaitForData         kw_sys(Process_WaitForData)
-#define kwsysProcess_Pipes_e             kw_sys(Process_Pipes_e)
-#define kwsysProcess_Pipe_None           kw_sys(Process_Pipe_None)
-#define kwsysProcess_Pipe_STDIN          kw_sys(Process_Pipe_STDIN)
-#define kwsysProcess_Pipe_STDOUT         kw_sys(Process_Pipe_STDOUT)
-#define kwsysProcess_Pipe_STDERR         kw_sys(Process_Pipe_STDERR)
-#define kwsysProcess_Pipe_Timeout        kw_sys(Process_Pipe_Timeout)
-#define kwsysProcess_WaitForExit         kw_sys(Process_WaitForExit)
-#define kwsysProcess_Kill                kw_sys(Process_Kill)
+#define kwsysProcess                     kwsys_ns(Process)
+#define kwsysProcess_s                   kwsys_ns(Process_s)
+#define kwsysProcess_New                 kwsys_ns(Process_New)
+#define kwsysProcess_Delete              kwsys_ns(Process_Delete)
+#define kwsysProcess_SetCommand          kwsys_ns(Process_SetCommand)
+#define kwsysProcess_AddCommand          kwsys_ns(Process_AddCommand)
+#define kwsysProcess_SetTimeout          kwsys_ns(Process_SetTimeout)
+#define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
+#define kwsysProcess_SetPipeFile         kwsys_ns(Process_SetPipeFile)
+#define kwsysProcess_SetPipeShared       kwsys_ns(Process_SetPipeShared)
+#define kwsysProcess_Option_HideWindow   kwsys_ns(Process_Option_HideWindow)
+#define kwsysProcess_GetOption           kwsys_ns(Process_GetOption)
+#define kwsysProcess_SetOption           kwsys_ns(Process_SetOption)
+#define kwsysProcess_Option_e            kwsys_ns(Process_Option_e)
+#define kwsysProcess_State_Starting      kwsys_ns(Process_State_Starting)
+#define kwsysProcess_State_Error         kwsys_ns(Process_State_Error)
+#define kwsysProcess_State_Exception     kwsys_ns(Process_State_Exception)
+#define kwsysProcess_State_Executing     kwsys_ns(Process_State_Executing)
+#define kwsysProcess_State_Exited        kwsys_ns(Process_State_Exited)
+#define kwsysProcess_State_Expired       kwsys_ns(Process_State_Expired)
+#define kwsysProcess_State_Killed        kwsys_ns(Process_State_Killed)
+#define kwsysProcess_GetState            kwsys_ns(Process_GetState)
+#define kwsysProcess_State_e             kwsys_ns(Process_State_e)
+#define kwsysProcess_Exception_None      kwsys_ns(Process_Exception_None)
+#define kwsysProcess_Exception_Fault     kwsys_ns(Process_Exception_Fault)
+#define kwsysProcess_Exception_Illegal   kwsys_ns(Process_Exception_Illegal)
+#define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
+#define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
+#define kwsysProcess_Exception_Other     kwsys_ns(Process_Exception_Other)
+#define kwsysProcess_GetExitException    kwsys_ns(Process_GetExitException)
+#define kwsysProcess_Exception_e         kwsys_ns(Process_Exception_e)
+#define kwsysProcess_GetExitCode         kwsys_ns(Process_GetExitCode)
+#define kwsysProcess_GetExitValue        kwsys_ns(Process_GetExitValue)
+#define kwsysProcess_GetErrorString      kwsys_ns(Process_GetErrorString)
+#define kwsysProcess_GetExceptionString  kwsys_ns(Process_GetExceptionString)
+#define kwsysProcess_Execute             kwsys_ns(Process_Execute)
+#define kwsysProcess_WaitForData         kwsys_ns(Process_WaitForData)
+#define kwsysProcess_Pipes_e             kwsys_ns(Process_Pipes_e)
+#define kwsysProcess_Pipe_None           kwsys_ns(Process_Pipe_None)
+#define kwsysProcess_Pipe_STDIN          kwsys_ns(Process_Pipe_STDIN)
+#define kwsysProcess_Pipe_STDOUT         kwsys_ns(Process_Pipe_STDOUT)
+#define kwsysProcess_Pipe_STDERR         kwsys_ns(Process_Pipe_STDERR)
+#define kwsysProcess_Pipe_Timeout        kwsys_ns(Process_Pipe_Timeout)
+#define kwsysProcess_WaitForExit         kwsys_ns(Process_WaitForExit)
+#define kwsysProcess_Kill                kwsys_ns(Process_Kill)
 
 #if defined(__cplusplus)
 extern "C"
 /* If we are building a kwsysProcess .c file, let it use these macros.
    Otherwise, undefine them to keep the namespace clean.  */
 #if !defined(KWSYS_IN_PROCESS_C)
-# undef kwsys
+# undef kwsys_ns
 # undef kwsysEXPORT
 # undef kwsysProcess
 # undef kwsysProcess_s

File GCC_XML/KWSys/ProcessWin32.c

 #define KWSYS_IN_PROCESS_C
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(ProcessWin32Kill.h)
 
 /*
 
 /* The maximum amount to read from a pipe at a time.  */
 #define KWSYSPE_PIPE_BUFFER_SIZE 1024
 
-#define kwsysEncodedWriteArrayProcessFwd9x kw_sys(EncodedWriteArrayProcessFwd9x)
+#define kwsysEncodedWriteArrayProcessFwd9x kwsys_ns(EncodedWriteArrayProcessFwd9x)
 
 typedef LARGE_INTEGER kwsysProcessTime;
 
 static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
 static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
 static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
+static void kwsysProcessKillTree(int pid);
 extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
 
 /*--------------------------------------------------------------------------*/
       {
       /* The process timeout has expired.  Kill the child now.  */
       kwsysProcess_Kill(cp);
-      cp->State = kwsysProcess_State_Expired;
       cp->TimeoutExpired = 1;
       cp->Killed = 0;
       return kwsysProcess_Pipe_None;
     /* Not Windows 9x.  Just terminate the children.  */
     for(i=0; i < cp->NumberOfCommands; ++i)
       {
-      if(!kwsysProcessWin32Kill(cp->ProcessInformation[i].dwProcessId))
-        {
-      TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
-        }
+      kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
       }
     }
 
-  /* Wait for windows to finish cleaning up the children.  */
-  for(i=0; i < cp->NumberOfCommands; ++i)
-    {
-    WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
-    }
+  /* We are killing the children and ignoring all data.  Do not wait
+     for them to exit.  */
 }
 
 /*--------------------------------------------------------------------------*/
 }
 #undef KWSYSPE_CASE
 
+typedef struct kwsysProcess_List_s kwsysProcess_List;
+static kwsysProcess_List* kwsysProcess_List_New();
+static void kwsysProcess_List_Delete(kwsysProcess_List* self);
+static int kwsysProcess_List_Update(kwsysProcess_List* self);
+static int kwsysProcess_List_NextProcess(kwsysProcess_List* self);
+static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self);
+static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self);
+
+/*--------------------------------------------------------------------------*/
+/* Windows NT 4 API definitions.  */
+#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
+typedef LONG NTSTATUS;
+typedef LONG KPRIORITY;
+typedef struct _UNICODE_STRING UNICODE_STRING;
+struct _UNICODE_STRING
+{
+  USHORT Length;
+  USHORT MaximumLength;
+  PWSTR Buffer;
+};
+
+/* The process information structure.  Declare only enough to get
+   process identifiers.  The rest may be ignored because we use the
+   NextEntryDelta to move through an array of instances.  */
+typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION;
+typedef SYSTEM_PROCESS_INFORMATION* PSYSTEM_PROCESS_INFORMATION;
+struct _SYSTEM_PROCESS_INFORMATION
+{
+  ULONG          NextEntryDelta;
+  ULONG          ThreadCount;
+  ULONG          Reserved1[6];
+  LARGE_INTEGER  CreateTime;
+  LARGE_INTEGER  UserTime;
+  LARGE_INTEGER  KernelTime;
+  UNICODE_STRING ProcessName;
+  KPRIORITY      BasePriority;
+  ULONG          ProcessId;
+  ULONG          InheritedFromProcessId;
+};
+
+/*--------------------------------------------------------------------------*/
+/* Toolhelp32 API definitions.  */
+#define TH32CS_SNAPPROCESS  0x00000002
+typedef struct tagPROCESSENTRY32 PROCESSENTRY32;
+typedef PROCESSENTRY32* LPPROCESSENTRY32;
+struct tagPROCESSENTRY32
+{
+  DWORD dwSize;
+  DWORD cntUsage;
+  DWORD th32ProcessID;
+  DWORD th32DefaultHeapID;
+  DWORD th32ModuleID;
+  DWORD cntThreads;
+  DWORD th32ParentProcessID;
+  LONG  pcPriClassBase;
+  DWORD dwFlags;
+  char szExeFile[MAX_PATH];
+};
+
+/*--------------------------------------------------------------------------*/
+/* Windows API function types.  */
+typedef HANDLE (WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD);
+typedef BOOL (WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32);
+typedef BOOL (WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32);
+typedef NTSTATUS (WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID,
+                                                        ULONG, PULONG);
+
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self);
+static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self);
+static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self);
+
+struct kwsysProcess_List_s
+{
+  /* Implementation switches at runtime based on version of Windows.  */
+  int NT4;
+
+  /* Implementation functions and data for NT 4.  */
+  ZwQuerySystemInformationType P_ZwQuerySystemInformation;
+  char* Buffer;
+  int BufferSize;
+  PSYSTEM_PROCESS_INFORMATION CurrentInfo;
+
+  /* Implementation functions and data for other Windows versions.  */
+  CreateToolhelp32SnapshotType P_CreateToolhelp32Snapshot;
+  Process32FirstType P_Process32First;
+  Process32NextType P_Process32Next;
+  HANDLE Snapshot;
+  PROCESSENTRY32 CurrentEntry;
+};
+
+/*--------------------------------------------------------------------------*/
+static kwsysProcess_List* kwsysProcess_List_New()
+{
+  OSVERSIONINFO osv;
+  kwsysProcess_List* self;
+
+  /* Allocate and initialize the list object.  */
+  if(!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List))))
+    {
+    return 0;
+    }
+  memset(self, 0, sizeof(*self));
+
+  /* Select an implementation.  */
+  ZeroMemory(&osv, sizeof(osv));
+  osv.dwOSVersionInfoSize = sizeof(osv);
+  GetVersionEx(&osv);
+  self->NT4 = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+               osv.dwMajorVersion < 5)? 1:0;
+
+  /* Initialize the selected implementation.  */
+  if(!(self->NT4?
+       kwsysProcess_List__New_NT4(self) :
+       kwsysProcess_List__New_Snapshot(self)))
+    {
+    kwsysProcess_List_Delete(self);
+    return 0;
+    }
+
+  /* Update to the current set of processes.  */
+  if(!kwsysProcess_List_Update(self))
+    {
+    kwsysProcess_List_Delete(self);
+    return 0;
+    }
+  return self;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List_Delete(kwsysProcess_List* self)
+{
+  if(self)
+    {
+    if(self->NT4)
+      {
+      kwsysProcess_List__Delete_NT4(self);
+      }
+    else
+      {
+      kwsysProcess_List__Delete_Snapshot(self);
+      }
+    free(self);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_Update(kwsysProcess_List* self)
+{
+  return self? (self->NT4?
+                kwsysProcess_List__Update_NT4(self) :
+                kwsysProcess_List__Update_Snapshot(self)) : 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self)
+{
+  return self? (self->NT4?
+                kwsysProcess_List__GetProcessId_NT4(self) :
+                kwsysProcess_List__GetProcessId_Snapshot(self)) : -1;
+
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self)
+{
+  return self? (self->NT4?
+                kwsysProcess_List__GetParentId_NT4(self) :
+                kwsysProcess_List__GetParentId_Snapshot(self)) : -1;
+
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_NextProcess(kwsysProcess_List* self)
+{
+  return (self? (self->NT4?
+                 kwsysProcess_List__Next_NT4(self) :
+                 kwsysProcess_List__Next_Snapshot(self)) : 0);
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
+{
+  HANDLE hNT = GetModuleHandle("ntdll.dll");
+  if(hNT)
+    {
+    /* Get pointers to the needed API functions.  */
+    self->P_ZwQuerySystemInformation =
+      ((ZwQuerySystemInformationType)
+       GetProcAddress(hNT, "ZwQuerySystemInformation"));
+    CloseHandle(hNT);
+    }
+  if(!self->P_ZwQuerySystemInformation)
+    {
+    return 0;
+    }
+
+  /* Allocate an initial process information buffer.  */
+  self->BufferSize = 32768;
+  self->Buffer = (char*)malloc(self->BufferSize);
+  return self->Buffer? 1:0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
+{
+  /* Free the process information buffer.  */
+  if(self->Buffer)
+    {
+    free(self->Buffer);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
+{
+  self->CurrentInfo = 0;
+  while(1)
+    {
+    /* Query number 5 is for system process list.  */
+    NTSTATUS status =
+      self->P_ZwQuerySystemInformation(5, self->Buffer, self->BufferSize, 0);
+    if(status == STATUS_INFO_LENGTH_MISMATCH)
+      {
+      /* The query requires a bigger buffer.  */
+      int newBufferSize = self->BufferSize * 2;
+      char* newBuffer = (char*)malloc(newBufferSize);
+      if(newBuffer)
+        {
+        free(self->Buffer);
+        self->Buffer = newBuffer;
+        self->BufferSize = newBufferSize;
+        }
+      else
+        {
+        return 0;
+        }
+      }
+    else if(status >= 0)
+      {
+      /* The query succeeded.  Initialize traversal of the process list.  */
+      self->CurrentInfo = (PSYSTEM_PROCESS_INFORMATION)self->Buffer;
+      return 1;
+      }
+    else
+      {
+      /* The query failed.  */
+      return 0;
+      }
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self)
+{
+  if(self->CurrentInfo)
+    {
+    if(self->CurrentInfo->NextEntryDelta > 0)
+      {
+      self->CurrentInfo = ((PSYSTEM_PROCESS_INFORMATION)
+                              ((char*)self->CurrentInfo +
+                               self->CurrentInfo->NextEntryDelta));
+      return 1;
+      }
+    self->CurrentInfo = 0;
+    }
+  return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self)
+{
+  return self->CurrentInfo? self->CurrentInfo->ProcessId : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self)
+{
+  return self->CurrentInfo? self->CurrentInfo->InheritedFromProcessId : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self)
+{
+  HANDLE hKernel = GetModuleHandle("kernel32.dll");
+  if(hKernel)
+    {
+    self->P_CreateToolhelp32Snapshot =
+      ((CreateToolhelp32SnapshotType)
+       GetProcAddress(hKernel, "CreateToolhelp32Snapshot"));
+    self->P_Process32First =
+      ((Process32FirstType)
+       GetProcAddress(hKernel, "Process32First"));
+    self->P_Process32Next =
+      ((Process32NextType)
+       GetProcAddress(hKernel, "Process32Next"));
+    CloseHandle(hKernel);
+    }
+  return (self->P_CreateToolhelp32Snapshot &&
+          self->P_Process32First &&
+          self->P_Process32Next)? 1:0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self)
+{
+  if(self->Snapshot)
+    {
+    CloseHandle(self->Snapshot);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self)
+{
+  if(self->Snapshot)
+    {
+    CloseHandle(self->Snapshot);
+    }
+  if(!(self->Snapshot =
+       self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)))
+    {
+    return 0;
+    }
+  ZeroMemory(&self->CurrentEntry, sizeof(self->CurrentEntry));
+  self->CurrentEntry.dwSize = sizeof(self->CurrentEntry);
+  if(!self->P_Process32First(self->Snapshot, &self->CurrentEntry))
+    {
+    CloseHandle(self->Snapshot);
+    self->Snapshot = 0;
+    return 0;
+    }
+  return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self)
+{
+  if(self->Snapshot)
+    {
+    if(self->P_Process32Next(self->Snapshot, &self->CurrentEntry))
+      {
+      return 1;
+      }
+    CloseHandle(self->Snapshot);
+    self->Snapshot = 0;
+    }
+  return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self)
+{
+  return self->Snapshot? self->CurrentEntry.th32ProcessID : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self)
+{
+  return self->Snapshot? self->CurrentEntry.th32ParentProcessID : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessKill(DWORD pid)
+{
+  HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid);
+  if(h)
+    {
+    TerminateProcess(h, 255);
+    WaitForSingleObject(h, INFINITE);
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessKillTree(int pid)
+{
+  kwsysProcess_List* plist = kwsysProcess_List_New();
+  kwsysProcessKill(pid);
+  if(plist)
+    {
+    do
+      {
+      if(kwsysProcess_List_GetCurrentParentId(plist) == pid)
+        {
+        int ppid = kwsysProcess_List_GetCurrentProcessId(plist);
+        kwsysProcessKillTree(ppid);
+        }
+      } while(kwsysProcess_List_NextProcess(plist));
+    kwsysProcess_List_Delete(plist);
+    }
+}

File GCC_XML/KWSys/ProcessWin32Kill.c

-/*=========================================================================
-
-  Program:   KWSys - Kitware System Library
-  Module:    $RCSfile$
-
-  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
-  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#define KWSYS_IN_PROCESS_C
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(ProcessWin32Kill.h)
-
-/* The following process tree kill implementation is taken from
-   http://www.alexfedotov.com/articles/killproc.asp
-   It will work only on some versions of windows.  Hopefully
-   I will eventually get some time to do a real implementation of this
-   for all windows versions.  */
-
-#include <windows.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <tlhelp32.h>
-
-//---------------------------------------------------------------------------
-// KillProcess
-//
-//  Terminates the specified process.
-//
-//  Parameters:
-//        dwProcessId - identifier of the process to terminate
-//
-//  Returns:
-//        TRUE, if successful, FALSE - otherwise.
-//
-static BOOL
-WINAPI
-KillProcess(
-  IN DWORD dwProcessId
-  )
-{
-  HANDLE hProcess;
-  DWORD dwError;
-
-  // first try to obtain handle to the process without the use of any
-  // additional privileges
-  hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
-  if (hProcess == NULL)
-    {
-    OSVERSIONINFO osvi;
-    TOKEN_PRIVILEGES Priv, PrivOld;
-    DWORD cbPriv;
-    HANDLE hToken;
-
-    if (GetLastError() != ERROR_ACCESS_DENIED)
-      return FALSE;
-
-    // determine operating system version
-    osvi.dwOSVersionInfoSize = sizeof(osvi);
-    GetVersionEx(&osvi);
-
-    // we cannot do anything else if this is not Windows NT
-    if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
-      return SetLastError(ERROR_ACCESS_DENIED), FALSE;
-
-    // enable SE_DEBUG_NAME privilege and try again
-
-    cbPriv = sizeof(PrivOld);
-
-    // obtain the token of the current thread 
-    if (!OpenThreadToken(GetCurrentThread(), 
-                         TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,
-                         FALSE, &hToken))
-      {
-      if (GetLastError() != ERROR_NO_TOKEN)
-        return FALSE;
-
-      // revert to the process token
-      if (!OpenProcessToken(GetCurrentProcess(),
-                            TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES,
-                            &hToken))
-        return FALSE;
-      }
-
-    if(!(ANYSIZE_ARRAY > 0))
-      {
-      return 0;
-      }
-
-    Priv.PrivilegeCount = 1;
-    Priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
-    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Priv.Privileges[0].Luid);
-
-    // try to enable the privilege
-    if (!AdjustTokenPrivileges(hToken, FALSE, &Priv, sizeof(Priv),
-                               &PrivOld, &cbPriv))
-      {
-      dwError = GetLastError();
-      CloseHandle(hToken);
-      return SetLastError(dwError), FALSE;
-      }
-
-    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
-      {
-      // the SE_DEBUG_NAME privilege is not present in the caller's
-      // token
-      CloseHandle(hToken);
-      return SetLastError(ERROR_ACCESS_DENIED), FALSE;
-      }
-
-    // try to open process handle again
-    hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
-    dwError = GetLastError();
-                
-    // restore the original state of the privilege
-    AdjustTokenPrivileges(hToken, FALSE, &PrivOld, sizeof(PrivOld),
-                          NULL, NULL);
-    CloseHandle(hToken);
-
-    if (hProcess == NULL)
-      {
-      return SetLastError(FALSE), 0;
-      }
-    
-    }
-
-  // terminate the process
-  if (!TerminateProcess(hProcess, (UINT)-1))
-    {
-    dwError = GetLastError();
-    CloseHandle(hProcess);
-    return SetLastError(dwError), FALSE;
-    }
-
-  CloseHandle(hProcess);
-
-  // completed successfully
-  return TRUE;
-}
-
-typedef LONG    NTSTATUS;
-typedef LONG    KPRIORITY;
-
-#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
-
-#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)
-
-#define SystemProcessesAndThreadsInformation    5
-
-typedef struct _CLIENT_ID {
-  DWORD           UniqueProcess;
-  DWORD           UniqueThread;
-} CLIENT_ID;
-
-typedef struct _UNICODE_STRING {
-  USHORT          Length;
-  USHORT          MaximumLength;
-  PWSTR           Buffer;
-} UNICODE_STRING;
-
-typedef struct _VM_COUNTERS {
-  SIZE_T          PeakVirtualSize;
-  SIZE_T          VirtualSize;
-  ULONG           PageFaultCount;
-  SIZE_T          PeakWorkingSetSize;
-  SIZE_T          WorkingSetSize;
-  SIZE_T          QuotaPeakPagedPoolUsage;
-  SIZE_T          QuotaPagedPoolUsage;
-  SIZE_T          QuotaPeakNonPagedPoolUsage;
-  SIZE_T          QuotaNonPagedPoolUsage;
-  SIZE_T          PagefileUsage;
-  SIZE_T          PeakPagefileUsage;
-} VM_COUNTERS;
-
-typedef struct _SYSTEM_THREADS {
-  LARGE_INTEGER   KernelTime;
-  LARGE_INTEGER   UserTime;
-  LARGE_INTEGER   CreateTime;
-  ULONG                       WaitTime;
-  PVOID                       StartAddress;
-  CLIENT_ID       ClientId;
-  KPRIORITY       Priority;
-  KPRIORITY       BasePriority;
-  ULONG                       ContextSwitchCount;
-  LONG                        State;
-  LONG                        WaitReason;
-} SYSTEM_THREADS, * PSYSTEM_THREADS;
-
-// Note that the size of the SYSTEM_PROCESSES structure is different on
-// NT 4 and Win2K, but we don't care about it, since we don't access neither
-// IoCounters member nor Threads array
-
-typedef struct _SYSTEM_PROCESSES {
-  ULONG                       NextEntryDelta;
-  ULONG                       ThreadCount;
-  ULONG                       Reserved1[6];
-  LARGE_INTEGER   CreateTime;
-  LARGE_INTEGER   UserTime;
-  LARGE_INTEGER   KernelTime;
-  UNICODE_STRING  ProcessName;
-  KPRIORITY       BasePriority;
-  ULONG                       ProcessId;
-  ULONG                       InheritedFromProcessId;
-  ULONG                       HandleCount;
-  ULONG                       Reserved2[2];
-  VM_COUNTERS     VmCounters;
-#if _WIN32_WINNT >= 0x500
-  IO_COUNTERS     IoCounters;
-#endif
-  SYSTEM_THREADS  Threads[1];
-} SYSTEM_PROCESSES, * PSYSTEM_PROCESSES;
-
-//---------------------------------------------------------------------------
-// KillProcessTreeNtHelper
-//
-//  This is a recursive helper function that terminates all the processes
-//  started by the specified process and them terminates the process itself
-//
-//  Parameters:
-//        pInfo       - processes information
-//        dwProcessId - identifier of the process to terminate
-//
-//  Returns:
-//        Win32 error code.
-//
-static
-BOOL
-WINAPI
-KillProcessTreeNtHelper(
-  IN PSYSTEM_PROCESSES pInfo,
-  IN DWORD dwProcessId
-  )
-{
-  PSYSTEM_PROCESSES p;
-  if(!pInfo)
-    {
-    return 0;
-    }
-
-  p = pInfo;
-
-  // kill all children first
-  for (;;)
-    {
-    if (p->InheritedFromProcessId == dwProcessId)
-      KillProcessTreeNtHelper(pInfo, p->ProcessId);
-
-    if (p->NextEntryDelta == 0)
-      break;
-
-    // find the address of the next process structure
-    p = (PSYSTEM_PROCESSES)(((LPBYTE)p) + p->NextEntryDelta);
-    }
-
-  // kill the process itself
-  if (!KillProcess(dwProcessId))
-    return GetLastError();
-
-  return ERROR_SUCCESS;
-}
-
-//---------------------------------------------------------------------------
-// KillProcessTreeWinHelper
-//
-//  This is a recursive helper function that terminates all the processes
-//  started by the specified process and them terminates the process itself
-//
-//  Parameters:
-//        dwProcessId - identifier of the process to terminate
-//
-//  Returns:
-//        Win32 error code.
-//
-static
-BOOL
-WINAPI
-KillProcessTreeWinHelper(
-  IN DWORD dwProcessId
-  )
-{
-  HINSTANCE hKernel; 
-  HANDLE hSnapshot;
-  PROCESSENTRY32 Entry;
-
-  HANDLE (WINAPI * _CreateToolhelp32Snapshot)(DWORD, DWORD);
-  BOOL (WINAPI * _Process32First)(HANDLE, PROCESSENTRY32 *);
-  BOOL (WINAPI * _Process32Next)(HANDLE, PROCESSENTRY32 *);
-
-  // get handle to KERNEL32.DLL
-  hKernel = GetModuleHandle(_T("kernel32.dll"));
-  if(!hKernel)
-    {
-    return 0;
-    }
-
-  // locate necessary functions in KERNEL32.DLL
-  *(FARPROC *)&_CreateToolhelp32Snapshot =
-    GetProcAddress(hKernel, "CreateToolhelp32Snapshot");
-  *(FARPROC *)&_Process32First =
-    GetProcAddress(hKernel, "Process32First");
-  *(FARPROC *)&_Process32Next =
-    GetProcAddress(hKernel, "Process32Next");
-
-  if (_CreateToolhelp32Snapshot == NULL ||
-      _Process32First == NULL ||
-      _Process32Next == NULL)
-    return ERROR_PROC_NOT_FOUND;
-
-
-  // create a snapshot
-  hSnapshot = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
-  if (hSnapshot == INVALID_HANDLE_VALUE)
-    return GetLastError();
-
-  Entry.dwSize = sizeof(Entry);
-  if (!_Process32First(hSnapshot, &Entry))
-    {
-    DWORD dwError = GetLastError();
-    CloseHandle(hSnapshot);
-    return dwError;
-    }
-
-  // kill all children first
-  do
-    {
-    if (Entry.th32ParentProcessID == dwProcessId)
-      KillProcessTreeWinHelper(Entry.th32ProcessID);
-
-    Entry.dwSize = sizeof(Entry);
-    }
-  while (_Process32Next(hSnapshot, &Entry));
-
-  CloseHandle(hSnapshot);
-
-  // kill the process itself
-  if (!KillProcess(dwProcessId))
-    return GetLastError();
-
-  return ERROR_SUCCESS;
-}
-
-//---------------------------------------------------------------------------
-// KillProcessEx
-//
-//  Terminates the specified process and, optionally, all processes started
-//      from the specified process (the so-called process tree).
-//
-//  Parameters:
-//        dwProcessId - identifier of the process to terminate
-//        bTree           - specifies whether the entire process tree should be
-//                                      terminated
-//
-//  Returns:
-//        TRUE, if successful, FALSE - otherwise.
-//
-static BOOL
-WINAPI
-KillProcessEx(
-  IN DWORD dwProcessId,
-  IN BOOL bTree
-  )
-{
-  OSVERSIONINFO osvi;
-  DWORD dwError;
-  HANDLE hHeap;
-  NTSTATUS Status;
-  ULONG cbBuffer;
-  PVOID pBuffer = NULL;
-
-  if (!bTree)
-    return KillProcess(dwProcessId);
-
-
-  // determine operating system version
-  osvi.dwOSVersionInfoSize = sizeof(osvi);
-  GetVersionEx(&osvi);
-
-  if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
-      osvi.dwMajorVersion < 5)
-    {
-    HINSTANCE hNtDll;
-    NTSTATUS (WINAPI * _ZwQuerySystemInformation)(UINT, PVOID, ULONG, PULONG);
-
-    // get handle to NTDLL.DLL
-    hNtDll = GetModuleHandle(_T("ntdll.dll"));
-    if(!hNtDll)
-      {
-      return 0;
-      }
-
-    // find the address of ZwQuerySystemInformation
-    *(FARPROC *)&_ZwQuerySystemInformation =
-      GetProcAddress(hNtDll, "ZwQuerySystemInformation");
-    if (_ZwQuerySystemInformation == NULL)
-      return SetLastError(ERROR_PROC_NOT_FOUND), 0;
-
-    // obtain a handle to the default process heap
-    hHeap = GetProcessHeap();
-    
-    cbBuffer = 0x8000;
-
-    // it is difficult to say a priory which size of the buffer 
-    // will be enough to retrieve all information, so we start
-    // with 32K buffer and increase its size until we get the
-    // information successfully
-    do
-      {
-      pBuffer = HeapAlloc(hHeap, 0, cbBuffer);
-      if (pBuffer == NULL)
-        return SetLastError(ERROR_NOT_ENOUGH_MEMORY), FALSE;
-
-      Status = _ZwQuerySystemInformation(
-        SystemProcessesAndThreadsInformation,
-        pBuffer, cbBuffer, NULL);
-
-      if (Status == STATUS_INFO_LENGTH_MISMATCH)
-        {
-        HeapFree(hHeap, 0, pBuffer);
-        cbBuffer *= 2;
-        }
-      else if (!NT_SUCCESS(Status))
-        {
-        HeapFree(hHeap, 0, pBuffer);
-        return SetLastError(Status), 0;
-        }
-      }
-    while (Status == STATUS_INFO_LENGTH_MISMATCH);
-
-    // call the helper function
-    dwError = KillProcessTreeNtHelper((PSYSTEM_PROCESSES)pBuffer, 
-                                      dwProcessId);
-                
-    HeapFree(hHeap, 0, pBuffer);
-    }
-  else
-    {
-    // call the helper function
-    dwError = KillProcessTreeWinHelper(dwProcessId);
-    }
-
-  SetLastError(dwError);
-  return dwError == ERROR_SUCCESS;
-}
-
-int kwsysProcessWin32Kill(int pid)
-{
-  return KillProcessEx(pid, 1)? 1:0;
-}

File GCC_XML/KWSys/ProcessWin32Kill.h.in

-/*=========================================================================
-
-  Program:   KWSys - Kitware System Library
-  Module:    $RCSfile$
-
-  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
-  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef @KWSYS_NAMESPACE@_ProcessWin32Kill_h
-#define @KWSYS_NAMESPACE@_ProcessWin32Kill_h
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-/* Redefine all public interface symbol names to be in the proper
-   namespace.  These macros are used internally to kwsys only, and are
-   not visible to user code.  Use kwsysHeaderDump.pl to reproduce
-   these macros after making changes to the interface.  */
-#define kw_sys(x) @KWSYS_NAMESPACE@##x
-#define kwsysEXPORT                      @KWSYS_NAMESPACE@_EXPORT
-#define kwsysProcessWin32Kill            kw_sys(ProcessWin32Kill)
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-kwsysEXPORT int kwsysProcessWin32Kill(int pid);
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-/* If we are building a kwsysProcess .c file, let it use these macros.
-   Otherwise, undefine them to keep the namespace clean.  */
-#if !defined(KWSYS_IN_PROCESS_C)
-# undef kwsys
-# undef kwsysEXPORT
-# undef kwsysProcessWin32Kill
-#endif
-
-#endif

File GCC_XML/KWSys/kwsysHeaderDump.pl

+#!/usr/bin/perl
+#
+# Program:   KWSys - Kitware System Library
+# Module:    $RCSfile$
+#
+# Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
+# See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+#
+#    This software is distributed WITHOUT ANY WARRANTY; without even
+#    the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+#    PURPOSE.  See the above copyright notices for more information.
+#
+
+if ( $#ARGV+1 < 2 )
+{
+    print "Usage: ./kwsysHeaderDump.pl <name> <header>\n";
+    exit(1);
+}
+
+$name = $ARGV[0];
+$max = 0;
+open(INFILE, $ARGV[1]);
+while (chomp ($line = <INFILE>))
+{
+    if (($line !~ /^\#/) &&
+        ($line =~ s/.*kwsys${name}_([A-Za-z0-9_]*).*/\1/) && 
+        ($i{$line}++ < 1))
+    {
+        push(@lines, "$line");
+        if (length($line) > $max)
+        {
+            $max = length($line);
+        }
+    }
+}
+close(INFILE);
+    
+$width = $max + 13;
+print sprintf("#define %-${width}s kwsys_ns(${name})\n", "kwsys${name}");
+foreach $l (@lines)
+{
+    print sprintf("#define %-${width}s kwsys_ns(${name}_$l)\n",
+                  "kwsys${name}_$l");
+}
+print "\n";
+print sprintf("# undef kwsys${name}\n");
+foreach $l (@lines)
+{
+    print sprintf("# undef kwsys${name}_$l\n");
+}