Improvements for a C getline implementation I wrote a function in C that reads an entire line from a stream into a dynamically allocated buffer. What would you suggest I should do to improve its performance? Also, are there any errors that could occur and are not handled?
This is the code:
#define ERRALLOC(ptr)                                        \
if (ptr == NULL) {                                           \
    printf(&quot;Unable to allocate memory for %s&quot;, #ptr);        \
    exit(1);                                                 \
}

#define PACK_SIZE 512

size_t readLine(FILE *istream, char **line_buffer, size_t *bufsize) {
    size_t line_size = 0;
    int eol_flag = 0;
    char temp_buffer[PACK_SIZE];
    while (fgets(temp_buffer, PACK_SIZE, istream) != NULL) {
        size_t temp_len = strlen(temp_buffer);
        line_size += temp_len;

        if (line_size+1 &gt; *bufsize) {
            *bufsize = line_size+1;
            *line_buffer = realloc(*line_buffer, *bufsize * sizeof(char));
            ERRALLOC(*line_buffer)
        }

        if (temp_buffer[ temp_len - 1 ] == '\n') {
            temp_buffer[ temp_len - 1 ] = '\0';
            eol_flag = 1;
        }
        strcpy(*line_buffer + (line_size-temp_len), temp_buffer);

        if (eol_flag) break;
    }

    return line_size;
}
Overall, it's a lot of effort (perhaps not in the right place) for one line. Textual data typically has lines that are very short, on the order of 80 bytes. If you're so deeply concerned about performance, you need to back out of this function and look at the I/O pattern of the calling program for more context. You'll very likely find that it's more efficient to have a buffer much larger than your current PACK_SIZE, perhaps 4MB. Read the file into it one such chunk at a time with fread, not fgets; then iterate through to find and split on newlines. Roughly,

Allocate a large buffer
fread as much as possible
memchr your way to a newline
Set that newline to '\0'
Consume the line
Repeat 3-5 until you're at the end of the buffer
If there is a partial line segment at the end, then memcpy the segment to the beginning of the buffer and plan for the next fread to use a buffer write position that starts after the end of the segment
Repeat until end of file

The principle to heed here is that I/O (particularly disk I/O) is expensive, and frequent calls to the I/O layer are expensive even when cached at the operating system level. Doing as much in RAM as possible is strongly preferred.
If you want a convenience interface, then consider accepting a FILE* and a callback function, making the buffer locally rather than accepting it, and invoking the callback for each line when found.