1276415Sdelphij/* $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $ */ 2226048Sobrien 3226048Sobrien/*- 4226048Sobrien * Copyright (c) 2011 The NetBSD Foundation, Inc. 5226048Sobrien * All rights reserved. 6226048Sobrien * 7226048Sobrien * This code is derived from software contributed to The NetBSD Foundation 8226048Sobrien * by Christos Zoulas. 9226048Sobrien * 10226048Sobrien * Redistribution and use in source and binary forms, with or without 11226048Sobrien * modification, are permitted provided that the following conditions 12226048Sobrien * are met: 13226048Sobrien * 1. Redistributions of source code must retain the above copyright 14226048Sobrien * notice, this list of conditions and the following disclaimer. 15226048Sobrien * 2. Redistributions in binary form must reproduce the above copyright 16226048Sobrien * notice, this list of conditions and the following disclaimer in the 17226048Sobrien * documentation and/or other materials provided with the distribution. 18226048Sobrien * 19226048Sobrien * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20226048Sobrien * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21226048Sobrien * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22226048Sobrien * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23226048Sobrien * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24226048Sobrien * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25226048Sobrien * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26226048Sobrien * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27226048Sobrien * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28226048Sobrien * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29226048Sobrien * POSSIBILITY OF SUCH DAMAGE. 30226048Sobrien */ 31226048Sobrien 32226048Sobrien#include "file.h" 33226048Sobrien#if !HAVE_GETLINE 34226048Sobrien#include <stdlib.h> 35226048Sobrien#include <stdio.h> 36226048Sobrien#include <unistd.h> 37226048Sobrien#include <errno.h> 38226048Sobrien#include <string.h> 39226048Sobrien 40267843Sdelphijpublic ssize_t 41226048Sobriengetdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) 42226048Sobrien{ 43226048Sobrien char *ptr, *eptr; 44226048Sobrien 45226048Sobrien 46226048Sobrien if (*buf == NULL || *bufsiz == 0) { 47226048Sobrien *bufsiz = BUFSIZ; 48226048Sobrien if ((*buf = malloc(*bufsiz)) == NULL) 49226048Sobrien return -1; 50226048Sobrien } 51226048Sobrien 52226048Sobrien for (ptr = *buf, eptr = *buf + *bufsiz;;) { 53226048Sobrien int c = fgetc(fp); 54226048Sobrien if (c == -1) { 55276415Sdelphij if (feof(fp)) { 56276415Sdelphij ssize_t diff = (ssize_t)(ptr - *buf); 57276415Sdelphij if (diff != 0) { 58276415Sdelphij *ptr = '\0'; 59276415Sdelphij return diff; 60276415Sdelphij } 61276415Sdelphij } 62276415Sdelphij return -1; 63226048Sobrien } 64226048Sobrien *ptr++ = c; 65226048Sobrien if (c == delimiter) { 66226048Sobrien *ptr = '\0'; 67226048Sobrien return ptr - *buf; 68226048Sobrien } 69226048Sobrien if (ptr + 2 >= eptr) { 70226048Sobrien char *nbuf; 71226048Sobrien size_t nbufsiz = *bufsiz * 2; 72226048Sobrien ssize_t d = ptr - *buf; 73226048Sobrien if ((nbuf = realloc(*buf, nbufsiz)) == NULL) 74226048Sobrien return -1; 75226048Sobrien *buf = nbuf; 76226048Sobrien *bufsiz = nbufsiz; 77226048Sobrien eptr = nbuf + nbufsiz; 78226048Sobrien ptr = nbuf + d; 79226048Sobrien } 80226048Sobrien } 81226048Sobrien} 82226048Sobrien 83277592Sdelphijpublic ssize_t 84226048Sobriengetline(char **buf, size_t *bufsiz, FILE *fp) 85226048Sobrien{ 86226048Sobrien return getdelim(buf, bufsiz, '\n', fp); 87226048Sobrien} 88226048Sobrien 89226048Sobrien#endif 90226048Sobrien 91226048Sobrien#ifdef TEST 92226048Sobrienint 93226048Sobrienmain(int argc, char *argv[]) 94226048Sobrien{ 95226048Sobrien char *p = NULL; 96226048Sobrien ssize_t len; 97226048Sobrien size_t n = 0; 98226048Sobrien 99226048Sobrien while ((len = getline(&p, &n, stdin)) != -1) 100276415Sdelphij (void)printf("%" SIZE_T_FORMAT "d %s", len, p); 101226048Sobrien free(p); 102226048Sobrien return 0; 103226048Sobrien} 104226048Sobrien#endif 105