diff options
| author | @syxhe <https://t.me/syxhe> | 2025-06-08 17:25:13 -0500 |
|---|---|---|
| committer | @syxhe <https://t.me/syxhe> | 2025-06-08 17:25:13 -0500 |
| commit | 08fb644c7d101551edfe8fc2608e0ac501b3df9f (patch) | |
| tree | 65660431cb77c7f482eb1d7a45fe47c562d49608 /src | |
| parent | 5431fec6726c18234c9c28b014cc6f18a0d79884 (diff) | |
Trim the fat
Diffstat (limited to 'src')
| -rw-r--r-- | src/arena.c | 143 | ||||
| -rw-r--r-- | src/arena.h | 41 | ||||
| -rw-r--r-- | src/encryption.c | 56 | ||||
| -rw-r--r-- | src/ll.c | 235 | ||||
| -rw-r--r-- | src/ll.h | 31 | ||||
| -rwxr-xr-x | src/main.c | 5 | ||||
| -rw-r--r-- | src/scanner.c | 49 | ||||
| -rw-r--r-- | src/scanner.h | 4 | ||||
| -rw-r--r-- | src/shared.c | 105 | ||||
| -rw-r--r-- | src/shared.h | 26 |
10 files changed, 89 insertions, 606 deletions
diff --git a/src/arena.c b/src/arena.c deleted file mode 100644 index 8f32064..0000000 --- a/src/arena.c +++ /dev/null | |||
| @@ -1,143 +0,0 @@ | |||
| 1 | #include "arena.h" | ||
| 2 | #include "shared.h" | ||
| 3 | |||
| 4 | #include <asm-generic/errno-base.h> | ||
| 5 | #include <stddef.h> | ||
| 6 | #include <stdint.h> | ||
| 7 | #include <stdlib.h> | ||
| 8 | #include <errno.h> | ||
| 9 | #include <error.h> | ||
| 10 | |||
| 11 | typedef struct an { | ||
| 12 | void *membase; | ||
| 13 | void *memcur; | ||
| 14 | size_t allocated; | ||
| 15 | size_t used; | ||
| 16 | |||
| 17 | struct an *next; | ||
| 18 | } arenanode; | ||
| 19 | |||
| 20 | typedef struct arena { | ||
| 21 | arenanode *start; | ||
| 22 | arenanode *current; | ||
| 23 | |||
| 24 | // For keeping track of the largest possible thing that can be allocated to one node | ||
| 25 | // I don't know if I care to keep this or remove it. I'll see if it becomes a problem / is useful | ||
| 26 | size_t node_memspace; | ||
| 27 | } arena; | ||
| 28 | |||
| 29 | arenanode * arenanode_init(size_t bytes) { | ||
| 30 | if(bytes < 1) ERRRET(EINVAL, NULL); | ||
| 31 | |||
| 32 | arenanode *an = VALLOC(1, sizeof(*an)); | ||
| 33 | if(!an) | ||
| 34 | return NULL; | ||
| 35 | |||
| 36 | an->allocated = bytes; | ||
| 37 | an->used = 0; | ||
| 38 | an->next = NULL; | ||
| 39 | |||
| 40 | void *mem = VALLOC(bytes, 1); | ||
| 41 | if(!mem) { | ||
| 42 | free(an); | ||
| 43 | return NULL; | ||
| 44 | } | ||
| 45 | |||
| 46 | an->membase = mem; | ||
| 47 | an->memcur = mem; | ||
| 48 | |||
| 49 | return an; | ||
| 50 | } | ||
| 51 | |||
| 52 | arena * arena_init(size_t bytes) { | ||
| 53 | if(!ISPOWOF2(MEM_ALIGN_BYTES)) XALLOC_EXIT("<arena_init> \"MEM_ALIGN_BYTES\" is not a power of 2. Refusing to create a new arena", ); | ||
| 54 | if(bytes < 1) ERRRET(EINVAL, NULL); | ||
| 55 | |||
| 56 | arena *a = VALLOC(1, sizeof(arena)); | ||
| 57 | if(!a) | ||
| 58 | return NULL; | ||
| 59 | |||
| 60 | a->start = NULL; | ||
| 61 | a->current = NULL; | ||
| 62 | a->node_memspace = bytes; | ||
| 63 | |||
| 64 | arenanode *base = arenanode_init(bytes); | ||
| 65 | if(!base) { | ||
| 66 | free(a); | ||
| 67 | return NULL; | ||
| 68 | } | ||
| 69 | |||
| 70 | a->start = base; | ||
| 71 | a->current = base; | ||
| 72 | |||
| 73 | return a; | ||
| 74 | } | ||
| 75 | |||
| 76 | void * arena_alloc(arena * const arena, size_t bytes) { | ||
| 77 | if(!ISPOWOF2(MEM_ALIGN_BYTES)) XALLOC_EXIT("<arena_alloc> \"MEM_ALIGN_BYTES\" is not a power of 2. Refusing to allocate any memory", ); | ||
| 78 | if(!arena) ERRRET(EINVAL, NULL); | ||
| 79 | if(bytes > arena->node_memspace) ERRRET(ENOMEM, NULL); | ||
| 80 | |||
| 81 | if(bytes > ((arena->current)->allocated - (arena->current)->used)) { | ||
| 82 | arenanode *new = arenanode_init(arena->node_memspace); | ||
| 83 | if(!new) | ||
| 84 | return NULL; | ||
| 85 | |||
| 86 | arena->current->next = new; | ||
| 87 | arena->current = new; | ||
| 88 | } | ||
| 89 | |||
| 90 | size_t alignment = MEM_ALIGN(bytes); | ||
| 91 | size_t offset = bytes + alignment; | ||
| 92 | |||
| 93 | void *mem = arena->current->memcur; | ||
| 94 | arena->current->memcur = (void*)(((uint8_t*)arena->current->memcur) + offset); | ||
| 95 | |||
| 96 | arena->current->used += offset; | ||
| 97 | |||
| 98 | return mem; | ||
| 99 | |||
| 100 | // Note: This implementation assumes that malloc provides already-aligned memory. If it | ||
| 101 | // doesn't, that sucks and blows everything up | ||
| 102 | } | ||
| 103 | |||
| 104 | void arena_free(void *a) { | ||
| 105 | if(!a) | ||
| 106 | return; | ||
| 107 | |||
| 108 | arena *real = (arena *)a; | ||
| 109 | real->current = real->start; | ||
| 110 | for(arenanode *n; real->current != NULL;) { | ||
| 111 | n = real->current->next; | ||
| 112 | |||
| 113 | free(real->current->membase); | ||
| 114 | free(real->current); | ||
| 115 | |||
| 116 | real->current = n; | ||
| 117 | } | ||
| 118 | free(real); | ||
| 119 | |||
| 120 | return; | ||
| 121 | } | ||
| 122 | |||
| 123 | |||
| 124 | |||
| 125 | |||
| 126 | simplearena * simplearena_init(size_t bytes) { | ||
| 127 | return arena_init(bytes); | ||
| 128 | } | ||
| 129 | |||
| 130 | void * simplearena_alloc(simplearena * const a, size_t bytes) { | ||
| 131 | // The criteria to allocate new memory in arena_alloc is 'bytes > ((a->current)->allocated - (a->current)->used)', so if this | ||
| 132 | // is true, just return NULL & set errno | ||
| 133 | |||
| 134 | if(!a) ERRRET(EINVAL, NULL); | ||
| 135 | if(bytes > ((a->current)->allocated - (a->current)->used)) ERRRET(ENOMEM, NULL); | ||
| 136 | |||
| 137 | return arena_alloc(a, bytes); | ||
| 138 | } | ||
| 139 | |||
| 140 | void simplearena_free(simplearena *a) { | ||
| 141 | arena_free(a); | ||
| 142 | return; | ||
| 143 | } \ No newline at end of file | ||
diff --git a/src/arena.h b/src/arena.h deleted file mode 100644 index 907a2fa..0000000 --- a/src/arena.h +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | #ifndef __VXGG_REWRITE___ARENA_H___25077218513438___ | ||
| 2 | #define __VXGG_REWRITE___ARENA_H___25077218513438___ | ||
| 3 | |||
| 4 | #include <stddef.h> | ||
| 5 | |||
| 6 | // Normal arena. Can expand in size beyond original allocation | ||
| 7 | typedef struct arena arena; | ||
| 8 | |||
| 9 | // A wrapper for the normal arena struct. Can not expand in size | ||
| 10 | typedef arena simplearena; | ||
| 11 | |||
| 12 | // Bitwise operation to check if a number is a power of 2 | ||
| 13 | #define ISPOWOF2(x) (((x) & ((x) - 1)) == 0) | ||
| 14 | |||
| 15 | // Variable for memory alignment | ||
| 16 | static const size_t MEM_ALIGN_BYTES = (2 * sizeof(void*)); | ||
| 17 | |||
| 18 | // Macro to get the remaining bytes necessary to be on a power of 2 | ||
| 19 | #define MEM_ALIGN(x) ((x) + (((x) & (MEM_ALIGN_BYTES - 1)) != 0) * (MEM_ALIGN_BYTES - ((x) & (MEM_ALIGN_BYTES - 1)))) | ||
| 20 | |||
| 21 | |||
| 22 | // Initialize an arena with `bytes` bytes of pre-allocated memory. Exits / returns NULL on error depending on the value of `___VXGG___USE_XALLOC_FOR_ARENAS___` | ||
| 23 | arena * arena_init(size_t bytes); | ||
| 24 | |||
| 25 | // Take `bytes` bytes of memory from `arena`'s memory pool. Exits / returns NULL on error depending on the value of `___VXGG___USE_XALLOC_FOR_ARENAS___` | ||
| 26 | void * arena_alloc(arena * const arena, size_t bytes); | ||
| 27 | |||
| 28 | // Free an arena its memory pool(s). Returns -1 and sets `errno` if the given arena is NULL | ||
| 29 | void arena_free(void *a); | ||
| 30 | |||
| 31 | |||
| 32 | // Initializes a simple arena. | ||
| 33 | simplearena * simplearena_init(size_t bytes); | ||
| 34 | |||
| 35 | // Grabs some memory from the simple arena's pool. Exits / returns NULL on error depending on the value of `___VXGG___USE_XALLOC_FOR_ARENAS___` | ||
| 36 | void * simplearena_alloc(simplearena * const a, size_t bytes); | ||
| 37 | |||
| 38 | // Free a simple arena. Exits / returns -1 on error depending on the value of `___VXGG___USE_XALLOC_FOR_ARENAS___` | ||
| 39 | void simplearena_free(simplearena *a); | ||
| 40 | |||
| 41 | #endif \ No newline at end of file | ||
diff --git a/src/encryption.c b/src/encryption.c index 3bf9dd4..b6832ed 100644 --- a/src/encryption.c +++ b/src/encryption.c | |||
| @@ -1,4 +1,7 @@ | |||
| 1 | // TODO: Go back and make sure every function has proper error handling | 1 | // TODO: Go back and make sure every function has proper error handling |
| 2 | // Oh fucking christ what have I done | ||
| 3 | // I need to make sure every single function in this file returns with an indicated error instead of nuking the whole program with | ||
| 4 | // error() | ||
| 2 | 5 | ||
| 3 | #define _GNU_SOURCE | 6 | #define _GNU_SOURCE |
| 4 | 7 | ||
| @@ -27,7 +30,7 @@ void naclfaildefault(void *none) { | |||
| 27 | exit(EXIT_FAILURE); | 30 | exit(EXIT_FAILURE); |
| 28 | } | 31 | } |
| 29 | 32 | ||
| 30 | int checksodiumcb(const vxgg_naclfailcb callback, void *data, unsigned char set) { | 33 | int checksodiumcb(vxgg_naclfailcb const callback, void *data, unsigned char set) { |
| 31 | static vxgg_naclfailcb cb = naclfaildefault; | 34 | static vxgg_naclfailcb cb = naclfaildefault; |
| 32 | static void *usr = NULL; | 35 | static void *usr = NULL; |
| 33 | int ret; | 36 | int ret; |
| @@ -84,7 +87,9 @@ int linkto(const char * const target, int tgfd) { | |||
| 84 | if(!path) | 87 | if(!path) |
| 85 | ERROR(1, errno, "<linkto> Couldn't get path to move file into system",); | 88 | ERROR(1, errno, "<linkto> Couldn't get path to move file into system",); |
| 86 | remove(target); // Make sure an old version isn't sticking around (it's not catastrophic if this fails, but it should be noted or logged somewhere) | 89 | remove(target); // Make sure an old version isn't sticking around (it's not catastrophic if this fails, but it should be noted or logged somewhere) |
| 87 | return linkat(AT_FDCWD, path, AT_FDCWD, target, AT_SYMLINK_FOLLOW); | 90 | int res = linkat(AT_FDCWD, path, AT_FDCWD, target, AT_SYMLINK_FOLLOW); |
| 91 | free(path); | ||
| 92 | return res; | ||
| 88 | } | 93 | } |
| 89 | 94 | ||
| 90 | int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 95 | int encryptviatmp(const char * const target, const char * const output, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| @@ -127,17 +132,11 @@ int encryptviatmp(const char * const target, const char * const output, const un | |||
| 127 | } | 132 | } |
| 128 | 133 | ||
| 129 | int decryptto(const char * const encrypted, const char * const target, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 134 | int decryptto(const char * const encrypted, const char * const target, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 135 | if(!encrypted || !target || !key) ERRRET(EINVAL, -1); | ||
| 130 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | 136 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 |
| 131 | checksodium(); | 137 | checksodium(); |
| 132 | #endif | 138 | #endif |
| 133 | 139 | ||
| 134 | if(!encrypted) | ||
| 135 | ERRRET(EINVAL, -1); | ||
| 136 | if(!target) | ||
| 137 | ERRRET(EINVAL, -1); | ||
| 138 | if(!key) | ||
| 139 | ERRRET(EINVAL, -1); | ||
| 140 | |||
| 141 | FILE *src, *dst; | 140 | FILE *src, *dst; |
| 142 | if(!(src = fopen(encrypted, "rb"))) | 141 | if(!(src = fopen(encrypted, "rb"))) |
| 143 | ERROR(1, errno, "<decryptto> Could not open \"%s\" for decryption", , encrypted); | 142 | ERROR(1, errno, "<decryptto> Could not open \"%s\" for decryption", , encrypted); |
| @@ -164,6 +163,11 @@ int decryptto(const char * const encrypted, const char * const target, const uns | |||
| 164 | } | 163 | } |
| 165 | 164 | ||
| 166 | int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 165 | int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 166 | if(!src || !dst || !key) ERRRET(EINVAL, -1); | ||
| 167 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 168 | checksodium(); | ||
| 169 | #endif | ||
| 170 | |||
| 167 | unsigned char buf[CHUNKSIZE], cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; | 171 | unsigned char buf[CHUNKSIZE], cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; |
| 168 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; | 172 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; |
| 169 | crypto_secretstream_xchacha20poly1305_state state; | 173 | crypto_secretstream_xchacha20poly1305_state state; |
| @@ -172,17 +176,6 @@ int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 172 | size_t bytesread; | 176 | size_t bytesread; |
| 173 | int eof; | 177 | int eof; |
| 174 | 178 | ||
| 175 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 176 | checksodium(); | ||
| 177 | #endif | ||
| 178 | |||
| 179 | if(!src) | ||
| 180 | ERRRET(EINVAL, -1); | ||
| 181 | if(!dst) | ||
| 182 | ERRRET(EINVAL, -1); | ||
| 183 | if(!key) | ||
| 184 | ERRRET(EINVAL, -1); | ||
| 185 | |||
| 186 | // Write the header | 179 | // Write the header |
| 187 | crypto_secretstream_xchacha20poly1305_init_push(&state, header, key); | 180 | crypto_secretstream_xchacha20poly1305_init_push(&state, header, key); |
| 188 | if(fwrite(header, 1, sizeof(header), dst) < sizeof(header)) | 181 | if(fwrite(header, 1, sizeof(header), dst) < sizeof(header)) |
| @@ -206,7 +199,12 @@ int encrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 206 | return 0; | 199 | return 0; |
| 207 | } | 200 | } |
| 208 | 201 | ||
| 209 | int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { | 202 | int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { |
| 203 | if(!src || !dst || !key) ERRRET(EINVAL, -1); | ||
| 204 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 205 | checksodium(); | ||
| 206 | #endif | ||
| 207 | |||
| 210 | unsigned char cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES], buf[CHUNKSIZE]; | 208 | unsigned char cbuf[CHUNKSIZE + crypto_secretstream_xchacha20poly1305_ABYTES], buf[CHUNKSIZE]; |
| 211 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; | 209 | unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; |
| 212 | crypto_secretstream_xchacha20poly1305_state state; | 210 | crypto_secretstream_xchacha20poly1305_state state; |
| @@ -215,17 +213,6 @@ int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 215 | size_t bytesread; | 213 | size_t bytesread; |
| 216 | int eof; | 214 | int eof; |
| 217 | 215 | ||
| 218 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | ||
| 219 | checksodium(); | ||
| 220 | #endif | ||
| 221 | |||
| 222 | if(!src) | ||
| 223 | ERRRET(EINVAL, -1); | ||
| 224 | if(!dst) | ||
| 225 | ERRRET(EINVAL, -1); | ||
| 226 | if(!key) | ||
| 227 | ERRRET(EINVAL, -1); | ||
| 228 | |||
| 229 | // Read the header | 216 | // Read the header |
| 230 | if(fread(header, 1, sizeof(header), src) < sizeof(header)) | 217 | if(fread(header, 1, sizeof(header), src) < sizeof(header)) |
| 231 | if(ferror(src)) | 218 | if(ferror(src)) |
| @@ -258,7 +245,8 @@ int decrypttofile(FILE *src, FILE *dst, const unsigned char key[crypto_secretstr | |||
| 258 | 245 | ||
| 259 | int genpassword(char **str, unsigned int words) { | 246 | int genpassword(char **str, unsigned int words) { |
| 260 | // Early returns | 247 | // Early returns |
| 261 | if(words < 1) {return 0;} | 248 | if(words < 1) return 0; |
| 249 | if(!str) ERRRET(EINVAL, -1); | ||
| 262 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 | 250 | #if ___VXGG___ALWAYS_CHECK_LIBSODIUM___ > 0 |
| 263 | checksodium(); | 251 | checksodium(); |
| 264 | #endif | 252 | #endif |
diff --git a/src/ll.c b/src/ll.c deleted file mode 100644 index 908f25f..0000000 --- a/src/ll.c +++ /dev/null | |||
| @@ -1,235 +0,0 @@ | |||
| 1 | #include "ll.h" | ||
| 2 | #include "shared.h" | ||
| 3 | |||
| 4 | #include <stdlib.h> | ||
| 5 | #include <errno.h> | ||
| 6 | #include <error.h> | ||
| 7 | |||
| 8 | typedef struct dln { | ||
| 9 | void *data; | ||
| 10 | dll_freecb freecb; | ||
| 11 | |||
| 12 | struct dln *next; | ||
| 13 | struct dln *prev; | ||
| 14 | |||
| 15 | } dllnode; | ||
| 16 | typedef struct dlinked { | ||
| 17 | int size; | ||
| 18 | dllnode *start; | ||
| 19 | dllnode *end; | ||
| 20 | |||
| 21 | } dlinkedlist; | ||
| 22 | |||
| 23 | dllnode * dllnode_init(void *data, dll_freecb fcb) { | ||
| 24 | dllnode *n = VALLOC(1, sizeof(*n)); | ||
| 25 | if(!n) | ||
| 26 | return NULL; | ||
| 27 | |||
| 28 | n->data = data; | ||
| 29 | n->freecb = fcb; | ||
| 30 | n->prev = NULL; | ||
| 31 | n->next = NULL; | ||
| 32 | |||
| 33 | return n; | ||
| 34 | } | ||
| 35 | |||
| 36 | dlinkedlist * dlinkedlist_init(void) { | ||
| 37 | dlinkedlist *ll = VALLOC(1, sizeof(*ll)); | ||
| 38 | if(!ll) | ||
| 39 | return NULL; | ||
| 40 | |||
| 41 | ll->end = NULL; | ||
| 42 | ll->start = NULL; | ||
| 43 | ll->size = 0; | ||
| 44 | |||
| 45 | return ll; | ||
| 46 | } | ||
| 47 | |||
| 48 | void dlinkedlist_free(void *dll) { | ||
| 49 | if(!dll) | ||
| 50 | return; | ||
| 51 | |||
| 52 | dlinkedlist *ll = (dlinkedlist *)dll; | ||
| 53 | for(dllnode *current = ll->start, *next; current != NULL; ) { | ||
| 54 | next = current->next; | ||
| 55 | |||
| 56 | // This used to be a function but was causing issues for some inscrutable reason | ||
| 57 | if(current->freecb != NULL) | ||
| 58 | current->freecb(current->data); | ||
| 59 | free(current); | ||
| 60 | |||
| 61 | current = next; | ||
| 62 | } | ||
| 63 | free(ll); | ||
| 64 | |||
| 65 | return; | ||
| 66 | } | ||
| 67 | |||
| 68 | int dlinkedlist_size(const dlinkedlist * const ll) { | ||
| 69 | if(!ll) ERRRET(EINVAL, -1); | ||
| 70 | return ll->size; | ||
| 71 | } | ||
| 72 | |||
| 73 | int dlinkedlist_handlefirstnode(dlinkedlist * const ll, void *data, dll_freecb fcb) { | ||
| 74 | if(!ll) ERRRET(EINVAL, 1); | ||
| 75 | if(ll->size > 0) | ||
| 76 | return 1; | ||
| 77 | |||
| 78 | // Need to handle adding the first element differently than other opers, so do it here | ||
| 79 | dllnode *n = dllnode_init(data, fcb); | ||
| 80 | if(!n) | ||
| 81 | return -1; | ||
| 82 | // dllnode_init already sets n.prev and n.next to null, so no need to do so again | ||
| 83 | |||
| 84 | ll->end = n; | ||
| 85 | ll->start = n; | ||
| 86 | ll->size = 1; | ||
| 87 | |||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 91 | int dlinkedlist_xxxend(dlinkedlist * const ll, void *data, dll_freecb fcb, char op) { | ||
| 92 | if(!ll || (op != 'a' && op != 'p')) ERRRET(EINVAL, 1); | ||
| 93 | |||
| 94 | int handleret; | ||
| 95 | if((handleret = dlinkedlist_handlefirstnode(ll, data, fcb)) == 0) | ||
| 96 | return 0; | ||
| 97 | |||
| 98 | dllnode *n = dllnode_init(data, fcb); | ||
| 99 | if(!n || handleret < 0) | ||
| 100 | return -1; | ||
| 101 | |||
| 102 | switch (op) { | ||
| 103 | case 'a': | ||
| 104 | n->prev = (ll->end); | ||
| 105 | (ll->end)->next = n; | ||
| 106 | ll->end = n; | ||
| 107 | break; | ||
| 108 | |||
| 109 | case 'p': | ||
| 110 | n->next = (ll->start); | ||
| 111 | (ll->start)->prev = n; | ||
| 112 | ll->start = n; | ||
| 113 | break; | ||
| 114 | |||
| 115 | default: | ||
| 116 | XALLOC_EXIT("<dlinkedlist_xxxend> got an invalid op token when it shouldn't be possible to recieve one", ); | ||
| 117 | // Technically not an alloc, but also there's no reason I can't reuse a perfectly good macro | ||
| 118 | } | ||
| 119 | |||
| 120 | ll->size++; | ||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | // TODO: Figure out where the memory leak gcc keeps complaining about is & fix it | ||
| 124 | |||
| 125 | |||
| 126 | int dlinkedlist_append(dlinkedlist * const ll, void *data, dll_freecb fcb) { | ||
| 127 | return dlinkedlist_xxxend(ll, data, fcb, 'a'); | ||
| 128 | } | ||
| 129 | |||
| 130 | int dlinkedlist_prepend(dlinkedlist * const ll, void *data, dll_freecb fcb) { | ||
| 131 | return dlinkedlist_xxxend(ll, data, fcb, 'p'); | ||
| 132 | } | ||
| 133 | |||
| 134 | dllnode * dlinkedlist_getnode(const dlinkedlist * const ll, int index) { | ||
| 135 | if(!ll) ERRRET(EINVAL, NULL); | ||
| 136 | if(index < 0 || index >= ll->size) ERRRET(EINVAL, NULL); | ||
| 137 | |||
| 138 | if(index == 0) | ||
| 139 | return ll->start; | ||
| 140 | if(index == (ll->size - 1)) | ||
| 141 | return ll->end; | ||
| 142 | |||
| 143 | int spoint = (index <= (ll->size / 2)); | ||
| 144 | dllnode *p = (spoint) ? ll->start : ll->end; | ||
| 145 | int i = (spoint) ? 0 : ll->size - 1; | ||
| 146 | |||
| 147 | // This should (theoretically) be faster on average | ||
| 148 | for(; p != NULL && ((spoint) ? (i < index) : (i > index)); (spoint) ? i++ : i--, p = (spoint) ? p->next : p->prev); | ||
| 149 | |||
| 150 | return p; | ||
| 151 | } | ||
| 152 | |||
| 153 | int dlinkedlist_insert(dlinkedlist * const ll, void *data, dll_freecb fcb, int index) { | ||
| 154 | if(!ll) ERRRET(EINVAL, 1); | ||
| 155 | if(index < 0 || index >= ll->size) ERRRET(EINVAL, 1); | ||
| 156 | |||
| 157 | // Handle the special cases of appending or prepending | ||
| 158 | if(index == 0) | ||
| 159 | return dlinkedlist_prepend(ll, data, fcb); | ||
| 160 | if(index == (ll->size - 1)) | ||
| 161 | return dlinkedlist_append(ll, data, fcb); | ||
| 162 | |||
| 163 | // Insert between 2 nodes | ||
| 164 | // If you're inserting at index 2, the new node becomes index 2, and the previous node at index 2 moves to index 3 | ||
| 165 | |||
| 166 | dllnode *new = dllnode_init(data, fcb); | ||
| 167 | if(!new) | ||
| 168 | return -1; | ||
| 169 | dllnode *current = dlinkedlist_getnode(ll, index); | ||
| 170 | if(!current) | ||
| 171 | XALLOC_EXIT("<dlinkedlist_insert> somehow managed to pull a null node from dlinkedlist_getnode(... , ... , ... , %d)", , (index)); | ||
| 172 | |||
| 173 | (current->prev)->next = new; | ||
| 174 | new->prev = (current->prev); | ||
| 175 | new->next = current; | ||
| 176 | current->prev = new; | ||
| 177 | |||
| 178 | ll->size++; | ||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | int dlinkedlist_remove(dlinkedlist * const ll, int index) { | ||
| 183 | if(!ll) ERRRET(EINVAL, 1); | ||
| 184 | if(index < 0 || index >= ll->size) ERRRET(EINVAL, 2); | ||
| 185 | |||
| 186 | dllnode *current = dlinkedlist_getnode(ll, index); | ||
| 187 | if(!current) | ||
| 188 | return -1; | ||
| 189 | |||
| 190 | if(index == 0) { | ||
| 191 | ll->start = current->next; | ||
| 192 | ll->start->prev = NULL; | ||
| 193 | } else if(index == (ll->size - 1)) { | ||
| 194 | ll->end = current->prev; | ||
| 195 | ll->end->next = NULL; | ||
| 196 | } else { | ||
| 197 | current->prev->next = current->next; | ||
| 198 | current->next->prev = current->prev; | ||
| 199 | } | ||
| 200 | |||
| 201 | if(current->freecb != NULL) | ||
| 202 | current->freecb(current->data); | ||
| 203 | free(current); | ||
| 204 | |||
| 205 | ll->size--; | ||
| 206 | |||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | void* dlinkedlist_get(const dlinkedlist * const ll, int index) { | ||
| 211 | dllnode *n = dlinkedlist_getnode(ll, index); | ||
| 212 | if(!n) | ||
| 213 | return NULL; | ||
| 214 | |||
| 215 | return n->data; | ||
| 216 | } | ||
| 217 | |||
| 218 | int dlinkedlist_foreach(dlinkedlist *ll, int (*callback)(void*)) { | ||
| 219 | if(!ll || callback == NULL) ERRRET(EINVAL, -1); | ||
| 220 | |||
| 221 | for(dllnode *p = ll->start; p != NULL; p = p->next) | ||
| 222 | callback(p->data); | ||
| 223 | |||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 227 | void * dlinkedlist_poplast(dlinkedlist *ll) { | ||
| 228 | if(!ll) ERRRET(EINVAL, NULL); | ||
| 229 | if(dlinkedlist_isempty(ll)) ERRRET(ENODATA, NULL); | ||
| 230 | |||
| 231 | void *data = dlinkedlist_get(ll, ll->size - 1); | ||
| 232 | dlinkedlist_remove(ll, ll->size - 1); | ||
| 233 | |||
| 234 | return data; | ||
| 235 | } \ No newline at end of file | ||
diff --git a/src/ll.h b/src/ll.h deleted file mode 100644 index f5801e0..0000000 --- a/src/ll.h +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | #ifndef __VXGG_REWRITE___LL_H___305861098005___ | ||
| 2 | #define __VXGG_REWRITE___LL_H___305861098005___ | ||
| 3 | |||
| 4 | // Notice: dlinked functions are no longer necessarily xalloc, but MAY be IF the `___VXGG___USE_XALLOC_FOR_VALLOC___` is greater than 0 | ||
| 5 | |||
| 6 | /* TODO: Implement a way to register a set of alloc functions to a linked list so I can give it arenas for memory allocation | ||
| 7 | // instead of just xcalloc */ | ||
| 8 | // I don't know if I care to do this right now. I might be able to hack it in but it would be a fugly hack, something as bad if not worse than that weird callback thing I was doing with the ALWAYS_CHECK_LIBSODIUM macro | ||
| 9 | |||
| 10 | typedef void (*dll_freecb)(void*); | ||
| 11 | typedef struct dlinked dlinkedlist; | ||
| 12 | |||
| 13 | #ifndef __VXGG_REWRITE___LL_INTERNAL___ | ||
| 14 | |||
| 15 | dlinkedlist * dlinkedlist_init(void); | ||
| 16 | void dlinkedlist_free(void *dll); | ||
| 17 | int dlinkedlist_append(dlinkedlist * const ll, void *data, dll_freecb fcb); | ||
| 18 | int dlinkedlist_prepend(dlinkedlist * const ll, void *data, dll_freecb fcb); | ||
| 19 | int dlinkedlist_insert(dlinkedlist * const ll, void *data, dll_freecb fcb, int index); | ||
| 20 | void* dlinkedlist_get(const dlinkedlist * const ll, int index); | ||
| 21 | int dlinkedlist_remove(dlinkedlist * const ll, int index); | ||
| 22 | void * dlinkedlist_poplast(dlinkedlist *ll); | ||
| 23 | |||
| 24 | int dlinkedlist_size(const dlinkedlist * const ll); | ||
| 25 | #define dlinkedlist_isempty(ll) (dlinkedlist_size((ll)) == 0) | ||
| 26 | |||
| 27 | int dlinkedlist_foreach(dlinkedlist *ll, int (*callback)(void*)); | ||
| 28 | |||
| 29 | #endif | ||
| 30 | |||
| 31 | #endif \ No newline at end of file | ||
| @@ -1,8 +1,7 @@ | |||
| 1 | #include "arena.h" | 1 | #include "shared.h" |
| 2 | |||
| 2 | #include "encryption.h" | 3 | #include "encryption.h" |
| 3 | #include "ll.h" | ||
| 4 | #include "scanner.h" | 4 | #include "scanner.h" |
| 5 | #include "shared.h" | ||
| 6 | #include "threadpool.h" | 5 | #include "threadpool.h" |
| 7 | 6 | ||
| 8 | #include <errno.h> | 7 | #include <errno.h> |
diff --git a/src/scanner.c b/src/scanner.c index ea35e3c..2ffbea4 100644 --- a/src/scanner.c +++ b/src/scanner.c | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | #define _GNU_SOURCE | 1 | #define _GNU_SOURCE |
| 2 | #include "shared.h" | 2 | #include "shared.h" |
| 3 | 3 | ||
| 4 | #include "ll.h" | ||
| 5 | #include "scanner.h" | 4 | #include "scanner.h" |
| 6 | 5 | ||
| 7 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| @@ -10,27 +9,29 @@ | |||
| 10 | #include <errno.h> | 9 | #include <errno.h> |
| 11 | #include <error.h> | 10 | #include <error.h> |
| 12 | 11 | ||
| 13 | dlinkedlist * scandirlist(const char * const dir, int (*selector)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)) { | 12 | // dlinkedlist * scandirlist(const char * const dir, int (*selector)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)) { |
| 14 | if(!dir || selector == NULL || cmp == NULL) ERRRET(EINVAL, NULL); | 13 | // if(!dir || selector == NULL || cmp == NULL) ERRRET(EINVAL, NULL); |
| 15 | 14 | ||
| 16 | struct dirent **namelist = NULL; | 15 | // struct dirent **namelist = NULL; |
| 17 | dlinkedlist *list = NULL; | 16 | // dlinkedlist *list = NULL; |
| 18 | int numentries = -1; | 17 | // int numentries = -1; |
| 19 | 18 | ||
| 20 | if((numentries = scandir(dir, &namelist, selector, cmp)) < 0) | 19 | // if((numentries = scandir(dir, &namelist, selector, cmp)) < 0) |
| 21 | ERRRET(errno, NULL); | 20 | // ERRRET(errno, NULL); |
| 22 | 21 | ||
| 23 | list = dlinkedlist_init(); | 22 | // list = dlinkedlist_init(); |
| 24 | for(int i = 0; i < numentries; i++) | 23 | // for(int i = 0; i < numentries; i++) |
| 25 | if(dlinkedlist_append(list, (void *)(namelist[i]), free) < 0) { | 24 | // if(dlinkedlist_append(list, (void *)(namelist[i]), free) < 0) { |
| 26 | dlinkedlist_free(list); | 25 | // dlinkedlist_free(list); |
| 27 | for(int j = i; j < numentries; j++) | 26 | // for(int j = i; j < numentries; j++) |
| 28 | free(namelist[j]); | 27 | // free(namelist[j]); |
| 29 | 28 | ||
| 30 | free(namelist); | 29 | // free(namelist); |
| 31 | ERRRET(errno, NULL); | 30 | // ERRRET(errno, NULL); |
| 32 | } | 31 | // } |
| 33 | free(namelist); | 32 | // free(namelist); |
| 34 | 33 | ||
| 35 | return list; | 34 | // return list; |
| 36 | } | 35 | // } |
| 36 | |||
| 37 | // TODO: Rewrite this to use the threadpool. Each newly scanned file should be pushed onto the threadpool as an encryption task \ No newline at end of file | ||
diff --git a/src/scanner.h b/src/scanner.h index f42d9b9..b9f2f9a 100644 --- a/src/scanner.h +++ b/src/scanner.h | |||
| @@ -1,9 +1,5 @@ | |||
| 1 | #ifndef __VXGG_REWRITE___SCANNER_H___7164133769617___ | 1 | #ifndef __VXGG_REWRITE___SCANNER_H___7164133769617___ |
| 2 | #define __VXGG_REWRITE___SCANNER_H___7164133769617___ | 2 | #define __VXGG_REWRITE___SCANNER_H___7164133769617___ |
| 3 | 3 | ||
| 4 | #include "ll.h" | ||
| 5 | #include <dirent.h> | ||
| 6 | |||
| 7 | dlinkedlist * scandirlist(const char * const dir, int (*selector)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)); | ||
| 8 | 4 | ||
| 9 | #endif \ No newline at end of file | 5 | #endif \ No newline at end of file |
diff --git a/src/shared.c b/src/shared.c index e83261c..c02414b 100644 --- a/src/shared.c +++ b/src/shared.c | |||
| @@ -6,55 +6,6 @@ | |||
| 6 | #include <errno.h> | 6 | #include <errno.h> |
| 7 | #include <error.h> | 7 | #include <error.h> |
| 8 | 8 | ||
| 9 | enum XALLOC_TYPE { | ||
| 10 | XALLOC_INVAL, // Default when unset | ||
| 11 | |||
| 12 | XALLOC_MALLOC, | ||
| 13 | XALLOC_CALLOC, | ||
| 14 | XALLOC_REALLOC, | ||
| 15 | |||
| 16 | XALLOC_2BIG // Out of range | ||
| 17 | }; | ||
| 18 | |||
| 19 | void * xalloc(size_t nmemb, size_t size, enum XALLOC_TYPE actype, void *ptr) { | ||
| 20 | if(actype <= XALLOC_INVAL || actype >= XALLOC_2BIG) ERRRET(EINVAL, NULL); | ||
| 21 | |||
| 22 | void *mem = NULL; | ||
| 23 | switch(actype) { | ||
| 24 | case XALLOC_MALLOC: | ||
| 25 | mem = malloc(nmemb * size); | ||
| 26 | break; | ||
| 27 | |||
| 28 | case XALLOC_CALLOC: | ||
| 29 | mem = calloc(nmemb, size); | ||
| 30 | break; | ||
| 31 | |||
| 32 | case XALLOC_REALLOC: | ||
| 33 | mem = realloc(ptr, nmemb * size); | ||
| 34 | break; | ||
| 35 | |||
| 36 | default: | ||
| 37 | XALLOC_EXIT("<xalloc> An unknown alloc type was passed, which shouldn't be possible", ); | ||
| 38 | } | ||
| 39 | |||
| 40 | if(!mem) | ||
| 41 | XALLOC_EXIT("<xalloc> Could not allocate memory", ); | ||
| 42 | |||
| 43 | return mem; | ||
| 44 | } | ||
| 45 | |||
| 46 | void * xmalloc(size_t size) { | ||
| 47 | return xalloc(size, 1, XALLOC_MALLOC, NULL); | ||
| 48 | } | ||
| 49 | |||
| 50 | void * xcalloc(size_t nmemb, size_t size) { | ||
| 51 | return xalloc(nmemb, size, XALLOC_CALLOC, NULL); | ||
| 52 | } | ||
| 53 | |||
| 54 | void * xreallocarray(void *ptr, size_t nmemb, size_t size) { | ||
| 55 | return xalloc(nmemb, size, XALLOC_REALLOC, ptr); | ||
| 56 | } | ||
| 57 | |||
| 58 | int rwbuf(char **str, unsigned long int initsize, int fd) { | 9 | int rwbuf(char **str, unsigned long int initsize, int fd) { |
| 59 | // Try to read bytes from fd into str | 10 | // Try to read bytes from fd into str |
| 60 | // Bytes read == 0, return 0 | 11 | // Bytes read == 0, return 0 |
| @@ -67,7 +18,10 @@ int rwbuf(char **str, unsigned long int initsize, int fd) { | |||
| 67 | ssize_t bytesread = -1; | 18 | ssize_t bytesread = -1; |
| 68 | int csize = initsize, ccap = initsize; | 19 | int csize = initsize, ccap = initsize; |
| 69 | 20 | ||
| 70 | lstr = xcalloc(initsize, sizeof(char)); | 21 | lstr = calloc(initsize, sizeof(char)); |
| 22 | if(!lstr) | ||
| 23 | return -1; | ||
| 24 | |||
| 71 | while((bytesread = read(fd, lstr + (csize - ccap), ccap)) > 0) { | 25 | while((bytesread = read(fd, lstr + (csize - ccap), ccap)) > 0) { |
| 72 | ccap -= bytesread; | 26 | ccap -= bytesread; |
| 73 | if(ccap <= 0) { | 27 | if(ccap <= 0) { |
| @@ -138,12 +92,14 @@ int wwbuf(int fd, const unsigned char *buf, int len) { | |||
| 138 | // Thanks Beej! | 92 | // Thanks Beej! |
| 139 | 93 | ||
| 140 | // dirname but less retarded hopefully | 94 | // dirname but less retarded hopefully |
| 141 | char * xdirname(const char * const path) { | 95 | char * vxdirname(const char * const path) { |
| 142 | char *tmp = NULL; | 96 | char *tmp = NULL; |
| 143 | if(!path) { // Path being null is a special case which should return super early, before anything else | 97 | if(!path) { // Path being null is a special case which should return early, before anything else (as to avoid null dereference) |
| 144 | tmp = strdup("."); | 98 | tmp = strdup("."); |
| 145 | if(!tmp) | 99 | if(!tmp) { |
| 146 | XALLOC_EXIT("<xdirname> could not strdup \".\" for set path result \"NULL\"", ); | 100 | WARN(errno, "<vxdirname> could not strdup \".\" for set path result \"NULL\"", ); |
| 101 | return NULL; | ||
| 102 | } | ||
| 147 | 103 | ||
| 148 | return tmp; | 104 | return tmp; |
| 149 | } | 105 | } |
| @@ -154,9 +110,11 @@ char * xdirname(const char * const path) { | |||
| 154 | if(strcmp(path, "..") == 0 && !flag) {tmp = strdup("."); flag++;} | 110 | if(strcmp(path, "..") == 0 && !flag) {tmp = strdup("."); flag++;} |
| 155 | 111 | ||
| 156 | if(flag) { | 112 | if(flag) { |
| 157 | if(!tmp) | 113 | if(!tmp) { |
| 158 | XALLOC_EXIT("<xdirname> could not strdup a set path result", ); | 114 | WARN(errno, "<vxdirname> could not strdup a set path result", ); |
| 159 | 115 | return NULL; | |
| 116 | } | ||
| 117 | |||
| 160 | return tmp; | 118 | return tmp; |
| 161 | } | 119 | } |
| 162 | 120 | ||
| @@ -173,8 +131,10 @@ char * xdirname(const char * const path) { | |||
| 173 | 131 | ||
| 174 | // Get a temp copy of the path for manipulation purposes | 132 | // Get a temp copy of the path for manipulation purposes |
| 175 | tmp = strdup(path); | 133 | tmp = strdup(path); |
| 176 | if(!tmp) | 134 | if(!tmp) { |
| 177 | XALLOC_EXIT("<xdirname> could not strdup the given path \"%s\" for internal manipulation", , path); | 135 | WARN(errno, "<vxdirname> could not strdup the given path \"%s\" for internal manipulation", , path); |
| 136 | return NULL; | ||
| 137 | } | ||
| 178 | 138 | ||
| 179 | // If there's a trailing '/', delete it | 139 | // If there's a trailing '/', delete it |
| 180 | size_t pathlen = strlen(path); | 140 | size_t pathlen = strlen(path); |
| @@ -193,21 +153,24 @@ char * xdirname(const char * const path) { | |||
| 193 | count++; | 153 | count++; |
| 194 | } | 154 | } |
| 195 | 155 | ||
| 196 | if(count == 0) { | 156 | if(count == 0 || count == 1) |
| 197 | free(tmp); | 157 | free(tmp); |
| 158 | if(count == 0) { | ||
| 198 | tmp = strdup("."); | 159 | tmp = strdup("."); |
| 199 | if(!tmp) | 160 | if(!tmp) { |
| 200 | XALLOC_EXIT("<xdirname> could not strdup \".\" for set path result", ); | 161 | WARN(errno, "<xdirname> could not strdup \".\" for set path result", ); |
| 162 | return NULL; | ||
| 163 | } | ||
| 201 | return tmp; | 164 | return tmp; |
| 202 | } | 165 | } else if(count == 1) { |
| 203 | if(count == 1) { | ||
| 204 | free(tmp); | ||
| 205 | tmp = strdup("/"); | 166 | tmp = strdup("/"); |
| 206 | if(!tmp) | 167 | if(!tmp) { |
| 207 | XALLOC_EXIT("<xdirname> could not strdup \"/\" for set path result", ); | 168 | WARN(errno, "<xdirname> could not strdup \"/\" for set path result", ); |
| 208 | 169 | return NULL; | |
| 170 | } | ||
| 209 | return tmp; | 171 | return tmp; |
| 210 | } | 172 | } |
| 173 | // This is retarded, fix it | ||
| 211 | 174 | ||
| 212 | for(size_t i = 0, c2 = 0; i < pathlen; i++) { | 175 | for(size_t i = 0, c2 = 0; i < pathlen; i++) { |
| 213 | if(tmp[i] == '/') | 176 | if(tmp[i] == '/') |
| @@ -217,9 +180,11 @@ char * xdirname(const char * const path) { | |||
| 217 | } | 180 | } |
| 218 | 181 | ||
| 219 | char * const actual = strdup(tmp); | 182 | char * const actual = strdup(tmp); |
| 220 | if(!actual) | ||
| 221 | XALLOC_EXIT("<xdirname> could not strdup tmp string to make a shorter end string", ); | ||
| 222 | free(tmp); | 183 | free(tmp); |
| 184 | if(!actual) { | ||
| 185 | WARN(errno, "<xdirname> could not strdup tmp string to make a shorter end string", ); | ||
| 186 | return NULL; | ||
| 187 | } | ||
| 223 | 188 | ||
| 224 | return actual; | 189 | return actual; |
| 225 | } | 190 | } |
diff --git a/src/shared.h b/src/shared.h index 0b401fe..efb95ad 100644 --- a/src/shared.h +++ b/src/shared.h | |||
| @@ -32,26 +32,19 @@ typedef void (*fcallback)(void*); // free()-like callback signature | |||
| 32 | exit(EXIT_FAILURE); /* Makes gcc happy */\ | 32 | exit(EXIT_FAILURE); /* Makes gcc happy */\ |
| 33 | } while (0) | 33 | } while (0) |
| 34 | 34 | ||
| 35 | // Whether to use `XALLOC` or normal `malloc` functions for acquiring new memory via the `VALLOC()` macro. `> 0` | 35 | |
| 36 | // enables XALLOC functionality | 36 | #define VALLOC(nmemb, size) malloc((nmemb) * (size)) |
| 37 | #define ___VXGG___USE_XALLOC_FOR_VALLOC___ 0 | ||
| 38 | #define VALLOC(nmemb, size) ((___VXGG___USE_XALLOC_FOR_VALLOC___ > 0) ? xmalloc((nmemb) * (size)) : malloc((nmemb) * (size))) | ||
| 39 | 37 | ||
| 40 | // Error macro that gcc will not complain about | 38 | // Error macro that gcc will not complain about |
| 41 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) | 39 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) |
| 40 | #define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0) | ||
| 42 | 41 | ||
| 43 | // `malloc()` with error checking. Calls `exit()` or `abort()` on error, depending on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___` | ||
| 44 | void * xmalloc(size_t size); | ||
| 45 | // `calloc()` with error checking. Calls `exit()` or `abort()` on error, depending on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___` | ||
| 46 | void * xcalloc(size_t nmemb, size_t size); | ||
| 47 | // `reallocarray()` with error checking. Calls `exit()` or `abort()` on error, depending on the value of `___VXGG___XALLOC_EXIT_ON_ERROR___` | ||
| 48 | void * xreallocarray(void *ptr, size_t nmemb, size_t size); | ||
| 49 | // Read the entire contents of a file descriptor into a malloc()'ed buffer | 42 | // Read the entire contents of a file descriptor into a malloc()'ed buffer |
| 50 | int rwbuf(char **str, unsigned long int initsize, int fd); | 43 | int rwbuf(char **str, unsigned long int initsize, int fd); |
| 51 | // Write the entire contents of a buffer into a file descriptor | 44 | // Write the entire contents of a buffer into a file descriptor |
| 52 | int wwbuf(int fd, const unsigned char *buf, int len); | 45 | int wwbuf(int fd, const unsigned char *buf, int len); |
| 53 | // `dirname()` reimplementation that returns a malloc()'ed string. According to the `x___` naming scheme, exits/aborts on alloc error. | 46 | // `dirname()` reimplementation that returns a malloc()'ed string |
| 54 | char * xdirname(const char * const path); | 47 | char * vxdirname(const char * const path); |
| 55 | 48 | ||
| 56 | 49 | ||
| 57 | 50 | ||
| @@ -87,13 +80,4 @@ cleanup_init(&__CLEANUP, __CLEANUP_FUNCS, __CLEANUP_ARGS, (size)) | |||
| 87 | #define cleanup_ERRORFLAGGED (__FLAG != 0) | 80 | #define cleanup_ERRORFLAGGED (__FLAG != 0) |
| 88 | #define cleanup_CNDEXEC(code) while(!cleanup_ERRORFLAGGED) {code; break;} | 81 | #define cleanup_CNDEXEC(code) while(!cleanup_ERRORFLAGGED) {code; break;} |
| 89 | 82 | ||
| 90 | |||
| 91 | |||
| 92 | // Generic task to be executed by a consumer | ||
| 93 | typedef struct task task; | ||
| 94 | // A queue of tasks | ||
| 95 | typedef struct taskqueue taskqueue; | ||
| 96 | // A concurrent queue of tasks, basically a threadpool tasks can be dispatched to | ||
| 97 | typedef struct ctqueue ctqueue; | ||
| 98 | |||
| 99 | #endif \ No newline at end of file | 83 | #endif \ No newline at end of file |
