[RFC-v2] Reenable compilation with cygwin 1.5 versions

Pierre Muller
2010-03-04T15:32:51Z

This new version of the patch that
tries to separate what is directly use of UNICODE versions
of Windows API from what is Cygwin API specific code.

Following Christopher's suggestion,
the patch for remote-fileio.c defines a static
cygwin_conv_path function, with the minimum need to
the restricted usage made inside that file.
__USE_OLD_CYGWIN_API_ macro could be renamed something like
__PROVIDE_LOCAL_CYGWIN_CONV_PATH_...
This patch can now be considered as independent of the
windows-nat.c patch.

Concerning windows-nat.c,
I changed most of Corinna's modifications into
#ifdef __USE_UNICODE_API_
This allows to use Unicode functions also for mingw32,
by compiling with -D__USE_UNICODE_API_ option.
A small number of code adaptation
was necessary to get this to work also,
but it was easier to check that the
separation between Unicode function and cygwin API
versions was made correctly this way.

The Cygwin versions must be compiled
according to the API >=181 condition.
Anyhow, all systems supported by the new cygwin do
have Unicode versions of their functions,
so that it does not restrict their usage...
Older cygwin's cannot compile using Unicode
function because that would require to isolate
the cygwin_conv_path issues, which seemed not
interesting to me.

Further suggestions?
Comments?

Pierre

2010-03-04 Pierre Muller <muller@ics.u-strasbg.fr>

* remote-fileio.c:
(__USE_OLD_CYGWIN_API_): New macro, set for
older cygwin API that does not have cygwin_conv_path.
(cygwin_conv_path): New static function emulating
new cygwin API.

* windows-nat.c:
__USE_UNICODE_API_: new macro.
Macro set by default for Cygwin API version >= 181.
(get_module_name): Handle macro __USE_UNICODE_API_.
(windows_make_so): Idem.
(get_image_name): Idem.
(windows_detach): Idem.
(windows_pid_to_exec_file): Idem.
(windows_create_inferior): Idem.
(_initialize_windows_nat): Idem.
(bad_GetModuleFileNameExW): Only define if __USE_UNICODE_API_ is
defined.
(_initialize_loadable): Idem.

Index: remote-fileio.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-fileio.c,v
retrieving revision 1.34
diff -u -p -r1.34 remote-fileio.c
--- remote-fileio.c 1 Mar 2010 09:09:24 -0000 1.34
+++ remote-fileio.c 4 Mar 2010 15:06:28 -0000
@@ -35,9 +35,45 @@
#include <sys/time.h>
#ifdef __CYGWIN__
#include <sys/cygwin.h> /* For
cygwin_conv_to_full_posix_path. */
+#include <cygwin/version.h>
+#if
CYGWIN_VERSION_DLL_MAKE_COMBINED(CYGWIN_VERSION_API_MAJOR,CYGWIN_VERSION_API
_MINOR) < 181
+#define __USE_OLD_CYGWIN_API_
+#endif
+
#endif
#include <signal.h>

