#include "shared.h" #include #include #include #include #include #include #include void* xcalloc(size_t nmemb, size_t size) { void *mem = calloc(nmemb, size); if(!mem) { #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 error(1, errno, " Could not allocate memory"); #endif abort(); } return mem; } void* xreallocarray(void *ptr, size_t nmemb, size_t size) { void *mem = reallocarray(ptr, nmemb, size); if(mem == NULL) { #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 error(1, errno, " Could not allocate memory"); #endif abort(); } return mem; } int readwholebuffer(char **str, unsigned long int initsize, int fd) { // Try to read bytes from fd into str // Bytes read == 0, return 0 // Bytes read < 0, free string, return -1; // When string hits capacity, double the capacity, and reallocate the string char *lstr = NULL, *tmp = NULL; ssize_t bytesread = -1; int csize = initsize, ccap = initsize; lstr = xcalloc(initsize, sizeof(char)); while((bytesread = read(fd, lstr + (csize - ccap), ccap)) > 0) { ccap -= bytesread; if(ccap <= 0) { csize *= 2; ccap = csize / 2; tmp = realloc(lstr, csize * sizeof(char)); if(!tmp) { error(0, errno, "Could not reallocate enough space for lstr"); free(lstr); lstr = NULL; // Need to set this because of the break bytesread = -100; break; } lstr = tmp; } } if(bytesread < 0 && bytesread != -100) { error(0, errno, "Ran into a read() error"); free(lstr); lstr = NULL; } if(lstr) { tmp = realloc(lstr, csize - ccap + 1); if(!tmp) { error(0, errno, "Could not shrink lstr after reading buffer"); free(lstr); bytesread = -100; } lstr = tmp; } if(lstr) { lstr[csize - ccap - 1] = '\0'; // Don't include the newline } *str = lstr; return ((bytesread == 0) ? (csize - ccap) : -1); }