From 1536f1e0287b8281014200ef6911b294272c4773 Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Wed, 11 Jun 2025 19:39:52 -0500 Subject: Start fixing the encryption scheme --- src/encryption.c | 272 +++++++++++++++++++++++++++++++++++++++++++------------ src/encryption.h | 101 +++++++++++++++++---- src/shared.h | 18 ++-- src/threadpool.h | 26 +++--- 4 files changed, 320 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/encryption.c b/src/encryption.c index fd42929..a3f75d1 100644 --- a/src/encryption.c +++ b/src/encryption.c @@ -16,13 +16,15 @@ #define _GNU_SOURCE -#include "encryption.h" #include "shared.h" +#include "encryption.h" +#include "threadpool.h" #include #include #include +#include #include #include #include @@ -34,19 +36,42 @@ #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 #if ___VXGG___USE_CLS_CALLBACK___ > 0 -void naclfaildefault(void *none) { +/** + * @brief Default sodium init fail callback for use in `checksodiumcb()` + * + * @param none Unused param to fit callback spec + */ +static void naclfaildefault(void *none) { none = none; // Makes gcc happy if(___VXGG___VERBOSE_ERRORS___) error(1, ENOTSUP, " Couldn't initialize sodium for some reason. Quitting..."); exit(EXIT_FAILURE); } -int checksodiumcb(vxgg_naclfailcb const callback, void *data, unsigned char set) { +/** + * @brief Internal function to deal with the `___VXGG___USE_CLS_CALLBACK___` macro + * + * `checksodiumcb()` runs the sodium function `sodium_init()` and on error calls the provided callback with the provided data. The + * callback and data default to `naclfaildefault` and `NULL`, but can be changed when the `set` parameter is non-zero. When `set` + * is zero, the sodium init check is preformed + * + * @note `checksodiumcb()` is ran when these conditions are true - 1: The `___VXGG___ALWAYS_CHECK_LIBSODIUM___` and `___VXGG___USE_CLS_CALLBACK___` + * macros are both greater than 0 when compiling, and 2: a function in `encryption.c` calls a function originating from sodium. This + * function exists as a way to deal with sodium failing yourself, instead of instantly calling `exit()`. If you don't care to handle + * it, or are initializing sodium yourself, this is unnecessary + * + * @param callback A callback to be ran when sodium fails to initialize itself. Ignored if `set` is zero. Must be non-null when `set` is non-zero + * @param data Data to be passed to the callback when it is fired. Ignored if `set` is zero. May be null + * @param set Flag on whether to check sodium or to set a new callback and data pair. Checks sodium when zero, sets callback & data when non-zero + * @retval int + */ +static int checksodiumcb(vxgg_naclfailcb const callback, void *data, unsigned char set) { static vxgg_naclfailcb cb = naclfaildefault; static void *usr = NULL; int ret; if(set) { + if(cb == NULL) ERRRET(EINVAL, -1); cb = callback; usr = data; return 2; // libsodium normally returns 1 if the library is already initialized, so this is to signal that the callback has been updated @@ -68,7 +93,15 @@ void vxgg_setsodiumfailcb(vxgg_naclfailcb cb, void *data) { #endif -void checksodium(void) { +/** + * @brief Simple function to check if sodium has been properly initialized + * + * `checksodium()` will run in functions located in `encryption.h` only when the macro `___VXGG___ALWAYS_CHECK_LIBSODIUM___` is greater + * than zero when compiling. It will call the `checksodiumcb()` function if compiled with the `___VXGG___USE_CLS_CALLBACK___` macro. + * When called, checksodium will run `sodium_init()`, and will either run the user-defined callback or `XALLOC_EXIT`. + * + */ +static void checksodium(void) { #if ___VXGG___USE_CLS_CALLBACK___ > 0 checksodiumcb(NULL, NULL, 0); #else @@ -103,42 +136,89 @@ int linkto(const char * const target, int tgfd) { return res; } + +static void __ucl_close(void *fd) { + if(!fd) return; + close(*(int*)fd); + *(int*)fd = -1; + return; +} + +static void __ucl_fclose(void *file) { + if(!file) return; + fclose((FILE*)file); + return; +} + int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 - checksodium(); + checksodium(); #endif + cleanup_CREATE(10); int fd = -1, tfd = -1; + FILE *src, *dst; + char *targetdir; // Open the target file if((fd = open(target, O_RDONLY)) < 0) return -1; + cleanup_REGISTER(__ucl_close, (void*)&fd); // Create a temp file for writing - char *targetdir = xdirname(output); - tfd = maketmp(targetdir); - free(targetdir); - if(tfd < 0) { - close(fd); - return -1; - } - - FILE *src, *dst; - if(!(src = fdopen(fd, "rb"))) - ERROR(1, errno, " Couldn't open \"%s\"", , target); - if(!(dst = fdopen(tfd, "wb"))) - ERROR(1, errno, " Couldn't open \"%s\"", , output); - if(encrypttofile(src, dst, key) < 0) - ERROR(1, ENOTRECOVERABLE, " I don't even have a way to cause an error here. How did you do it?",); - - // Link the temp file into the system - if(linkto(output, tfd) < 0) - ERROR(1, errno, " Could not link \"%s\" into system after encryption", , output); - - fclose(dst); - fclose(src); - // fclose alco closes fd and tfd, as fdopen does not dup the file descriptors + targetdir = vxdirname(output); + if(!targetdir) + cleanup_MARK(); + cleanup_CNDREGISTER(free, targetdir); + + // Actually get the file descriptor for the temp file + cleanup_CNDEXEC( + tfd = maketmp(targetdir); + if(tfd < 0) + cleanup_MARK(); + cleanup_CNDREGISTER(__ucl_close, (void*)&tfd); + ); + + // Create a FILE* version of the source fd + cleanup_CNDEXEC( + if(!(src = fdopen(fd, "rb"))) { + WARN(errno, " Couldn't open \"%s\"", , target); + cleanup_MARK(); + } + cleanup_CNDREGISTER(__ucl_fclose, (void*)&src); + ) + + // Create a FILE* version of the target fd + cleanup_CNDEXEC( + if(!(dst = fdopen(tfd, "wb"))) { + WARN(errno, " Couldn't open \"%s\"", , output); + cleanup_MARK(); + } + cleanup_CNDREGISTER(__ucl_fclose, (void*)dst); + ); + + + // Do the encryption now that everything has been set up + cleanup_CNDEXEC( + // Not going to bother changing this, it probably is catastrophic if an error happens when it shouldn't + if(encrypttofile(src, dst, key) < 0) + ERROR(1, ENOTRECOVERABLE, " I don't even have a way to cause an error here. How did you do it?",); + + // Link the temp file into the system + if(linkto(output, tfd) < 0) + WARN(errno, " Could not link \"%s\" into system after encryption", , output); + + free(targetdir); + fclose(dst); + fclose(src); + // fclose alco closes fd and tfd, as fdopen does not dup the file descriptors + ); + + cleanup_CNDFIRE(); + if(cleanup_ERRORFLAGGED) + return -1; + return 0; } @@ -148,31 +228,64 @@ int decryptto(const char * const encrypted, const char * const target, const uns checksodium(); #endif + cleanup_CREATE(10); FILE *src, *dst; - if(!(src = fopen(encrypted, "rb"))) - ERROR(1, errno, " Could not open \"%s\" for decryption", , encrypted); - - int fdst = maketmp(target); - if(!fdst) - ERROR(1, errno, " Could not get temp file for decryption", ); - if(!(dst = fdopen(fdst, "wb"))) - ERROR(1, errno, " Could not open \"%s\" for writing decrypted data", , target); - - if(decrypttofile(src, dst, key) < 0) - ERROR(1, errno, " How did you even cause an error?",); - - // Link temp into system - if(linkto(target, fdst) < 0) - ERROR(1, errno, " Could not link \"%s\" into system", , target); + int fdst; - fclose(dst); - fclose(src); - // fclose alco closes fd and tfd, as fdopen does not dup the file descriptors + // Open the source file + if(!(src = fopen(encrypted, "rb"))) { + WARN(errno, " Could not open \"%s\" for decryption", , encrypted); + return -1; + } + cleanup_REGISTER(__ucl_fclose, src); + + // Get a temp descriptor for the temp file + cleanup_CNDEXEC( + fdst = maketmp(target); + if(!fdst) { + WARN(errno, " Could not get temp file for decryption", ); + cleanup_MARK(); + } + cleanup_CNDREGISTER(__ucl_close, (void*)&fdst); + ); + + // Open a FILE* version of the temp file + cleanup_CNDEXEC( + if(!(dst = fdopen(fdst, "wb"))) { + WARN(errno, " Could not open \"%s\" for writing decrypted data", , target); + cleanup_MARK(); + } + cleanup_CNDREGISTER(__ucl_fclose, dst); + ); + + // Follow through with the rest of the decryption + cleanup_CNDEXEC( + if(decrypttofile(src, dst, key) < 0) + ERROR(1, errno, " How did you even cause an error?",); + + // Link temp into system + if(linkto(target, fdst) < 0) + WARN(errno, " Could not link \"%s\" into system", , target); + + fclose(dst); + fclose(src); + // fclose alco closes fd and tfd, as fdopen does not dup the file descriptors + ); + + cleanup_CNDFIRE(); + if(cleanup_ERRORFLAGGED) + return -1; + // Note: If an error were to theoretically occur, which shouldn't be possible but I'm covering my bases here, after the + // `dst = fdopen` line, a double close on the temp file descriptor would occur. I've been told that this is not catastrophic, + // and considering how my multithreading works it *should* be fine, but it very well could cause problems. The easy solution is + // to man up and just write another cleanup function to pop the last thing off the stack, but again this is an error I can't + // actually trigger so it's fine for now return 0; } +// TODO: Fix this mess int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { if(!src || !dst || !key) ERRRET(EINVAL, -1); #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 @@ -210,6 +323,7 @@ int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr return 0; } +// TODO: Fix this as well int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { if(!src || !dst || !key) ERRRET(EINVAL, -1); #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 @@ -283,7 +397,6 @@ int genpassword(char **str, unsigned int words) { return words; } -// sodium_malloc wrapper. Calls `error()` or `abort()` depnding on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___`. Will make sure libsodium is initialized if `___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0` void* xsodium_malloc(size_t size) { #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 checksodium(); @@ -298,15 +411,9 @@ void* xsodium_malloc(size_t size) { -/* - -#include "threadpool.h" +// TODO: Rewrite this to use the threadpool. Each newly scanned file should be pushed onto the threadpool as an encryption task -// #include // #include -// #include -// #include -// #include // dlinkedlist * scandirlist(const char * const dir, int (*selector)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)) { // if(!dir || selector == NULL || cmp == NULL) ERRRET(EINVAL, NULL); @@ -333,8 +440,61 @@ void* xsodium_malloc(size_t size) { // return list; // } -// TODO: Rewrite this to use the threadpool. Each newly scanned file should be pushed onto the threadpool as an encryption task -*/ + + +struct __ucl_namelist_vals { + struct dirent **namelist; + int entries; +}; + +static void __ucl_namelist(void *namelist) { + if(!namelist) return; + struct __ucl_namelist_vals *real = namelist; + for(int i = 0; i > real->entries; i++) + free(real->namelist[i]); + free(real->namelist); + return; +} + +enum VXGG_FLC { + VXGG_FLC__INVALID, + VXGG_FLC__ENCRYPT, + VXGG_FLC__DECRYPT, + VXGG_FLC__TOOBIG +}; + +ctqueue * getfilelist(enum VXGG_FLC mode, const char * const dir, int threads, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) { + if(mode <= VXGG_FLC__INVALID || mode >= VXGG_FLC__TOOBIG || !dir || threads <= 0 || !filter || !compar) ERRRET(EINVAL, NULL); + + cleanup_CREATE(10); + ctqueue *ctq = NULL; + int files = -1; + + // Create the ctqueue for later + ctq = ctqueue_init(threads); + if(!ctq) + return NULL; + cleanup_REGISTER(ctqueue_free, ctq); + + // Get the scandir list + struct dirent **namelist; + if((files = scandir(dir, &namelist, filter, compar)) < 0) + cleanup_MARK(); + cleanup_CNDREGISTER(__ucl_namelist, (void*)(&(struct __ucl_namelist_vals){.namelist = namelist, .entries = files})); + + // Push everything onto the ctqueue + // TODO: Write task* compatible callbacks for encryption and decryption, then populate the ctqueue based on the specified mode + + cleanup_CNDFIRE(); + if(cleanup_ERRORFLAGGED) + return NULL; + + return ctq; +} + + + + /* int main(void) { diff --git a/src/encryption.h b/src/encryption.h index 5c6a08c..a23cbdf 100644 --- a/src/encryption.h +++ b/src/encryption.h @@ -13,35 +13,41 @@ #define __VXGG_REWRITE___ENCRYPTION_H___1481879318188___ #include +#include "shared.h" -// Determines whether any function that calls libsodium functions also checks to make sure libsodium is actually initialized. May -// cause unexpected issues with early exiting due to libsodium failing to initialize properly. It's recommended that you just -// manually run `sodium_init()` in some main or init function of your own so that you can deal with a potential error yourself +/// Determines whether any function that calls libsodium functions also checks to make sure libsodium is actually initialized. May +/// cause unexpected issues with early exiting due to libsodium failing to initialize properly. It's recommended that you just +/// manually run `sodium_init()` in some main or init function of your own so that you can deal with a potential error yourself #define ___VXGG___ALWAYS_CHECK_LIBSODIUM___ 1 -// Grants access to the `vxgg_setsodiumfailcb` function, which can be used to set a custom callback for what to do when libsodium -// fails upon initialization +/// Grants access to the `vxgg_setsodiumfailcb` function, which can be used to set a custom callback for what to do when libsodium +/// fails upon initialization #define ___VXGG___USE_CLS_CALLBACK___ 1 #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 -// Checks if sodium is initialized. Initializes it if not. If `___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0`, it's possible to set an error callback to avoid exiting the entire program. Otherwise calls `error()` if libsodium can't initialize -void checksodium(void); - #if ___VXGG___USE_CLS_CALLBACK___ > 0 -// Definition for the callback function that fires when a call to checksodium fails +//! Definition for the callback function that fires when a call to checksodium fails typedef void (*vxgg_naclfailcb)(void*); -// Sets the error callback for when libsodium fails. Runs `cb(data)` if `(sodium_init() < 0)` +/** + * @brief Sets a callback and data pair to be ran if/when sodium fails to initialize + * + * @param cb The new callback to set. Must be non-null + * @param data The data to be fed to the callback. May be null + */ void vxgg_setsodiumfailcb(const vxgg_naclfailcb cb, void *data); #endif #endif -// Chunk size for en/de-cryption. I originally wanted to use st_blksize from stat(), but given that those chunks may be of different -// sizes between computers / filesystems / architectures / files, it's easier to just have this be a consistent macro +/// Chunk size for en/decryption. I originally wanted to use st_blksize from stat(), but given that those chunks may be of different +/// sizes between computers / filesystems / architectures / files, it's easier to just have this be a consistent macro #define CHUNKSIZE (1 << 9) +const static char * test = "this is a test"; + // Fuck reading from a file. Even if someone ran strings on the binary and got this they wouldn't be able to regenerate the key +//! A list of possible words for password creation #define PASSWORD_WORDS (\ (const char * const []){\ "the", "of", "to", "and", "for", "our", "their", "has", "in", "he", "a", "them", "that", "these", "by", "have", "we", \ @@ -96,27 +102,84 @@ void vxgg_setsodiumfailcb(const vxgg_naclfailcb cb, void *data); "reliance", "divine", "providence", "mutually", "pledge", "each", "fortunes", "sacred", "honor"\ }\ ) +//! Short macro for getting the `PASSWORD_WORDS` array size #define PASSWORD_WORDS_LEN (STATIC_ARRAY_LEN(PASSWORD_WORDS)) -// open() with the flags O_TMPFILE, O_WRONLY, O_CLOEXEC, and O_SYNC. Opened with mode S_IRUSR, S_IWUSR +/** + * @brief open() with the flags O_TMPFILE, O_WRONLY, O_CLOEXEC, and O_SYNC. Opened with mode S_IRUSR, S_IWUSR + * + * @param dest The filename the new descriptor should have. Must be non-null + * @retval (int)[-1,int] A new file descriptor. -1 on error + */ int maketmp(const char * const dest); -// Encrypt src to dst using libsodium's xchacha encryption suite +/** + * @brief Encrypt src to dst using libsodium's xchacha encryption suite + * + * @param src File to encrypt + * @param dst Destination to write encrypted file + * @param key Key for encryption + * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error + */ int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); -// Decrypt src to dst using libsodium's xchacha encryption suite +/** + * @brief Decrypt src to dst using libsodium's xchacha encryption suite + * + * @param src File to decrypt + * @param dst Destination to write decrypted file + * @param key Key used to encrypt + * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error + */ int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); -// Encrypt file at `target` to `output` using Linux's named temp file system to do it in the background +/** + * @brief Encrypt file at `target` to `output` using Linux's named temp file system to do it in the background + * + * @param target + * @param output + * @param key + * @retval (int)[,] + */ int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); -// Decrypt the file at `encrypted` to `target` +/** + * @brief Decrypt the file at `encrypted` to `target` + * + * @param encrypted + * @param target + * @param key + * @retval (int)[,] + */ int decryptto(const char * const encrypted, const char * const target, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); -// +/** + * @brief Link a file descriptor into the filesystem + * + * @param target New filename the descriptor should have + * @param tgfd The file descriptor to link + * @retval (int)[-1, 0] 0 on success, -1 on error + */ int linkto(const char * const target, int tgfd); -// +/** + * @brief Generate a password viable for use in the derivation of a key + * + * @param str Pointer to a string. This will be filled by a malloc'ed string of words (the password). Must be non-null + * @param words The number of words to include in the password. A password of at least 20 words and probably not more than 40 is recommended + * @retval (int)[-1, words] On success, returns the number of words requested. On error, returns -1 and sets errno + */ int genpassword(char **str, unsigned int words); +/** + * @brief sodium_malloc wrapper. + * + * Calls `error()` or `abort()` depnding on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___`. Will make sure libsodium is initialized if `___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0` + * + * @param size + * @retval (void*) A pointer to some data allocated via `sodium_malloc()` + */ +void* xsodium_malloc(size_t size); + + #endif \ No newline at end of file diff --git a/src/shared.h b/src/shared.h index 6276281..94c6f06 100644 --- a/src/shared.h +++ b/src/shared.h @@ -62,7 +62,7 @@ typedef void (*fcallback)(void*); //!< free()-like callback signature * @param str Pointer to a string. Will be replaced with the malloc()'ed string * @param initsize The initial size of the malloc()'ed string * @param fd A file descriptor to read from - * @return int Returns the size of the array on success, or -1 on error + * @retval (int)[-1, strlen(str)] Returns the size of the array on success, or -1 on error * @note The allocated buffer will expand and contract as necessary, but it's recommended to set `initsize` to some value close to or equal to the size of the file being read to reduce the number of resizes */ int rwbuf(char **str, unsigned long int initsize, int fd); @@ -73,7 +73,7 @@ int rwbuf(char **str, unsigned long int initsize, int fd); * @param fd The file descriptor to write to * @param buf The buffer to write from * @param len The length of the buffer - * @return int Returns 0 on success, -1 on error + * @retval (int)[-1, 0] Returns 0 on success, -1 on error */ int wwbuf(int fd, const unsigned char *buf, int len); @@ -83,7 +83,7 @@ int wwbuf(int fd, const unsigned char *buf, int len); * @brief `dirname()` reimplementation that returns a malloc()'ed string * * @param path The filepath to be inspected - * @return char* Returns a null-terminated string on success, or `null` on error + * @retval (char*)[NULL, char*] Returns a null-terminated string on success, or `null` on error */ char * vxdirname(const char * const path); @@ -107,7 +107,7 @@ typedef struct cl { * @param callbacks An array of free()-like callbacks. Must be `size` elements long * @param arguments An array of void pointers. Must be `size` elements long * @param size The number of elements the callbacks and arguments array are long - * @return int Returns 0 on success, -1 on error + * @retval (int)[-1, 0] Returns 0 on success, -1 on error */ int cleanup_init(cleanup *loc, fcallback callbacks[], void *arguments[], int size); @@ -117,7 +117,7 @@ int cleanup_init(cleanup *loc, fcallback callbacks[], void *arguments[], int siz * @param loc The cleanup object to modify * @param cb A free()-like callback to run * @param arg A piece of data for the callback to run - * @return int Returns 0 on success, -1 on error + * @retval (int)[-1, 0] Returns 0 on success, -1 on error */ int cleanup_register(cleanup *loc, fcallback cb, void *arg); @@ -128,7 +128,7 @@ int cleanup_register(cleanup *loc, fcallback cb, void *arg); * @param cb A free()-like callback to run * @param arg A piece of data for the callback to run * @param flag Whether or not the register should take place. Will not run if `flag` is non-zero - * @return int Returns 0 on success or skip, -1 on error + * @retval (int)[-1, 0] Returns 0 on success or skip, -1 on error */ int cleanup_cndregister(cleanup *loc, fcallback cb, void *arg, unsigned char flag); @@ -137,7 +137,7 @@ int cleanup_cndregister(cleanup *loc, fcallback cb, void *arg, unsigned char fla * @attention Does not free any registered callbacks or arguments, just marks them as available space * * @param loc The cleanup object to modify - * @return int Returns 0 on success, -1 on error + * @retval (int)[-1, 0] Returns 0 on success, -1 on error */ int cleanup_clear(cleanup *loc); @@ -145,7 +145,7 @@ int cleanup_clear(cleanup *loc); * @brief Fires all the registered callbacks and arguments in a cleanup object in FIFO (stack) order * * @param loc The cleanup object to fire - * @return int Returns 0 on success, -1 on error + * @retval (int)[-1, 0] Returns 0 on success, -1 on error */ int cleanup_fire(cleanup *loc); @@ -154,7 +154,7 @@ int cleanup_fire(cleanup *loc); * * @param loc The cleanup object in question * @param flag Whether the object should be fired. Will skip firing if non-zero - * @return int Returns 0 on success, -1 on error + * @retval (int)[-1, 0] Returns 0 on success, -1 on error */ int cleanup_cndfire(cleanup *loc, unsigned char flag); diff --git a/src/threadpool.h b/src/threadpool.h index 91c903c..61dbacd 100644 --- a/src/threadpool.h +++ b/src/threadpool.h @@ -25,7 +25,7 @@ typedef struct ctqueue ctqueue; * @param callback Callback function the given data should be ran with. Must be non-null * @param freecb Callback function for freeing the given data. May be null * @param data Data to be passed to the callback. May be null - * @return task* Returns a task object with set parameters. Returns `null` and sets errno on error + * @retval (task*)[NULL, task*] Returns a task object with set parameters. Returns `null` and sets errno on error */ task * task_init(gcallback callback, fcallback freecb, void *data); @@ -40,7 +40,7 @@ void task_free(void *tsk); * @brief Fire a task. Passes the `data` member to the specified `callback` * * @param tsk A task to be fired. Must be non-null - * @return int Returns value of the fired callback. Returns -1 and sets errno on error + * @retval (int) Returns value of the fired callback. Returns -1 and sets errno on error */ int task_fire(task *tsk); @@ -48,7 +48,7 @@ int task_fire(task *tsk); * @brief Fire and destroy a task simultaneously. Calls specified callback and free-callback on associated data * * @param tsk Task to be fired and destroyed. Must be non-null - * @return int Returns value of the callback. Returns -1 and sets errno on error + * @retval (int) Returns value of the callback. Returns -1 and sets errno on error */ int task_fired(task *tsk); @@ -57,7 +57,7 @@ int task_fired(task *tsk); /** * @brief Create a FIFO queue of tasks * - * @return taskqueue* Returns a new taskqueue object. Returns `null` and sets errno on error + * @retval (taskqueue*)[NULL, taskqueue*] Returns a new taskqueue object. Returns `null` and sets errno on error */ taskqueue * taskqueue_init(void); @@ -73,7 +73,7 @@ void taskqueue_free(void *tq); * * @param tq The taskqueue to be modified. Must be non-null * @param tsk The task to push. Must be non-null - * @return int Returns 0 on success, sets errno and returns -1 on error + * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error */ int taskqueue_push(taskqueue *tq, task *tsk); @@ -81,7 +81,7 @@ int taskqueue_push(taskqueue *tq, task *tsk); * @brief Pop a task from a taskqueue * * @param tq A taskqueue to grab a task from. Must be non-null - * @return task* Returns a task on success, sets errno and returns `null` on error + * @retval (task*)[NULL, task*] Returns a task on success, sets errno and returns `null` on error */ task * taskqueue_pop(taskqueue *tq); @@ -90,7 +90,7 @@ task * taskqueue_pop(taskqueue *tq); * * @param tq The taskqueue to be modified. Must be non-null * @param tsk The task to be appended. Must be non-null - * @return int Returns 0 on success, sets errno and returns `null` on error + * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error */ int taskqueue_pushfront(taskqueue *tq, task *tsk); @@ -98,7 +98,7 @@ int taskqueue_pushfront(taskqueue *tq, task *tsk); * @brief Pop a task from the back (most recently pushed task) of a taskqueue * * @param tq A taskqueue to pop from. Must be non-null - * @return task* Returns a task on success, sets errno and returns `null` on error + * @retval (task*)[NULL, task*] Returns a task on success, sets errno and returns `null` on error */ task * taskqueue_popback(taskqueue *tq); @@ -108,7 +108,7 @@ task * taskqueue_popback(taskqueue *tq); * @brief Create a concurrent taskqueue with `size` allocated threads * * @param size Number of threads in the threadpool. Must be greater than zero - * @return ctqueue* Returns a new ctqueue, sets errno and returns `null` on error + * @retval (ctqueue*)[NULL, ctqueue*] Returns a new ctqueue, sets errno and returns `null` on error */ ctqueue * ctqueue_init(int size); @@ -116,7 +116,7 @@ ctqueue * ctqueue_init(int size); * @brief Cancel all tasks being processed in a currently running concurrent taskqueue * * @param ctq The concurrent taskqueue to be canceled. Must be non-null - * @return int Returns 0 on success, sets errno and returns -1 on error + * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error */ int ctqueue_cancel(ctqueue *ctq); @@ -134,7 +134,7 @@ void ctqueue_free(void *ctq); * * @param ctq The concurrent taskqueue to modify. Must be non-null * @param tsk The task to push. Must be non-null - * @return Returns `thrd_success` on success, returns `thrd_error` or `thrd_nomem` on error + * @retval (int) Returns `thrd_success` on success, returns `thrd_error` or `thrd_nomem` on error */ int ctqueue_waitpush(ctqueue *ctq, task *tsk); @@ -144,7 +144,7 @@ int ctqueue_waitpush(ctqueue *ctq, task *tsk); * @attention May block for an indefinite amount of time to pop the task * * @param ctq The concurrent taskqueue to pop from. Must be non-null - * @return Returns a task on success, sets errno and returns `null` on error + * @retval (task*)[NULL, task*] Returns a task on success, sets errno and returns `null` on error */ task * ctqueue_waitpop(ctqueue *ctq); @@ -153,7 +153,7 @@ task * ctqueue_waitpop(ctqueue *ctq); * @attention Threads will not consume pushed tasks until this function is ran * * @param ctq A concurrent taskqueue to start. Must be non-null - * @return int Returns 0 on success, sets errno and returns -1 on error + * @retval (int)[-1, 0] Returns 0 on success, sets errno and returns -1 on error */ int ctqueue_start(ctqueue *ctq); -- cgit v1.2.3