blob: 987e32a199a8d8251e062c5aa1731e6a14b90dae [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
2 *
3 * GNU Library General Public License (LGPL) version 2 or later.
4 *
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
6 */
7
8#include <features.h>
9
10#ifdef __USE_GNU
11#include "_stdio.h"
12
13
14
15/* Note: There is a defect in this function. (size_t vs ssize_t). */
16
17/* glibc function --
18 * Return -1 if error or EOF prior to any chars read.
19 * Return number of chars read (including possible delimiter but not
20 * the terminating nul) otherwise.
21 *
22 * NOTE: If we need to allocate a buffer, we do so prior to attempting
23 * a reading. So space may be allocated even if initially at EOF.
24 */
25
26#define GETDELIM_GROWBY 64
27
28ssize_t getdelim(char **__restrict lineptr, size_t *__restrict n,
29 int delimiter, register FILE *__restrict stream)
30{
31 register char *buf;
32 ssize_t pos = -1;
33 int c;
34 __STDIO_AUTO_THREADLOCK_VAR;
35
36 if (!lineptr || !n || !stream) { /* Be compatable with glibc... even */
37 __set_errno(EINVAL); /* though I think we should assert here */
38 } else {
39 __STDIO_AUTO_THREADLOCK(stream);
40
41 if (!(buf = *lineptr)) { /* If passed NULL for buffer, */
42 *n = 0; /* ignore value passed and treat size as 0. */
43 }
44
45 /* Within the loop, pos is actually the current buffer index + 2,
46 * because we want to make sure we have enough space to store
47 * an additional char plus a nul terminator.
48 */
49 pos = 1;
50
51 do {
52 if (pos >= *n) {
53 if (!(buf = realloc(buf, *n + GETDELIM_GROWBY))) {
54 pos = -1;
55 break;
56 }
57 *n += GETDELIM_GROWBY;
58 *lineptr = buf;
59 }
60
61 if ((c = __GETC_UNLOCKED(stream)) != EOF) {
62 buf[++pos - 2] = c;
63 if (c != delimiter) {
64 continue;
65 }
66 }
67
68 /* We're done, so correct pos back to being the current index. */
69 if ((pos -= 2) >= 0) {
70 buf[++pos] = 0;
71 }
72 break;
73
74 } while (1);
75
76 __STDIO_AUTO_THREADUNLOCK(stream);
77 }
78
79 return pos;
80}
81libc_hidden_def(getdelim)
82#endif