summaryrefslogtreecommitdiff
path: root/src/shared.c
blob: f3e98ee670d13e911e0f59189831d4a62abdb157 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "shared.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <stdio.h>

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, "<xcalloc> 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, "<xreallocarray> 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);
}