This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Separate Cygwin/mingw and ANSI/Unicode parts in windows-nat.c


  As nobody reacted to my earlier email,
I send here a first attempt to separate out
what depends on the fact that we use ANSI or Wide functions
in the Windows API calls from what is specific to Cygwin code.
(No attempt to use UNICODE standard macros here).

  The present code can be compiled in 6 versions:
cygwin (using wide Windows API by default)
mingw32 (using ANSI Windows API functions)
mingw64 (also using ANSI Windows API functions)
but also
mingw32 with wide Windows API functions (by adding -D__USEWIDE to CFLAGS)
likewise for mingw64
and finally also
cygwin with ANSI windows functions (by adding -D__USEANSI to CFLAGS).

  As I stated earlier, I am mostly interested in the fact 
that mingw32 still supports ANSI versions to be able to still use it on 
old Windows 95 OS.

  The fact that all 6 versions compile allowed me to better separate
out Cygwin specific code from what is related to the use of Wide strings.
In particular, windows_create_inferior is simplified which 
is important for the yet to come GDB local environment variable changes
support.

  Comments?

Pierre Muller

2011-04-19  Pierre Muller  <muller@ics.u-strasbg.fr>

	* windows-nat.c: Allow compilation using ANSI and Unicode versions
	of Windows API functions for both cygwin and mingw hosts.
	(__USEANSI): Check if defined before setting __USEWIDE macro
	as default for cygwin compilation.
	(CCP_WIN_TO_POSIX, CCP_POSIX_TO_WIN): New macros to allow
	using same code for ANSI and Unicode Cygwin compilation.
	(cygwin_buf_t): Rename type to...
	(win_buf_t): this.
	(useshell): Only define varaible for Cygwin compilation.
	Reorganize code using __USEWIDE instead of __CYGWIN__ conditional
	when appropriate.
	(get_module_name): Ditto.
	(windows_make_so): Ditto.
	(windows_create_inferior): Reorganize to simplify code.
	

Index: windows-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/windows-nat.c,v
retrieving revision 1.216
diff -u -p -r1.216 windows-nat.c
--- windows-nat.c	7 Apr 2011 22:24:17 -0000	1.216
+++ windows-nat.c	19 Apr 2011 15:55:15 -0000
@@ -101,24 +101,36 @@ static struct target_ops windows_ops;
 
 #ifndef __CYGWIN__
 # define __PMAX	(MAX_PATH + 1)
+#else
+# define __PMAX	PATH_MAX
+/* The starting and ending address of the cygwin1.dll text segment.  */
+  static CORE_ADDR cygwin_load_start;
+  static CORE_ADDR cygwin_load_end;
+# ifndef __USEANSI
+#  define __USEWIDE
+#  define CCP_WIN_TO_POSIX CCP_WIN_W_TO_POSIX
+#  define CCP_POSIX_TO_WIN CCP_POSIX_TO_WIN_W
+# else
+#  define CCP_WIN_TO_POSIX CCP_WIN_A_TO_POSIX
+#  define CCP_POSIX_TO_WIN CCP_POSIX_TO_WIN_A
+#endif
+#endif
+
+#ifndef __USEWIDE
+  typedef char win_buf_t;
   static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR,
DWORD);
 # define STARTUPINFO STARTUPINFOA
 # define CreateProcess CreateProcessA
 # define GetModuleFileNameEx_name "GetModuleFileNameExA"
 # define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
 #else
-# define __PMAX	PATH_MAX
-/* The starting and ending address of the cygwin1.dll text segment.  */
-  static CORE_ADDR cygwin_load_start;
-  static CORE_ADDR cygwin_load_end;
-#   define __USEWIDE
-    typedef wchar_t cygwin_buf_t;
-    static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE,
-						LPWSTR, DWORD);
-#   define STARTUPINFO STARTUPINFOW
-#   define CreateProcess CreateProcessW
-#   define GetModuleFileNameEx_name "GetModuleFileNameExW"
-#   define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
+  typedef wchar_t win_buf_t;
+  static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE,
+					      LPWSTR, DWORD);
+# define STARTUPINFO STARTUPINFOW
+# define CreateProcess CreateProcessW
+# define GetModuleFileNameEx_name "GetModuleFileNameExW"
+# define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
 #endif
 
 static int have_saved_context;	/* True if we've saved context from a
@@ -212,13 +224,13 @@ static int open_process_used = 0;
 static int new_console = 0;
 #ifdef __CYGWIN__
 static int cygwin_exceptions = 0;
+static int useshell = 0;		/* use shell for subprocesses */
 #endif
 static int new_group = 1;
 static int debug_exec = 0;		/* show execution */
 static int debug_events = 0;		/* show events from kernel */
 static int debug_memory = 0;		/* show target memory accesses */
 static int debug_exceptions = 0;	/* show target exceptions */
