aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmdsserver
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmdsserver')
-rw-r--r--src/libmdsserver/fd-table.c48
-rw-r--r--src/libmdsserver/hash-table.c28
-rw-r--r--src/libmdsserver/linked-list.c178
-rw-r--r--src/libmdsserver/macros.h68
-rw-r--r--src/libmdsserver/mds-message.c56
-rw-r--r--src/libmdsserver/util.c27
-rw-r--r--src/libmdsserver/util.h11
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