summaryrefslogtreecommitdiffstats
path: root/compat
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2016-02-19 13:35:46 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2016-02-19 13:35:46 +0000
commite9d369a09e48ea8f940958025c8444988d31e840 (patch)
tree402b991d3ad5629931881146e07327ad5a094da3 /compat
parentfc864529f587fc4c913d1ad40da41eab2e512521 (diff)
Fixed fgetln(3) implementation (from Joerg Jung) which does not depend on *BSD
fgets(3) semantics.
Diffstat (limited to 'compat')
-rw-r--r--compat/fgetln.c108
1 files changed, 42 insertions, 66 deletions
diff --git a/compat/fgetln.c b/compat/fgetln.c
index a5c2489d..0ad6378a 100644
--- a/compat/fgetln.c
+++ b/compat/fgetln.c
@@ -1,43 +1,26 @@
-/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Christos Zoulas.
+/*
+ * Copyright (c) 2015 Joerg Jung <jung@openbsd.org>
*
- * 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.
- * 3. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
+/*
+ * portable fgetln() version, NOT reentrant
+ */
-#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
+#include <errno.h>
#include "tmux.h"
@@ -45,41 +28,34 @@ char *
fgetln(FILE *fp, size_t *len)
{
static char *buf = NULL;
- static size_t bufsiz = 0;
- char *ptr;
-
-
- if (buf == NULL) {
- bufsiz = BUFSIZ;
- if ((buf = malloc(bufsiz)) == NULL)
- return NULL;
- }
+ static size_t bufsz = 0;
+ size_t r = 0;
+ char *p;
+ int c, e;
- if (fgets(buf, bufsiz, fp) == NULL)
+ if (!fp || !len) {
+ errno = EINVAL;
return NULL;
-
- *len = 0;
- while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
- size_t nbufsiz = bufsiz + BUFSIZ;
- char *nbuf = realloc(buf, nbufsiz);
-
- if (nbuf == NULL) {
- int oerrno = errno;
- free(buf);
- errno = oerrno;
- buf = NULL;
+ }
+ if (!buf) {
+ if (!(buf = calloc(1, BUFSIZ)))
return NULL;
- } else
- buf = nbuf;
-
- *len = bufsiz;
- if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
- return buf;
-
- bufsiz = nbufsiz;
+ bufsz = BUFSIZ;
}
-
- *len = (ptr - buf) + 1;
- return buf;
+ while ((c = getc(fp)) != EOF) {
+ buf[r++] = c;
+ if (r == bufsz) {
+ if (!(p = reallocarray(buf, 2, bufsz))) {
+ e = errno;
+ free(buf);
+ errno = e;
+ buf = NULL, bufsz = 0;
+ return NULL;
+ }
+ buf = p, bufsz = 2 * bufsz;
+ }
+ if (c == '\n')
+ break;
+ }
+ return (*len = r) ? buf : NULL;
}
-