2009-07-13 Vasiliy Fofanov <fofanov@adacore.com>
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Jul 2009 12:16:51 +0000 (12:16 +0000)
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Jul 2009 12:16:51 +0000 (12:16 +0000)
* mingw32.h: Make it explicit that we need XP or later.

* initialize.c: Remove useless extern symbol declaration.

* adaint.h: Ditto, also expose __gnat_win32_remove_handle to allow
code reuse in expect.c.

* adaint.c: Changes throughout the Windows section to redesign storage
of the child process list and the process identification.

* expect.c (__gnat_kill, __gnat_waitpid): Simplify, cleanup, use pids
for interfacing, fix errors.
(__gnat_expect_portable_execvp): use function in adaint.c

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149573 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/adaint.c
gcc/ada/adaint.h
gcc/ada/expect.c
gcc/ada/initialize.c
gcc/ada/mingw32.h

index 4108429..7975955 100644 (file)
@@ -1,3 +1,19 @@
+2009-07-13  Vasiliy Fofanov  <fofanov@adacore.com>
+
+       * mingw32.h: Make it explicit that we need XP or later.
+
+       * initialize.c: Remove useless extern symbol declaration.
+
+       * adaint.h: Ditto, also expose __gnat_win32_remove_handle to allow
+       code reuse in expect.c.
+
+       * adaint.c: Changes throughout the Windows section to redesign storage
+       of the child process list and the process identification.
+
+       * expect.c (__gnat_kill, __gnat_waitpid): Simplify, cleanup, use pids
+       for interfacing, fix errors.
+       (__gnat_expect_portable_execvp): use function in adaint.c
+
 2009-07-13  Emmanuel Briot  <briot@adacore.com>
 
        * prj-proc.adb, prj-part.adb, prj-part.ads, prj-strt.adb,
index f8ef6b1..06c95c6 100644 (file)
@@ -188,6 +188,7 @@ struct vstring
 #endif
 
 #if defined (_WIN32)
+
 #include <dir.h>
 #include <windows.h>
 #include <accctrl.h>
