summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doxyfile.in2
-rw-r--r--src/async.c12
-rw-r--r--src/async.h13
-rw-r--r--src/compat.h26
-rw-r--r--src/dlist.h9
-rw-r--r--src/shell.c26
-rw-r--r--src/shell.h16
-rw-r--r--src/vector.c29
-rw-r--r--src/vector.h64
9 files changed, 183 insertions, 14 deletions
diff --git a/Doxyfile.in b/Doxyfile.in
index 2603770..8334b9e 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -1943,7 +1943,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-PREDEFINED = __attribute__(x)= VECTOR(x):=VECTOR WITH_CAPABILITIES WITH_VERIFY USE_FREEBIND __linux__
+PREDEFINED = __attribute__(x)= VECTOR(x):=VECTOR<x> WITH_CAPABILITIES WITH_VERIFY USE_FREEBIND __linux__
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
diff --git a/src/async.c b/src/async.c
index 21a6930..6025ef3 100644
--- a/src/async.c
+++ b/src/async.c
@@ -23,17 +23,25 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file async.c
+
+ Asynchronous notifications
+*/
+
#include "async.h"
#include "fastd.h"
+/** The packet header used on the async notification sockets */
typedef struct fastd_async_hdr {
fastd_async_type_t type;
size_t len;
} fastd_async_hdr_t;
+/** Initializes the async notification sockets */
void fastd_async_init(void) {
int fds[2];
@@ -50,6 +58,7 @@ void fastd_async_init(void) {
ctx.async_wfd = fds[1];
}
+/** Handles a DNS resolver response */
static void handle_resolve_return(const fastd_async_resolve_return_t *resolve_return) {
fastd_peer_t *peer = fastd_peer_find_by_id(resolve_return->peer_id);
if (!peer)
@@ -64,6 +73,7 @@ static void handle_resolve_return(const fastd_async_resolve_return_t *resolve_re
#ifdef WITH_VERIFY
+/** Handles a on-verify response */
static void handle_verify_return(const fastd_async_verify_return_t *verify_return) {
fastd_peer_t *peer = fastd_peer_find_by_id(verify_return->peer_id);
if (!peer)
@@ -81,6 +91,7 @@ static void handle_verify_return(const fastd_async_verify_return_t *verify_retur
#endif
+/** Reads and handles a single notification from the async notification socket */
void fastd_async_handle(void) {
fastd_async_hdr_t header;
struct iovec vec[2] = {
@@ -122,6 +133,7 @@ void fastd_async_handle(void) {
}
}
+/** Enqueues a new async notification */
void fastd_async_enqueue(fastd_async_type_t type, const void *data, size_t len) {
fastd_async_hdr_t header;
/* use memset to zero the holes in the struct to make valgrind happy */
diff --git a/src/async.h b/src/async.h
index fd6ebd5..ee81b73 100644
--- a/src/async.h
+++ b/src/async.h
@@ -23,6 +23,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file async.h
+
+ Asynchronous notifications
+*/
+
#pragma once
@@ -30,12 +36,14 @@
#include "peer.h"
+/** A type of asynchronous notification */
typedef enum fastd_async_type {
- ASYNC_TYPE_RESOLVE_RETURN,
- ASYNC_TYPE_VERIFY_RETURN,
+ ASYNC_TYPE_RESOLVE_RETURN, /**< A DNS resolver response */
+ ASYNC_TYPE_VERIFY_RETURN, /**< A on-verify return */
} fastd_async_type_t;
+/** A DNS resolver response */
typedef struct fastd_async_resolve_return {
uint64_t peer_id;
size_t remote;
@@ -44,6 +52,7 @@ typedef struct fastd_async_resolve_return {
fastd_peer_address_t addr[];
} fastd_async_resolve_return_t;
+/** A on-verify response */
typedef struct fastd_async_verify_return {
bool ok;
diff --git a/src/compat.h b/src/compat.h
index 1ab8452..1e857a0 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -47,11 +47,13 @@
#include <netinet/if_ether.h>
#ifndef ETH_ALEN
-#define ETH_ALEN 6 /**< The length of a MAC address */
+/** The length of a MAC address */
+#define ETH_ALEN 6
#endif
#ifndef ETH_HLEN
-#define ETH_HLEN 14 /**< The length of the standard ethernet header */
+/** The length of the standard ethernet header */
+#define ETH_HLEN 14
#endif
#ifndef HAVE_ETHHDR
@@ -64,27 +66,35 @@ struct ethhdr {
#endif
#if defined(USE_FREEBIND) && !defined(IP_FREEBIND)
-#define IP_FREEBIND 15 /**< Compatiblity define for systems supporting, but not defining IP_FREEBIND */
+/** Compatiblity define for systems supporting, but not defining IP_FREEBIND */
+#define IP_FREEBIND 15
#endif
#ifndef SOCK_NONBLOCK
-#define NO_HAVE_SOCK_NONBLOCK /**< Defined if SOCK_NONBLOCK doesn't have an effect */
-#define SOCK_NONBLOCK 0 /**< Compatiblity define for systems not supporting SOCK_NONBLOCK */
+/** Defined if SOCK_NONBLOCK doesn't have an effect */
+#define NO_HAVE_SOCK_NONBLOCK
+
+/** Compatiblity define for systems not supporting SOCK_NONBLOCK */
+#define SOCK_NONBLOCK 0
#endif
#ifndef HAVE_GET_CURRENT_DIR_NAME
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-/**< Replacement function for *BSD systems not supporting get_current_dir_name() */
+/** Replacement function for *BSD systems not supporting get_current_dir_name() */
static inline char *get_current_dir_name(void) {
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+
return getcwd(NULL, 0);
-}
+
#else
#error unknown system, get_current_dir_name() not implemented
#endif
+}
+
#endif
diff --git a/src/dlist.h b/src/dlist.h
index ac7a5a9..d1fc40c 100644
--- a/src/dlist.h
+++ b/src/dlist.h
@@ -23,6 +23,11 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file dlist.h
+
+ Doubly-linked lists
+*/
#pragma once
@@ -31,16 +36,19 @@
typedef struct fastd_dlist_head fastd_dlist_head_t;
+/** Doubly-linked list element */
struct fastd_dlist_head {
fastd_dlist_head_t *prev;
fastd_dlist_head_t *next;
};
+/** Checks if a fastd_dlist_head_t is currently part of a list */
static inline bool fastd_dlist_linked(fastd_dlist_head_t *elem) {
return elem->prev;
}
+/** Adds the element \e elem after \e list */
static inline void fastd_dlist_insert(fastd_dlist_head_t *list, fastd_dlist_head_t *elem) {
elem->prev = list;
elem->next = list->next;
@@ -51,6 +59,7 @@ static inline void fastd_dlist_insert(fastd_dlist_head_t *list, fastd_dlist_head
elem->next->prev = elem;
}
+/** Removes \e elem from a list */
static inline void fastd_dlist_remove(fastd_dlist_head_t *elem) {
if (elem->prev)
elem->prev->next = elem->next;
diff --git a/src/shell.c b/src/shell.c
index 24497f9..d8f044b 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -24,6 +24,13 @@
*/
+/**
+ \file shell.c
+
+ Execution of shell commands and management of environment variables
+*/
+
+
#include "shell.h"
#include "fastd.h"
@@ -31,17 +38,20 @@
#include <sys/wait.h>
+/** An environment variable */
typedef struct shell_env_entry {
const char *key;
char *value;
} shell_env_entry_t;
+/** A shell environment */
struct fastd_shell_env {
VECTOR(shell_env_entry_t) entries;
};
+/** Allocated a new shell environment */
fastd_shell_env_t * fastd_shell_env_alloc(void) {
fastd_shell_env_t *env = malloc(sizeof(fastd_shell_env_t));
VECTOR_ALLOC(env->entries, 0);
@@ -49,11 +59,13 @@ fastd_shell_env_t * fastd_shell_env_alloc(void) {
return env;
}
+/** Sets a variable in a shell environment */
void fastd_shell_env_set(fastd_shell_env_t *env, const char *key, const char *value) {
shell_env_entry_t entry = {.key = key, .value = value ? strdup(value) : NULL};
VECTOR_ADD(env->entries, entry);
}
+/** Frees a variable in a shell environment */
void fastd_shell_env_free(fastd_shell_env_t *env) {
size_t i;
for (i = 0; i < VECTOR_LEN(env->entries); i++) {
@@ -65,6 +77,7 @@ void fastd_shell_env_free(fastd_shell_env_t *env) {
free(env);
}
+/** Applies a shell environment to the current process */
static void shell_command_setenv(pid_t pid, const fastd_shell_env_t *env) {
char buf[20];
@@ -103,6 +116,7 @@ static void shell_command_setenv(pid_t pid, const fastd_shell_env_t *env) {
}
}
+/** Tries to fork and execute the given command with some environment */
static bool shell_command_do_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env, pid_t *pid) {
pid_t parent = getpid();
@@ -134,6 +148,11 @@ static bool shell_command_do_exec(const fastd_shell_command_t *command, const fa
_exit(127);
}
+/**
+ Executes a shell command synchronously, regardless of the value of the \e sync field
+
+ May be called from secondary threads.
+*/
bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const fastd_shell_env_t *env, int *ret) {
if (!fastd_shell_command_isset(command))
return true;
@@ -173,6 +192,12 @@ bool fastd_shell_command_exec_sync(const fastd_shell_command_t *command, const f
return true;
}
+/**
+ Executes a shell command asynchronously
+
+ The new process's pid is added to \e ctx.async_pids so it can be reaped later
+ on SIGCHLD.
+*/
static void shell_command_exec_async(const fastd_shell_command_t *command, const fastd_shell_env_t *env) {
/* block SIGCHLD */
sigset_t set, oldset;
@@ -187,6 +212,7 @@ static void shell_command_exec_async(const fastd_shell_command_t *command, const
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}
+/** Executes a shell command */
void fastd_shell_command_exec(const fastd_shell_command_t *command, const fastd_shell_env_t *env) {
if (!fastd_shell_command_isset(command))
return;
diff --git a/src/shell.h b/src/shell.h
index 9b66477..9c2b8ab 100644
--- a/src/shell.h
+++ b/src/shell.h
@@ -23,6 +23,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file shell.h
+
+ Execution of shell commands and management of environment variables
+*/
+
#pragma once
@@ -32,13 +38,15 @@
#include <string.h>
+/** A shell command */
struct fastd_shell_command {
- char *command;
- char *dir;
- bool sync;
+ char *command; /**< The command as given to \em /bin/sh */
+ char *dir; /**< The working directory for the command */
+ bool sync; /**< If false, the command will be executed in the background by default */
};
+/** Frees the resources used by a shell command */
static inline void fastd_shell_command_unset(fastd_shell_command_t *command) {
free(command->command);
command->command = NULL;
@@ -47,6 +55,7 @@ static inline void fastd_shell_command_unset(fastd_shell_command_t *command) {
command->dir = NULL;
}
+/** Sets a shell command */
static inline void fastd_shell_command_set(fastd_shell_command_t *command, const char *val, bool sync) {
fastd_shell_command_unset(command);
@@ -55,6 +64,7 @@ static inline void fastd_shell_command_set(fastd_shell_command_t *command, const
command->sync = sync;
}
+/** Checks if a shell command is set */
static inline bool fastd_shell_command_isset(const fastd_shell_command_t *command) {
return command->command;
}
diff --git a/src/vector.c b/src/vector.c
index bda1fe1..4bf5853 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -23,15 +23,27 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file vector.c
+
+ Typesafe dynamically sized arrays
+*/
+
#include "vector.h"
#include <string.h>
+/** The minimum number of elements to allocate even when less elements are used */
#define MIN_VECTOR_ALLOC 4
+/**
+ Allocates a new vector
+
+ Internal function, use VECTOR_ALLOC() instead.
+*/
void _fastd_vector_alloc(fastd_vector_desc_t *desc, void **data, size_t n, size_t elemsize) {
desc->allocated = MIN_VECTOR_ALLOC;
@@ -43,6 +55,13 @@ void _fastd_vector_alloc(fastd_vector_desc_t *desc, void **data, size_t n, size_
*data = malloc(desc->allocated * elemsize);
}
+/**
+ Resizes a vector
+
+ Vector allocations are always powers of 2.
+
+ Internal function, use VECTOR_RESIZE() instead.
+*/
void _fastd_vector_resize(fastd_vector_desc_t *desc, void **data, size_t n, size_t elemsize) {
desc->length = n;
@@ -59,6 +78,11 @@ void _fastd_vector_resize(fastd_vector_desc_t *desc, void **data, size_t n, size
}
}
+/**
+ Inserts an element into a vector
+
+ Internal function, use VECTOR_INSERT() and VECTOR_ADD() instead.
+*/
void _fastd_vector_insert(fastd_vector_desc_t *desc, void **data, void *element, size_t pos, size_t elemsize) {
_fastd_vector_resize(desc, data, desc->length+1, elemsize);
@@ -68,6 +92,11 @@ void _fastd_vector_insert(fastd_vector_desc_t *desc, void **data, void *element,
memcpy(p, element, elemsize);
}
+/**
+ Deletes an element from a vector
+
+ Internal function, use VECTOR_DELETE() instead.
+*/
void _fastd_vector_delete(fastd_vector_desc_t *desc, void **data, size_t pos, size_t elemsize) {
void *p = *data + pos*elemsize;
memmove(p, p+elemsize, (desc->length-pos-1)*elemsize);
diff --git a/src/vector.h b/src/vector.h
index 0396c01..0a61341 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -23,18 +23,30 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file vector.h
+
+ Typesafe dynamically sized arrays
+*/
+
#pragma once
#include <stdlib.h>
+/** A vector descriptor */
typedef struct fastd_vector_desc {
size_t allocated;
size_t length;
} fastd_vector_desc_t;
+/**
+ A type for a vector of \e type elements
+
+ \hideinitializer
+*/
#define VECTOR(type) \
struct { \
fastd_vector_desc_t desc; \
@@ -49,39 +61,91 @@ void _fastd_vector_insert(fastd_vector_desc_t *desc, void **data, void *element,
void _fastd_vector_delete(fastd_vector_desc_t *desc, void **data, size_t pos, size_t elemsize);
+/**
+ Allocates resources for the vector \e a, starting with \e n elements
+
+ \hideinitializer
+*/
#define VECTOR_ALLOC(v, n) ({ \
__typeof__(v) *_v = &(v); \
_fastd_vector_alloc(&_v->desc, (void**)&_v->data, (n), sizeof(*_v->data)); \
})
+/**
+ Resizes the vector \e a to \e n elements
+
+ \hideinitializer
+*/
#define VECTOR_RESIZE(v, n) ({ \
__typeof__(v) *_v = &(v); \
_fastd_vector_resize(&_v->desc, (void**)&_v->data, (n), sizeof(*_v->data)); \
})
+/**
+ Frees all resources used by the vector \e v
+
+ \hideinitializer
+*/
#define VECTOR_FREE(v) free((v).data)
+/**
+ Returns the number of elements in the vector \e v
+
+ \hideinitializer
+*/
#define VECTOR_LEN(v) ((v).desc.length)
+
+/**
+ Returns the element with index \e i in the vector \e v
+
+ \hideinitializer
+*/
#define VECTOR_INDEX(v, i) ((v).data[i])
+
+/**
+ Returns a pointer to the vector elements of \e v
+
+ \hideinitializer
+*/
#define VECTOR_DATA(v) ((v).data)
+/**
+ Inserts the element \e elem at index \e pos of vector \e v
+
+ \hideinitializer
+*/
#define VECTOR_INSERT(v, elem, pos) ({ \
__typeof__(v) *_v = &(v); \
__typeof__(*_v->data) _e = (elem); \
_fastd_vector_insert(&_v->desc, (void**)&_v->data, &_e, (pos), sizeof(_e)); \
})
+/**
+ Adds the element \e elem at the end of vector \e v
+
+ \hideinitializer
+*/
#define VECTOR_ADD(v, elem) ({ \
__typeof__(v) *_v = &(v); \
__typeof__(*_v->data) _e = (elem); \
_fastd_vector_insert(&_v->desc, (void**)&_v->data, &_e, _v->desc.length, sizeof(_e)); \
})
+/**
+ Deletes the element at index \e pos of vector \e v
+
+ \hideinitializer
+*/
#define VECTOR_DELETE(v, pos) ({ \
__typeof__(v) *_v = &(v); \
_fastd_vector_delete(&_v->desc, (void**)&_v->data, (pos), sizeof(*_v->data)); \
})
+/**
+ Performs a binary search on the vector \e v, returning a pointer to a matching vector element
+
+ \hideinitializer
+*/
#define VECTOR_BSEARCH(key, v, cmp) ({ \
__typeof__(v) *_v = &(v); \
const __typeof__(*_v->data) *_key = (key); \