diff options
-rw-r--r-- | Doxyfile.in | 2 | ||||
-rw-r--r-- | src/async.c | 12 | ||||
-rw-r--r-- | src/async.h | 13 | ||||
-rw-r--r-- | src/compat.h | 26 | ||||
-rw-r--r-- | src/dlist.h | 9 | ||||
-rw-r--r-- | src/shell.c | 26 | ||||
-rw-r--r-- | src/shell.h | 16 | ||||
-rw-r--r-- | src/vector.c | 29 | ||||
-rw-r--r-- | src/vector.h | 64 |
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); \ |