diff options
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/ada/adaint.c | 110 | ||||
-rw-r--r-- | gcc/ada/adaint.h | 7 | ||||
-rw-r--r-- | gcc/ada/expect.c | 99 | ||||
-rw-r--r-- | gcc/ada/initialize.c | 6 | ||||
-rw-r--r-- | gcc/ada/mingw32.h | 3 |
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> |