diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2016-02-19 13:35:46 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2016-02-19 13:35:46 +0000 |
commit | e9d369a09e48ea8f940958025c8444988d31e840 (patch) | |
tree | 402b991d3ad5629931881146e07327ad5a094da3 /compat/fgetln.c | |
parent | fc864529f587fc4c913d1ad40da41eab2e512521 (diff) |
Fixed fgetln(3) implementation (from Joerg Jung) which does not depend on *BSD
fgets(3) semantics.
Diffstat (limited to 'compat/fgetln.c')
-rw-r--r-- | compat/fgetln.c | 108 |
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; } - |