@@ -1909,9 +1910,9 @@ __gnat_set_OWNER_ACL
  DWORD AccessMode,
  DWORD AccessPermissions)
 {
-  ACL* pOldDACL = NULL;
-  ACL* pNewDACL = NULL;
-  SECURITY_DESCRIPTOR* pSD = NULL;
+  PACL pOldDACL = NULL;
+  PACL pNewDACL = NULL;
+  PSECURITY_DESCRIPTOR pSD = NULL;
   EXPLICIT_ACCESS ea;
   TCHAR username [100];
   DWORD unsize = 100;
@@ -2316,70 +2317,58 @@ extern void (*Unlock_Task) (void);
 
 #endif
 
-typedef struct _process_list
-{
-  HANDLE h;
-  struct _process_list *next;
-} Process_List;
-
-static Process_List *PLIST = NULL;
-
-static int plist_length = 0;
+static HANDLE *HANDLES_LIST = NULL;
+static int *PID_LIST = NULL, plist_length = 0, plist_max_length = 0;
 
 static void
 add_handle (HANDLE h)
 {
-  Process_List *pl;
-
-  pl = (Process_List *) xmalloc (sizeof (Process_List));
 
   /* -------------------- critical section -------------------- */
   (*Lock_Task) ();
 
-  pl->h = h;
-  pl->next = PLIST;
-  PLIST = pl;
+  if (plist_length == plist_max_length)
+    {
+      plist_max_length += 1000;
+      HANDLES_LIST =
+        xrealloc (HANDLES_LIST, sizeof (HANDLE) * plist_max_length);
+      PID_LIST =
+        xrealloc (PID_LIST, sizeof (int) * plist_max_length);
+    }
+
+  HANDLES_LIST[plist_length] = h;
+  PID_LIST[plist_length] = GetProcessId (h);
   ++plist_length;
 
   (*Unlock_Task) ();
   /* -------------------- critical section -------------------- */
 }
 
-static void
-remove_handle (HANDLE h)
+void
+__gnat_win32_remove_handle (HANDLE h, int pid)
 {
-  Process_List *pl;
-  Process_List *prev = NULL;
+  int j;
 
   /* -------------------- critical section -------------------- */
   (*Lock_Task) ();
 
-  pl = PLIST;
-  while (pl)
+  for (j = 0; j < plist_length; j++)
     {
-      if (pl->h == h)
+      if ((HANDLES_LIST[j] == h) || (PID_LIST[j] == pid))
         {
-          if (pl == PLIST)
-           PLIST = pl->next;
-          else
-           prev->next = pl->next;
-          free (pl);
+          CloseHandle (h);
+          --plist_length;
+          HANDLES_LIST[j] = HANDLES_LIST[plist_length];
+          PID_LIST[j] = PID_LIST[plist_length];
           break;
         }
-      else
-        {
-          prev = pl;
-          pl = pl->next;
-        }
     }
 
-  --plist_length;
-
   (*Unlock_Task) ();
   /* -------------------- critical section -------------------- */
 }
 
-static int
+static HANDLE
 win32_no_block_spawn (char *command, char *args[])
 {
   BOOL result;
@@ -2444,23 +2433,21 @@ win32_no_block_spawn (char *command, char *args[])
 
   if (result == TRUE)
     {
-      add_handle (PI.hProcess);
       CloseHandle (PI.hThread);
-      return (int) PI.hProcess;
+      return PI.hProcess;
     }
   else
-    return -1;
+    return NULL;
 }
 
 static int
 win32_wait (int *status)
 {
-  DWORD exitcode;
+  DWORD exitcode, pid;
   HANDLE *hl;
   HANDLE h;
   DWORD res;
   int k;
-  Process_List *pl;
   int hl_len;
 
   if (plist_length == 0)
@@ -2478,27 +2465,22 @@ win32_wait (int *status)
 
   hl = (HANDLE *) xmalloc (sizeof (HANDLE) * hl_len);
 
-  pl = PLIST;
-  while (pl)
-    {
-      hl[k++] = pl->h;
-      pl = pl->next;
-    }
+  memmove (hl, HANDLES_LIST, sizeof (HANDLE) * hl_len);
 
   (*Unlock_Task) ();
   /* -------------------- critical section -------------------- */
 
   res = WaitForMultipleObjects (hl_len, hl, FALSE, INFINITE);
   h = hl[res - WAIT_OBJECT_0];
-  free (hl);
-
-  remove_handle (h);
 
   GetExitCodeProcess (h, &exitcode);
-  CloseHandle (h);
+  pid = GetProcessId (h);
+  __gnat_win32_remove_handle (h, -1);
+
+  free (hl);
 
   *status = (int) exitcode;
-  return (int) h;
+  return (int) pid;
 }
 
 #endif
@@ -2506,7 +2488,6 @@ win32_wait (int *status)
 int
 __gnat_portable_no_block_spawn (char *args[])
 {
-  int pid = 0;
 
 #if defined (__vxworks) || defined (__nucleus__) || defined (RTX)
   return -1;
@@ -2526,11 +2507,17 @@ __gnat_portable_no_block_spawn (char *args[])
 
 #elif defined (_WIN32)
 
-  pid = win32_no_block_spawn (args[0], args);
-  return pid;
+  HANDLE h = NULL;
+
+  h = win32_no_block_spawn (args[0], args);
+  if (h != NULL)
+    add_handle (h);
+
+  return GetProcessId (h);
 
 #else
-  pid = fork ();
+
+  int pid = fork ();
 
   if (pid == 0)
     {
@@ -2543,9 +2530,9 @@ __gnat_portable_no_block_spawn (char *args[])
 #endif
     }
 
-#endif
-
   return pid;
+
+  #endif
 }
 
 int
@@ -3256,7 +3243,8 @@ __gnat_to_canonical_file_list_init
 char *
 __gnat_to_canonical_file_list_next (void)
 {
-  return (char *) "";
+  static char *empty = "";
+  return empty;
 }
 
 void
index e8fb40b..57cedf8 100644 (file)
@@ -199,8 +199,11 @@ extern void   __gnat_os_filename                   (char *, char *, char *,
 extern void   *__gnat_lwp_self                    (void);
 #endif
 
-#if defined (__MINGW32__) && !defined (RTX)
-extern void   __gnat_plist_init                    (void);
+#if defined (_WIN32)
+/* Interface to delete a handle from internally maintained list of child
+   process handles on Windows */
+extern void
+__gnat_win32_remove_handle (HANDLE h, int pid);
 #endif
 
 #ifdef IN_RTS
index aa18a33..c11a3aa 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *                     Copyright (C) 2001-2007, AdaCore                     *
+ *                     Copyright (C) 2001-2009, AdaCore                     *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
 
 #ifdef _WIN32
 
+/* We need functionality available only starting with Windows XP */
+#define _WIN32_WINNT 0x0501
+
 #include <windows.h>
 #include <process.h>
+#include <signal.h>
 
 void
 __gnat_kill (int pid, int sig, int close)
 {
+  HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
+  if (h == NULL)
+    return;
   if (sig == 9)
     {
-      if ((HANDLE)pid != NULL)
-       {
-         TerminateProcess ((HANDLE)pid, 0);
-         if (close)
-           CloseHandle ((HANDLE)pid);
-       }
-    }
-  else if (sig == 2)
-    {
-      GenerateConsoleCtrlEvent (CTRL_C_EVENT, (HANDLE)pid);
-      if (close)
-       CloseHandle ((HANDLE)pid);
+      TerminateProcess (h, 0);
+      __gnat_win32_remove_handle (NULL, pid);
     }
+  else if (sig == SIGINT)
+    GenerateConsoleCtrlEvent (CTRL_C_EVENT, pid);
+  else if (sig == SIGBREAK)
+    GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid);
+  /* ??? The last two alternatives don't really work. SIGBREAK requires setting
+     up process groups at start time which we don't do; treating SIGINT is just
+     not possible apparently. So we really only support signal 9. Fortunately
+     that's all we use in GNAT.Expect */
+
+  CloseHandle (h);
 }
 
 int
 __gnat_waitpid (int pid)
 {
+  HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
   DWORD exitcode = 1;
   DWORD res;
 
-  if ((HANDLE)pid != NULL)
+  if (h != NULL)
     {
-      res = WaitForSingleObject ((HANDLE)pid, INFINITE);
-      GetExitCodeProcess ((HANDLE)pid, &exitcode);
-      CloseHandle ((HANDLE)pid);
+      res = WaitForSingleObject (h, INFINITE);
+      GetExitCodeProcess (h, &exitcode);
+      CloseHandle (h);
     }
 
+  __gnat_win32_remove_handle (NULL, pid);
   return (int) exitcode;
 }
 
@@ -126,61 +135,7 @@ __gnat_expect_fork (void)
 void
 __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
 {
-  BOOL result;
-  STARTUPINFO SI;
-  PROCESS_INFORMATION PI;
-  SECURITY_ATTRIBUTES SA;
-  int csize = 1;
-  char *full_command;
-  int k;
-
-  /* compute the total command line length.  */
-  k = 0;
-  while (argv[k])
-    {
-      csize += strlen (argv[k]) + 1;
-      k++;
-    }
-
-  full_command = (char *) malloc (csize);
-  full_command[0] = '\0';
-
-  /* Startup info. */
-  SI.cb          = sizeof (STARTUPINFO);
-  SI.lpReserved  = NULL;
-  SI.lpReserved2 = NULL;
-  SI.lpDesktop   = NULL;
-  SI.cbReserved2 = 0;
-  SI.lpTitle     = NULL;
-  SI.dwFlags     = 0;
-  SI.wShowWindow = SW_HIDE;
-
-  /* Security attributes. */
-  SA.nLength = sizeof (SECURITY_ATTRIBUTES);
-  SA.bInheritHandle = TRUE;
-  SA.lpSecurityDescriptor = NULL;
-
-  k = 0;
-  while (argv[k])
-    {
-      strcat (full_command, argv[k]);
-      strcat (full_command, " ");
-      k++;
-    }
-
-  result = CreateProcess
-            (NULL, (char *) full_command, &SA, NULL, TRUE,
-              GetPriorityClass (GetCurrentProcess()), NULL, NULL, &SI, &PI);
-
-  free (full_command);
-
-  if (result == TRUE)
-    {
-      CloseHandle (PI.hThread);
-      *pid = (int) PI.hProcess;
-    }
-  else
-    *pid = -1;
+  *pid = __gnat_portable_no_block_spawn (argv);
 }
 
 int
index ccad170..fbbdf60 100644 (file)
@@ -67,12 +67,6 @@ extern void __gnat_install_SEH_handler (void *);
 extern int gnat_argc;
 extern char **gnat_argv;
 
-#ifndef RTX
-/* Do not define for RTX since it is only used for creating child processes
-   which is not supported in RTX. */
-extern void __gnat_plist_init (void);
-#endif
-
 #ifdef GNAT_UNICODE_SUPPORT
 
 #define EXPAND_ARGV_RATE 128
index 2c52920..2ad4d36 100644 (file)
@@ -61,6 +61,9 @@
 #define UNICODE  /* For Win32 API */
 #endif
 
+/* We need functionality available only starting with Windows XP */
+#define _WIN32_WINNT 0x0501
+
 #include <tchar.h>
 #include <windows.h>