Re: [RFA] testsuite: Add a test for passing of environment variables to inferior

Corinna Vinschen
2011-10-05T11:40:24Z

On Oct 4 18:11, Pierre Muller wrote:
> here is an update that unsets all environment
> variables both in environ list before calling
> CreateProcess and in in_env list after...
>
> This passes the new updated test I just sent.

Oh boy, I guess there's no way around that for now. I will create
a new cygwin_internal call for just such a scenario, as proposed in
http://sourceware.org/ml/gdb-patches/2011-10/msg00079.html and add a
patch to GDB to use it if it's available. That way, we can limit this
complicated method to current and older versions of Cygwin.

> + /* Reset all environment variables to avoid leftover on next run. */
> + for (i = 0; environ[i] && *environ[i]; i++)
> + {
> + char *equalpos;
> + char *copy = alloca (strlen(environ[i]) + 1);

If the environment is very large, using alloca here in a loop might
result in a stack overflow. Pretty unlikely, I assume, but possible.

> + strcpy (copy, environ[i]);
> + equalpos = strchr (copy, '=');
> + if (equalpos)
> + *equalpos = '\0';
> + SetEnvironmentVariableA (copy, NULL);

Since Cygwin 1.7, the Cygwin multibyte charset does not correspond with
the current Windows ANSI codepage. Cygwin's default multibyte charset
is UTF-8, for instance, while the ANSI Windows functions will use some
arbitrary Windows codepage depending on system and user language. So we
should convert the variables to UNICODE and use the corresponding Win32
function.

Here's my proposal, based on your patch. I'll work on using the
yet-to-be-created new cygwin_internal call after I implemented it in
Cygwin.

* windows-nat.c: Include wchar.h to avoid compiler warnings.
(clear_win32_environment): New function for Cygwin to clear out
Win32 environment.
(windows_create_inferior): Prepare new environment from in_env
for Cygwin, too.

Index: windows-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/windows-nat.c,v
retrieving revision 1.219
diff -u -p -r1.219 windows-nat.c
--- windows-nat.c 28 Sep 2011 09:07:54 -0000 1.219
+++ windows-nat.c 5 Oct 2011 11:36:10 -0000
@@ -40,6 +40,7 @@
#include <imagehlp.h>
#include <psapi.h>
#ifdef __CYGWIN__
+#include <wchar.h>
#include <sys/cygwin.h>
#endif
#include <signal.h>
@@ -1963,6 +1964,28 @@ envvar_cmp (const void *a, const void *b
}
#endif

+#ifdef __CYGWIN__
+static void
+clear_win32_environment (char **env)
+{
+ int i;
+ size_t len;
+ wchar_t *copy = NULL, *equalpos;
+
+ for (i = 0; env[i] && *env[i]; i++)
+ {
+ len = mbstowcs (NULL, env[i], 0) + 1;
+ copy = (wchar_t *) xrealloc (copy, len * sizeof (wchar_t));
+ mbstowcs (copy, env[i], len);
+ equalpos = wcschr (copy, L'=');
+ if (equalpos)
+ *equalpos = L'\0';
+ SetEnvironmentVariableW (copy, NULL);
+ }
+ xfree (copy);
+}
+#endif
+
/* Start an inferior windows child process and sets inferior_ptid to its pid.
EXEC_FILE is the file to run.
ALLARGS is a string containing the arguments to the program.
@@ -1980,6 +2003,7 @@ windows_create_inferior (struct target_o
cygwin_buf_t *toexec;
cygwin_buf_t *cygallargs;
cygwin_buf_t *args;
+ char **old_env;
size_t len;
int tty;
int ostdin, ostdout, ostderr;
@@ -2066,7 +2090,11 @@ windows_create_inferior (struct target_o
strcat (args, cygallargs);
#endif

+ /* Reset all Win32 environment variables to avoid leftover on next run. */
+ clear_win32_environment (environ);
/* Prepare the environment vars for CreateProcess. */
+ old_env = environ;
+ environ = in_env;
cygwin_internal (CW_SYNC_WINENV);

if (!inferior_io_terminal)
@@ -2101,6 +2129,12 @@ windows_create_inferior (struct target_o
NULL, /* current directory */
&si,
&pi);
+ /* Reset all environment variables to avoid leftover on next run. */
+ clear_win32_environment (in_env);
+ /* Restore normal GDB environment variables. */
+ environ = old_env;
+ cygwin_internal (CW_SYNC_WINENV);
+
if (tty >= 0)
{
close (tty);

Corinna

--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat