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