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