From: Vincent Bernat Date: Sat, 12 Dec 2015 21:47:41 +0000 (+0100) Subject: compat: use getline() instead of fgetln() X-Git-Tag: 0.8.0~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af828c473244ebff5c8ada0a1ff29d95e673e555;p=thirdparty%2Flldpd.git compat: use getline() instead of fgetln() getline() is POSIX.1-2008 while fgetln() is BSD. Write a simple implementation from the NetBSD one for too old OSes. --- diff --git a/configure.ac b/configure.ac index 52dbc1b8..9743404e 100644 --- a/configure.ac +++ b/configure.ac @@ -142,7 +142,7 @@ AC_CHECK_FUNCS([setproctitle_init]) AC_REPLACE_FUNCS([strlcpy strnlen strndup - fgetln + getline asprintf vsyslog daemon]) diff --git a/src/client/lldpcli.c b/src/client/lldpcli.c index e38256a0..f04bdadc 100644 --- a/src/client/lldpcli.c +++ b/src/client/lldpcli.c @@ -508,16 +508,17 @@ main(int argc, char *argv[]) log_debug("lldpctl", "process: %s", first->name); FILE *file = fopen(first->name, "r"); if (file) { - size_t len; + size_t n; + ssize_t len; char *line; - while ((line = fgetln(file, &len))) { - line = strndup(line, len); + while (line = NULL, len = 0, (len = getline(&line, &n, file)) > 0) { if (line[len - 1] == '\n') { line[len - 1] = '\0'; parse_and_exec(conn, fmt, line); } free(line); } + free(line); fclose(file); } else { log_warn("lldpctl", "unable to open %s", diff --git a/src/compat/compat.h b/src/compat/compat.h index 5232c530..982f9f1b 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -68,8 +68,8 @@ size_t strnlen(const char *, size_t); char *strndup(const char *, size_t); #endif -#if !HAVE_FGETLN -char *fgetln(FILE *, size_t *); +#if !HAVE_GETLINE +ssize_t getline(char **, size_t *, FILE *); #endif #if !HAVE_SETPROCTITLE diff --git a/src/compat/fgetln.c b/src/compat/fgetln.c deleted file mode 100644 index 6590875f..00000000 --- a/src/compat/fgetln.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- mode: c; c-file-style: "openbsd" -*- */ -/* - * Copyright (c) 2001 Marc Espie. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD - * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -char * -fgetln(FILE *stream, size_t *len) -{ - static char *buffer = NULL; - static size_t buflen = 0; - char *newbuf; - - if (buflen == 0) { - buflen = 512; - if ((buffer = malloc(buflen+1)) == NULL) - return NULL; - } - if (fgets(buffer, buflen+1, stream) == NULL) - return NULL; - *len = strlen(buffer); - while (*len == buflen && buffer[*len-1] != '\n') { - if ((newbuf = realloc(buffer, 2*buflen + 1)) == NULL) - return NULL; - buffer = newbuf; - if (fgets(buffer + buflen, buflen + 1, stream) == NULL) - return NULL; - *len += strlen(buffer + buflen); - buflen *= 2; - } - return buffer; -} diff --git a/src/compat/getline.c b/src/compat/getline.c new file mode 100644 index 00000000..2e11f23b --- /dev/null +++ b/src/compat/getline.c @@ -0,0 +1,112 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Roy Marples. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Several modifications to make the code more portable (and less robust and far less efficient) */ + +#include +#include +#include +#include +#include +#include +#include + +#define MINBUF 128 + +static ssize_t +___getdelim(char **buf, size_t *buflen, + int sep, FILE *fp) +{ + int p; + size_t len = 0, newlen; + char *newb; + + if (buf == NULL || buflen == NULL) { + errno = EINVAL; + return -1; + } + + /* If buf is NULL, we have to assume a size of zero */ + if (*buf == NULL) + *buflen = 0; + + do { + p = fgetc(fp); + if (ferror(fp)) + return -1; + if (p == EOF) + break; + + /* Ensure we can handle it */ + if (len > SSIZE_MAX) { + errno = EOVERFLOW; + return -1; + } + newlen = len + 2; /* reserve space for NUL terminator */ + if (newlen > *buflen) { + if (newlen < MINBUF) + newlen = MINBUF; +#define powerof2(x) ((((x)-1)&(x))==0) + if (!powerof2(newlen)) { + /* Grow the buffer to the next power of 2 */ + newlen--; + newlen |= newlen >> 1; + newlen |= newlen >> 2; + newlen |= newlen >> 4; + newlen |= newlen >> 8; + newlen |= newlen >> 16; +#if SIZE_MAX > 0xffffffffU + newlen |= newlen >> 32; +#endif + newlen++; + } + + newb = realloc(*buf, newlen); + if (newb == NULL) + return -1; + *buf = newb; + *buflen = newlen; + } + + (*buf)[len++] = p; + } while (p != sep); + + /* POSIX demands we return -1 on EOF. */ + if (len == 0) + return -1; + + if (*buf != NULL) + (*buf)[len] = '\0'; + return (ssize_t)len; +} + +ssize_t +getline(char **buf, size_t *buflen, FILE *fp) +{ + return ___getdelim(buf, buflen, '\n', fp); +}