+#ifdef __USE_OLD_CYGWIN_API_
+/* Possible 'what' values in calls to cygwin_conv_path/cygwin_create_path.
*/
+enum
+{
+ CCP_POSIX_TO_WIN_A = 0, /* from is char*, to is char* */
+ CCP_POSIX_TO_WIN_W, /* from is char*, to is wchar_t* */
+ CCP_WIN_A_TO_POSIX, /* from is char*, to is char* */
+ CCP_WIN_W_TO_POSIX, /* from is wchar_t*, to is char* */
+
+ /* Or these values to the above as needed. */
+ CCP_ABSOLUTE = 0, /* Request absolute path (default). */
+ CCP_RELATIVE = 0x100 /* Request to keep path relative. */
+};
+typedef unsigned int cygwin_conv_path_t;
+
+static ssize_t
+cygwin_conv_path (cygwin_conv_path_t what, const void *from,
+ void *to, size_t size)
+{
+ if (size < PATH_MAX)
+ internal_error (__FILE__,__LINE__,
+ "string buffer too short in cygwin_conv_path");
+
+ if (what == CCP_WIN_A_TO_POSIX)
+ return cygwin_conv_to_full_posix_path (from, to);
+ else
+ internal_error (__FILE__,__LINE__,"Error in cygwin_conv_path");
+}
+#endif /* __USE_OLD_CYGWIN_API_ */
+
+
static struct {
int *fd_map;
int fd_map_size;
Index: windows-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/windows-nat.c,v
retrieving revision 1.204
diff -u -p -r1.204 windows-nat.c
--- windows-nat.c 1 Mar 2010 09:09:24 -0000 1.204
+++ windows-nat.c 4 Mar 2010 15:06:28 -0000
@@ -41,6 +41,10 @@
#include <psapi.h>
#ifdef __CYGWIN__
#include <sys/cygwin.h>
+#include <cygwin/version.h>
+#if
CYGWIN_VERSION_DLL_MAKE_COMBINED(CYGWIN_VERSION_API_MAJOR,CYGWIN_VERSION_API
_MINOR) >= 181
+#define __USE_UNICODE_API_
+#endif
#endif
#include <signal.h>

@@ -71,11 +75,11 @@
#define DebugBreakProcess dyn_DebugBreakProcess
#define DebugSetProcessKillOnExit dyn_DebugSetProcessKillOnExit
#define EnumProcessModules dyn_EnumProcessModules
-#ifndef __CYGWIN__
+#ifndef __USE_UNICODE_API_
#define GetModuleFileNameExA dyn_GetModuleFileNameExA
-#else
+#else /* __USE_UNICODE_API_ */
#define GetModuleFileNameExW dyn_GetModuleFileNameExW
-#endif
+#endif /* __USE_UNICODE_API_ */
#define GetModuleInformation dyn_GetModuleInformation
#define LookupPrivilegeValueA dyn_LookupPrivilegeValueA
#define OpenProcessToken dyn_OpenProcessToken
@@ -87,13 +91,13 @@ static BOOL WINAPI (*DebugBreakProcess)
static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
LPDWORD);
-#ifndef __CYGWIN__
+#ifndef __USE_UNICODE_API_
static DWORD WINAPI (*GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
DWORD);
-#else
+#else /* __USE_UNICODE_API_ */
static DWORD WINAPI (*GetModuleFileNameExW) (HANDLE, HMODULE, LPWSTR,
DWORD);
-#endif
+#endif /* __USE_UNICODE_API_ */
static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
DWORD);
static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
@@ -491,12 +495,19 @@ get_module_name (LPVOID base_address, ch
HMODULE dh_buf[1];
HMODULE *DllHandle = dh_buf; /* Set to temporary storage for initial
query */
DWORD cbNeeded;
-#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
wchar_t pathbuf[PATH_MAX]; /* Temporary storage prior to converting to
posix form. PATH_MAX is always enough
as long as SO_NAME_MAX_PATH_SIZE is
defined
as 512. */
+#else /* not __USE_NOT_CYGWIN_API_ */
+#ifdef __CYGWIN__
+ char pathbuf[PATH_MAX]; /* Temporary storage prior to converting to
+ posix form */
+#else
+ char *pathbuf = dll_name_ret; /* Just copy directly to passed-in
arg */
#endif
+#endif /* not __USE_UNICODE_API_ */

cbNeeded = 0;
/* Find size of buffer needed to handle list of modules loaded in
inferior */
@@ -524,21 +535,31 @@ get_module_name (LPVOID base_address, ch
if (!base_address || mi.lpBaseOfDll == base_address)
{
/* Try to find the name of the given module */
-#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
/* Cygwin prefers that the path be in /x/y/z format */
len = GetModuleFileNameExW (current_process_handle,
DllHandle[i], pathbuf, PATH_MAX);
+#else /* not __USE_UNICODE_API_ */
+ len = GetModuleFileNameExA (current_process_handle,
+ DllHandle[i], pathbuf, MAX_PATH);
+#endif /* not __USE_iUNICODE_API_ */
if (len == 0)
error (_("Error getting dll name: %lu."), GetLastError ());
+#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret,
PATH_MAX) < 0)
error (_("Error converting dll name to POSIX: %d."), errno);
-#else
- len = GetModuleFileNameExA (current_process_handle,
- DllHandle[i], dll_name_ret, MAX_PATH);
- if (len == 0)
- error (_("Error getting dll name: %u."), (unsigned) GetLastError
());
-#endif
+#else /* not __USE_UNICODE_API_ */
+ /* Cygwin prefers that the path be in /x/y/z format */
+ cygwin_conv_to_full_posix_path (pathbuf, dll_name_ret);
+#endif /* __USE_UNICODE_API_ */
+#else /* not __CYGWIN__ */
+#ifdef __USE_UNICODE_API_
+ wcscpy (pathbuf, (wchar_t *)dll_name_ret);
+#endif /* __USE_UNICODE_API_ */
+
+#endif /* __CYGWIN__ */
return 1; /* success */
}
}
@@ -629,7 +650,7 @@ windows_make_so (const char *name, LPVOI
{
struct so_list *so;
char *p;
-#ifndef __CYGWIN__
+#ifndef __USE_UNICODE_API_
char buf[MAX_PATH + 1];
char cwd[MAX_PATH + 1];
WIN32_FIND_DATA w32_fd;
@@ -651,13 +672,17 @@ windows_make_so (const char *name, LPVOI
SetCurrentDirectory (cwd);
}
}
+
if (strcasecmp (buf, "ntdll.dll") == 0)
{
GetSystemDirectory (buf, sizeof (buf));
strcat (buf, "\\ntdll.dll");
}
-#else
+#else /* __USE_UNICODE_API_ */
wchar_t buf[PATH_MAX];
+#ifndef __CYGWIN__
+ char bufa [PATH_MAX];
+#endif /* not __CYGWIN__ */

buf[0] = L'\0';
if (access (name, F_OK) != 0)
@@ -668,14 +693,26 @@ windows_make_so (const char *name, LPVOI
wcscat (buf, L"\\ntdll.dll");
}
}
-#endif
+#endif /* __USE_UNICODE_API_ */
so = XZALLOC (struct so_list);
so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
so->lm_info->load_addr = load_addr;
strcpy (so->so_original_name, name);
#ifndef __CYGWIN__
+#ifdef __USE_UNICODE_API_
+ if (buf[0])
+ {
+ WideCharToMultiByte (CP_ACP, 0, buf, wcslen (buf) + 1, bufa, sizeof
bufa,
+ 0, 0);
+ strcpy (so->so_name, bufa);
+ }
+ else
+ strcpy (so->so_name, name);
+#else /* not __USE_UNICODE_API_ */
strcpy (so->so_name, buf);
+#endif /* not __USE_UNICODE_API_ */
#else
+#ifdef __USE_UNICODE_API_
if (buf[0])
cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
SO_NAME_MAX_PATH_SIZE);
@@ -690,6 +727,9 @@ windows_make_so (const char *name, LPVOI
else
error (_("dll path too long"));
}
+#else /* not __USE_UNICODE_API_ */
+ cygwin_conv_to_posix_path (buf, so->so_name);
+#endif /* not __USE_UNICODE_API_ */
/* Record cygwin1.dll .text start/end. */
p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
@@ -728,7 +768,7 @@ windows_make_so (const char *name, LPVOI
static char *
get_image_name (HANDLE h, void *address, int unicode)
{
-#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
static char buf[PATH_MAX];
#else
static char buf[(2 * MAX_PATH) + 1];
@@ -763,12 +803,12 @@ get_image_name (HANDLE h, void *address,
WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof
(WCHAR),
&done);
-#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
wcstombs (buf, unicode_address, PATH_MAX);
#else
WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof
buf,
0, 0);
-#endif
+#endif /* __USE_UNICODE_API_ */
}

