1 /* $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $ */ 2 3 /*- 4 * SPDX-License-Identifier: BSD-2-Clause 5 * 6 * Copyright (c) 2011 The NetBSD Foundation, Inc. 7 * All rights reserved. 8 */ 9 10 #include "bsdunzip_platform.h" 11 #ifndef HAVE_GETLINE 12 13 #ifdef HAVE_STDLIB_H 14 #include <stdlib.h> 15 #endif 16 #ifdef HAVE_STDIO_H 17 #include <stdio.h> 18 #endif 19 #ifdef HAVE_UNISTD_H 20 #include <unistd.h> 21 #endif 22 #ifdef HAVE_ERRNO_H 23 #include <errno.h> 24 #endif 25 #ifdef HAVE_STRING_H 26 #include <string.h> 27 #endif 28 29 static ssize_t 30 la_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) 31 { 32 char *ptr, *eptr; 33 34 35 if (*buf == NULL || *bufsiz == 0) { 36 *bufsiz = BUFSIZ; 37 if ((*buf = malloc(*bufsiz)) == NULL) 38 return -1; 39 } 40 41 for (ptr = *buf, eptr = *buf + *bufsiz;;) { 42 int c = fgetc(fp); 43 if (c == -1) { 44 if (feof(fp)) { 45 ssize_t diff = (ssize_t)(ptr - *buf); 46 if (diff != 0) { 47 *ptr = '\0'; 48 return diff; 49 } 50 } 51 return -1; 52 } 53 *ptr++ = c; 54 if (c == delimiter) { 55 *ptr = '\0'; 56 return ptr - *buf; 57 } 58 if (ptr + 2 >= eptr) { 59 char *nbuf; 60 size_t nbufsiz = *bufsiz * 2; 61 ssize_t d = ptr - *buf; 62 if ((nbuf = realloc(*buf, nbufsiz)) == NULL) 63 return -1; 64 *buf = nbuf; 65 *bufsiz = nbufsiz; 66 eptr = nbuf + nbufsiz; 67 ptr = nbuf + d; 68 } 69 } 70 } 71 72 ssize_t 73 getline(char **buf, size_t *bufsiz, FILE *fp) 74 { 75 return la_getdelim(buf, bufsiz, '\n', fp); 76 } 77 #endif 78