-static int useshell = 0;		/* use shell for subprocesses */
 
 /* This vector maps GDB's idea of a register's number into an offset
    in the windows exception context vector.
@@ -513,8 +525,8 @@ get_module_name (LPVOID base_address, ch
   HMODULE *DllHandle = dh_buf;	/* Set to temporary storage for
 				   initial query.  */
   DWORD cbNeeded;
-#ifdef __CYGWIN__
-  cygwin_buf_t pathbuf[__PMAX];	/* Temporary storage prior to
converting to
+#ifdef __USEWIDE
+  win_buf_t pathbuf[__PMAX];	/* Temporary storage prior to converting to
 				   posix form.  __PMAX is always enough
 				   as long as SO_NAME_MAX_PATH_SIZE is
defined
 				   as 512.  */
@@ -547,15 +559,19 @@ 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__
-	  /* Cygwin prefers that the path be in /x/y/z format.  */
+#ifdef __USEWIDE
 	  len = GetModuleFileNameEx (current_process_handle,
 				      DllHandle[i], pathbuf, __PMAX);
 	  if (len == 0)
 	    error (_("Error getting dll name: %lu."), GetLastError ());
-	  if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret,
+# ifdef __CYGWIN__
+	  /* Cygwin prefers that the path be in /x/y/z format.  */
+	  if (cygwin_conv_path (CCP_WIN_TO_POSIX, pathbuf, dll_name_ret,
 				__PMAX) < 0)
 	    error (_("Error converting dll name to POSIX: %d."), errno);
+# else
+	  wcstombs (dll_name_ret, pathbuf, __PMAX);
+# endif
 #else
 	  len = GetModuleFileNameEx (current_process_handle,
 				      DllHandle[i], dll_name_ret, __PMAX);
@@ -681,7 +697,7 @@ windows_make_so (const char *name, LPVOI
       strcat (buf, "\\ntdll.dll");
     }
 #else
-  cygwin_buf_t buf[__PMAX];
+  win_buf_t buf[__PMAX];
 
   buf[0] = 0;
   if (access (name, F_OK) != 0)
@@ -689,12 +705,12 @@ windows_make_so (const char *name, LPVOI
       if (strcasecmp (name, "ntdll.dll") == 0)
 #ifdef __USEWIDE
 	{
-	  GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t));
+	  GetSystemDirectoryW (buf, sizeof (buf) / sizeof (win_buf_t));
 	  wcscat (buf, L"\\ntdll.dll");
 	}
 #else
 	{
-	  GetSystemDirectoryA (buf, sizeof (buf) / sizeof (wchar_t));
+	  GetSystemDirectoryA (buf, sizeof (buf) / sizeof (win_buf_t));
 	  strcat (buf, "\\ntdll.dll");
 	}
 #endif
@@ -708,7 +724,7 @@ windows_make_so (const char *name, LPVOI
   strcpy (so->so_name, buf);
 #else
   if (buf[0])
-    cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
+    cygwin_conv_path (CCP_WIN_TO_POSIX, buf, so->so_name,
 		      SO_NAME_MAX_PATH_SIZE);
   else
     {
@@ -1961,21 +1977,19 @@ windows_create_inferior (struct target_o
 		       char *allargs, char **in_env, int from_tty)
 {
   STARTUPINFO si;
-#ifdef __CYGWIN__
-  cygwin_buf_t real_path[__PMAX];
-  cygwin_buf_t shell[__PMAX]; /* Path to shell */
+  win_buf_t real_path[__PMAX];
+  win_buf_t shell[__PMAX]; /* Path to shell */
   const char *sh;
-  cygwin_buf_t *toexec;
-  cygwin_buf_t *cygallargs;
-  cygwin_buf_t *args;
+  win_buf_t *toexec;
+  win_buf_t *cygallargs;
+  win_buf_t *args;
+#ifdef __USEWIDE
   size_t len;
+#endif
+#ifdef __CYGWIN__
   int tty;
   int ostdin, ostdout, ostderr;
 #else
-  char real_path[__PMAX];
-  char shell[__PMAX]; /* Path to shell */
-  char *toexec;
-  char *args;
   HANDLE tty;
 #endif
   PROCESS_INFORMATION pi;
@@ -1997,33 +2011,48 @@ windows_create_inferior (struct target_o
 
 #ifdef __CYGWIN__
   if (!useshell)
+#endif
     {
       flags |= DEBUG_ONLY_THIS_PROCESS;
-      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path,
-			    __PMAX * sizeof (cygwin_buf_t)) < 0)
+#ifdef __CYGWIN__
+      if (cygwin_conv_path (CCP_POSIX_TO_WIN, exec_file, real_path,
+			    __PMAX * sizeof (win_buf_t)) < 0)
 	error (_("Error starting executable: %d"), errno);
       toexec = real_path;
+#else
+#ifndef __USEWIDE
+      toexec = exec_file;
+#else
+      len = mbstowcs (NULL, exec_file, 0) + 1;
+      if (len == (size_t) -1)
+	error (_("Error starting executable: %d"), errno);
+      toexec = (win_buf_t *) alloca (len * sizeof (win_buf_t));
+      mbstowcs (toexec, exec_file, len);
+#endif
+#endif /* not __CYGWIN__ */
+
 #ifdef __USEWIDE
       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));
+      cygallargs = (win_buf_t *) alloca (len * sizeof (win_buf_t));
       mbstowcs (cygallargs, allargs, len);
 #else
       cygallargs = allargs;
 #endif
     }
