Commit 75069667 by Vasiliy Fofanov Committed by Arnaud Charlet

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
parent e2d9085b
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> 2009-07-13 Emmanuel Briot <briot@adacore.com>
* prj-proc.adb, prj-part.adb, prj-part.ads, prj-strt.adb, * prj-proc.adb, prj-part.adb, prj-part.ads, prj-strt.adb,
......
...@@ -188,6 +188,7 @@ struct vstring ...@@ -188,6 +188,7 @@ struct vstring
#endif #endif
#if defined (_WIN32) #if defined (_WIN32)
#include <dir.h> #include <dir.h>
#include <windows.h> #include <windows.h>
#include <accctrl.h> #include <accctrl.h>
...@@ -1909,9 +1910,9 @@ __gnat_set_OWNER_ACL ...@@ -1909,9 +1910,9 @@ __gnat_set_OWNER_ACL
DWORD AccessMode, DWORD AccessMode,
DWORD AccessPermissions) DWORD AccessPermissions)
{ {
ACL* pOldDACL = NULL; PACL pOldDACL = NULL;
ACL* pNewDACL = NULL; PACL pNewDACL = NULL;
SECURITY_DESCRIPTOR* pSD = NULL; PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea; EXPLICIT_ACCESS ea;
TCHAR username [100]; TCHAR username [100];
DWORD unsize = 100; DWORD unsize = 100;
...@@ -2316,70 +2317,58 @@ extern void (*Unlock_Task) (void); ...@@ -2316,70 +2317,58 @@ extern void (*Unlock_Task) (void);
#endif #endif
typedef struct _process_list static HANDLE *HANDLES_LIST = NULL;
{ static int *PID_LIST = NULL, plist_length = 0, plist_max_length = 0;
HANDLE h;
struct _process_list *next;
} Process_List;
static Process_List *PLIST = NULL;
static int plist_length = 0;
static void static void
add_handle (HANDLE h) add_handle (HANDLE h)
{ {
Process_List *pl;
pl = (Process_List *) xmalloc (sizeof (Process_List));
/* -------------------- critical section -------------------- */ /* -------------------- critical section -------------------- */
(*Lock_Task) (); (*Lock_Task) ();
pl->h = h; if (plist_length == plist_max_length)
pl->next = PLIST; {
PLIST = pl; 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; ++plist_length;
(*Unlock_Task) (); (*Unlock_Task) ();
/* -------------------- critical section -------------------- */ /* -------------------- critical section -------------------- */
} }
static void void
remove_handle (HANDLE h) __gnat_win32_remove_handle (HANDLE h, int pid)
{ {
Process_List *pl; int j;
Process_List *prev = NULL;
/* -------------------- critical section -------------------- */ /* -------------------- critical section -------------------- */
(*Lock_Task) (); (*Lock_Task) ();
pl = PLIST; for (j = 0; j < plist_length; j++)
while (pl)
{ {
if (pl->h == h) if ((HANDLES_LIST[j] == h) || (PID_LIST[j] == pid))
{ {
if (pl == PLIST) CloseHandle (h);
PLIST = pl->next; --plist_length;
else HANDLES_LIST[j] = HANDLES_LIST[plist_length];
prev->next = pl->next; PID_LIST[j] = PID_LIST[plist_length];
free (pl);
break; break;
} }
else
{
prev = pl;
pl = pl->next;
}
} }
--plist_length;
(*Unlock_Task) (); (*Unlock_Task) ();
/* -------------------- critical section -------------------- */ /* -------------------- critical section -------------------- */
} }
static int static HANDLE
win32_no_block_spawn (char *command, char *args[]) win32_no_block_spawn (char *command, char *args[])
{ {
BOOL result; BOOL result;
...@@ -2444,23 +2433,21 @@ win32_no_block_spawn (char *command, char *args[]) ...@@ -2444,23 +2433,21 @@ win32_no_block_spawn (char *command, char *args[])
if (result == TRUE) if (result == TRUE)
{ {
add_handle (PI.hProcess);
CloseHandle (PI.hThread); CloseHandle (PI.hThread);
return (int) PI.hProcess; return PI.hProcess;
} }
else else
return -1; return NULL;
} }
static int static int
win32_wait (int *status) win32_wait (int *status)
{ {
DWORD exitcode; DWORD exitcode, pid;
HANDLE *hl; HANDLE *hl;
HANDLE h; HANDLE h;
DWORD res; DWORD res;
int k; int k;
Process_List *pl;
int hl_len; int hl_len;
if (plist_length == 0) if (plist_length == 0)
...@@ -2478,27 +2465,22 @@ win32_wait (int *status) ...@@ -2478,27 +2465,22 @@ win32_wait (int *status)
hl = (HANDLE *) xmalloc (sizeof (HANDLE) * hl_len); hl = (HANDLE *) xmalloc (sizeof (HANDLE) * hl_len);
pl = PLIST; memmove (hl, HANDLES_LIST, sizeof (HANDLE) * hl_len);
while (pl)
{
hl[k++] = pl->h;
pl = pl->next;
}
(*Unlock_Task) (); (*Unlock_Task) ();
/* -------------------- critical section -------------------- */ /* -------------------- critical section -------------------- */
res = WaitForMultipleObjects (hl_len, hl, FALSE, INFINITE); res = WaitForMultipleObjects (hl_len, hl, FALSE, INFINITE);
h = hl[res - WAIT_OBJECT_0]; h = hl[res - WAIT_OBJECT_0];
free (hl);
remove_handle (h);
GetExitCodeProcess (h, &exitcode); GetExitCodeProcess (h, &exitcode);
CloseHandle (h); pid = GetProcessId (h);
__gnat_win32_remove_handle (h, -1);
free (hl);
*status = (int) exitcode; *status = (int) exitcode;
return (int) h; return (int) pid;
} }
#endif #endif
...@@ -2506,7 +2488,6 @@ win32_wait (int *status) ...@@ -2506,7 +2488,6 @@ win32_wait (int *status)
int int
__gnat_portable_no_block_spawn (char *args[]) __gnat_portable_no_block_spawn (char *args[])
{ {
int pid = 0;
#if defined (__vxworks) || defined (__nucleus__) || defined (RTX) #if defined (__vxworks) || defined (__nucleus__) || defined (RTX)
return -1; return -1;
...@@ -2526,11 +2507,17 @@ __gnat_portable_no_block_spawn (char *args[]) ...@@ -2526,11 +2507,17 @@ __gnat_portable_no_block_spawn (char *args[])
#elif defined (_WIN32) #elif defined (_WIN32)
pid = win32_no_block_spawn (args[0], args); HANDLE h = NULL;
return pid;
h = win32_no_block_spawn (args[0], args);
if (h != NULL)
add_handle (h);
return GetProcessId (h);
#else #else
pid = fork ();
int pid = fork ();
if (pid == 0) if (pid == 0)
{ {
...@@ -2543,9 +2530,9 @@ __gnat_portable_no_block_spawn (char *args[]) ...@@ -2543,9 +2530,9 @@ __gnat_portable_no_block_spawn (char *args[])
#endif #endif
} }
#endif
return pid; return pid;
#endif
} }
int int
...@@ -3256,7 +3243,8 @@ __gnat_to_canonical_file_list_init ...@@ -3256,7 +3243,8 @@ __gnat_to_canonical_file_list_init
char * char *
__gnat_to_canonical_file_list_next (void) __gnat_to_canonical_file_list_next (void)
{ {
return (char *) ""; static char *empty = "";
return empty;
} }
void void
......
...@@ -199,8 +199,11 @@ extern void __gnat_os_filename (char *, char *, char *, ...@@ -199,8 +199,11 @@ extern void __gnat_os_filename (char *, char *, char *,
extern void *__gnat_lwp_self (void); extern void *__gnat_lwp_self (void);
#endif #endif
#if defined (__MINGW32__) && !defined (RTX) #if defined (_WIN32)
extern void __gnat_plist_init (void); /* 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 #endif
#ifdef IN_RTS #ifdef IN_RTS
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* C Implementation File * * 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 * * 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- * * terms of the GNU General Public License as published by the Free Soft- *
...@@ -78,42 +78,51 @@ ...@@ -78,42 +78,51 @@
#ifdef _WIN32 #ifdef _WIN32
/* We need functionality available only starting with Windows XP */
#define _WIN32_WINNT 0x0501
#include <windows.h> #include <windows.h>
#include <process.h> #include <process.h>
#include <signal.h>
void void
__gnat_kill (int pid, int sig, int close) __gnat_kill (int pid, int sig, int close)
{ {
HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
if (h == NULL)
return;
if (sig == 9) if (sig == 9)
{ {
if ((HANDLE)pid != NULL) TerminateProcess (h, 0);
{ __gnat_win32_remove_handle (NULL, pid);
TerminateProcess ((HANDLE)pid, 0);
if (close)
CloseHandle ((HANDLE)pid);
}
}
else if (sig == 2)
{
GenerateConsoleCtrlEvent (CTRL_C_EVENT, (HANDLE)pid);
if (close)
CloseHandle ((HANDLE)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 int
__gnat_waitpid (int pid) __gnat_waitpid (int pid)
{ {
HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
DWORD exitcode = 1; DWORD exitcode = 1;
DWORD res; DWORD res;
if ((HANDLE)pid != NULL) if (h != NULL)
{ {
res = WaitForSingleObject ((HANDLE)pid, INFINITE); res = WaitForSingleObject (h, INFINITE);
GetExitCodeProcess ((HANDLE)pid, &exitcode); GetExitCodeProcess (h, &exitcode);
CloseHandle ((HANDLE)pid); CloseHandle (h);
} }
__gnat_win32_remove_handle (NULL, pid);
return (int) exitcode; return (int) exitcode;
} }
...@@ -126,61 +135,7 @@ __gnat_expect_fork (void) ...@@ -126,61 +135,7 @@ __gnat_expect_fork (void)
void void
__gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[]) __gnat_expect_portable_execvp (int *pid, char *cmd, char *argv[])
{ {
BOOL result; *pid = __gnat_portable_no_block_spawn (argv);
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;
} }
int int
......
...@@ -67,12 +67,6 @@ extern void __gnat_install_SEH_handler (void *); ...@@ -67,12 +67,6 @@ extern void __gnat_install_SEH_handler (void *);
extern int gnat_argc; extern int gnat_argc;
extern char **gnat_argv; 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 #ifdef GNAT_UNICODE_SUPPORT
#define EXPAND_ARGV_RATE 128 #define EXPAND_ARGV_RATE 128
......
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
#define UNICODE /* For Win32 API */ #define UNICODE /* For Win32 API */
#endif #endif
/* We need functionality available only starting with Windows XP */
#define _WIN32_WINNT 0x0501
#include <tchar.h> #include <tchar.h>
#include <windows.h> #include <windows.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment