From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21181 invoked by alias); 20 Apr 2011 10:26:47 -0000 Received: (qmail 21169 invoked by uid 22791); 20 Apr 2011 10:26:45 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL,BAYES_00,MSGID_MULTIPLE_AT,TW_CP X-Spam-Check-By: sourceware.org Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.200.156) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 20 Apr 2011 10:26:30 +0000 Received: from md2.u-strasbg.fr (md2.u-strasbg.fr [IPv6:2001:660:2402::187]) by mailhost.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id p3KAQP9O051010 ; Wed, 20 Apr 2011 12:26:25 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from mailserver.u-strasbg.fr (ms5.u-strasbg.fr [130.79.204.14]) by md2.u-strasbg.fr (8.14.4/jtpda-5.5pre1) with ESMTP id p3KAQPgw076787 ; Wed, 20 Apr 2011 12:26:25 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from E6510Muller (gw-ics.u-strasbg.fr [130.79.210.225]) (user=mullerp mech=LOGIN) by mailserver.u-strasbg.fr (8.14.4/jtpda-5.5pre1) with ESMTP id p3KAQOs2023648 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) ; Wed, 20 Apr 2011 12:26:25 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) From: "Pierre Muller" To: Cc: "=?iso-8859-1?Q?'Sebasti=E1n_Puebla_Castro'?=" Subject: [RFC] Add support for locally modified environment variables for windows-nat.c Date: Wed, 20 Apr 2011 10:26:00 -0000 Message-ID: <000601cbff45$66fa5820$34ef0860$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-04/txt/msg00347.txt.bz2 A while ago Sebastian Puebla submitted a patch for support of locally modified environment variables. http://sourceware.org/ml/gdb-patches/2010-05/msg00317.html http://sourceware.org/ml/gdb-patches/2010-08/msg00026.html http://sourceware.org/ml/gdb-patches/2010-11/msg00128.html Nevertheless, I suspect that his patch would not have worked for Cygwin, because Cygwin converts several environment variables from windows style to POSIX style. Here is a patch that does support also Cygwin special variables. This patch applies on top of my previously submitted patch to separate out Cygwin/mingw and ANSI/Unicode specific code. http://sourceware.org/ml/gdb-patches/2011-04/msg00328.html The patch allows to propagate locally modified environment variables to inferior for both Cygwin and mingw compilation hosts. There list of cygwin converted variables was extracted from from winsup/cygwin/environ.cc source, from January 2011. Comments welcome, Pierre Muller 2011-04-20 Pierre Muller Add support for locally modifed environment variables in windows native hosts. (win_env): New type. (conv_envvars): New array of type win_env. (cygwin_convert_envs, cywin_restore_envs): New functions using CONV_ENVVARS array to convert Cygwin environment variables back and forth to Windows style. (windows_create_inferior): Add support for setting 7th parameter of CreateProcess call containing possibly locally modified environment variables. diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 9b49e6e..90e52af 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -1967,6 +1967,95 @@ windows_set_console_info (STARTUPINFO *si, DWORD *flags) *flags |= CREATE_NEW_CONSOLE; } +#ifdef __CYGWIN__ +/* List of names which are converted from dos to unix on the way in + and back again on the way out. + PATH needs to be here because CreateProcess uses it and gdb uses + CreateProcess. HOME is here because most shells use it and would be + confused by Windows style path names. */ +typedef struct struct_win_env { + char *name; + int in_index; + void *in_orig_val; + int is_list; +} win_env; + +/* This list is extracted from cygwin/environ.cc source, + list from January 2011. */ +static win_env conv_envvars[] = + { + {"PATH=", -1, NULL, 1}, + {"HOME=", -1, NULL, 0}, + {"LD_LIBRARY_PATH=", -1, NULL, 1}, + {"TMPDIR=", -1, NULL, 0}, + {"TMP=", -1, NULL, 0}, + {"TEMP=", -1, NULL, 0}, + {NULL, -1, NULL, 0} + }; + +/* cgwin_convert_envs function uses conv_envvars array above to + convert Cygwin environment variables back to win32 format. */ + +static void +cygwin_convert_envs (char **in_env) +{ + int i, j; + + for (i = 0; in_env[i]; i++) + { + for (j = 0; conv_envvars[j].name; j++) + { + char *name = conv_envvars[j].name; + int nlen = strlen(name); + + if (strncmp (in_env[i], name, nlen) == 0) + { + char *conv; + int len; + + /* We found this environment variable that we need to convert. */ + conv_envvars[j].in_index = i; + conv_envvars[j].in_orig_val = in_env[i]; + if (conv_envvars[j].is_list) + { + len = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, + &in_env[i][nlen], NULL, 0); + conv = (char *) alloca (len + nlen + 1); + strcpy (conv, name); + cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, + &in_env[i][nlen], &conv[nlen], len); + } + else + { + conv = (char *) alloca (__PMAX + nlen); + strcpy (conv, name); + cygwin_conv_path (CCP_POSIX_TO_WIN_A, + &in_env[i][nlen], &conv[nlen], __PMAX); + } + in_env[i] = xstrdup (conv); + } + } + } +} + +/* cygwin_restore_envs function restores in_env elements to their + original value. */ + +static void +cygwin_restore_envs (char **in_env) +{ + int i, j; + + for (j = 0; conv_envvars[j].name; j++) + if (conv_envvars[j].in_index != -1) + { + xfree (in_env[conv_envvars[j].in_index]); + in_env[conv_envvars[j].in_index] = conv_envvars[j].in_orig_val; + } +} + +#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. @@ -1983,6 +2072,9 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, win_buf_t *toexec; win_buf_t *cygallargs; win_buf_t *args; + size_t env_size; + int i; + win_buf_t *out_env; #ifdef __USEWIDE size_t len; #endif @@ -2010,6 +2102,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, windows_set_console_info (&si, &flags); #ifdef __CYGWIN__ + cygwin_convert_envs (in_env); if (!useshell) #endif { @@ -2071,15 +2164,43 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, wcscpy (args, toexec); wcscat (args, L" "); wcscat (args, cygallargs); + env_size = 1; + for (i = 0; in_env[i]; i++) + { + env_size += mbstowcs (NULL, in_env[i], 0) + 1; + } + out_env = (win_buf_t *) alloca (env_size * sizeof (win_buf_t *)); + env_size = 0; + for (i = 0; in_env[i]; i++) + { + int len = mbstowcs (NULL, in_env[i], 0) + 1; + mbstowcs (&out_env[env_size], in_env[i], len); + env_size += len; + } + out_env[env_size] = L'\0'; + flags |= CREATE_UNICODE_ENVIRONMENT; #else args = (win_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2); strcpy (args, toexec); strcat (args, " "); strcat (args, cygallargs); + env_size = 1; + for (i = 0; in_env[i]; i++) + { + env_size += strlen(in_env[i]) + 1; + } + out_env = (win_buf_t *) alloca (env_size * sizeof (win_buf_t *)); + env_size = 0; + for (i = 0; in_env[i]; i++) + { + int len = strlen(in_env[i]) + 1; + strcpy (&out_env[env_size], in_env[i]); + env_size += len; + } + out_env[env_size] = '\0'; #endif #ifdef __CYGWIN__ - /* Prepare the environment vars for CreateProcess. */ cygwin_internal (CW_SYNC_WINENV); if (!inferior_io_terminal) @@ -2137,11 +2258,13 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, NULL, /* thread */ TRUE, /* inherit handles */ flags, /* start flags */ - NULL, /* environment */ + out_env, /* environment */ NULL, /* current directory */ &si, &pi); #ifdef __CYGWIN__ + cygwin_restore_envs (in_env); + if (tty >= 0) { close (tty);