diff options
author | Wojtek Kosior <wk@koszkonutek-tmp.pl.eu.org> | 2021-04-30 00:33:56 +0200 |
---|---|---|
committer | Wojtek Kosior <wk@koszkonutek-tmp.pl.eu.org> | 2021-04-30 00:33:56 +0200 |
commit | aa4d426b4d3527d7e166df1a05058c9a4a0f6683 (patch) | |
tree | 4ff17ce8b89a2321b9d0ed4bcfc37c447bcb6820 /iniparser-4.1/src/getline.c | |
download | smtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.tar.gz smtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.zip |
Diffstat (limited to 'iniparser-4.1/src/getline.c')
-rw-r--r-- | iniparser-4.1/src/getline.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/iniparser-4.1/src/getline.c b/iniparser-4.1/src/getline.c new file mode 100644 index 0000000..4fde05b --- /dev/null +++ b/iniparser-4.1/src/getline.c @@ -0,0 +1,58 @@ +/* The original code is public domain -- Will Hartung 4/9/09 */ +/* Modifications, public domain as well, by Antti Haapala, 11/10/17 */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <stdint.h> + +ssize_t _getline(char **lineptr, size_t *n, FILE *stream, + int (*fgetc_impl)(FILE*)) { + size_t pos; + int c; + + if (lineptr == NULL || stream == NULL || n == NULL) { + errno = EINVAL; + return -1; + } + + c = fgetc_impl(stream); + if (c == EOF) { + return -1; + } + + if (*lineptr == NULL) { + *lineptr = malloc(128); + if (*lineptr == NULL) { + return -1; + } + *n = 128; + } + + pos = 0; + while(c != EOF) { + if (pos + 1 >= *n) { + char *new_ptr; + size_t new_size = *n + (*n >> 2); + if (new_size < 128) { + new_size = 128; + } + new_ptr = realloc(*lineptr, new_size); + if (new_ptr == NULL) { + return -1; + } + *n = new_size; + *lineptr = new_ptr; + } + + ((unsigned char *)(*lineptr))[pos ++] = c; + if (c == '\n') { + break; + } + c = fgetc_impl(stream); + } + + (*lineptr)[pos] = '\0'; + return pos; +} |