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
la_getdelim(char ** buf,size_t * bufsiz,int delimiter,FILE * fp)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
getline(char ** buf,size_t * bufsiz,FILE * fp)73 getline(char **buf, size_t *bufsiz, FILE *fp)
74 {
75 return la_getdelim(buf, bufsiz, '\n', fp);
76 }
77 #endif
78