wrapper.c: introduce gentle xmallocz that does not die()
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Aug 16, 2014 at 10:08 UTC
f8bb1d94311b7438e7e9831b51ffb047b7ae65d7
2 files changed
+53
-16
git-compat-util.h
+1
@@ -593,6 +593,7 @@ extern try_to_free_t set_try_to_free_routine(try_to_free_t);
593
extern char *xstrdup(const char *str);
594
extern void *xmalloc(size_t size);
595
extern void *xmallocz(size_t size);
596
+extern void *xmallocz_gently(size_t size);
597
extern void *xmemdupz(const void *data, size_t len);
598
extern char *xstrndup(const char *str, size_t len);
599
extern void *xrealloc(void *ptr, size_t size);
wrapper.c
+52
-16
@@ -9,16 +9,23 @@ static void do_nothing(size_t size)
9
10
static void (*try_to_free_routine)(size_t size) = do_nothing;
11
12
-static void memory_limit_check(size_t size)
12
+static int memory_limit_check(size_t size, int gentle)
13
{
14
static int limit = -1;
15
if (limit == -1) {
16
const char *env = getenv("GIT_ALLOC_LIMIT");
17
limit = env ? atoi(env) * 1024 : 0;
18
}
19
- if (limit && size > limit)
20
- die("attempting to allocate %"PRIuMAX" over limit %d",
21
- (intmax_t)size, limit);
19
+ if (limit && size > limit) {
20
+ if (gentle) {
21
+ error("attempting to allocate %"PRIuMAX" over limit %d",
22
+ (intmax_t)size, limit);
23
+ return -1;
24
+ } else
25
+ die("attempting to allocate %"PRIuMAX" over limit %d",
26
+ (intmax_t)size, limit);
27
+ }
28
+ return 0;
29
}
30
31
try_to_free_t set_try_to_free_routine(try_to_free_t routine)
@@ -42,11 +49,12 @@ char *xstrdup(const char *str)
49
return ret;
50
}
51
45
-void *xmalloc(size_t size)
52
+static void *do_xmalloc(size_t size, int gentle)
53
{
54
void *ret;
55
49
- memory_limit_check(size);
56
+ if (memory_limit_check(size, gentle))
57
+ return NULL;
58
ret = malloc(size);
59
if (!ret && !size)
60
ret = malloc(1);
@@ -55,9 +63,16 @@ void *xmalloc(size_t size)
63
ret = malloc(size);
64
if (!ret && !size)
65
ret = malloc(1);
58
- if (!ret)
59
- die("Out of memory, malloc failed (tried to allocate %lu bytes)",
60
- (unsigned long)size);
66
+ if (!ret) {
67
+ if (!gentle)
68
+ die("Out of memory, malloc failed (tried to allocate %lu bytes)",
69
+ (unsigned long)size);
70
+ else {
71
+ error("Out of memory, malloc failed (tried to allocate %lu bytes)",
72
+ (unsigned long)size);
73
+ return NULL;
74
+ }
75
+ }
76
}
77
#ifdef XMALLOC_POISON
78
memset(ret, 0xA5, size);
@@ -65,16 +80,37 @@ void *xmalloc(size_t size)
80
return ret;
81
}
82
68
-void *xmallocz(size_t size)
83
+void *xmalloc(size_t size)
84
+{
85
+ return do_xmalloc(size, 0);
86
+}
87
+
88
+static void *do_xmallocz(size_t size, int gentle)
89
{
90
void *ret;
71
- if (unsigned_add_overflows(size, 1))
72
- die("Data too large to fit into virtual memory space.");
73
- ret = xmalloc(size + 1);
74
- ((char*)ret)[size] = 0;
91
+ if (unsigned_add_overflows(size, 1)) {
92
+ if (gentle) {
93
+ error("Data too large to fit into virtual memory space.");
94
+ return NULL;
95
+ } else
96
+ die("Data too large to fit into virtual memory space.");
97
+ }
98
+ ret = do_xmalloc(size + 1, gentle);
99
+ if (ret)
100
+ ((char*)ret)[size] = 0;
101
return ret;
102
}
103
104
+void *xmallocz(size_t size)
105
+{
106
+ return do_xmallocz(size, 0);
107
+}
108
+
109
+void *xmallocz_gently(size_t size)
110
+{
111
+ return do_xmallocz(size, 1);
112
+}
113
+
114
/*
115
* xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
116
* "data" to the allocated memory, zero terminates the allocated memory,
@@ -96,7 +132,7 @@ void *xrealloc(void *ptr, size_t size)
132
{
133
void *ret;
134
99
- memory_limit_check(size);
135
+ memory_limit_check(size, 0);
136
ret = realloc(ptr, size);
137
if (!ret && !size)
138
ret = realloc(ptr, 1);
@@ -115,7 +151,7 @@ void *xcalloc(size_t nmemb, size_t size)
151
{
152
void *ret;
153
118
- memory_limit_check(size * nmemb);
154
+ memory_limit_check(size * nmemb, 0);
155
ret = calloc(nmemb, size);
156
if (!ret && (!nmemb || !size))
157
ret = calloc(1, 1);