diff options
Diffstat (limited to 'src/shared.c')
| -rw-r--r-- | src/shared.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/src/shared.c b/src/shared.c index b154391..e5f0f13 100644 --- a/src/shared.c +++ b/src/shared.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | #include <stdarg.h> | 3 | #include <stdarg.h> |
| 4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
| 5 | #include <string.h> | ||
| 6 | #include <unistd.h> | ||
| 5 | #include <errno.h> | 7 | #include <errno.h> |
| 6 | #include <error.h> | 8 | #include <error.h> |
| 7 | #include <stdio.h> | 9 | #include <stdio.h> |
| @@ -9,7 +11,7 @@ | |||
| 9 | void* xcalloc(size_t nmemb, size_t size) { | 11 | void* xcalloc(size_t nmemb, size_t size) { |
| 10 | void *mem = calloc(nmemb, size); | 12 | void *mem = calloc(nmemb, size); |
| 11 | 13 | ||
| 12 | if(mem == NULL) { | 14 | if(!mem) { |
| 13 | #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 | 15 | #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 |
| 14 | error(1, errno, "<xcalloc> Could not allocate memory"); | 16 | error(1, errno, "<xcalloc> Could not allocate memory"); |
| 15 | #endif | 17 | #endif |
| @@ -33,4 +35,55 @@ void* xreallocarray(void *ptr, size_t nmemb, size_t size) { | |||
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | return mem; | 37 | return mem; |
| 36 | } \ No newline at end of file | 38 | } |
| 39 | |||
| 40 | int readwholebuffer(char **str, unsigned long int initsize, int fd) { | ||
| 41 | // Try to read bytes from fd into str | ||
| 42 | // Bytes read == 0, return 0 | ||
| 43 | // Bytes read < 0, free string, return -1; | ||
| 44 | // When string hits capacity, double the capacity, and reallocate the string | ||
| 45 | |||
| 46 | char *lstr = NULL, *tmp = NULL; | ||
| 47 | ssize_t bytesread = -1; | ||
| 48 | int csize = initsize, ccap = initsize; | ||
| 49 | |||
| 50 | lstr = xcalloc(initsize, sizeof(char)); | ||
| 51 | while((bytesread = read(fd, lstr + (csize - ccap), ccap)) > 0) { | ||
| 52 | ccap -= bytesread; | ||
| 53 | if(ccap <= 0) { | ||
| 54 | csize *= 2; | ||
| 55 | ccap = csize / 2; | ||
| 56 | |||
| 57 | tmp = realloc(lstr, csize * sizeof(char)); | ||
| 58 | if(!tmp) { | ||
| 59 | error(0, errno, "Could not reallocate enough space for lstr"); | ||
| 60 | free(lstr); | ||
| 61 | bytesread = -100; | ||
| 62 | break; | ||
| 63 | } | ||
| 64 | lstr = tmp; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | if(bytesread < 0 && bytesread != -100) { | ||
| 68 | error(0, errno, "Ran into a read() error"); | ||
| 69 | free(lstr); | ||
| 70 | lstr = NULL; | ||
| 71 | } | ||
| 72 | |||
| 73 | if(lstr) { | ||
| 74 | tmp = realloc(lstr, csize - ccap + 1); | ||
| 75 | if(!tmp) { | ||
| 76 | error(0, errno, "Could not shrink lstr after reading buffer"); | ||
| 77 | free(lstr); | ||
| 78 | bytesread = -100; | ||
| 79 | } | ||
| 80 | lstr = tmp; | ||
| 81 | } | ||
| 82 | |||
| 83 | if(lstr) { | ||
| 84 | lstr[csize - ccap - 1] = '\0'; // Don't include the newline | ||
| 85 | } | ||
| 86 | |||
| 87 | *str = lstr; | ||
| 88 | return ((bytesread == 0) ? (csize - ccap) : -1); | ||
| 89 | } | ||
