17ec1ec4fSAlex Richardson /*
27ec1ec4fSAlex Richardson * Copyright © 2005 Hector Garcia Alvarez
37ec1ec4fSAlex Richardson * Copyright © 2005, 2008-2012 Guillem Jover <guillem@hadrons.org>
47ec1ec4fSAlex Richardson *
57ec1ec4fSAlex Richardson * Redistribution and use in source and binary forms, with or without
67ec1ec4fSAlex Richardson * modification, are permitted provided that the following conditions
77ec1ec4fSAlex Richardson * are met:
87ec1ec4fSAlex Richardson * 1. Redistributions of source code must retain the above copyright
97ec1ec4fSAlex Richardson * notice, this list of conditions and the following disclaimer.
107ec1ec4fSAlex Richardson * 2. Redistributions in binary form must reproduce the above copyright
117ec1ec4fSAlex Richardson * notice, this list of conditions and the following disclaimer in the
127ec1ec4fSAlex Richardson * documentation and/or other materials provided with the distribution.
137ec1ec4fSAlex Richardson * 3. The name of the author may not be used to endorse or promote products
147ec1ec4fSAlex Richardson * derived from this software without specific prior written permission.
157ec1ec4fSAlex Richardson *
167ec1ec4fSAlex Richardson * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
177ec1ec4fSAlex Richardson * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
187ec1ec4fSAlex Richardson * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
197ec1ec4fSAlex Richardson * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
207ec1ec4fSAlex Richardson * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
217ec1ec4fSAlex Richardson * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
227ec1ec4fSAlex Richardson * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
237ec1ec4fSAlex Richardson * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
247ec1ec4fSAlex Richardson * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
257ec1ec4fSAlex Richardson * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
267ec1ec4fSAlex Richardson */
277ec1ec4fSAlex Richardson
287ec1ec4fSAlex Richardson #include <stdio.h>
29*6bfca4dcSWarner Losh
307ec1ec4fSAlex Richardson #include <sys/types.h>
317ec1ec4fSAlex Richardson #include <string.h>
327ec1ec4fSAlex Richardson
337ec1ec4fSAlex Richardson #include "local-link.h"
347ec1ec4fSAlex Richardson
357ec1ec4fSAlex Richardson #define HAVE_GETLINE 1
367ec1ec4fSAlex Richardson #ifdef HAVE_GETLINE
377ec1ec4fSAlex Richardson struct filebuf {
387ec1ec4fSAlex Richardson FILE *fp;
397ec1ec4fSAlex Richardson char *buf;
407ec1ec4fSAlex Richardson size_t len;
417ec1ec4fSAlex Richardson };
427ec1ec4fSAlex Richardson
437ec1ec4fSAlex Richardson #define FILEBUF_POOL_ITEMS 32
447ec1ec4fSAlex Richardson
457ec1ec4fSAlex Richardson static struct filebuf fb_pool[FILEBUF_POOL_ITEMS];
467ec1ec4fSAlex Richardson static int fb_pool_cur;
477ec1ec4fSAlex Richardson
487ec1ec4fSAlex Richardson char *
fgetln(FILE * stream,size_t * len)497ec1ec4fSAlex Richardson fgetln(FILE *stream, size_t *len)
507ec1ec4fSAlex Richardson {
517ec1ec4fSAlex Richardson struct filebuf *fb;
527ec1ec4fSAlex Richardson ssize_t nread;
537ec1ec4fSAlex Richardson
547ec1ec4fSAlex Richardson flockfile(stream);
557ec1ec4fSAlex Richardson
567ec1ec4fSAlex Richardson /* Try to diminish the possibility of several fgetln() calls being
577ec1ec4fSAlex Richardson * used on different streams, by using a pool of buffers per file. */
587ec1ec4fSAlex Richardson fb = &fb_pool[fb_pool_cur];
597ec1ec4fSAlex Richardson if (fb->fp != stream && fb->fp != NULL) {
607ec1ec4fSAlex Richardson fb_pool_cur++;
617ec1ec4fSAlex Richardson fb_pool_cur %= FILEBUF_POOL_ITEMS;
627ec1ec4fSAlex Richardson fb = &fb_pool[fb_pool_cur];
637ec1ec4fSAlex Richardson }
647ec1ec4fSAlex Richardson fb->fp = stream;
657ec1ec4fSAlex Richardson
667ec1ec4fSAlex Richardson nread = getline(&fb->buf, &fb->len, stream);
677ec1ec4fSAlex Richardson
687ec1ec4fSAlex Richardson funlockfile(stream);
697ec1ec4fSAlex Richardson
707ec1ec4fSAlex Richardson /* Note: the getdelim/getline API ensures nread != 0. */
717ec1ec4fSAlex Richardson if (nread == -1) {
727ec1ec4fSAlex Richardson *len = 0;
737ec1ec4fSAlex Richardson return NULL;
747ec1ec4fSAlex Richardson } else {
757ec1ec4fSAlex Richardson *len = (size_t)nread;
767ec1ec4fSAlex Richardson return fb->buf;
777ec1ec4fSAlex Richardson }
787ec1ec4fSAlex Richardson }
797ec1ec4fSAlex Richardson libbsd_link_warning(fgetln,
807ec1ec4fSAlex Richardson "This function cannot be safely ported, use getline(3) "
817ec1ec4fSAlex Richardson "instead, as it is supported by GNU and POSIX.1-2008.")
827ec1ec4fSAlex Richardson #else
837ec1ec4fSAlex Richardson #error "Function fgetln() needs to be ported."
847ec1ec4fSAlex Richardson #endif
85