1*7ec1ec4fSAlex Richardson /* 2*7ec1ec4fSAlex Richardson * Copyright © 2005 Hector Garcia Alvarez 3*7ec1ec4fSAlex Richardson * Copyright © 2005, 2008-2012 Guillem Jover <guillem@hadrons.org> 4*7ec1ec4fSAlex Richardson * 5*7ec1ec4fSAlex Richardson * Redistribution and use in source and binary forms, with or without 6*7ec1ec4fSAlex Richardson * modification, are permitted provided that the following conditions 7*7ec1ec4fSAlex Richardson * are met: 8*7ec1ec4fSAlex Richardson * 1. Redistributions of source code must retain the above copyright 9*7ec1ec4fSAlex Richardson * notice, this list of conditions and the following disclaimer. 10*7ec1ec4fSAlex Richardson * 2. Redistributions in binary form must reproduce the above copyright 11*7ec1ec4fSAlex Richardson * notice, this list of conditions and the following disclaimer in the 12*7ec1ec4fSAlex Richardson * documentation and/or other materials provided with the distribution. 13*7ec1ec4fSAlex Richardson * 3. The name of the author may not be used to endorse or promote products 14*7ec1ec4fSAlex Richardson * derived from this software without specific prior written permission. 15*7ec1ec4fSAlex Richardson * 16*7ec1ec4fSAlex Richardson * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17*7ec1ec4fSAlex Richardson * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 18*7ec1ec4fSAlex Richardson * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 19*7ec1ec4fSAlex Richardson * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20*7ec1ec4fSAlex Richardson * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21*7ec1ec4fSAlex Richardson * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22*7ec1ec4fSAlex Richardson * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23*7ec1ec4fSAlex Richardson * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24*7ec1ec4fSAlex Richardson * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25*7ec1ec4fSAlex Richardson * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*7ec1ec4fSAlex Richardson */ 27*7ec1ec4fSAlex Richardson 28*7ec1ec4fSAlex Richardson #include <stdio.h> 29*7ec1ec4fSAlex Richardson #include <sys/cdefs.h> 30*7ec1ec4fSAlex Richardson #include <sys/types.h> 31*7ec1ec4fSAlex Richardson #include <string.h> 32*7ec1ec4fSAlex Richardson 33*7ec1ec4fSAlex Richardson #include "local-link.h" 34*7ec1ec4fSAlex Richardson 35*7ec1ec4fSAlex Richardson #define HAVE_GETLINE 1 36*7ec1ec4fSAlex Richardson #ifdef HAVE_GETLINE 37*7ec1ec4fSAlex Richardson struct filebuf { 38*7ec1ec4fSAlex Richardson FILE *fp; 39*7ec1ec4fSAlex Richardson char *buf; 40*7ec1ec4fSAlex Richardson size_t len; 41*7ec1ec4fSAlex Richardson }; 42*7ec1ec4fSAlex Richardson 43*7ec1ec4fSAlex Richardson #define FILEBUF_POOL_ITEMS 32 44*7ec1ec4fSAlex Richardson 45*7ec1ec4fSAlex Richardson static struct filebuf fb_pool[FILEBUF_POOL_ITEMS]; 46*7ec1ec4fSAlex Richardson static int fb_pool_cur; 47*7ec1ec4fSAlex Richardson 48*7ec1ec4fSAlex Richardson char * 49*7ec1ec4fSAlex Richardson fgetln(FILE *stream, size_t *len) 50*7ec1ec4fSAlex Richardson { 51*7ec1ec4fSAlex Richardson struct filebuf *fb; 52*7ec1ec4fSAlex Richardson ssize_t nread; 53*7ec1ec4fSAlex Richardson 54*7ec1ec4fSAlex Richardson flockfile(stream); 55*7ec1ec4fSAlex Richardson 56*7ec1ec4fSAlex Richardson /* Try to diminish the possibility of several fgetln() calls being 57*7ec1ec4fSAlex Richardson * used on different streams, by using a pool of buffers per file. */ 58*7ec1ec4fSAlex Richardson fb = &fb_pool[fb_pool_cur]; 59*7ec1ec4fSAlex Richardson if (fb->fp != stream && fb->fp != NULL) { 60*7ec1ec4fSAlex Richardson fb_pool_cur++; 61*7ec1ec4fSAlex Richardson fb_pool_cur %= FILEBUF_POOL_ITEMS; 62*7ec1ec4fSAlex Richardson fb = &fb_pool[fb_pool_cur]; 63*7ec1ec4fSAlex Richardson } 64*7ec1ec4fSAlex Richardson fb->fp = stream; 65*7ec1ec4fSAlex Richardson 66*7ec1ec4fSAlex Richardson nread = getline(&fb->buf, &fb->len, stream); 67*7ec1ec4fSAlex Richardson 68*7ec1ec4fSAlex Richardson funlockfile(stream); 69*7ec1ec4fSAlex Richardson 70*7ec1ec4fSAlex Richardson /* Note: the getdelim/getline API ensures nread != 0. */ 71*7ec1ec4fSAlex Richardson if (nread == -1) { 72*7ec1ec4fSAlex Richardson *len = 0; 73*7ec1ec4fSAlex Richardson return NULL; 74*7ec1ec4fSAlex Richardson } else { 75*7ec1ec4fSAlex Richardson *len = (size_t)nread; 76*7ec1ec4fSAlex Richardson return fb->buf; 77*7ec1ec4fSAlex Richardson } 78*7ec1ec4fSAlex Richardson } 79*7ec1ec4fSAlex Richardson libbsd_link_warning(fgetln, 80*7ec1ec4fSAlex Richardson "This function cannot be safely ported, use getline(3) " 81*7ec1ec4fSAlex Richardson "instead, as it is supported by GNU and POSIX.1-2008.") 82*7ec1ec4fSAlex Richardson #else 83*7ec1ec4fSAlex Richardson #error "Function fgetln() needs to be ported." 84*7ec1ec4fSAlex Richardson #endif 85