164884e0dSMartin Matuska /* $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $ */ 264884e0dSMartin Matuska 364884e0dSMartin Matuska /*- 4*bd66c1b4SMartin Matuska * SPDX-License-Identifier: BSD-2-Clause 5*bd66c1b4SMartin Matuska * 664884e0dSMartin Matuska * Copyright (c) 2011 The NetBSD Foundation, Inc. 764884e0dSMartin Matuska * All rights reserved. 864884e0dSMartin Matuska */ 964884e0dSMartin Matuska 1064884e0dSMartin Matuska #include "bsdunzip_platform.h" 1164884e0dSMartin Matuska #ifndef HAVE_GETLINE 1264884e0dSMartin Matuska 1364884e0dSMartin Matuska #ifdef HAVE_STDLIB_H 1464884e0dSMartin Matuska #include <stdlib.h> 1564884e0dSMartin Matuska #endif 1664884e0dSMartin Matuska #ifdef HAVE_STDIO_H 1764884e0dSMartin Matuska #include <stdio.h> 1864884e0dSMartin Matuska #endif 1964884e0dSMartin Matuska #ifdef HAVE_UNISTD_H 2064884e0dSMartin Matuska #include <unistd.h> 2164884e0dSMartin Matuska #endif 2264884e0dSMartin Matuska #ifdef HAVE_ERRNO_H 2364884e0dSMartin Matuska #include <errno.h> 2464884e0dSMartin Matuska #endif 2564884e0dSMartin Matuska #ifdef HAVE_STRING_H 2664884e0dSMartin Matuska #include <string.h> 2764884e0dSMartin Matuska #endif 2864884e0dSMartin Matuska 2964884e0dSMartin Matuska static ssize_t 3064884e0dSMartin Matuska la_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) 3164884e0dSMartin Matuska { 3264884e0dSMartin Matuska char *ptr, *eptr; 3364884e0dSMartin Matuska 3464884e0dSMartin Matuska 3564884e0dSMartin Matuska if (*buf == NULL || *bufsiz == 0) { 3664884e0dSMartin Matuska *bufsiz = BUFSIZ; 3764884e0dSMartin Matuska if ((*buf = malloc(*bufsiz)) == NULL) 3864884e0dSMartin Matuska return -1; 3964884e0dSMartin Matuska } 4064884e0dSMartin Matuska 4164884e0dSMartin Matuska for (ptr = *buf, eptr = *buf + *bufsiz;;) { 4264884e0dSMartin Matuska int c = fgetc(fp); 4364884e0dSMartin Matuska if (c == -1) { 4464884e0dSMartin Matuska if (feof(fp)) { 4564884e0dSMartin Matuska ssize_t diff = (ssize_t)(ptr - *buf); 4664884e0dSMartin Matuska if (diff != 0) { 4764884e0dSMartin Matuska *ptr = '\0'; 4864884e0dSMartin Matuska return diff; 4964884e0dSMartin Matuska } 5064884e0dSMartin Matuska } 5164884e0dSMartin Matuska return -1; 5264884e0dSMartin Matuska } 5364884e0dSMartin Matuska *ptr++ = c; 5464884e0dSMartin Matuska if (c == delimiter) { 5564884e0dSMartin Matuska *ptr = '\0'; 5664884e0dSMartin Matuska return ptr - *buf; 5764884e0dSMartin Matuska } 5864884e0dSMartin Matuska if (ptr + 2 >= eptr) { 5964884e0dSMartin Matuska char *nbuf; 6064884e0dSMartin Matuska size_t nbufsiz = *bufsiz * 2; 6164884e0dSMartin Matuska ssize_t d = ptr - *buf; 6264884e0dSMartin Matuska if ((nbuf = realloc(*buf, nbufsiz)) == NULL) 6364884e0dSMartin Matuska return -1; 6464884e0dSMartin Matuska *buf = nbuf; 6564884e0dSMartin Matuska *bufsiz = nbufsiz; 6664884e0dSMartin Matuska eptr = nbuf + nbufsiz; 6764884e0dSMartin Matuska ptr = nbuf + d; 6864884e0dSMartin Matuska } 6964884e0dSMartin Matuska } 7064884e0dSMartin Matuska } 7164884e0dSMartin Matuska 7264884e0dSMartin Matuska ssize_t 7364884e0dSMartin Matuska getline(char **buf, size_t *bufsiz, FILE *fp) 7464884e0dSMartin Matuska { 7564884e0dSMartin Matuska return la_getdelim(buf, bufsiz, '\n', fp); 7664884e0dSMartin Matuska } 7764884e0dSMartin Matuska #endif 78