142542f5fSchristos#include <stdio.h>
242542f5fSchristos#include <stdlib.h>
342542f5fSchristos#include <errno.h>
442542f5fSchristos
542542f5fSchristosextern int getline(char **line, size_t *len, FILE *file);
642542f5fSchristos
742542f5fSchristosint getline(char **line, size_t *len, FILE *file)
842542f5fSchristos{
942542f5fSchristos	char *ptr, *end;
1042542f5fSchristos	int c;
1142542f5fSchristos
1242542f5fSchristos	if (*line == NULL) {
1342542f5fSchristos		errno = EINVAL;
1442542f5fSchristos		if (*len == 0)
1542542f5fSchristos			*line = malloc(4096);
1642542f5fSchristos		if (*line == NULL)
1742542f5fSchristos			return -1;
1842542f5fSchristos
1942542f5fSchristos		*len = 4096;
2042542f5fSchristos	}
2142542f5fSchristos
2242542f5fSchristos	ptr = *line;
2342542f5fSchristos	end = *line + *len;
2442542f5fSchristos
2542542f5fSchristos	while ((c = fgetc(file)) != EOF) {
2642542f5fSchristos		if (ptr + 1 >= end) {
2742542f5fSchristos			char *newline;
2842542f5fSchristos			int offset;
2942542f5fSchristos
3042542f5fSchristos			newline = realloc(*line, *len + 4096);
3142542f5fSchristos			if (newline == NULL)
3242542f5fSchristos				return -1;
3342542f5fSchristos
3442542f5fSchristos			offset = ptr - *line;
3542542f5fSchristos
3642542f5fSchristos			*line = newline;
3742542f5fSchristos			*len += 4096;
3842542f5fSchristos
3942542f5fSchristos			ptr = *line + offset;
4042542f5fSchristos			end = *line + *len;
4142542f5fSchristos		}
4242542f5fSchristos
4342542f5fSchristos		*ptr++ = c;
4442542f5fSchristos		if (c == '\n') {
4542542f5fSchristos			*ptr = '\0';
4642542f5fSchristos			return ptr - *line;
4742542f5fSchristos		}
4842542f5fSchristos	}
4942542f5fSchristos	*ptr = '\0';
5042542f5fSchristos	return -1;
5142542f5fSchristos}
52