Switch fparseln() implementation from fgetln() to getline()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
diff --git a/man/fparseln.3 b/man/fparseln.3
index 1c215ac..9170417 100644
--- a/man/fparseln.3
+++ b/man/fparseln.3
@@ -126,9 +126,9 @@ is returned.
The
.Fn fparseln
function uses internally
-.Xr fgetln 3 ,
+.Xr getline 3 ,
so all error conditions that apply to
-.Xr fgetln 3 ,
+.Xr getline 3 ,
apply to
.Fn fparseln .
In addition
@@ -141,7 +141,7 @@ and return
.Dv NULL
if it runs out of memory.
.Sh SEE ALSO
-.Xr fgetln 3
+.Xr getline 3
.Sh HISTORY
The
.Fn fparseln
diff --git a/src/fparseln.c b/src/fparseln.c
index 8fbf75c..959df11 100644
--- a/src/fparseln.c
+++ b/src/fparseln.c
@@ -77,7 +77,8 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
{
static const char dstr[3] = { '\\', '\\', '#' };
- size_t s, len;
+ ssize_t s;
+ size_t len, ptrlen;
char *buf;
char *ptr, *cp;
int cnt;
@@ -87,6 +88,8 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
len = 0;
buf = NULL;
+ ptrlen = 0;
+ ptr = NULL;
cnt = 1;
if (str == NULL)
@@ -97,7 +100,7 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
com = str[2];
/*
* XXX: it would be cool to be able to specify the newline character,
- * but unfortunately, fgetln does not let us
+ * getdelim(3) does let us, but supporting it would diverge from BSDs.
*/
nl = '\n';
@@ -109,7 +112,8 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
if (lineno)
(*lineno)++;
- if ((ptr = fgetln(fp, &s)) == NULL)
+ s = getline(&ptr, &ptrlen, fp);
+ if (s < 0)
break;
if (s && com) { /* Check and eliminate comments */
@@ -149,6 +153,7 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
if ((cp = realloc(buf, len + s + 1)) == NULL) {
FUNLOCKFILE(fp);
free(buf);
+ free(ptr);
return NULL;
}
buf = cp;
@@ -159,6 +164,7 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
}
FUNLOCKFILE(fp);
+ free(ptr);
if ((flags & FPARSELN_UNESCALL) != 0 && esc && buf != NULL &&
strchr(buf, esc) != NULL) {