aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog16
-rw-r--r--gcc/ada/adaint.c110
-rw-r--r--gcc/ada/adaint.h7
-rw-r--r--gcc/ada/expect.c99
-rw-r--r--gcc/ada/initialize.c6
-rw-r--r--gcc/ada/mingw32.h3
6 files changed, 100 insertions, 141 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 4108429..7975955 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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,
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index f8ef6b1..06c95c6 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -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
diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
index e8fb40b..57cedf8 100644
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -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
diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c
index aa18a33..c11a3aa 100644
--- a/gcc/ada/expect.c
+++ b/gcc/ada/expect.c
@@ -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- *
@@ -78,42 +78,51 @@
#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
diff --git a/gcc/ada/initialize.c b/gcc/ada/initialize.c
index ccad170..fbbdf60 100644
--- a/gcc/ada/initialize.c
+++ b/gcc/ada/initialize.c
@@ -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
diff --git a/gcc/ada/mingw32.h b/gcc/ada/mingw32.h
index 2c52920..2ad4d36 100644
--- a/gcc/ada/mingw32.h
+++ b/gcc/ada/mingw32.h
@@ -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>