From 02e6053e5976c6aa4bf538f3469335835d54e478 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 26 May 2008 22:51:43 +0200 Subject: [PATCH] Get rid of string.c and string.h. These function contained only the malloc wrappers which exited on allocation failures which is not an acceptable behaviour for a library. We must therefore bite the bullet and check the return values in the callers. --- Makefile | 2 +- Makefile.deps | 3 +- log.h | 42 +++++++++------- osl.c | 136 ++++++++++++++++++++++++++++++++++++++++---------- osl_core.h | 16 +++--- string.c | 85 ------------------------------- string.h | 11 ---- 7 files changed, 146 insertions(+), 149 deletions(-) delete mode 100644 string.c delete mode 100644 string.h diff --git a/Makefile b/Makefile index e79390c..55c5922 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ uname_s := $(shell uname -s 2>/dev/null || echo "UNKNOWN_OS") uname_rs := $(shell uname -rs) -objects := osl.o fd.o rbtree.o string.o sha1.o +objects := osl.o fd.o rbtree.o sha1.o major_version := 0 minor_version := 1 patchlevel_version := 0 diff --git a/Makefile.deps b/Makefile.deps index 3f50651..a7a4f7c 100644 --- a/Makefile.deps +++ b/Makefile.deps @@ -1,6 +1,5 @@ fd.o: fd.c log.h gcc-compat.h error.h osl.o: osl.c log.h gcc-compat.h error.h fd.h list.h osl_core.h rbtree.h \ - osl.h string.h hash.h portable_io.h sha1.h + osl.h hash.h portable_io.h sha1.h rbtree.o: rbtree.c rbtree.h sha1.o: sha1.c log.h gcc-compat.h -string.o: string.c log.h gcc-compat.h string.h error.h diff --git a/log.h b/log.h index d78b48a..dfb0565 100644 --- a/log.h +++ b/log.h @@ -101,23 +101,29 @@ __printf_2_3 void __log(int, const char*, ...); { \ int n; \ size_t size = 100; \ - p = para_malloc(size); \ - while (1) { \ - va_list ap; \ - /* Try to print in the allocated space. */ \ - va_start(ap, fmt); \ - n = vsnprintf(p, size, fmt, ap); \ - va_end(ap); \ - /* If that worked, return the string. */ \ - if (n > -1 && n < size) \ - break; \ - /* Else try again with more space. */ \ - if (n > -1) /* glibc 2.1 */ \ - size = n + 1; /* precisely what is needed */ \ - else /* glibc 2.0 */ \ - size *= 2; /* twice the old size */ \ - p = realloc(p, size); \ - if (!p) \ - break; \ + p = malloc(size); \ + if (p) { \ + while (1) { \ + char *q; \ + va_list ap; \ + /* Try to print in the allocated space. */ \ + va_start(ap, fmt); \ + n = vsnprintf(p, size, fmt, ap); \ + va_end(ap); \ + /* If that worked, return the string. */ \ + if (n > -1 && n < size) \ + break; \ + /* Else try again with more space. */ \ + if (n > -1) /* glibc 2.1 */ \ + size = n + 1; /* precisely what is needed */ \ + else /* glibc 2.0 */ \ + size *= 2; /* twice the old size */ \ + q = realloc(p, size); \ + if (!q) { \ + free(p); \ + p = NULL; \ + break; \ + } \ + } \ } \ } diff --git a/osl.c b/osl.c index b64a3c8..31f49a2 100644 --- a/osl.c +++ b/osl.c @@ -24,7 +24,7 @@ * resulting string is imposed. * * \return This function either returns a pointer to a string that must be - * freed by the caller or aborts without returning. + * freed by the caller or \p NULL if memory allocation failed. * * \sa printf(3). */ @@ -40,7 +40,7 @@ static __must_check __printf_1_2 __malloc char *make_message(const char *fmt, .. * The log function. * * \param ll Loglevel. - * \param fml Usual format string. + * \param fmt Usual format string. * * All XXX_LOG() macros use this function. */ @@ -245,6 +245,9 @@ int for_each_file_in_dir(const char *dirname, if (!S_ISREG(m) && !S_ISDIR(m)) continue; tmp = make_message("%s/%s", dirname, entry->d_name); + ret = -ERRNO_TO_ERROR(ENOMEM); + if (!tmp) + goto out; if (!S_ISDIR(m)) { ret = func(tmp, private_data); free(tmp); @@ -325,6 +328,8 @@ static char *disk_storage_dirname(const struct osl_table *t, unsigned col_num, { char *dirname, *column_name = column_filename(t, col_num); + if (!column_name) + return NULL; if (!(t->desc->flags & OSL_LARGE_TABLE)) return column_name; dirname = make_message("%s/%.2s", column_name, ds_name); @@ -349,7 +354,9 @@ static int disk_storage_name_of_row(const struct osl_table *t, if (ret < 0) return ret; *name = disk_storage_name_of_object(t, &obj); - return 1; + if (*name) + return 1; + return -ERRNO_TO_ERROR(ENOMEM); } static void column_name_hash(const char *col_name, HASH_TYPE *hash) @@ -421,9 +428,12 @@ int init_table_structure(const struct osl_table_description *desc, struct osl_table **table_ptr) { const struct osl_column_description *cd; - struct osl_table *t = para_calloc(sizeof(*t)); - int i, ret = -E_BAD_TABLE_DESC, have_disk_storage_name_column = 0; + struct osl_table *t = calloc(1, sizeof(*t)); + int i, ret = -ERRNO_TO_ERROR(ENOMEM), have_disk_storage_name_column = 0; + if (!t) + return ret; + ret = -E_BAD_TABLE_DESC; if (!desc) goto err; DEBUG_LOG("creating table structure for '%s' from table " @@ -434,7 +444,10 @@ int init_table_structure(const struct osl_table_description *desc, ret = -E_NO_COLUMNS; if (!desc->num_columns) goto err; - t->columns = para_calloc(desc->num_columns * sizeof(struct osl_column)); + ret = -ERRNO_TO_ERROR(ENOMEM); + t->columns = calloc(desc->num_columns, sizeof(struct osl_column)); + if (!t->columns) + goto err; t->desc = desc; FOR_EACH_COLUMN(i, t->desc, cd) { enum osl_storage_type st = cd->storage_type; @@ -531,8 +544,10 @@ int read_table_desc(struct osl_object *map, struct osl_table_description *desc) header_size = read_u16(buf + IDX_HEADER_SIZE); if (map->size < header_size) return -E_BAD_SIZE; - desc->column_descriptions = para_calloc(desc->num_columns - * sizeof(struct osl_column_description)); + desc->column_descriptions = calloc(desc->num_columns, + sizeof(struct osl_column_description)); + if (!desc->column_descriptions) + return -ERRNO_TO_ERROR(ENOMEM); offset = IDX_COLUMN_DESCRIPTIONS; FOR_EACH_COLUMN(i, desc, cd) { char *null_byte; @@ -552,7 +567,10 @@ int read_table_desc(struct osl_object *map, struct osl_table_description *desc) ret = -E_INDEX_CORRUPTION; if (!null_byte) goto err; - cd->name = para_strdup(buf + offset + IDX_CD_NAME); + ret = -ERRNO_TO_ERROR(ENOMEM); + cd->name = strdup(buf + offset + IDX_CD_NAME); + if (!cd->name) + goto err; offset += index_column_description_size(cd->name); } if (offset != header_size) { @@ -645,7 +663,9 @@ static int create_table_index(struct osl_table *t) INFO_LOG("creating %zu byte index for table %s\n", size, t->desc->name); - buf = para_calloc(size); + buf = calloc(1, size); + if (!buf) + return -ERRNO_TO_ERROR(ENOMEM); sprintf(buf + IDX_PARA_MAGIC, "%s", PARA_MAGIC); write_u8(buf + IDX_TABLE_FLAGS, t->desc->flags); write_u8(buf + IDX_DIRTY_FLAG, 0); @@ -669,7 +689,10 @@ static int create_table_index(struct osl_table *t) } assert(offset = size); filename = index_filename(t->desc); - ret = para_write_file(filename, buf, size); + if (filename) + ret = para_write_file(filename, buf, size); + else + ret = -ERRNO_TO_ERROR(ENOMEM); free(buf); free(filename); return ret; @@ -701,11 +724,17 @@ int osl_create_table(const struct osl_table_description *desc) goto out; table_dir = make_message("%s/%s", desc->dir, desc->name); + ret = -ERRNO_TO_ERROR(ENOMEM); + if (!table_dir) + goto out; ret = para_mkdir(table_dir, 0777); if (ret < 0) goto out; } + ret = -ERRNO_TO_ERROR(ENOMEM); filename = column_filename(t, i); + if (!filename) + goto out; INFO_LOG("filename: %s\n", filename); if (cd->storage_type == OSL_MAPPED_STORAGE) { ret = para_open(filename, O_RDWR | O_CREAT | O_EXCL, @@ -804,6 +833,9 @@ static int map_column(struct osl_table *t, unsigned col_num) struct stat statbuf; char *filename = column_filename(t, col_num); int ret = -E_STAT; + + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); if (stat(filename, &statbuf) < 0) { free(filename); return ret; @@ -842,6 +874,8 @@ int map_table(struct osl_table *t, enum map_table_flags flags) if (t->index_map.data) return -E_ALREADY_MAPPED; filename = index_filename(t->desc); + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); DEBUG_LOG("mapping table '%s' (index: %s)\n", t->desc->name, filename); ret = mmap_full_file(filename, flags & MAP_TBL_FL_MAP_RDONLY? O_RDONLY : O_RDWR, &t->index_map.data, &t->index_map.size, NULL); @@ -1018,6 +1052,8 @@ static int add_row_to_rbtrees(struct osl_table *t, uint32_t row_num, struct osl_row *row = allocate_row(t->num_rbtrees); const struct osl_column_description *cd; + if (!row) + return -ERRNO_TO_ERROR(ENOMEM); row->num = row_num; row->volatile_objects = volatile_objs; FOR_EACH_RBTREE_COLUMN(i, t, cd) { @@ -1243,9 +1279,13 @@ int osl_open_table(const struct osl_table_description *table_desc, if (ret < 0) return ret; FOR_EACH_DISK_STORAGE_COLUMN(i, t, cd) { - /* check if directory exists */ - char *dirname = column_filename(t, i); struct stat statbuf; + char *dirname = column_filename(t, i); + + ret = -ERRNO_TO_ERROR(ENOMEM); + if (!dirname) + goto err; + /* check if directory exists */ ret = stat(dirname, &statbuf); free(dirname); if (ret < 0) { @@ -1283,6 +1323,8 @@ static int create_disk_storage_object_dir(const struct osl_table *t, if (!(t->desc->flags & OSL_LARGE_TABLE)) return 1; dirname = disk_storage_dirname(t, col_num, ds_name); + if (!dirname) + return -ERRNO_TO_ERROR(ENOMEM); ret = para_mkdir(dirname, 0777); free(dirname); if (ret < 0 && !is_errno(-ret, EEXIST)) @@ -1300,6 +1342,8 @@ static int write_disk_storage_file(const struct osl_table *t, unsigned col_num, if (ret < 0) return ret; filename = disk_storage_path(t, col_num, ds_name); + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); ret = para_write_file(filename, obj->data, obj->size); free(filename); return ret; @@ -1312,7 +1356,8 @@ static int append_map_file(const struct osl_table *t, unsigned col_num, int ret; char header = 0; /* zero means valid object */ -// DEBUG_LOG("appending %zu + 1 byte\n", obj->size); + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); ret = append_file(filename, &header, 1, obj->data, obj->size, new_size); free(filename); @@ -1327,6 +1372,8 @@ static int append_row_index(const struct osl_table *t, char *row_index) if (!t->num_mapped_columns) return 1; filename = index_filename(t->desc); + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); ret = append_file(filename, NULL, 0, row_index, t->row_index_size, NULL); free(filename); @@ -1368,8 +1415,12 @@ out: static int truncate_mapped_file(const struct osl_table *t, unsigned col_num, off_t size) { + int ret; char *filename = column_filename(t, col_num); - int ret = para_truncate(filename, size); + + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); + ret = para_truncate(filename, size); free(filename); return ret; } @@ -1378,14 +1429,20 @@ static int delete_disk_storage_file(const struct osl_table *t, unsigned col_num, const char *ds_name) { char *dirname, *filename = disk_storage_path(t, col_num, ds_name); - int ret = unlink(filename), err = errno; + int ret, err; + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); + ret = unlink(filename); + err = errno; free(filename); if (ret < 0) return -ERRNO_TO_ERROR(err); if (!(t->desc->flags & OSL_LARGE_TABLE)) return 1; dirname = disk_storage_dirname(t, col_num, ds_name); + if (!dirname) + return -ERRNO_TO_ERROR(ENOMEM); rmdir(dirname); free(dirname); return 1; @@ -1428,10 +1485,22 @@ int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects, if (!t) return -E_BAD_TABLE; - rb_parents = para_malloc(t->num_rbtrees * sizeof(struct rn_node*)); - rb_links = para_malloc(t->num_rbtrees * sizeof(struct rn_node**)); - if (t->num_mapped_columns) - new_row_index = para_malloc(t->row_index_size); + rb_parents = malloc(t->num_rbtrees * sizeof(struct rn_node*)); + if (!rb_parents) + return -ERRNO_TO_ERROR(ENOMEM); + rb_links = malloc(t->num_rbtrees * sizeof(struct rn_node**)); + if (!rb_links) { + free(rb_parents); + return -ERRNO_TO_ERROR(ENOMEM); + } + if (t->num_mapped_columns) { + new_row_index = malloc(t->row_index_size); + if (!new_row_index) { + free(rb_links); + free(rb_parents); + return -ERRNO_TO_ERROR(ENOMEM); + } + } /* pass 1: sanity checks */ // DEBUG_LOG("sanity tests: %p:%p\n", objects[0].data, // objects[1].data); @@ -1462,9 +1531,13 @@ int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects, goto out; } } - if (t->num_disk_storage_columns) + if (t->num_disk_storage_columns) { ds_name = disk_storage_name_of_object(t, &objects[t->disk_storage_name_column]); + ret = -ERRNO_TO_ERROR(ENOMEM); + if (!ds_name) + goto out; + } ret = unmap_table(t, OSL_MARK_CLEAN); if (ret < 0) goto out; @@ -1497,14 +1570,18 @@ int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects, ret = map_table(t, MAP_TBL_FL_VERIFY_INDEX); if (ret < 0) { /* truncate index and rollback changes */ char *filename = index_filename(t->desc); - para_truncate(filename, t->row_index_size); + if (filename) + para_truncate(filename, t->row_index_size); free(filename); goto rollback; } /* pass 3: add entry to rbtrees */ if (t->num_volatile_columns) { - volatile_objs = para_calloc(t->num_volatile_columns - * sizeof(struct osl_object)); + ret = -ERRNO_TO_ERROR(ENOMEM); + volatile_objs = calloc(t->num_volatile_columns, + sizeof(struct osl_object)); + if (!volatile_objs) + goto out; FOR_EACH_VOLATILE_COLUMN(i, t, cd) volatile_objs[t->columns[i].volatile_num] = objects[i]; } @@ -1821,6 +1898,10 @@ static int rename_disk_storage_objects(struct osl_table *t, return 1; /* object did not change */ old_ds_name = disk_storage_name_of_object(t, old_obj); new_ds_name = disk_storage_name_of_object(t, new_obj); + ret = -ERRNO_TO_ERROR(ENOMEM); + if (!old_ds_name || ! new_ds_name) + goto out; + FOR_EACH_DISK_STORAGE_COLUMN(i, t, cd) { char *old_filename, *new_filename; ret = create_disk_storage_object_dir(t, i, new_ds_name); @@ -1828,7 +1909,10 @@ static int rename_disk_storage_objects(struct osl_table *t, goto out; old_filename = disk_storage_path(t, i, old_ds_name); new_filename = disk_storage_path(t, i, new_ds_name); - ret = para_rename(old_filename, new_filename); + if (!old_filename || !new_filename) + ret = -ERRNO_TO_ERROR(ENOMEM); + else + ret = para_rename(old_filename, new_filename); free(old_filename); free(new_filename); if (ret < 0) @@ -1980,6 +2064,8 @@ int osl_open_disk_object(const struct osl_table *t, const struct osl_row *r, return ret; filename = disk_storage_path(t, col_num, ds_name); free(ds_name); + if (!filename) + return -ERRNO_TO_ERROR(ENOMEM); DEBUG_LOG("filename: %s\n", filename); ret = mmap_full_file(filename, O_RDONLY, &obj->data, &obj->size, NULL); free(filename); diff --git a/osl_core.h b/osl_core.h index 87a1188..b6d1f82 100644 --- a/osl_core.h +++ b/osl_core.h @@ -8,7 +8,6 @@ #include "rbtree.h" #include "osl.h" -#include "string.h" #include "hash.h" static __must_check __printf_1_2 __malloc char *make_message(const char *fmt, ...); @@ -324,8 +323,11 @@ _static_inline_ void update_cell_index(char *row_index, struct osl_column *col, _static_inline_ char *disk_storage_path(const struct osl_table *t, unsigned col_num, const char *ds_name) { - char *dirname = column_filename(t, col_num); - char *filename = make_message("%s/%s", dirname, ds_name); + char *filename, *dirname = column_filename(t, col_num); + + if (!dirname) + return NULL; + filename = make_message("%s/%s", dirname, ds_name); free(dirname); return filename; } @@ -398,13 +400,13 @@ _static_inline_ int next_rbtree_column(int col_num, const struct osl_table *t, * * \param num_rbtrees The number of rbtrees for this row. * - * \return A pointer to a zeroed-out area suitable for holding an osl row - * with \a num_rbtrees rbtree columns. + * \return A pointer to a zeroed-out area suitable for holding an osl row with + * \a num_rbtrees rbtree columns or \p NULL if no memory could be allocated. */ _static_inline_ struct osl_row *allocate_row(unsigned num_rbtrees) { size_t s = RB_NODES_OFFSET + num_rbtrees * sizeof(struct rb_node); - return para_calloc(s); + return calloc(1, s); } /** @@ -469,7 +471,7 @@ _static_inline_ char *disk_storage_name_of_hash(const struct osl_table *t, HASH_ hash_to_asc(hash, asc); if (t->desc->flags & OSL_LARGE_TABLE) return make_message("%.2s/%s", asc, asc + 2); - return para_strdup(asc); + return strdup(asc); } /** diff --git a/string.c b/string.c deleted file mode 100644 index 7ac77d0..0000000 --- a/string.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2004-2008 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ - -/** \file string.c Memory allocation and string handling functions. */ - -#include "log.h" -#include "string.h" - -#include /* gettimeofday */ -#include -#include /* uname() */ -#include - -#include "error.h" - -/** - * Paraslash's version of malloc(). - * - * \param size The desired new size. - * - * A wrapper for malloc(3) which exits on errors. - * - * \return A pointer to the allocated memory, which is suitably aligned for any - * kind of variable. - * - * \sa malloc(3). - */ -__must_check __malloc void *para_malloc(size_t size) -{ - assert(size); - void *p = malloc(size); - - if (!p) { - EMERG_LOG("malloc failed (size = %zu), aborting\n", - size); - exit(EXIT_FAILURE); - } - return p; -} - -/** - * Paraslash's version of calloc(). - * - * \param size The desired new size. - * - * A wrapper for calloc(3) which exits on errors. - * - * \return A pointer to the allocated and zeroed-out memory, which is suitably - * aligned for any kind of variable. - * - * \sa calloc(3) - */ -__must_check __malloc void *para_calloc(size_t size) -{ - void *ret = para_malloc(size); - - memset(ret, 0, size); - return ret; -} - -/** - * Paraslash's version of strdup(). - * - * \param s The string to be duplicated. - * - * A wrapper for strdup(3). It calls \p exit(EXIT_FAILURE) on errors, i.e. - * there is no need to check the return value in the caller. - * - * \return A pointer to the duplicated string. If \p s was the NULL pointer, - * an pointer to an empty string is returned. - * - * \sa strdup(3) - */ -__must_check __malloc char *para_strdup(const char *s) -{ - char *ret; - - if ((ret = strdup(s? s: ""))) - return ret; - EMERG_LOG("strdup failed, aborting\n"); - exit(EXIT_FAILURE); -} diff --git a/string.h b/string.h deleted file mode 100644 index 3bee128..0000000 --- a/string.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (C) 2006-2008 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ - -/** \file string.h exported sybmols from string.c */ - -__must_check __malloc void *para_malloc(size_t size); -__must_check __malloc void *para_calloc(size_t size); -__must_check __malloc char *para_strdup(const char *s); -- 2.39.5