mingw32.h: Make it explicit that we need XP or later.
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 From-SVN: r149573
This commit is contained in:
parent
e2d9085b0f
commit
75069667df
@ -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,
|
||||
|
110
gcc/ada/adaint.c
110
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user