1: /*
2: * Copyright (c) 2009-2010, 2012-2013 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: #include <config.h>
18:
19: #ifndef HAVE_GETLINE
20:
21: #include <sys/types.h>
22:
23: #include <stdio.h>
24: #ifdef STDC_HEADERS
25: # include <stdlib.h>
26: # include <stddef.h>
27: #else
28: # ifdef HAVE_STDLIB_H
29: # include <stdlib.h>
30: # endif
31: #endif /* STDC_HEADERS */
32: #ifdef HAVE_STRING_H
33: # include <string.h>
34: #endif /* HAVE_STRING_H */
35: #ifdef HAVE_STRINGS_H
36: # include <strings.h>
37: #endif /* HAVE_STRINGS_H */
38: #include <limits.h>
39:
40: #include "missing.h"
41:
42: #ifndef LINE_MAX
43: # define LINE_MAX 2048
44: #endif
45:
46: #ifdef HAVE_FGETLN
47: ssize_t
48: getline(char **bufp, size_t *bufsizep, FILE *fp)
49: {
50: char *buf, *cp;
51: size_t bufsize;
52: size_t len;
53:
54: buf = fgetln(fp, &len);
55: if (buf) {
56: bufsize = *bufp ? *bufsizep : 0;
57: if (bufsize == 0 || bufsize - 1 < len) {
58: bufsize = len + 1;
59: cp = *bufp ? realloc(*bufp, bufsize) : malloc(bufsize);
60: if (cp == NULL)
61: return -1;
62: *bufp = cp;
63: *bufsizep = bufsize;
64: }
65: memcpy(*bufp, buf, len);
66: (*bufp)[len] = '\0';
67: }
68: return buf ? len : -1;
69: }
70: #else
71: ssize_t
72: getline(char **bufp, size_t *bufsizep, FILE *fp)
73: {
74: char *buf, *cp;
75: size_t bufsize;
76: ssize_t len = 0;
77:
78: buf = *bufp;
79: bufsize = *bufsizep;
80: if (buf == NULL || bufsize == 0) {
81: bufsize = LINE_MAX;
82: cp = buf ? realloc(buf, bufsize) : malloc(bufsize);
83: if (cp == NULL)
84: return -1;
85: buf = cp;
86: }
87:
88: for (;;) {
89: if (fgets(buf + len, bufsize - len, fp) == NULL) {
90: len = -1;
91: break;
92: }
93: len = strlen(buf);
94: if (!len || buf[len - 1] == '\n' || feof(fp))
95: break;
96: bufsize *= 2;
97: cp = realloc(buf, bufsize);
98: if (cp == NULL)
99: return -1;
100: buf = cp;
101: }
102: *bufp = buf;
103: *bufsizep = bufsize;
104: return len;
105: }
106: #endif /* HAVE_FGETLN */
107: #endif /* HAVE_GETLINE */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>