From 812666c8e66a21e668c0789d0422aa5a7db54961 Mon Sep 17 00:00:00 2001 From: Christopher Li Date: Tue, 26 Apr 2005 12:00:58 -0700 Subject: [PATCH] [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 Signed-off-by: Linus Torvalds --- blob.c | 2 +- cache.h | 16 ++++++++++++++++ checkout-cache.c | 2 +- commit-tree.c | 4 ++-- commit.c | 4 ++-- convert-cache.c | 11 +++++------ diff-tree.c | 4 ++-- diff.c | 5 ++--- http-pull.c | 2 +- init-db.c | 2 +- object.c | 4 ++-- read-cache.c | 2 +- sha1_file.c | 8 +++----- show-files.c | 4 ++-- strbuf.c | 3 ++- tree.c | 8 ++++---- update-cache.c | 10 +++++----- write-tree.c | 4 ++-- 18 files changed, 54 insertions(+), 41 deletions(-) diff --git a/blob.c b/blob.c index f79f5abd0..3d99b93f0 100644 --- a/blob.c +++ b/blob.c @@ -8,7 +8,7 @@ struct blob *lookup_blob(unsigned char *sha1) { 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 4ef80c392..3277d4870 100644 --- a/cache.h +++ b/cache.h @@ -147,4 +147,20 @@ extern void *read_tree_with_tree_or_commit_sha1(const unsigned char *sha1, 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 d1661eb5f..a1ef9448c 100644 --- a/checkout-cache.c +++ b/checkout-cache.c @@ -39,7 +39,7 @@ static int force = 0, quiet = 0, not_new = 0; 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 f6e408756..23de13361 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 @@ static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...) 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 9fbcbd33c..3956c7ba9 100644 --- a/commit.c +++ b/commit.c @@ -9,7 +9,7 @@ struct commit *lookup_commit(unsigned char *sha1) { 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 @@ int parse_commit(struct commit *item) 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 7102e4551..631d1aa91 100644 --- a/convert-cache.c +++ b/convert-cache.c @@ -18,8 +18,7 @@ static struct entry * convert_entry(unsigned char *sha1); 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 void convert_ascii_sha1(void *buffer) 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 int convert_date_line(char *dst, void **buf, unsigned long *sp) 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 \n" memcpy(new + newlen, buffer, 46); newlen += 46; @@ -283,7 +282,7 @@ static struct entry * convert_entry(unsigned char *sha1) 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 618fdb616..3579b5fd1 100644 --- a/diff-tree.c +++ b/diff-tree.c @@ -37,7 +37,7 @@ static const unsigned char *extract(void *tree, unsigned long size, const char * 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 @@ int main(int argc, char **argv) paths = &argv[3]; nr_paths = argc - 3; - pathlens = malloc(nr_paths * sizeof(int)); + pathlens = xmalloc(nr_paths * sizeof(int)); for (i=0; iused = 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 f67aceb6b..2354e8039 100644 --- a/read-cache.c +++ b/read-cache.c @@ -143,7 +143,7 @@ int add_cache_entry(struct cache_entry *ce, int ok_to_add) /* 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 d98b265bb..db2880e38 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -73,7 +73,7 @@ char *sha1_file_name(const unsigned char *sha1) 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 @@ void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned l 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 @@ int write_sha1_file(char *buf, unsigned long len, const char *type, unsigned cha 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 b53ab1053..afeb63567 100644 --- a/show-files.c +++ b/show-files.c @@ -30,9 +30,9 @@ static void add_name(const char *pathname, int len) 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 dac945c7c..d381c1d95 100644 --- a/strbuf.c +++ b/strbuf.c @@ -1,6 +1,7 @@ #include #include #include "strbuf.h" +#include "cache.h" void strbuf_init(struct strbuf *sb) { sb->buf = 0; @@ -15,7 +16,7 @@ static void strbuf_begin(struct strbuf *sb) { 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 26b792708..15a16d560 100644 --- a/tree.c +++ b/tree.c @@ -9,7 +9,7 @@ static int read_one_entry(unsigned char *sha1, const char *base, int baselen, co { 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 @@ static int read_tree_recursive(void *buffer, unsigned long size, 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 tree *lookup_tree(unsigned char *sha1) { 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 @@ int parse_tree(struct tree *item) 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 e759c647a..16e1bb9ae 100644 --- a/update-cache.c +++ b/update-cache.c @@ -36,8 +36,8 @@ static int index_fd(unsigned char *sha1, int fd, struct stat *st) 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 @@ static int add_file_to_cache(char *path) } 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 @@ static struct cache_entry *refresh_entry(struct cache_entry *ce) 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 @@ static int add_cacheinfo(char *arg1, char *arg2, char *arg3) 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 bb7ceedb8..168352853 100644 --- a/write-tree.c +++ b/write-tree.c @@ -26,7 +26,7 @@ static int write_tree(struct cache_entry **cachep, int maxentries, const char *b /* Guess at some random initial size */ size = 8192; - buffer = malloc(size); + buffer = xmalloc(size); offset = 0; nr = 0; @@ -68,7 +68,7 @@ static int write_tree(struct cache_entry **cachep, int maxentries, const char *b 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; -- 2.30.2