diff options
Diffstat (limited to 'src/shared.c')
| -rw-r--r-- | src/shared.c | 132 |
1 files changed, 49 insertions, 83 deletions
diff --git a/src/shared.c b/src/shared.c index 0a2121b..9a147eb 100644 --- a/src/shared.c +++ b/src/shared.c | |||
| @@ -19,18 +19,17 @@ | |||
| 19 | return (retval);\ | 19 | return (retval);\ |
| 20 | } while (0) | 20 | } while (0) |
| 21 | 21 | ||
| 22 | /// Defines how `x___alloc()` functions should exit. `___VXGG___XALLOC_EXIT_ON_ERROR___ > 0` calls `error()`, and thus functions | 22 | /// Determines how `vx__alloc()` functions exit. `> 0` calls `error()`, otherwise calls `abort()`. `vx__alloc()` type functions will |
| 23 | /// registered with `atexit()` and `on_exit()`. `___VXGG___XALLOC_EXIT_ON_ERROR___ <= 0` calls `abort()` on error. `x___alloc()` | 23 | /// always halt execution |
| 24 | /// type functions will ALWAYS 'abort', doing otherwise defeats the purpose of the function type | 24 | #define ___VXGG___VXALLOC_EXIT_ON_ERROR___ 1 |
| 25 | #define ___VXGG___XALLOC_EXIT_ON_ERROR___ 1 | ||
| 26 | 25 | ||
| 27 | /// Defines whether vxgg functions that can error print out a short warning of the error when one is encountered. | 26 | /// Determines whether vxgg functions that can error print out a short warning of the error when one is encountered. |
| 28 | /// `___VXGG___VERBOSE_ERRORS___ > 0` will print diagnostic error messages, and will do nothing otherwise | 27 | /// `> 0` will print diagnostic error messages, and will do nothing otherwise |
| 29 | #define ___VXGG___VERBOSE_ERRORS___ 1 | 28 | #define ___VXGG___VERBOSE_ERRORS___ 1 |
| 30 | 29 | ||
| 31 | //! Macro to exit on an alloc error instead of doing the terrible nested if statement that was being used previously | 30 | //! Macro to exit on an alloc error instead of doing the terrible nested if statement that was being used previously |
| 32 | #define XALLOC_EXIT(msg, ...) do {\ | 31 | #define XALLOC_EXIT(msg, ...) do {\ |
| 33 | if(!___VXGG___XALLOC_EXIT_ON_ERROR___)\ | 32 | if(!___VXGG___VXALLOC_EXIT_ON_ERROR___)\ |
| 34 | abort();\ | 33 | abort();\ |
| 35 | if(!___VXGG___VERBOSE_ERRORS___)\ | 34 | if(!___VXGG___VERBOSE_ERRORS___)\ |
| 36 | exit(EXIT_FAILURE);\ | 35 | exit(EXIT_FAILURE);\ |
| @@ -38,9 +37,6 @@ | |||
| 38 | exit(EXIT_FAILURE); /* Makes gcc happy */\ | 37 | exit(EXIT_FAILURE); /* Makes gcc happy */\ |
| 39 | } while (0) | 38 | } while (0) |
| 40 | 39 | ||
| 41 | //! Holdover macro because I'm lazy. Used to call either malloc or xmalloc, but the xalloc functions were a bad idea, so I removed them | ||
| 42 | #define VALLOC(nmemb, size) malloc((nmemb) * (size)) | ||
| 43 | |||
| 44 | //! Error macro that gcc will not complain about | 40 | //! Error macro that gcc will not complain about |
| 45 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) | 41 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) |
| 46 | //! Spit out a warning using `error` | 42 | //! Spit out a warning using `error` |
| @@ -60,6 +56,7 @@ typedef struct cl { | |||
| 60 | int size; //!< The size of each array | 56 | int size; //!< The size of each array |
| 61 | int used; //!< The current number of used elements in each array | 57 | int used; //!< The current number of used elements in each array |
| 62 | } cleanup; | 58 | } cleanup; |
| 59 | // While the cleanup thing is useful, it's also a complete fucking mess. Swtich to error gotos asap | ||
| 63 | 60 | ||
| 64 | #include <stdlib.h> | 61 | #include <stdlib.h> |
| 65 | #include <string.h> | 62 | #include <string.h> |
| @@ -83,16 +80,15 @@ int rwbuf(char **str, unsigned long int initsize, int fd) { | |||
| 83 | // Bytes read == 0, return 0 | 80 | // Bytes read == 0, return 0 |
| 84 | // Bytes read < 0, free string, return -1; | 81 | // Bytes read < 0, free string, return -1; |
| 85 | // When string hits capacity, double the capacity, and reallocate the string | 82 | // When string hits capacity, double the capacity, and reallocate the string |
| 86 | if(!str || initsize < 1) ERRRET(EINVAL, -1); | ||
| 87 | const int ECODE = -100; | ||
| 88 | 83 | ||
| 89 | char *lstr = NULL, *tmp = NULL; | 84 | if(!str || initsize < 1 || fd < 0) ERRRET(EINVAL, -1); |
| 85 | |||
| 86 | char *lstr = NULL, *tmp = NULL; | ||
| 90 | ssize_t bytesread = -1; | 87 | ssize_t bytesread = -1; |
| 91 | int csize = initsize, ccap = initsize; | 88 | int csize = initsize, ccap = initsize, eflag = 0; |
| 92 | 89 | ||
| 93 | lstr = calloc(initsize, sizeof(char)); | 90 | lstr = calloc(initsize, sizeof(char)); |
| 94 | if(!lstr) | 91 | if(!lstr) return -1; |
| 95 | return -1; | ||
| 96 | 92 | ||
| 97 | while((bytesread = read(fd, lstr + (csize - ccap), ccap)) > 0) { | 93 | while((bytesread = read(fd, lstr + (csize - ccap), ccap)) > 0) { |
| 98 | ccap -= bytesread; | 94 | ccap -= bytesread; |
| @@ -101,35 +97,15 @@ int rwbuf(char **str, unsigned long int initsize, int fd) { | |||
| 101 | ccap = csize / 2; | 97 | ccap = csize / 2; |
| 102 | 98 | ||
| 103 | tmp = realloc(lstr, csize * sizeof(char)); | 99 | tmp = realloc(lstr, csize * sizeof(char)); |
| 104 | if(!tmp) { | 100 | if(!tmp) {eflag = 1; goto ERR_rwbuf;} |
| 105 | if(___VXGG___VERBOSE_ERRORS___) | ||
| 106 | error(0, errno, "Could not reallocate enough space for lstr"); | ||
| 107 | |||
| 108 | free(lstr); | ||
| 109 | lstr = NULL; // Need to set this because of the break | ||
| 110 | bytesread = ECODE; | ||
| 111 | break; | ||
| 112 | } | ||
| 113 | lstr = tmp; | 101 | lstr = tmp; |
| 114 | } | 102 | } |
| 115 | } | 103 | } |
| 116 | if(bytesread < 0 && bytesread != ECODE) { | 104 | if(bytesread < 0) {eflag = 2; goto ERR_rwbuf;} |
| 117 | if(___VXGG___VERBOSE_ERRORS___) | ||
| 118 | error(0, errno, "Ran into a read() error"); | ||
| 119 | |||
| 120 | free(lstr); | ||
| 121 | lstr = NULL; | ||
| 122 | } | ||
| 123 | 105 | ||
| 124 | if(lstr) { | 106 | if(lstr) { |
| 125 | tmp = realloc(lstr, csize - ccap + 1); | 107 | tmp = realloc(lstr, csize - ccap + 1); |
| 126 | if(!tmp) { | 108 | if(!tmp) {eflag = 3; goto ERR_rwbuf;} |
| 127 | if(___VXGG___VERBOSE_ERRORS___) | ||
| 128 | error(0, errno, "Could not shrink lstr after reading buffer"); | ||
| 129 | |||
| 130 | free(lstr); | ||
| 131 | bytesread = ECODE; | ||
| 132 | } | ||
| 133 | lstr = tmp; | 109 | lstr = tmp; |
| 134 | } | 110 | } |
| 135 | 111 | ||
| @@ -138,7 +114,20 @@ int rwbuf(char **str, unsigned long int initsize, int fd) { | |||
| 138 | } | 114 | } |
| 139 | 115 | ||
| 140 | *str = lstr; | 116 | *str = lstr; |
| 141 | return ((bytesread == 0) ? (csize - ccap) : -1); | 117 | return csize - ccap; |
| 118 | |||
| 119 | ERR_rwbuf: | ||
| 120 | if(___VXGG___VERBOSE_ERRORS___) { | ||
| 121 | switch (eflag) { | ||
| 122 | case 1: WARN(errno, "Could not reallocate enough space for lstr",); | ||
| 123 | case 2: WARN(errno, "Ran into a read() error",); | ||
| 124 | case 3: WARN(errno, "Could not shrink lstr after reading buffer",); | ||
| 125 | default: WARN(errno, "Ran into some error",); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | free(lstr); | ||
| 129 | |||
| 130 | return -1; | ||
| 142 | } | 131 | } |
| 143 | 132 | ||
| 144 | 133 | ||
| @@ -152,7 +141,7 @@ int rwbuf(char **str, unsigned long int initsize, int fd) { | |||
| 152 | */ | 141 | */ |
| 153 | 142 | ||
| 154 | int wwbuf(int fd, const unsigned char *buf, int len) { | 143 | int wwbuf(int fd, const unsigned char *buf, int len) { |
| 155 | if(!buf || len <= 0) ERRRET(EINVAL, -1); | 144 | if(!buf || len <= 0 || fd < 0) ERRRET(EINVAL, -1); |
| 156 | 145 | ||
| 157 | int total = 0; | 146 | int total = 0; |
| 158 | int left = len; | 147 | int left = len; |
| @@ -182,28 +171,18 @@ char * vxdirname(const char * const path) { | |||
| 182 | char *tmp = NULL; | 171 | char *tmp = NULL; |
| 183 | if(!path) { // Path being null is a special case which should return early, before anything else (as to avoid null dereference) | 172 | if(!path) { // Path being null is a special case which should return early, before anything else (as to avoid null dereference) |
| 184 | tmp = strdup("."); | 173 | tmp = strdup("."); |
| 185 | if(!tmp) { | 174 | if(!tmp && ___VXGG___VERBOSE_ERRORS___) WARN(errno, "<vxdirname> could not strdup \".\" for set path result \"NULL\"", ); |
| 186 | WARN(errno, "<vxdirname> could not strdup \".\" for set path result \"NULL\"", ); | ||
| 187 | return NULL; | ||
| 188 | } | ||
| 189 | |||
| 190 | return tmp; | ||
| 191 | } | ||
| 192 | |||
| 193 | unsigned char flag = 0; | ||
| 194 | if(strcmp(path, ".") == 0) {tmp = strdup("."); flag++;} | ||
| 195 | if(strcmp(path, "/") == 0 && !flag) {tmp = strdup("/"); flag++;} | ||
| 196 | if(strcmp(path, "..") == 0 && !flag) {tmp = strdup("."); flag++;} | ||
| 197 | |||
| 198 | if(flag) { | ||
| 199 | if(!tmp) { | ||
| 200 | WARN(errno, "<vxdirname> could not strdup a set path result", ); | ||
| 201 | return NULL; | ||
| 202 | } | ||
| 203 | |||
| 204 | return tmp; | 175 | return tmp; |
| 205 | } | 176 | } |
| 206 | 177 | ||
| 178 | const char * const special[] = {"..", ".", "/"}; | ||
| 179 | for(int i = 0; i < STATIC_ARRAY_LEN(special); i++) { | ||
| 180 | if(strncmp(path, special[i], strlen(special[i])) == 0) { | ||
| 181 | tmp = strdup(special[i]); | ||
| 182 | if(!tmp && ___VXGG___VERBOSE_ERRORS___) WARN(errno, "<vxdirname> could not strdup a set path result", ); | ||
| 183 | return tmp; | ||
| 184 | } | ||
| 185 | } | ||
| 207 | 186 | ||
| 208 | /* From the manpages: (man 3 dirname) | 187 | /* From the manpages: (man 3 dirname) |
| 209 | // +=======================================+ | 188 | // +=======================================+ |
| @@ -218,7 +197,7 @@ char * vxdirname(const char * const path) { | |||
| 218 | // Get a temp copy of the path for manipulation purposes | 197 | // Get a temp copy of the path for manipulation purposes |
| 219 | tmp = strdup(path); | 198 | tmp = strdup(path); |
| 220 | if(!tmp) { | 199 | if(!tmp) { |
| 221 | WARN(errno, "<vxdirname> could not strdup the given path \"%s\" for internal manipulation", , path); | 200 | if(___VXGG___VERBOSE_ERRORS___) WARN(errno, "<vxdirname> could not strdup the given path \"%s\" for internal manipulation", , path); |
| 222 | return NULL; | 201 | return NULL; |
| 223 | } | 202 | } |
| 224 | 203 | ||
| @@ -239,24 +218,14 @@ char * vxdirname(const char * const path) { | |||
| 239 | count++; | 218 | count++; |
| 240 | } | 219 | } |
| 241 | 220 | ||
| 242 | if(count == 0 || count == 1) | 221 | if(count < 2) { |
| 243 | free(tmp); | 222 | free(tmp); |
| 244 | if(count == 0) { | 223 | if(count == 1) tmp = strdup("/"); |
| 245 | tmp = strdup("."); | 224 | else tmp = strdup("."); |
| 246 | if(!tmp) { | 225 | |
| 247 | WARN(errno, "<xdirname> could not strdup \".\" for set path result", ); | 226 | if(!tmp && ___VXGG___VERBOSE_ERRORS___) WARN(errno, "<vxdirname> Error: Could not strdup \"%s\" for set path result", , ((count == 0) ? "." : "/")); |
| 248 | return NULL; | 227 | return tmp; |
| 249 | } | 228 | } |
| 250 | return tmp; | ||
| 251 | } else if(count == 1) { | ||
| 252 | tmp = strdup("/"); | ||
| 253 | if(!tmp) { | ||
| 254 | WARN(errno, "<xdirname> could not strdup \"/\" for set path result", ); | ||
| 255 | return NULL; | ||
| 256 | } | ||
| 257 | return tmp; | ||
| 258 | } | ||
| 259 | // This is retarded, fix it | ||
| 260 | 229 | ||
| 261 | for(size_t i = 0, c2 = 0; i < pathlen; i++) { | 230 | for(size_t i = 0, c2 = 0; i < pathlen; i++) { |
| 262 | if(tmp[i] == '/') | 231 | if(tmp[i] == '/') |
| @@ -267,10 +236,7 @@ char * vxdirname(const char * const path) { | |||
| 267 | 236 | ||
| 268 | char * const actual = strdup(tmp); | 237 | char * const actual = strdup(tmp); |
| 269 | free(tmp); | 238 | free(tmp); |
| 270 | if(!actual) { | 239 | if(!actual && ___VXGG___VERBOSE_ERRORS___) WARN(errno, "<xdirname> could not strdup tmp string to make a shorter end string", ); |
| 271 | WARN(errno, "<xdirname> could not strdup tmp string to make a shorter end string", ); | ||
| 272 | return NULL; | ||
| 273 | } | ||
| 274 | 240 | ||
| 275 | return actual; | 241 | return actual; |
| 276 | } | 242 | } |
