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().
---
This is version 3 of the patch, with only minor modifications,
comparing to version 2.

 Makefile |    5 ++-
 exec.c   |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 exec.h   |   11 +++++++++
 menu.c   |   46 ++-----------------------------------
 4 files changed, 93 insertions(+), 45 deletions(-)
 create mode 100644 exec.c
 create mode 100644 exec.h

diff --git a/Makefile b/Makefile
index dd6c1fe..bfc2bc6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-OBJECTS=ext.o debug.o dll.o factory.o menu.o systeminfo.o registry.o
+OBJECTS=ext.o debug.o dll.o factory.o menu.o systeminfo.o registry.o exec.o
 CFLAGS=-O -g

 TARGET=git_shell_ext.dll
@@ -20,9 +20,10 @@ $(TARGET): $(OBJECTS) git_shell_ext.def
 dll.o: dll.h ext.h factory.h systeminfo.h registry.h
 ext.o: ext.h debug.h
 factory.o: factory.h ext.h menu.h
-menu.o: menu.h ext.h debug.h systeminfo.h
+menu.o: menu.h ext.h debug.h systeminfo.h exec.h
 systeminfo.o: systeminfo.h
 registry.o: registry.h
+exec.o: debug.h systeminfo.h exec.h

 install: all
        regsvr32 -s -n -i:machine $(DLL_PATH)
diff --git a/exec.c b/exec.c
new file mode 100644
index 0000000..2da2c08
--- /dev/null
+++ b/exec.c
@@ -0,0 +1,76 @@
+#include <windows.h>
+#include <stdio.h>
+#include "debug.h"
+#include "systeminfo.h"
+#include "exec.h"
+
+char *env_for_git()
+{
+       static char *environment;
+
+       /*
+        * if we can't find path to msys in the registry, return NULL and
+        * the CreateProcess will copy the environment for us
+        */
+       if (!environment && msys_path()) {
+               char *old = GetEnvironmentStrings();
+               size_t space = 0, path_index = -1, name_len = 0, len2;
+
+               while (old[space]) {
+                       /* if it's PATH variable (could be Path= too!) */
+                       if (!strnicmp(old + space, "PATH=", 5)) {
+                               path_index = space;
+                               name_len = 5;
+                       }
+
+                       while (old[space])
+                               space++;
+                       space++; /* skip var-terminating NULL */
+               }
+
+               if (path_index == -1)
+                       path_index = space;
+
+               environment = malloc(space +
+                               2 * strlen(msys_path()) + 32);
+
+               /* copy the block up to the equal sign of PATH var */
+               memcpy(environment, old, path_index);
+               /* insert new segments of the PATH */
+               len2 = sprintf(environment + path_index,
+                       "PATH=%s\\bin;%s\\mingw\\bin%s",
+                       msys_path(), msys_path(), name_len ? ";" : "");
+               /* append original value of PATH and variables after it */
+               memcpy(environment + path_index + len2,
+                       old + path_index + name_len,
+                       space + 1 - path_index - name_len);
+
+               FreeEnvironmentStrings(old);
+       }
+
+       return environment;
+}
+
+void exec_gui(char *command, const char *wd)
+{
+       STARTUPINFO si = { sizeof(si) };
+       PROCESS_INFORMATION pi;
+
+       si.dwFlags = STARTF_USESHOWWINDOW;
+       si.wShowWindow = SW_HIDE;
+
+       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))
+       {
+               CloseHandle(pi.hProcess);
+               CloseHandle(pi.hThread);
+       }
+       else
+               debug_git("[ERROR] Could not create process (%d)"
+                       "wd: %s; cmd: %s",
+                       GetLastError(), wd, command);
+
+}
+
diff --git a/exec.h b/exec.h
new file mode 100644
index 0000000..cebb56b
--- /dev/null
+++ b/exec.h
@@ -0,0 +1,11 @@
+
+/*
+ * Modifies a copy of the environment to include Git in PATH
+ */
+char *env_for_git();
+
+/*
+ * Executes a console application hidden as in "git gui" to hide git
+ */
+void exec_gui(char *cmd, const char *wd);
+
diff --git a/menu.c b/menu.c
index c6a5a55..97811fa 100644
--- a/menu.c
+++ b/menu.c
@@ -6,6 +6,7 @@
 #include "ext.h"
 #include "debug.h"
 #include "systeminfo.h"
+#include "exec.h"

 /*
  * These are the functions for handling the context menu.
@@ -82,24 +83,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)
 {
@@ -112,9 +95,6 @@ static STDMETHODIMP invoke_command(void *p,

        if (command == 1)
        {
-               STARTUPINFO si = { sizeof(si) };
-               PROCESS_INFORMATION pi;
-               
                TCHAR * msysPath = msys_path();

                if (msysPath)
@@ -123,8 +103,7 @@ static STDMETHODIMP invoke_command(void *p,
                        const char *wd;
                        DWORD dwAttr, fa;

-                       adjust_path_for_git(msysPath);
-                       wsprintf(command, TEXT("wish.exe \"%s/bin/git-gui\""),
+                       wsprintf(command, TEXT("\"%s\\bin\\git.exe\" gui"),
                                 msysPath);
                        
                        
@@ -137,30 +116,11 @@ static STDMETHODIMP invoke_command(void *p,
                        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);
-                       }
+                       exec_gui(command, wd);
                }
                else
-               {
                        debug_git("[ERROR] %s/%s:%d Could not find msysPath",
                                  __FILE__, __FUNCTION__, __LINE__);
-               }
                
                return S_OK;
        }
-- 
1.5.4.rc0.929.g50e2

Reply via email to