return buf;
@@ -780,7 +820,7 @@ static int
handle_load_dll (void *dummy)
{
LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
-#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
char dll_buf[PATH_MAX];
#else
char dll_buf[MAX_PATH + 1];
@@ -1825,9 +1865,13 @@ windows_detach (struct target_ops *ops,
static char *
windows_pid_to_exec_file (int pid)
{
-#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
static char path[PATH_MAX];
+#else /* not __USE_UNICODE_API_ */
+ static char path[MAX_PATH + 1];
+#endif /* not __USE_UNICODE_API_ */

+#ifdef __CYGWIN__
/* Try to find exe name as symlink target of /proc/<pid>/exe */
int nchars;
char procexe[sizeof ("/proc/4294967295/exe")];
@@ -1838,8 +1882,6 @@ windows_pid_to_exec_file (int pid)
path[nchars] = '\0'; /* Got it */
return path;
}
-#else
- static char path[MAX_PATH + 1];
#endif

/* If we get here then either Cygwin is hosed, this isn't a Cygwin
version
@@ -1877,23 +1919,31 @@ static void
windows_create_inferior (struct target_ops *ops, char *exec_file,
char *allargs, char **in_env, int from_tty)
{
-#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
STARTUPINFOW si;
wchar_t real_path[PATH_MAX];
wchar_t shell[PATH_MAX]; /* Path to shell */
- const char *sh;
+#ifdef __CYGWIN__
wchar_t *toexec;
- wchar_t *cygallargs;
+#else /* not __CYGWIN__ */
+ wchar_t toexec[PATH_MAX];
+#endif /* not __CYGWIN__ */
+ wchar_t *uniallargs;
wchar_t *args;
size_t len;
- int tty;
- int ostdin, ostdout, ostderr;
-#else
- STARTUPINFOA si;
- char real_path[PATH_MAX];
+#else /* not __USE_UNICODE_API_ */
+ STARTUPINFO si;
+ char real_path[MAXPATHLEN];
char shell[MAX_PATH + 1]; /* Path to shell */
char *toexec;
char *args;
+ char *newallargs;
+#endif /* __USE_UNICODE_API_ */
+ const char *sh;
+#ifdef __CYGWIN__
+ int tty;
+ int ostdin, ostdout, ostderr;
+#else
HANDLE tty;
#endif
PROCESS_INFORMATION pi;
@@ -1917,35 +1967,69 @@ windows_create_inferior (struct target_o
if (!useshell)
{
flags |= DEBUG_ONLY_THIS_PROCESS;
+#ifdef __USE_UNICODE_API_
if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
PATH_MAX * sizeof (wchar_t)) < 0)
error (_("Error starting executable: %d"), errno);
+#else /* not __USE_UNICODE_API_ */
+ cygwin_conv_to_win32_path (exec_file, real_path);
+#endif /* not __USE_UNICODE_API_ */
toexec = real_path;
+#ifdef __USE_UNICODE_API_
len = mbstowcs (NULL, allargs, 0) + 1;
if (len == (size_t) -1)
error (_("Error starting executable: %d"), errno);
- cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
- mbstowcs (cygallargs, allargs, len);
+ uniallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
+ mbstowcs (uniallargs, allargs, len);
+#endif /* __USE_UNICODE_API_ */
}
else
{
sh = getenv ("SHELL");
if (!sh)
sh = "/bin/sh";
+#ifdef __USE_UNICODE_API_
if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, PATH_MAX) < 0)
error (_("Error starting executable via shell: %d"), errno);
len = sizeof (L" -c 'exec '") + mbstowcs (NULL, exec_file, 0)
+ mbstowcs (NULL, allargs, 0) + 2;
- cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
- swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
+ uniallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
+ swprintf (uniallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
+#else /* not __USE_UNICODE_API_ */
+ cygwin_conv_to_win32_path (sh, shell);
+ newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
+ + strlen (allargs) + 2);
+ sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
+ allargs = newallargs;
+#endif /* not __USE_UNICODE_API_ */
toexec = shell;
flags |= DEBUG_PROCESS;
}
- args = (wchar_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
+#else /* not __CYGWIN__ */
+#ifdef __USE_UNICODE_API_
+ MultiByteToWideChar (CP_ACP, 0, exec_file, strlen (exec_file) + 1,
toexec,
+ sizeof toexec);
+ uniallargs = (wchar_t *) alloca ((strlen (allargs) + 1) * sizeof
(wchar_t));
+ mbstowcs (uniallargs, allargs, len);
+#else /* not __USE_UNICODE_API_ */
+ toexec = exec_file;
+#endif /* not __USE_UNICODE_API_ */
+ flags |= DEBUG_ONLY_THIS_PROCESS;
+#endif /* __CYGWIN__ */
+#ifdef __USE_UNICODE_API_
+ args = (wchar_t *) alloca ((wcslen (toexec) + wcslen (uniallargs) + 2)
* sizeof (wchar_t));
wcscpy (args, toexec);
wcscat (args, L" ");
- wcscat (args, cygallargs);
+ wcscat (args, uniallargs);
+#else /* not __USE_UNICODE_API_ */
+ args = alloca (strlen (toexec) + strlen (allargs) + 2);
+ strcpy (args, toexec);
+ strcat (args, " ");
+ strcat (args, allargs);
+#endif /* not __USE_UNICODE_API_ */
+
+#ifdef __CYGWIN__
/* Prepare the environment vars for CreateProcess. */
cygwin_internal (CW_SYNC_WINENV);

@@ -1969,37 +2053,7 @@ windows_create_inferior (struct target_o
dup2 (tty, 2);
}
}
-
- windows_init_thread_list ();
- ret = CreateProcessW (0,
- args, /* command line */
- NULL, /* Security */
- NULL, /* thread */
- TRUE, /* inherit handles */
- flags, /* start flags */
- NULL, /* environment */
- NULL, /* current directory */
- &si,
- &pi);
- if (tty >= 0)
- {
- close (tty);
- dup2 (ostdin, 0);
- dup2 (ostdout, 1);
- dup2 (ostderr, 2);
- close (ostdin);
- close (ostdout);
- close (ostderr);
- }
-#else
- args = alloca (strlen (toexec) + strlen (allargs) + 2);
- strcpy (args, toexec);
- strcat (args, " ");
- strcat (args, allargs);
-
- toexec = exec_file;
- flags |= DEBUG_ONLY_THIS_PROCESS;
-
+#else /* not __CYGWIN__ */
if (!inferior_io_terminal)
tty = INVALID_HANDLE_VALUE;
else
@@ -2021,8 +2075,20 @@ windows_create_inferior (struct target_o
si.dwFlags |= STARTF_USESTDHANDLES;
}
}
-
+#endif /* not __CYGWIN__ */
windows_init_thread_list ();
+#ifdef __USE_UNICODE_API_
+ ret = CreateProcessW (0,
+ args, /* command line */
+ NULL, /* Security */
+ NULL, /* thread */
+ TRUE, /* inherit handles */
+ flags, /* start flags */
+ NULL, /* environment */
+ NULL, /* current directory */
+ &si,
+ &pi);
+#else /* not __USE_UNICODE_API_ */
ret = CreateProcessA (0,
args, /* command line */
NULL, /* Security */
@@ -2033,6 +2099,19 @@ windows_create_inferior (struct target_o
NULL, /* current directory */
&si,
&pi);
+#endif /* not _USE_UNICODE_API_ */
+#ifdef __CYGWIN__
+ if (tty >= 0)
+ {
+ close (tty);
+ dup2 (ostdin, 0);
+ dup2 (ostdout, 1);
+ dup2 (ostderr, 2);
+ close (ostdin);
+ close (ostdout);
+ close (ostderr);
+ }
+#else
if (tty != INVALID_HANDLE_VALUE)
CloseHandle (tty);
#endif
@@ -2300,9 +2379,10 @@ _initialize_windows_nat (void)
init_windows_ops ();

#ifdef __CYGWIN__
+#ifdef __USE_UNICODE_API_
cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
#endif
-
+#endif
c = add_com ("dll-symbols", class_files, dll_symbol_command,
_("Load dll library symbols from FILE."));
set_cmd_completer (c, filename_completer);
@@ -2485,7 +2565,7 @@ bad_EnumProcessModules (HANDLE w, HMODUL
{
return FALSE;
}
-#ifndef __CYGWIN__
+#ifndef __USE_UNICODE_API_
static DWORD WINAPI
bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
{
@@ -2547,17 +2627,17 @@ _initialize_loadable (void)
GetProcAddress (hm, "EnumProcessModules");
dyn_GetModuleInformation = (void *)
GetProcAddress (hm, "GetModuleInformation");
-#ifndef __CYGWIN__
+#ifndef __USE_UNICODE_API_
dyn_GetModuleFileNameExA = (void *)
GetProcAddress (hm, "GetModuleFileNameExA");
#else
dyn_GetModuleFileNameExW = (void *)
GetProcAddress (hm, "GetModuleFileNameExW");
-#endif
+#endif /* __USE_UNICODE_API_ */
}

if (!dyn_EnumProcessModules || !dyn_GetModuleInformation
-#ifndef __CYGWIN__
+#ifndef __USE_UNICODE_API_
|| !dyn_GetModuleFileNameExA
#else
|| !dyn_GetModuleFileNameExW
@@ -2568,7 +2648,7 @@ _initialize_loadable (void)
wasn't found in psapi.dll. */
dyn_EnumProcessModules = bad_EnumProcessModules;
dyn_GetModuleInformation = bad_GetModuleInformation;
-#ifndef __CYGWIN__
+#ifndef __USE_UNICODE_API_
dyn_GetModuleFileNameExA = bad_GetModuleFileNameExA;
#else
dyn_GetModuleFileNameExW = bad_GetModuleFileNameExW;