about summary refs log tree commit diff
path: root/third_party/git/wrapper.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/git/wrapper.c')
-rw-r--r--third_party/git/wrapper.c84
1 files changed, 60 insertions, 24 deletions
diff --git a/third_party/git/wrapper.c b/third_party/git/wrapper.c
index e1eaef2e16..1e45ab7b92 100644
--- a/third_party/git/wrapper.c
+++ b/third_party/git/wrapper.c
@@ -4,6 +4,12 @@
 #include "cache.h"
 #include "config.h"
 
+static void do_nothing(size_t size)
+{
+}
+
+static void (*try_to_free_routine)(size_t size) = do_nothing;
+
 static int memory_limit_check(size_t size, int gentle)
 {
 	static size_t limit = 0;
@@ -24,11 +30,24 @@ static int memory_limit_check(size_t size, int gentle)
 	return 0;
 }
 
+try_to_free_t set_try_to_free_routine(try_to_free_t routine)
+{
+	try_to_free_t old = try_to_free_routine;
+	if (!routine)
+		routine = do_nothing;
+	try_to_free_routine = routine;
+	return old;
+}
+
 char *xstrdup(const char *str)
 {
 	char *ret = strdup(str);
-	if (!ret)
-		die("Out of memory, strdup failed");
+	if (!ret) {
+		try_to_free_routine(strlen(str) + 1);
+		ret = strdup(str);
+		if (!ret)
+			die("Out of memory, strdup failed");
+	}
 	return ret;
 }
 
@@ -42,13 +61,19 @@ static void *do_xmalloc(size_t size, int gentle)
 	if (!ret && !size)
 		ret = malloc(1);
 	if (!ret) {
-		if (!gentle)
-			die("Out of memory, malloc failed (tried to allocate %lu bytes)",
-			    (unsigned long)size);
-		else {
-			error("Out of memory, malloc failed (tried to allocate %lu bytes)",
-			      (unsigned long)size);
-			return NULL;
+		try_to_free_routine(size);
+		ret = malloc(size);
+		if (!ret && !size)
+			ret = malloc(1);
+		if (!ret) {
+			if (!gentle)
+				die("Out of memory, malloc failed (tried to allocate %lu bytes)",
+				    (unsigned long)size);
+			else {
+				error("Out of memory, malloc failed (tried to allocate %lu bytes)",
+				      (unsigned long)size);
+				return NULL;
+			}
 		}
 	}
 #ifdef XMALLOC_POISON
@@ -113,8 +138,14 @@ void *xrealloc(void *ptr, size_t size)
 	ret = realloc(ptr, size);
 	if (!ret && !size)
 		ret = realloc(ptr, 1);
-	if (!ret)
-		die("Out of memory, realloc failed");
+	if (!ret) {
+		try_to_free_routine(size);
+		ret = realloc(ptr, size);
+		if (!ret && !size)
+			ret = realloc(ptr, 1);
+		if (!ret)
+			die("Out of memory, realloc failed");
+	}
 	return ret;
 }
 
@@ -129,8 +160,14 @@ void *xcalloc(size_t nmemb, size_t size)
 	ret = calloc(nmemb, size);
 	if (!ret && (!nmemb || !size))
 		ret = calloc(1, 1);
-	if (!ret)
-		die("Out of memory, calloc failed");
+	if (!ret) {
+		try_to_free_routine(nmemb * size);
+		ret = calloc(nmemb, size);
+		if (!ret && (!nmemb || !size))
+			ret = calloc(1, 1);
+		if (!ret)
+			die("Out of memory, calloc failed");
+	}
 	return ret;
 }
 
@@ -441,9 +478,7 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
 		"abcdefghijklmnopqrstuvwxyz"
 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 		"0123456789";
-	static const int num_letters = ARRAY_SIZE(letters) - 1;
-	static const char x_pattern[] = "XXXXXX";
-	static const int num_x = ARRAY_SIZE(x_pattern) - 1;
+	static const int num_letters = 62;
 	uint64_t value;
 	struct timeval tv;
 	char *filename_template;
@@ -452,12 +487,12 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
 
 	len = strlen(pattern);
 
-	if (len < num_x + suffix_len) {
+	if (len < 6 + suffix_len) {
 		errno = EINVAL;
 		return -1;
 	}
 
-	if (strncmp(&pattern[len - num_x - suffix_len], x_pattern, num_x)) {
+	if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
 		errno = EINVAL;
 		return -1;
 	}
@@ -468,15 +503,16 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
 	 */
 	gettimeofday(&tv, NULL);
 	value = ((uint64_t)tv.tv_usec << 16) ^ tv.tv_sec ^ getpid();
-	filename_template = &pattern[len - num_x - suffix_len];
+	filename_template = &pattern[len - 6 - suffix_len];
 	for (count = 0; count < TMP_MAX; ++count) {
 		uint64_t v = value;
-		int i;
 		/* Fill in the random bits. */
-		for (i = 0; i < num_x; i++) {
-			filename_template[i] = letters[v % num_letters];
-			v /= num_letters;
-		}
+		filename_template[0] = letters[v % num_letters]; v /= num_letters;
+		filename_template[1] = letters[v % num_letters]; v /= num_letters;
+		filename_template[2] = letters[v % num_letters]; v /= num_letters;
+		filename_template[3] = letters[v % num_letters]; v /= num_letters;
+		filename_template[4] = letters[v % num_letters]; v /= num_letters;
+		filename_template[5] = letters[v % num_letters]; v /= num_letters;
 
 		fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
 		if (fd >= 0)