1*b6cee71dSXin LI /* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */ 2*b6cee71dSXin LI 3*b6cee71dSXin LI /*- 4*b6cee71dSXin LI * Copyright (c) 2011 The NetBSD Foundation, Inc. 5*b6cee71dSXin LI * All rights reserved. 6*b6cee71dSXin LI * 7*b6cee71dSXin LI * This code is derived from software contributed to The NetBSD Foundation 8*b6cee71dSXin LI * by Christos Zoulas. 9*b6cee71dSXin LI * 10*b6cee71dSXin LI * Redistribution and use in source and binary forms, with or without 11*b6cee71dSXin LI * modification, are permitted provided that the following conditions 12*b6cee71dSXin LI * are met: 13*b6cee71dSXin LI * 1. Redistributions of source code must retain the above copyright 14*b6cee71dSXin LI * notice, this list of conditions and the following disclaimer. 15*b6cee71dSXin LI * 2. Redistributions in binary form must reproduce the above copyright 16*b6cee71dSXin LI * notice, this list of conditions and the following disclaimer in the 17*b6cee71dSXin LI * documentation and/or other materials provided with the distribution. 18*b6cee71dSXin LI * 19*b6cee71dSXin LI * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20*b6cee71dSXin LI * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21*b6cee71dSXin LI * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22*b6cee71dSXin LI * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23*b6cee71dSXin LI * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*b6cee71dSXin LI * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*b6cee71dSXin LI * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*b6cee71dSXin LI * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*b6cee71dSXin LI * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*b6cee71dSXin LI * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*b6cee71dSXin LI * POSSIBILITY OF SUCH DAMAGE. 30*b6cee71dSXin LI */ 31*b6cee71dSXin LI 32*b6cee71dSXin LI #include "file.h" 33*b6cee71dSXin LI #if !HAVE_GETLINE 34*b6cee71dSXin LI #include <stdlib.h> 35*b6cee71dSXin LI #include <stdio.h> 36*b6cee71dSXin LI #include <unistd.h> 37*b6cee71dSXin LI #include <errno.h> 38*b6cee71dSXin LI #include <string.h> 39*b6cee71dSXin LI 40*b6cee71dSXin LI public ssize_t 41*b6cee71dSXin LI getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) 42*b6cee71dSXin LI { 43*b6cee71dSXin LI char *ptr, *eptr; 44*b6cee71dSXin LI 45*b6cee71dSXin LI 46*b6cee71dSXin LI if (*buf == NULL || *bufsiz == 0) { 47*b6cee71dSXin LI *bufsiz = BUFSIZ; 48*b6cee71dSXin LI if ((*buf = malloc(*bufsiz)) == NULL) 49*b6cee71dSXin LI return -1; 50*b6cee71dSXin LI } 51*b6cee71dSXin LI 52*b6cee71dSXin LI for (ptr = *buf, eptr = *buf + *bufsiz;;) { 53*b6cee71dSXin LI int c = fgetc(fp); 54*b6cee71dSXin LI if (c == -1) { 55*b6cee71dSXin LI if (feof(fp)) 56*b6cee71dSXin LI return ptr == *buf ? -1 : ptr - *buf; 57*b6cee71dSXin LI else 58*b6cee71dSXin LI return -1; 59*b6cee71dSXin LI } 60*b6cee71dSXin LI *ptr++ = c; 61*b6cee71dSXin LI if (c == delimiter) { 62*b6cee71dSXin LI *ptr = '\0'; 63*b6cee71dSXin LI return ptr - *buf; 64*b6cee71dSXin LI } 65*b6cee71dSXin LI if (ptr + 2 >= eptr) { 66*b6cee71dSXin LI char *nbuf; 67*b6cee71dSXin LI size_t nbufsiz = *bufsiz * 2; 68*b6cee71dSXin LI ssize_t d = ptr - *buf; 69*b6cee71dSXin LI if ((nbuf = realloc(*buf, nbufsiz)) == NULL) 70*b6cee71dSXin LI return -1; 71*b6cee71dSXin LI *buf = nbuf; 72*b6cee71dSXin LI *bufsiz = nbufsiz; 73*b6cee71dSXin LI eptr = nbuf + nbufsiz; 74*b6cee71dSXin LI ptr = nbuf + d; 75*b6cee71dSXin LI } 76*b6cee71dSXin LI } 77*b6cee71dSXin LI } 78*b6cee71dSXin LI 79*b6cee71dSXin LI ssize_t 80*b6cee71dSXin LI getline(char **buf, size_t *bufsiz, FILE *fp) 81*b6cee71dSXin LI { 82*b6cee71dSXin LI return getdelim(buf, bufsiz, '\n', fp); 83*b6cee71dSXin LI } 84*b6cee71dSXin LI 85*b6cee71dSXin LI #endif 86*b6cee71dSXin LI 87*b6cee71dSXin LI #ifdef TEST 88*b6cee71dSXin LI int 89*b6cee71dSXin LI main(int argc, char *argv[]) 90*b6cee71dSXin LI { 91*b6cee71dSXin LI char *p = NULL; 92*b6cee71dSXin LI ssize_t len; 93*b6cee71dSXin LI size_t n = 0; 94*b6cee71dSXin LI 95*b6cee71dSXin LI while ((len = getline(&p, &n, stdin)) != -1) 96*b6cee71dSXin LI (void)printf("%zd %s", len, p); 97*b6cee71dSXin LI free(p); 98*b6cee71dSXin LI return 0; 99*b6cee71dSXin LI } 100*b6cee71dSXin LI #endif 101