+#ifdef __CYGWIN__
   else
     {
       sh = getenv ("SHELL");
       if (!sh)
 	sh = "/bin/sh";
-      if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0)
+      if (cygwin_conv_path (CCP_POSIX_TO_WIN, sh, shell, __PMAX) < 0)
       	error (_("Error starting executable via shell: %d"), errno);
 #ifdef __USEWIDE
       len = sizeof (L" -c 'exec  '") + mbstowcs (NULL, exec_file, 0)
 	    + mbstowcs (NULL, allargs, 0) + 2;
-      cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t));
+      cygallargs = (win_buf_t *) alloca (len * sizeof (win_buf_t));
       swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs);
 #else
       cygallargs = (char *)
@@ -2034,20 +2063,22 @@ windows_create_inferior (struct target_o
       toexec = shell;
       flags |= DEBUG_PROCESS;
     }
+#endif /* __CYGWIN__ */
 
 #ifdef __USEWIDE
-  args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) +
2)
-				  * sizeof (wchar_t));
+  args = (win_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2)
+				  * sizeof (win_buf_t));
   wcscpy (args, toexec);
   wcscat (args, L" ");
   wcscat (args, cygallargs);
 #else
-  args = (cygwin_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) +
2);
+  args = (win_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2);
   strcpy (args, toexec);
   strcat (args, " ");
   strcat (args, cygallargs);
 #endif
 
+#ifdef __CYGWIN__
   /* Prepare the environment vars for CreateProcess.  */
   cygwin_internal (CW_SYNC_WINENV);
 
@@ -2072,34 +2103,7 @@ windows_create_inferior (struct target_o
 	}
     }
 
-  windows_init_thread_list ();
-  ret = CreateProcess (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
-  toexec = exec_file;
-  args = alloca (strlen (toexec) + strlen (allargs) + 2);
-  strcpy (args, toexec);
-  strcat (args, " ");
-  strcat (args, allargs);
-
   flags |= DEBUG_ONLY_THIS_PROCESS;
 
   if (!inferior_io_terminal)
@@ -2124,17 +2128,31 @@ windows_create_inferior (struct target_o
 	}
     }
 
+#endif /* not __CYGWIN__ */
+
   windows_init_thread_list ();
-  ret = CreateProcessA (0,
-			args,	/* command line */
-			NULL,	/* Security */
-			NULL,	/* thread */
-			TRUE,	/* inherit handles */
-			flags,	/* start flags */
-			NULL,	/* environment */
-			NULL,	/* current directory */
-			&si,
-			&pi);
+  ret = CreateProcess (0,
+		       args,	/* command line */
+		       NULL,	/* Security */
+		       NULL,	/* thread */
+		       TRUE,	/* inherit handles */
+		       flags,	/* start flags */
+		       NULL,	/* environment */
+		       NULL,	/* current directory */
+		       &si,
+		       &pi);
+#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
@@ -2146,9 +2164,11 @@ windows_create_inferior (struct target_o
   CloseHandle (pi.hThread);
   CloseHandle (pi.hProcess);
 
+#ifdef __CYGWIN__
   if (useshell && shell[0] != '\0')
     saw_create = -1;
   else
+#endif
     saw_create = 0;
 
   do_initial_windows_stuff (ops, pi.dwProcessId, 0);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]