Commit e1b86444676b70154bf8ab450d429bdef57a8276

Paul Betts 2011-09-21T11:17:30

Rewrite getenv to use Win32 version on Windows

diff --git a/src/config.c b/src/config.c
index f233e76..261beb4 100644
--- a/src/config.c
+++ b/src/config.c
@@ -306,20 +306,24 @@ int git_config_get_string(git_config *cfg, const char *name, const char **out)
 
 int git_config_find_global(char *global_config_path)
 {
-	const char *home;
+	char *home;
 
-	home = getenv("HOME");
+	home = p_getenv("HOME");
 
 #ifdef GIT_WIN32
 	if (home == NULL)
-		home = getenv("USERPROFILE");
+		home = p_getenv("USERPROFILE");
 #endif
 
-	if (home == NULL)
+	if (home == NULL) {
+		free(home);
 		return git__throw(GIT_EOSERR, "Failed to open global config file. Cannot locate the user's home directory");
+	}
 
 	git_path_join(global_config_path, home, GIT_CONFIG_FILENAME);
 
+	free(home);
+
 	if (git_futils_exists(global_config_path) < GIT_SUCCESS)
 		return git__throw(GIT_EOSERR, "Failed to open global config file. The file does not exist");
 
diff --git a/src/posix.c b/src/posix.c
index 1b85b05..fb8ce37 100644
--- a/src/posix.c
+++ b/src/posix.c
@@ -39,6 +39,15 @@ int p_getcwd(char *buffer_out, size_t size)
 	return GIT_SUCCESS;
 }
 
+char* p_getenv(const char* name)
+{
+	char* buf = getenv(name);
+	if (!buf)
+		return buf;
+
+	return git__strdup(buf);
+}
+
 #endif
 
 int p_read(git_file fd, void *buf, size_t cnt)
diff --git a/src/posix.h b/src/posix.h
index 48b0255..d656e8e 100644
--- a/src/posix.h
+++ b/src/posix.h
@@ -44,6 +44,7 @@ extern int p_write(git_file fd, const void *buf, size_t cnt);
 extern int p_open(const char *path, int flags);
 extern int p_creat(const char *path, int mode);
 extern int p_getcwd(char *buffer_out, size_t size);
+extern char* p_getenv(const char* name);
 
 #ifndef GIT_WIN32
 
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index af54e7f..85a04bc 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -370,6 +370,30 @@ int p_mkstemp(char *tmp_path)
 	return p_creat(tmp_path, 0744);
 }
 
+char* p_getenv(const char* name)
+{
+	wchar_t* buf;
+	wchar_t* name_w = conv_utf8_to_utf16(name);
+	char* ret;
+	DWORD len;
+
+	len = GetEnvironmentVariableW(name_w, NULL, 0);
+	if (len == 0) {
+		free(name_w);
+		return NULL;
+	}
+
+	len++;  /* Null Terminator */
+	buf = malloc(sizeof(wchar_t) * len);
+	GetEnvironmentVariableW(name_w, buf, len);
+
+	ret = conv_utf16_to_utf8(buf);
+
+	free(name_w);
+	free(buf);
+	return ret;
+}
+
 int p_setenv(const char* name, const char* value, int overwrite)
 {
 	if (overwrite != 1)
diff --git a/tests-clay/clay_main.c b/tests-clay/clay_main.c
index 25342e7..b2849d5 100644
--- a/tests-clay/clay_main.c
+++ b/tests-clay/clay_main.c
@@ -388,14 +388,17 @@ find_tmp_path(char *buffer, size_t length)
  	size_t i;
 
 	for (i = 0; i < var_count; ++i) {
-		const char *env = getenv(env_vars[i]);
+		char *env = p_getenv(env_vars[i]);
 		if (!env)
 			continue;
 
 		if (is_valid_tmp_path(env)) {
 			strncpy(buffer, env, length);
+			free(env);
 			return 0;
 		}
+
+		free(env);
 	}
 
 	/* If the environment doesn't say anything, try to use /tmp */
diff --git a/tests/t15-config.c b/tests/t15-config.c
index d912abb..ac460bc 100644
--- a/tests/t15-config.c
+++ b/tests/t15-config.c
@@ -217,7 +217,7 @@ BEGIN_TEST(config10, "a repo's config overrides the global config")
 	int version;
 	char *old_home;
 
-	old_home = git__strdup(getenv("HOME"));
+	old_home = p_getenv("HOME");
 	p_setenv("HOME", CONFIG_BASE, 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
@@ -237,7 +237,7 @@ BEGIN_TEST(config11, "fall back to the global config")
 	int num;
 	char *old_home;
 
-	old_home = git__strdup(getenv("HOME"));
+	old_home = p_getenv("HOME");
 	p_setenv("HOME", CONFIG_BASE, 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
diff --git a/tests/t16-remotes.c b/tests/t16-remotes.c
index af54f29..b76557f 100644
--- a/tests/t16-remotes.c
+++ b/tests/t16-remotes.c
@@ -34,7 +34,7 @@ BEGIN_TEST(remotes0, "remote parsing works")
 	git_config *cfg;
 	char *old_home;
 
-	old_home = git__strdup(getenv("HOME"));
+	old_home = p_getenv("HOME");
 	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
@@ -58,7 +58,7 @@ BEGIN_TEST(refspec0, "remote with refspec works")
 	const git_refspec *refspec = NULL;
 	char *old_home;
 
-	old_home = git__strdup(getenv("HOME"));
+	old_home = p_getenv("HOME");
 	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
@@ -83,7 +83,7 @@ BEGIN_TEST(refspec1, "remote fnmatch works as expected")
 	const git_refspec *refspec = NULL;
 	char *old_home;
 
-	old_home = git__strdup(getenv("HOME"));
+	old_home = p_getenv("HOME");
 	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
@@ -109,7 +109,7 @@ BEGIN_TEST(refspec2, "refspec transform")
 	char ref[1024] = {0};
 	char *old_home;
 
-	old_home = git__strdup(getenv("HOME"));
+	old_home = p_getenv("HOME");
 	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));