diff options
Diffstat (limited to 'src/libmdsserver')
-rw-r--r-- | src/libmdsserver/fd-table.c | 48 | ||||
-rw-r--r-- | src/libmdsserver/hash-table.c | 28 | ||||
-rw-r--r-- | src/libmdsserver/linked-list.c | 178 | ||||
-rw-r--r-- | src/libmdsserver/macros.h | 68 | ||||
-rw-r--r-- | src/libmdsserver/mds-message.c | 56 | ||||
-rw-r--r-- | src/libmdsserver/util.c | 27 | ||||
-rw-r--r-- | src/libmdsserver/util.h | 11 |
7 files changed, 212 insertions, 204 deletions
diff --git a/src/libmdsserver/fd-table.c b/src/libmdsserver/fd-table.c index 8e78b76..0d5a0dc 100644 --- a/src/libmdsserver/fd-table.c +++ b/src/libmdsserver/fd-table.c @@ -48,13 +48,8 @@ int fd_table_create_tuned(fd_table_t* restrict this, size_t initial_capacity) the time overhead of `fd_table_contains_value`. */ bitcap = (this->capacity + 63) / 64; - this->used = calloc(bitcap, sizeof(size_t)); - if (this->used == NULL) - return -1; - - this->values = calloc(this->capacity, sizeof(size_t)); - if (this->values == NULL) - return -1; + if (xcalloc(this->used, bitcap, sizeof(size_t))) return -1; + if (xcalloc(this->values, this->capacity, sizeof(size_t))) return -1; return 0; } @@ -70,31 +65,18 @@ int fd_table_create_tuned(fd_table_t* restrict this, size_t initial_capacity) */ void fd_table_destroy(fd_table_t* restrict this, free_func* key_freer, free_func* value_freer) { - if (((key_freer == NULL) && (value_freer == NULL)) || (this->used == NULL)) - { - if (this->values != NULL) - free(this->values); - - if (this->used != NULL) - free(this->used); - } - else + if (((key_freer != NULL) || (value_freer != NULL)) && (this->used != NULL) && (this->values != NULL)) { - if (this->values != NULL) - { - size_t i; - for (i = 0; i < this->capacity; i++) - if (this->used[i / 64] & ((uint64_t)1 << (i % 64))) - { - if (key_freer != NULL) - key_freer(i); - if (value_freer != NULL) - value_freer(this->values[i]); - } - free(this->values); - } - free(this->used); + size_t i; + for (i = 0; i < this->capacity; i++) + if (this->used[i / 64] & ((uint64_t)1 << (i % 64))) + { + if (key_freer != NULL) key_freer(i); + if (value_freer != NULL) value_freer(this->values[i]); + } } + free(this->values); + free(this->used); } @@ -303,13 +285,11 @@ int fd_table_unmarshal(fd_table_t* restrict this, char* restrict data, remap_fun this->used = NULL; this->value_comparator = NULL; - this->values = malloc(this->capacity * sizeof(size_t)); - if (this->values == NULL) + if (xmalloc(this->values, this->capacity, size_t)) return -1; bitcap = (this->capacity + 63) / 64; - this->used = malloc(bitcap * sizeof(size_t)); - if (this->used == NULL) + if (xmalloc(this->used, bitcap, size_t)) return -1; memcpy(this->values, data, this->capacity * sizeof(size_t)); diff --git a/src/libmdsserver/hash-table.c b/src/libmdsserver/hash-table.c index 4498616..4397af9 100644 --- a/src/libmdsserver/hash-table.c +++ b/src/libmdsserver/hash-table.c @@ -76,8 +76,7 @@ static int rehash(hash_table_t* restrict this) hash_entry_t* destination; hash_entry_t* next; - this->buckets = calloc((old_capacity * 2 + 1), sizeof(hash_entry_t*)); - if (this->buckets == NULL) + if (xcalloc(this->buckets, old_capacity * 2 + 1, sizeof(hash_entry_t*))) return -1; this->capacity = old_capacity * 2 + 1; this->threshold = (size_t)((float)(this->capacity) * this->load_factor); @@ -125,8 +124,7 @@ int hash_table_create_fine_tuned(hash_table_t* restrict this, size_t initial_cap this->buckets = NULL; this->capacity = initial_capacity ? initial_capacity : 1; - this->buckets = calloc(this->capacity, sizeof(hash_entry_t*)); - if (this->buckets == NULL) + if (xcalloc(this->buckets, this->capacity, sizeof(hash_entry_t*))) return -1; this->load_factor = load_factor; this->threshold = (size_t)((float)(this->capacity) * load_factor); @@ -160,10 +158,8 @@ void hash_table_destroy(hash_table_t* restrict this, free_func* key_freer, free_ bucket = this->buckets[--i]; while (bucket) { - if (key_freer != NULL) - key_freer(bucket->key); - if (value_freer != NULL) - value_freer(bucket->value); + if (key_freer != NULL) key_freer(bucket->key); + if (value_freer != NULL) value_freer(bucket->value); bucket = (last = bucket)->next; free(last); } @@ -285,8 +281,7 @@ size_t hash_table_put(hash_table_t* restrict this, size_t key, size_t value) } errno = 0; - bucket = malloc(sizeof(hash_entry_t)); - if (bucket == NULL) + if (xmalloc(bucket, 1, hash_entry_t)) return 0; bucket->value = value; bucket->key = key; @@ -453,8 +448,7 @@ int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap buf_get_next(data, size_t, this->threshold); buf_get_next(data, size_t, this->size); - this->buckets = calloc(this->capacity, sizeof(hash_entry_t*)); - if (this->buckets == NULL) + if (xcalloc(this->buckets, this->capacity, sizeof(hash_entry_t*))) return -1; for (i = 0; i < n; i++) @@ -463,8 +457,7 @@ int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap hash_entry_t* restrict bucket; buf_get_next(data, size_t, m); - this->buckets[i] = bucket = malloc(sizeof(hash_entry_t)); - if (bucket == NULL) + if (xmalloc(this->buckets[i] = bucket, 1, hash_entry_t)) return -1; while (m--) @@ -472,11 +465,8 @@ int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap if (m == 0) bucket->next = NULL; else - { - bucket->next = malloc(sizeof(hash_entry_t)); - if (bucket->next == NULL) - return -1; - } + if (xmalloc(bucket->next, 1, hash_entry_t)) + return -1; buf_get_next(data, size_t, bucket->key); buf_get_next(data, size_t, bucket->value); if (remapper != NULL) diff --git a/src/libmdsserver/linked-list.c b/src/libmdsserver/linked-list.c index 1413358..4755ad4 100644 --- a/src/libmdsserver/linked-list.c +++ b/src/libmdsserver/linked-list.c @@ -67,25 +67,20 @@ int linked_list_create(linked_list_t* restrict this, size_t capacity) capacity = LINKED_LIST_DEFAULT_INITIAL_CAPACITY; /* Initialise the linked list. */ - capacity = to_power_of_two(capacity); - this->capacity = capacity; - this->edge = 0; - this->end = 1; + this->capacity = capacity = to_power_of_two(capacity); + this->edge = 0; + this->end = 1; this->reuse_head = 0; - this->reusable = NULL; - this->values = NULL; - this->next = NULL; - this->previous = NULL; - if ((this->reusable = malloc(capacity * sizeof(ssize_t))) == NULL) - return -1; - if ((this->values = malloc(capacity * sizeof(size_t))) == NULL) - return -1; - if ((this->next = malloc(capacity * sizeof(ssize_t))) == NULL) - return -1; - if ((this->previous = malloc(capacity * sizeof(ssize_t))) == NULL) - return -1; - this->values[this->edge] = 0; - this->next[this->edge] = this->edge; + this->reusable = NULL; + this->values = NULL; + this->next = NULL; + this->previous = NULL; + if (xmalloc(this->reusable, capacity, ssize_t)) return -1; + if (xmalloc(this->values, capacity, size_t)) return -1; + if (xmalloc(this->next, capacity, ssize_t)) return -1; + if (xmalloc(this->previous, capacity, ssize_t)) return -1; + this->values[this->edge] = 0; + this->next[this->edge] = this->edge; this->previous[this->edge] = this->edge; return 0; @@ -100,15 +95,10 @@ int linked_list_create(linked_list_t* restrict this, size_t capacity) */ void linked_list_destroy(linked_list_t* restrict this) { - if (this->reusable != NULL) free(this->reusable); - if (this->values != NULL) free(this->values); - if (this->next != NULL) free(this->next); - if (this->previous != NULL) free(this->previous); - - this->reusable = NULL; - this->values = NULL; - this->next = NULL; - this->previous = NULL; + free(this->reusable); this->reusable = NULL; + free(this->values); this->values = NULL; + free(this->next); this->next = NULL; + free(this->previous); this->previous = NULL; } @@ -122,53 +112,43 @@ void linked_list_destroy(linked_list_t* restrict this) int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restrict out) { size_t n = this->capacity * sizeof(ssize_t); - size_t* restrict new_values; - ssize_t* restrict new_next; - ssize_t* restrict new_previous; + size_t* restrict new_values = NULL; + ssize_t* restrict new_next = NULL; + ssize_t* restrict new_previous = NULL; ssize_t* restrict new_reusable; - out->values = NULL; - out->next = NULL; + out->values = NULL; + out->next = NULL; out->previous = NULL; out->reusable = NULL; - if ((new_values = malloc(n)) == NULL) - return -1; - if ((new_next = malloc(n)) == NULL) - { - free(new_values); - return -1; - } - if ((new_previous = malloc(n)) == NULL) - { - free(new_values); - free(new_previous); - return -1; - } - if ((new_reusable = malloc(n)) == NULL) - { - free(new_values); - free(new_previous); - free(new_reusable); - return -1; - } + if ((new_values = malloc(n)) == NULL) goto fail; + if ((new_next = malloc(n)) == NULL) goto fail; + if ((new_previous = malloc(n)) == NULL) goto fail; + if ((new_reusable = malloc(n)) == NULL) goto fail; - out->values = new_values; - out->next = new_next; + out->values = new_values; + out->next = new_next; out->previous = new_previous; out->reusable = new_reusable; - out->capacity = this->capacity; - out->end = this->end; + out->capacity = this->capacity; + out->end = this->end; out->reuse_head = this->reuse_head; - out->edge = this->edge; + out->edge = this->edge; - memcpy(out->values, this->values, n); - memcpy(out->next, this->next, n); + memcpy(out->values, this->values, n); + memcpy(out->next, this->next, n); memcpy(out->previous, this->previous, n); memcpy(out->reusable, this->reusable, n); return 0; + + fail: + free(new_values); + free(new_next); + free(new_previous); + return -1; } @@ -188,6 +168,9 @@ int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restric */ int linked_list_pack(linked_list_t* restrict this) { + ssize_t* restrict new_next = NULL; + ssize_t* restrict new_previous = NULL; + ssize_t* restrict new_reusable = NULL; size_t size = this->end - this->reuse_head; size_t cap = to_power_of_two(size); ssize_t head = 0; @@ -195,8 +178,7 @@ int linked_list_pack(linked_list_t* restrict this) ssize_t node; size_t* restrict vals; - vals = malloc(cap * sizeof(size_t)); - if (vals == NULL) + if (xmalloc(vals, cap, size_t)) return -1; while (((size_t)head != this->end) && (this->next[head] == LINKED_LIST_UNUSED)) head++; @@ -209,37 +191,15 @@ int linked_list_pack(linked_list_t* restrict this) if (cap != this->capacity) { - ssize_t* restrict new_next; - ssize_t* restrict new_previous; - ssize_t* restrict new_reusable; - - new_next = malloc(cap * sizeof(ssize_t)); - if (new_next == NULL) - { - free(vals); - return -1; - } - new_previous = malloc(cap * sizeof(ssize_t)); - if (new_previous == NULL) - { - free(vals); - free(new_next); - return -1; - } - new_reusable = malloc(cap * sizeof(ssize_t)); - if (new_reusable == NULL) - { - free(vals); - free(new_next); - free(new_previous); - return -1; - } + if (xmalloc(new_next, cap, ssize_t)) goto fail; + if (xmalloc(new_previous, cap, ssize_t)) goto fail; + if (xmalloc(new_reusable, cap, ssize_t)) goto fail; free(this->next); free(this->previous); free(this->reusable); - this->next = new_next; + this->next = new_next; this->previous = new_previous; this->reusable = new_reusable; } @@ -257,6 +217,12 @@ int linked_list_pack(linked_list_t* restrict this) this->reuse_head = 0; return 0; + + fail: + free(vals); + free(new_next); + free(new_previous); + return -1; } @@ -285,30 +251,20 @@ static ssize_t linked_list_get_next(linked_list_t* restrict this) } this->capacity <<= 1; - this->values = realloc(old_values = this->values, this->capacity * sizeof(size_t)); - if (this->values == NULL) - { - this->values = old_values; - return LINKED_LIST_UNUSED; - } - this->next = realloc(old = this->next, this->capacity * sizeof(ssize_t)); - if (this->next == NULL) - { - this->next = old; - return LINKED_LIST_UNUSED; - } - this->previous = realloc(old = this->previous, this->capacity * sizeof(ssize_t)); - if (this->previous == NULL) - { - this->previous = old; - return LINKED_LIST_UNUSED; - } - this->reusable = realloc(old = this->reusable, this->capacity * sizeof(ssize_t)); - if (this->reusable == NULL) - { - this->reusable = old; - return LINKED_LIST_UNUSED; - } + +#define __realloc(new_var, old_var, type) \ + if ((new_var = realloc(old_var = new_var, this->capacity * sizeof(type))) == NULL) \ + { \ + new_var = old_var; \ + return LINKED_LIST_UNUSED; \ + } + + __realloc(this->values, old_values, size_t) + __realloc(this->next, old, ssize_t) + __realloc(this->previous, old, ssize_t) + __realloc(this->reusable, old, ssize_t) + +#undef __realloc } return (ssize_t)(this->end++); } diff --git a/src/libmdsserver/macros.h b/src/libmdsserver/macros.h index b464732..df18d0f 100644 --- a/src/libmdsserver/macros.h +++ b/src/libmdsserver/macros.h @@ -19,12 +19,18 @@ #define MDS_LIBMDSSERVER_MACROS_H +#include "config.h" + + /* #include <stdio.h> #include <unistd.h> #include <pthread.h> #include <string.h> #include <time.h> +#include <sys/types.h> +#include <dirent.h> +#include <stdlib.h> */ @@ -227,5 +233,67 @@ clock_gettime(CLOCK_MONOTONIC, time_slot) +/** + * Close all file descriptors that satisfies a condition + * + * @param condition The condition, it should evaluate the variable `fd` + */ +#define close_files(condition) \ +{ \ + DIR* dir = opendir(SELF_FD); \ + struct dirent* file; \ + \ + if (dir == NULL) \ + perror(*argv); /* Well, that is just unfortunate, but we cannot really do anything. */ \ + else \ + while ((file = readdir(dir)) != NULL) \ + if (strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) \ + { \ + int fd = atoi(file->d_name); \ + if (condition) \ + close(fd); \ + } \ + \ + closedir(dir); \ +} + + +/** + * Free an array and all elements in an array + * + * @param array:¿V?* The array to free + * @param elements:size_t The number of elements, in the array, to free + * @scope i:size_t The variable `i` must be declared as `size_t` and avaiable for use + */ +#define xfree(array, elements) \ + for (i = 0; i < elements; i++) \ + free((array)[i]); \ + free(array) + + +/** + * `malloc` wrapper that returns whether the allocation was successful + * + * @param var The variable to which to assign the allocation + * @param elements The number of elements to allocate + * @parma type The data type of the elements for which to create an allocation + * @return :int Evaluates to true if an only if the allocation failed + */ +#define xmalloc(var, elements, type) \ + ((var = malloc((elements) * sizeof(type))) == NULL) + + +/** + * `calloc` wrapper that returns whether the allocation was successful + * + * @param var The variable to which to assign the allocation + * @param elements The number of elements to allocate + * @parma type The data type of the elements for which to create an allocation + * @return :int Evaluates to true if an only if the allocation failed + */ +#define xcalloc(var, elements, type) \ + ((var = calloc(elements, sizeof(type))) == NULL) + + #endif diff --git a/src/libmdsserver/mds-message.c b/src/libmdsserver/mds-message.c index 5f17ec7..eb5db4c 100644 --- a/src/libmdsserver/mds-message.c +++ b/src/libmdsserver/mds-message.c @@ -43,9 +43,8 @@ int mds_message_initialise(mds_message_t* this) this->payload_ptr = 0; this->buffer_size = 128; this->buffer_ptr = 0; - this->buffer = malloc(this->buffer_size * sizeof(char)); this->stage = 0; - if (this->buffer == NULL) + if (xmalloc(this->buffer, this->buffer_size, char)) return -1; return 0; } @@ -62,17 +61,11 @@ void mds_message_destroy(mds_message_t* this) if (this->headers != NULL) { size_t i; - for (i = 0; i < this->header_count; i++) - if (this->headers[i] != NULL) - free(this->headers[i]); - free(this->headers); + xfree(this->headers, this->header_count); } - if (this->payload != NULL) - free(this->payload); - - if (this->buffer != NULL) - free(this->buffer); + free(this->payload); + free(this->buffer); } @@ -100,15 +93,11 @@ int mds_message_read(mds_message_t* this, int fd) if (this->headers != NULL) { size_t i; - for (i = 0; i < this->header_count; i++) - if (this->headers[i] != NULL) - free(this->headers[i]); - free(this->headers); + xfree(this->headers, this->header_count); } this->header_count = 0; - if (this->payload != NULL) - free(this->payload); + free(this->payload); this->payload_size = 0; this->payload_ptr = 0; @@ -155,11 +144,8 @@ int mds_message_read(mds_message_t* this, int fd) /* Allocate the payload buffer. */ if (this->payload_size > 0) - { - this->payload = malloc(this->payload_size * sizeof(char)); - if (this->payload == NULL) - return -1; - } + if (xmalloc(this->payload, this->payload_size, char)) + return -1; /* Mark end of stage, next stage is getting the payload. */ this->stage = 1; @@ -178,8 +164,7 @@ int mds_message_read(mds_message_t* this, int fd) header_commit_buffer = 8; if (this->headers == NULL) { - this->headers = malloc(header_commit_buffer * sizeof(char*)); - if (this->headers == NULL) + if (xmalloc(this->headers, header_commit_buffer, char*)) return -1; } else @@ -196,8 +181,7 @@ int mds_message_read(mds_message_t* this, int fd) } /* Allocat the header.*/ - header = malloc(len * sizeof(char)); - if (header == NULL) + if (xmalloc(header, len, char)) return -1; /* Copy the header data into the allocated header, */ memcpy(header, this->buffer, len); @@ -411,21 +395,14 @@ int mds_message_unmarshal(mds_message_t* this, char* data) /* Allocate header list, payload and read buffer. */ if (header_count > 0) - { - this->headers = malloc(header_count * sizeof(char*)); - if (this->headers == NULL) - return -1; - } + if (xmalloc(this->headers, header_count, char*)) + return -1; if (this->payload_size > 0) - { - this->payload = malloc(this->payload_size * sizeof(char)); - if (this->payload == NULL) - return -1; - } + if (xmalloc(this->payload, this->payload_size, char)) + return -1; - this->buffer = malloc(this->buffer_size * sizeof(char)); - if (this->buffer == NULL) + if (xmalloc(this->buffer, this->buffer_size, char)) return -1; /* Fill the header list, payload and read buffer. */ @@ -433,8 +410,7 @@ int mds_message_unmarshal(mds_message_t* this, char* data) for (i = 0; i < this->header_count; i++) { n = strlen(data) + 1; - this->headers[i] = malloc(n * sizeof(char)); - if (this->headers[i] == NULL) + if (xmalloc(this->headers[i], n, char)) return -1; memcpy(this->headers[i], data, n * sizeof(char)); buf_next(data, char, n); diff --git a/src/libmdsserver/util.c b/src/libmdsserver/util.c index 5780176..9eb88fe 100644 --- a/src/libmdsserver/util.c +++ b/src/libmdsserver/util.c @@ -26,6 +26,7 @@ #include <signal.h> #include <sys/socket.h> #include <errno.h> +#include <ctype.h> /** @@ -145,3 +146,29 @@ size_t send_message(int socket, const char* message, size_t length) return sent; } + +/** + * A version of `atoi` that is strict about the syntax and bounds + * + * @param str The text to parse + * @param value Slot in which to store the value + * @param min The minimum accepted value + * @param max The maximum accepted value + * @return Zero on success, -1 on syntax error + */ +int strict_atoi(const char* str, int* value, int min, int max) +{ + long long int r; + char* endptr; + + r = strtoll(str, &endptr, 10); + if ((*str == '\0') || isspace(*str) || + (endptr - str != (ssize_t)strlen(str)) || + (r < (long long int)min) || + (r > (long long int)max)) + return -1; + + *value = (int)r; + return 0; +} + diff --git a/src/libmdsserver/util.h b/src/libmdsserver/util.h index 3a6e9b1..3de6f02 100644 --- a/src/libmdsserver/util.h +++ b/src/libmdsserver/util.h @@ -63,6 +63,17 @@ int xsigaction(int signo, void (*function)(int signo)); */ size_t send_message(int socket, const char* message, size_t length); +/** + * A version of `atoi` that is strict about the syntax and bounds + * + * @param str The text to parse + * @param value Slot in which to store the value + * @param min The minimum accepted value + * @param max The maximum accepted value + * @return Zero on success, -1 on syntax error + */ +int strict_atoi(const char* str, int* value, int min, int max); + #endif |