This is a fix, suggested by Lode Leroy, to not modify PATH in
"our" environment, because it's actually Explorer's environment.
See env_for_git().

To simplify the code, msys_path() now never returns NULL.
---
 menu.c       |  139 +++++++++++++++++++++++++++++++++------------------------
 systeminfo.c |   10 ++--
 2 files changed, 85 insertions(+), 64 deletions(-)

diff --git a/menu.c b/menu.c
index c6a5a55..f3e876c 100644
--- a/menu.c
+++ b/menu.c
@@ -8,9 +8,59 @@
 #include "systeminfo.h"

 /*
- * These are the functions for handling the context menu.
+ * Modifies a copy of the environment, to include Git in PATH
  */
+static void *env_for_git()
+{
+       static char *environment = NULL;
+
+       char *old_env, *old_path;
+       size_t old_len;
+
+       char *src, *dst;
+
+       if (NULL != environment)
+               return environment;
+
+       old_env = GetEnvironmentStrings();
+
+       /* calculate the length of the old_env */
+       old_len = 0;
+       src = old_env;
+       while (*src) {
+               size_t varlen = strlen(src) + 1;
+               old_len += varlen;
+               src += varlen;
+       };
+
+       /* allocate new env, adjusting to the new path */
+       // 16 is the length of all added constant string
+       // (e.g. the length of \bin;\mingw\bin;)
+       environment = malloc(old_len + 2 * strlen(msys_path()) + 16);
+
+       /* copy old environment skipping the PATH */
+       dst = environment;
+       for (src = old_env; *src; src += strlen(src)+1) {
+               if (strstr(src, "PATH=") != src) {
+                       strcpy(dst, src);
+                       dst += strlen(src)+1;
+               } else
+                       old_path = src + 5; // +5 to skip PATH=
+       }
+
+       /* append the new path */
+       dst += sprintf(dst, "PATH=%s\\bin;%s\\mingw\\bin;%s",
+               msys_path(), msys_path(), old_path) + 1;
+       *dst = '\0'; // terminate the environment block

+       FreeEnvironmentStrings(old_env);
+
+       return environment;
+}
+
+/*
+ * These are the functions for handling the context menu.
+ */
 static STDMETHODIMP query_context_menu(void *p, HMENU menu,
                                       UINT index, UINT first_command,
                                       UINT last_command, UINT flags)
@@ -82,24 +132,6 @@ static char *convert_directory_format(const char *path)
        return converted;
 }

-static void adjust_path_for_git(const char *msys_path)
-{
-       static int initialized = 0;
-
-       if (!initialized) {
-               const char *old_path = getenv("PATH");
-               size_t old_len = strlen(old_path);
-               size_t msys_path_len = strlen(msys_path);
-               char *new_path = malloc(old_len + 2 * msys_path_len + 23);
-               if (!new_path)
-                       return;
-               sprintf(new_path, "PATH=%s\\bin;%s\\mingw\\bin;%s",
-                       old_path, msys_path, msys_path);
-               putenv(new_path);
-               initialized = 1;
-       }
-}
-
 static STDMETHODIMP invoke_command(void *p,
                                   LPCMINVOKECOMMANDINFO info)
 {
@@ -115,51 +147,40 @@ static STDMETHODIMP invoke_command(void *p,
                STARTUPINFO si = { sizeof(si) };
                PROCESS_INFORMATION pi;
                
-               TCHAR * msysPath = msys_path();
+               TCHAR command[1024];
+               const char *wd;
+               DWORD dwAttr, fa;

-               if (msysPath)
+               wsprintf(command, TEXT("wish.exe \"%s/bin/git-gui\""),
+                        msys_path());
+               
+               
+               wd = this_->name;
+               if (wd == NULL || strlen(wd) == 0)
+                       wd = info->lpDirectory;
+
+               dwAttr = FILE_ATTRIBUTE_DIRECTORY;
+               fa = GetFileAttributes(wd);
+               if (! (fa & dwAttr))
+                       wd = info->lpDirectory;
+
+               debug_git("Trying to spawn '%s' in working directory '%s'\n", 
command, wd);
+               if (CreateProcess(
+                           NULL,
+                           command,
+                           NULL,
+                           NULL,
+                           FALSE,
+                           0, env_for_git(), wd, &si, &pi))
                {
-                       TCHAR command[1024];
-                       const char *wd;
-                       DWORD dwAttr, fa;
-
-                       adjust_path_for_git(msysPath);
-                       wsprintf(command, TEXT("wish.exe \"%s/bin/git-gui\""),
-                                msysPath);
-                       
-                       
-                       wd = this_->name;
-                       if (wd == NULL || strlen(wd) == 0)
-                               wd = info->lpDirectory;
-
-                       dwAttr = FILE_ATTRIBUTE_DIRECTORY;
-                       fa = GetFileAttributes(wd);
-                       if (! (fa & dwAttr))
-                               wd = info->lpDirectory;
-
-                       debug_git("Trying to spawn '%s' in working directory 
'%s'\n", command, wd);
-                       if (CreateProcess(
-                                   NULL,
-                                   command,
-                                   NULL,
-                                   NULL,
-                                   FALSE,
-                                   0, NULL, wd, &si, &pi))
-                       {
-                               CloseHandle(pi.hProcess);
-                               CloseHandle(pi.hThread);
-                       }
-                       else
-                       {
-                               debug_git("[ERROR] %s/%s:%d Could not create 
git gui process (%d)
Command: %s",
-                                         __FILE__, __FUNCTION__, __LINE__,
-                                         GetLastError(), command);
-                       }
+                       CloseHandle(pi.hProcess);
+                       CloseHandle(pi.hThread);
                }
                else
                {
-                       debug_git("[ERROR] %s/%s:%d Could not find msysPath",
-                                 __FILE__, __FUNCTION__, __LINE__);
+                       debug_git("[ERROR] %s/%s:%d Could not create git gui 
process (%d)
Command: %s",
+                                 __FILE__, __FUNCTION__, __LINE__,
+                                 GetLastError(), command);
                }
                
                return S_OK;
diff --git a/systeminfo.c b/systeminfo.c
index 2b046df..1e938d9 100644
--- a/systeminfo.c
+++ b/systeminfo.c
@@ -1,7 +1,7 @@
 #include <windows.h>
 #include "systeminfo.h"

-static TCHAR msysPath[MAX_PATH];
+static char msysPath[MAX_PATH];

 static int get_msys_path_from_registry (HKEY root) {
        HKEY key;
@@ -21,7 +21,7 @@ static int get_msys_path_from_registry (HKEY root) {
        return ERROR_SUCCESS == result;
 }

-TCHAR * msys_path(void)
+char *msys_path(void)
 {
        static int found_path = 0;

@@ -36,8 +36,8 @@ TCHAR * msys_path(void)
        if (! found_path)
                found_path = get_msys_path_from_registry (HKEY_LOCAL_MACHINE);

-       if (found_path)
-               return msysPath;
+       if (! found_path)
+               msysPath[0] = '\0';

-       return NULL;
+       return msysPath;
 }
-- 
1.5.4.rc0.929.g50e2

Reply via email to