lafe_getline.c revision 1.1 1 /* $NetBSD: lafe_getline.c,v 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