[PATCH] introduce xmalloc and xrealloc

Introduce xmalloc and xrealloc to die gracefully with a descriptive
message when out of memory, rather than taking a SIGSEGV. 

Signed-off-by: Christopher Li<chrislgit@chrisli.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/blob.c b/blob.c
index f79f5ab..3d99b93 100644
--- a/blob.c
+++ b/blob.c
@@ -8,7 +8,7 @@
 {
 	struct object *obj = lookup_object(sha1);
 	if (!obj) {
-		struct blob *ret = malloc(sizeof(struct blob));
+		struct blob *ret = xmalloc(sizeof(struct blob));
 		memset(ret, 0, sizeof(struct blob));
 		created_object(sha1, &ret->object);
 		ret->object.type = blob_type;
diff --git a/cache.h b/cache.h
index 4ef80c3..3277d48 100644
--- a/cache.h
+++ b/cache.h
@@ -147,4 +147,20 @@
 						unsigned long *size,
 						unsigned char *tree_sha1_ret);
 
+static inline void *xmalloc(int size)
+{
+	void *ret = malloc(size);
+	if (!ret)
+		die("Out of memory, malloc failed");
+	return ret;
+}
+
+static inline void *xrealloc(void *ptr, int size)
+{
+	void *ret = realloc(ptr, size);
+	if (!ret)
+		die("Out of memory, realloc failed");
+	return ret;
+}
+
 #endif /* CACHE_H */
diff --git a/checkout-cache.c b/checkout-cache.c
index d1661eb..a1ef944 100644
--- a/checkout-cache.c
+++ b/checkout-cache.c
@@ -39,7 +39,7 @@
 static void create_directories(const char *path)
 {
 	int len = strlen(path);
-	char *buf = malloc(len + 1);
+	char *buf = xmalloc(len + 1);
 	const char *slash = path;
 
 	while ((slash = strchr(slash+1, '/')) != NULL) {
diff --git a/commit-tree.c b/commit-tree.c
index f6e4087..23de133 100644
--- a/commit-tree.c
+++ b/commit-tree.c
@@ -18,7 +18,7 @@
  */
 static void init_buffer(char **bufp, unsigned int *sizep)
 {
-	char *buf = malloc(BLOCKING);
+	char *buf = xmalloc(BLOCKING);
 	*sizep = 0;
 	*bufp = buf;
 }
@@ -40,7 +40,7 @@
 	buf = *bufp;
 	if (newsize > alloc) {
 		alloc = (newsize + 32767) & ~32767;
-		buf = realloc(buf, alloc);
+		buf = xrealloc(buf, alloc);
 		*bufp = buf;
 	}
 	*sizep = newsize;
diff --git a/commit.c b/commit.c
index 9fbcbd3..3956c7b 100644
--- a/commit.c
+++ b/commit.c
@@ -9,7 +9,7 @@
 {
 	struct object *obj = lookup_object(sha1);
 	if (!obj) {
-		struct commit *ret = malloc(sizeof(struct commit));
+		struct commit *ret = xmalloc(sizeof(struct commit));
 		memset(ret, 0, sizeof(struct commit));
 		created_object(sha1, &ret->object);
 		ret->object.type = commit_type;
@@ -78,7 +78,7 @@
 
 void commit_list_insert(struct commit *item, struct commit_list **list_p)
 {
-	struct commit_list *new_list = malloc(sizeof(struct commit_list));
+	struct commit_list *new_list = xmalloc(sizeof(struct commit_list));
 	new_list->item = item;
 	new_list->next = *list_p;
 	*list_p = new_list;
diff --git a/convert-cache.c b/convert-cache.c
index 7102e45..631d1aa 100644
--- a/convert-cache.c
+++ b/convert-cache.c
@@ -18,8 +18,7 @@
 
 static struct entry *insert_new(unsigned char *sha1, int pos)
 {
-	struct entry *new = malloc(sizeof(struct entry));
-
+	struct entry *new = xmalloc(sizeof(struct entry));
 	memset(new, 0, sizeof(*new));
 	memcpy(new->old_sha1, sha1, 20);
 	memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
@@ -68,7 +67,7 @@
 
 static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
 {
-	char *new = malloc(size);
+	char *new = xmalloc(size);
 	unsigned long newlen = 0;
 	unsigned long used;
 
@@ -226,9 +225,9 @@
 
 static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
 {
-	char *new = malloc(size + 100);
+	char *new = xmalloc(size + 100);
 	unsigned long newlen = 0;
-
+	
 	// "tree <sha1>\n"
 	memcpy(new + newlen, buffer, 46);
 	newlen += 46;
@@ -283,7 +282,7 @@
 	if (!data)
 		die("unable to read object %s", sha1_to_hex(sha1));
 
-	buffer = malloc(size);
+	buffer = xmalloc(size);
 	memcpy(buffer, data, size);
 	
 	if (!strcmp(type, "blob")) {
diff --git a/diff-tree.c b/diff-tree.c
index 618fdb6..3579b5f 100644
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -37,7 +37,7 @@
 static char *malloc_base(const char *base, const char *path, int pathlen)
 {
 	int baselen = strlen(base);
-	char *newbase = malloc(baselen + pathlen + 2);
+	char *newbase = xmalloc(baselen + pathlen + 2);
 	memcpy(newbase, base, baselen);
 	memcpy(newbase + baselen, path, pathlen);
 	memcpy(newbase + baselen + pathlen, "/", 2);
@@ -270,7 +270,7 @@
 
 		paths = &argv[3];
 		nr_paths = argc - 3;
-		pathlens = malloc(nr_paths * sizeof(int));
+		pathlens = xmalloc(nr_paths * sizeof(int));
 		for (i=0; i<nr_paths; i++)
 			pathlens[i] = strlen(paths[i]);
 	}
diff --git a/diff.c b/diff.c
index 9905cdb..dd71d83 100644
--- a/diff.c
+++ b/diff.c
@@ -59,8 +59,7 @@
 		if (*cp == '\'')
 			cnt += 3;
 
-	if (! (buf = malloc(cnt)))
-	    return buf;
+	buf = xmalloc(cnt);
 	bp = buf;
 	while ((c = *src++)) {
 		if (c != '\'')
@@ -100,7 +99,7 @@
 			strlen(diff_arg) +
 			strlen(name_1_sq) + strlen(name_2_sq)
 			- 5);
-	char *cmd = malloc(cmd_size);
+	char *cmd = xmalloc(cmd_size);
 	int next_at = 0;
 
 	next_at += snprintf(cmd+next_at, cmd_size-next_at,
diff --git a/http-pull.c b/http-pull.c
index a172257..192dcc3 100644
--- a/http-pull.c
+++ b/http-pull.c
@@ -73,7 +73,7 @@
 	curl_easy_setopt(curl, CURLOPT_FILE, NULL);
 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file);
 
-	url = malloc(strlen(base) + 50);
+	url = xmalloc(strlen(base) + 50);
 	strcpy(url, base);
 	posn = url + strlen(base);
 	strcpy(posn, "objects/");
diff --git a/init-db.c b/init-db.c
index dad0635..83f95e8 100644
--- a/init-db.c
+++ b/init-db.c
@@ -34,7 +34,7 @@
 		fprintf(stderr, "defaulting to local storage area\n");
 	}
 	len = strlen(sha1_dir);
-	path = malloc(len + 40);
+	path = xmalloc(len + 40);
 	memcpy(path, sha1_dir, len);
 
 	safe_create_dir(sha1_dir);
diff --git a/object.c b/object.c
index cfa2337..91bbc6e 100644
--- a/object.c
+++ b/object.c
@@ -52,7 +52,7 @@
 
 	if (obj_allocs == nr_objs) {
 		obj_allocs = alloc_nr(obj_allocs);
-		objs = realloc(objs, obj_allocs * sizeof(struct object *));
+		objs = xrealloc(objs, obj_allocs * sizeof(struct object *));
 	}
 
 	/* Insert it into the right place */
@@ -75,7 +75,7 @@
 	}
 
 	target->used = 1;
-	p = malloc(sizeof(*p));
+	p = xmalloc(sizeof(*p));
 	p->item = target;
 	p->next = NULL;
 	*pp = p;
diff --git a/read-cache.c b/read-cache.c
index f67aceb..2354e80 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -143,7 +143,7 @@
 	/* Make sure the array is big enough .. */
 	if (active_nr == active_alloc) {
 		active_alloc = alloc_nr(active_alloc);
-		active_cache = realloc(active_cache, active_alloc * sizeof(struct cache_entry *));
+		active_cache = xrealloc(active_cache, active_alloc * sizeof(struct cache_entry *));
 	}
 
 	/* Add it in.. */
diff --git a/sha1_file.c b/sha1_file.c
index d98b265..db2880e 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -73,7 +73,7 @@
 	if (!base) {
 		char *sha1_file_directory = getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT;
 		int len = strlen(sha1_file_directory);
-		base = malloc(len + 60);
+		base = xmalloc(len + 60);
 		memcpy(base, sha1_file_directory, len);
 		memset(base+len, 0, 60);
 		base[len] = '/';
@@ -161,9 +161,7 @@
 		return NULL;
 
 	bytes = strlen(buffer) + 1;
-	buf = malloc(*size);
-	if (!buf)
-		return NULL;
+	buf = xmalloc(*size);
 
 	memcpy(buf, buffer + bytes, stream.total_out - bytes);
 	bytes = stream.total_out - bytes;
@@ -271,7 +269,7 @@
 	memset(&stream, 0, sizeof(stream));
 	deflateInit(&stream, Z_BEST_COMPRESSION);
 	size = deflateBound(&stream, len+hdrlen);
-	compressed = malloc(size);
+	compressed = xmalloc(size);
 
 	/* Compress it */
 	stream.next_out = compressed;
diff --git a/show-files.c b/show-files.c
index b53ab10..afeb635 100644
--- a/show-files.c
+++ b/show-files.c
@@ -30,9 +30,9 @@
 
 	if (nr_dir == dir_alloc) {
 		dir_alloc = alloc_nr(dir_alloc);
-		dir = realloc(dir, dir_alloc*sizeof(char *));
+		dir = xrealloc(dir, dir_alloc*sizeof(char *));
 	}
-	name = malloc(len + 1);
+	name = xmalloc(len + 1);
 	memcpy(name, pathname, len + 1);
 	dir[nr_dir++] = name;
 }
diff --git a/strbuf.c b/strbuf.c
index dac945c..d381c1d 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "strbuf.h"
+#include "cache.h"
 
 void strbuf_init(struct strbuf *sb) {
 	sb->buf = 0;
@@ -15,7 +16,7 @@
 static void inline strbuf_add(struct strbuf *sb, int ch) {
 	if (sb->alloc <= sb->len) {
 		sb->alloc = sb->alloc * 3 / 2 + 16;
-		sb->buf = realloc(sb->buf, sb->alloc);
+		sb->buf = xrealloc(sb->buf, sb->alloc);
 	}
 	sb->buf[sb->len++] = ch;
 }
diff --git a/tree.c b/tree.c
index 26b7927..15a16d5 100644
--- a/tree.c
+++ b/tree.c
@@ -9,7 +9,7 @@
 {
 	int len = strlen(pathname);
 	unsigned int size = cache_entry_size(baselen + len);
-	struct cache_entry *ce = malloc(size);
+	struct cache_entry *ce = xmalloc(size);
 
 	memset(ce, 0, size);
 
@@ -39,7 +39,7 @@
 		if (S_ISDIR(mode)) {
 			int retval;
 			int pathlen = strlen(path);
-			char *newbase = malloc(baselen + 1 + pathlen);
+			char *newbase = xmalloc(baselen + 1 + pathlen);
 			void *eltbuf;
 			char elttype[20];
 			unsigned long eltsize;
@@ -74,7 +74,7 @@
 {
 	struct object *obj = lookup_object(sha1);
 	if (!obj) {
-		struct tree *ret = malloc(sizeof(struct tree));
+		struct tree *ret = xmalloc(sizeof(struct tree));
 		memset(ret, 0, sizeof(struct tree));
 		created_object(sha1, &ret->object);
 		ret->object.type = tree_type;
@@ -116,7 +116,7 @@
 		    sscanf(bufptr, "%o", &mode) != 1)
 			return -1;
 
-		entry = malloc(sizeof(struct tree_entry_list));
+		entry = xmalloc(sizeof(struct tree_entry_list));
 		entry->name = strdup(path + 1);
 		entry->directory = S_ISDIR(mode);
 		entry->executable = mode & S_IXUSR;
diff --git a/update-cache.c b/update-cache.c
index e759c64..16e1bb9 100644
--- a/update-cache.c
+++ b/update-cache.c
@@ -36,8 +36,8 @@
 	z_stream stream;
 	unsigned long size = st->st_size;
 	int max_out_bytes = size + 200;
-	void *out = malloc(max_out_bytes);
-	void *metadata = malloc(200);
+	void *out = xmalloc(max_out_bytes);
+	void *metadata = xmalloc(200);
 	int metadata_size;
 	void *in;
 	SHA_CTX c;
@@ -123,7 +123,7 @@
 	}
 	namelen = strlen(path);
 	size = cache_entry_size(namelen);
-	ce = malloc(size);
+	ce = xmalloc(size);
 	memset(ce, 0, size);
 	memcpy(ce->name, path, namelen);
 	fill_stat_cache_info(ce, &st);
@@ -206,7 +206,7 @@
 		return ERR_PTR(-EINVAL);
 
 	size = ce_size(ce);
-	updated = malloc(size);
+	updated = xmalloc(size);
 	memcpy(updated, ce, size);
 	fill_stat_cache_info(updated, &st);
 	return updated;
@@ -282,7 +282,7 @@
 
 	len = strlen(arg3);
 	size = cache_entry_size(len);
-	ce = malloc(size);
+	ce = xmalloc(size);
 	memset(ce, 0, size);
 
 	memcpy(ce->sha1, sha1, 20);
diff --git a/write-tree.c b/write-tree.c
index bb7ceed..1683528 100644
--- a/write-tree.c
+++ b/write-tree.c
@@ -26,7 +26,7 @@
 
 	/* Guess at some random initial size */
 	size = 8192;
-	buffer = malloc(size);
+	buffer = xmalloc(size);
 	offset = 0;
 
 	nr = 0;
@@ -68,7 +68,7 @@
 		entrylen = pathlen - baselen;
 		if (offset + entrylen + 100 > size) {
 			size = alloc_nr(offset + entrylen + 100);
-			buffer = realloc(buffer, size);
+			buffer = xrealloc(buffer, size);
 		}
 		offset += sprintf(buffer + offset, "%o %.*s", mode, entrylen, filename);
 		buffer[offset++] = 0;