Home | History | Annotate | Line # | Download | only in libarchive_fe
      1 /*	$NetBSD: lafe_getline.c,v 1.1.1.1 2026/05/03 14:37:18 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 "lafe_platform.h"
     11 #ifndef HAVE_GETLINE
     12 
     13 #ifdef HAVE_STDLIB_H
     14 #include <stdlib.h>
     15 #endif
     16 #ifdef HAVE_STDINT_H
     17 #include <stdint.h>
     18 #endif
     19 #ifdef HAVE_STDIO_H
     20 #include <stdio.h>
     21 #endif
     22 #ifdef HAVE_UNISTD_H
     23 #include <unistd.h>
     24 #endif
     25 #ifdef HAVE_ERRNO_H
     26 #include <errno.h>
     27 #endif
     28 #ifdef HAVE_STRING_H
     29 #include <string.h>
     30 #endif
     31 
     32 #include "lafe_getline.h"
     33 
     34 static ssize_t
     35 lafe_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
     36 {
     37 	char *ptr, *eptr;
     38 
     39 
     40 	if (*buf == NULL || *bufsiz == 0) {
     41 		*bufsiz = BUFSIZ;
     42 		if ((*buf = malloc(*bufsiz)) == NULL)
     43 			return -1;
     44 	}
     45 
     46 	for (ptr = *buf, eptr = *buf + *bufsiz;;) {
     47 		int c = fgetc(fp);
     48 		if (c == -1) {
     49 			if (feof(fp)) {
     50 				ssize_t diff = (ssize_t)(ptr - *buf);
     51 				if (diff != 0) {
     52 					*ptr = '\0';
     53 					return diff;
     54 				}
     55 			}
     56 			return -1;
     57 		}
     58 		*ptr++ = c;
     59 		if (c == delimiter) {
     60 			*ptr = '\0';
     61 			return ptr - *buf;
     62 		}
     63 		if (ptr + 2 >= eptr) {
     64 			char *nbuf;
     65 			size_t nbufsiz = *bufsiz * 2;
     66 			ssize_t d = ptr - *buf;
     67 			if ((nbuf = realloc(*buf, nbufsiz)) == NULL)
     68 				return -1;
     69 			*buf = nbuf;
     70 			*bufsiz = nbufsiz;
     71 			eptr = nbuf + nbufsiz;
     72 			ptr = nbuf + d;
     73 		}
     74 	}
     75 }
     76 
     77 ssize_t
     78 getline(char **buf, size_t *bufsiz, FILE *fp)
     79 {
     80 	return lafe_getdelim(buf, bufsiz, '\n', fp);
     81 }
     82 #endif
     83