mg

port of mg editor (openbsd to linux)
Log | Files | Refs | README

commit ee6c9916abe1490c9a80acbce5cbd7fa304be92b
parent efa5ff9045b546653814ff53262927702ed13131
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Fri, 28 Nov 2014 16:58:31 +0100

update fgetln: use POSIX getline

Diffstat:
libopenbsd/fgetln.c | 100++++++++++++++++++++++++++++++++++++-------------------------------------------
1 file changed, 45 insertions(+), 55 deletions(-)

diff --git a/libopenbsd/fgetln.c b/libopenbsd/fgetln.c @@ -1,11 +1,6 @@ -/* $NetBSD: fgetln.c,v 1.4 2014/10/31 18:59:32 spz 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 © 2005 Hector Garcia Alvarez + * Copyright © 2005, 2008-2012 Guillem Jover <guillem@hadrons.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -15,64 +10,59 @@ * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * 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. + * THIS SOFTWARE IS PROVIDED ``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. */ -#include <errno.h> #include <stdio.h> -#include <stdlib.h> +#include <sys/types.h> #include <string.h> +struct filebuf { + FILE *fp; + char *buf; + size_t len; +}; + +#define FILEBUF_POOL_ITEMS 32 + +static struct filebuf fb_pool[FILEBUF_POOL_ITEMS]; +static int fb_pool_cur; + char * -fgetln(FILE *fp, size_t *len) +fgetln(FILE *stream, size_t *len) { - static char *buf = NULL; - static size_t bufsiz = 0; - char *ptr, *nbuf; - size_t nbufsiz; - int oerrno; + struct filebuf *fb; + ssize_t nread; - if (buf == NULL) { - bufsiz = BUFSIZ; - if ((buf = malloc(bufsiz)) == NULL) - return NULL; + /* Try to diminish the possibility of several fgetln() calls being + * used on different streams, by using a pool of buffers per file. */ + fb = &fb_pool[fb_pool_cur]; + if (fb->fp != stream && fb->fp != NULL) { + fb_pool_cur++; + fb_pool_cur %= FILEBUF_POOL_ITEMS; + fb = &fb_pool[fb_pool_cur]; } + fb->fp = stream; - if (fgets(buf, bufsiz, fp) == NULL) + nread = getline(&fb->buf, &fb->len, stream); + /* Note: the getdelim/getline API ensures nread != 0. */ + if (nread == -1) { + *len = 0; return NULL; - - *len = 0; - while ((ptr = strchr(&buf[*len], '\n')) == NULL) { - nbufsiz = bufsiz + BUFSIZ; - nbuf = realloc(buf, nbufsiz); - - if (nbuf == NULL) { - oerrno = errno; - free(buf); - errno = oerrno; - buf = NULL; - return NULL; - } else - buf = nbuf; - - *len = bufsiz; - if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) - return buf; - - bufsiz = nbufsiz; + } else { + *len = (size_t)nread; + return fb->buf; } - *len = (ptr - buf) + 1; - return buf; } -