diff options
author | Darren Tucker <dtucker@dtucker.net> | 2018-07-02 21:16:58 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@dtucker.net> | 2018-07-02 21:36:31 +1000 |
commit | 6301e6c787d4e26bfae1119ab4f747bbcaa94e44 (patch) | |
tree | e2aa2c85f60d32983b6017cc485df17bd2d9aeb6 /openbsd-compat/bsd-getline.c | |
parent | 84623e0037628f9992839063151f7a9f5f13099a (diff) |
Add implementation of getline.
Add getline for the benefit of platforms that don't have it. Sourced
from NetBSD (OpenBSD's implementation is a little too chummy with the
internals of FILE).
Diffstat (limited to 'openbsd-compat/bsd-getline.c')
-rw-r--r-- | openbsd-compat/bsd-getline.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/openbsd-compat/bsd-getline.c b/openbsd-compat/bsd-getline.c new file mode 100644 index 000000000..681062e80 --- /dev/null +++ b/openbsd-compat/bsd-getline.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* $NetBSD: getline.c,v 1.1.1.6 2015/01/02 20:34:27 christos Exp $ */ | ||
2 | |||
3 | /* NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp */ | ||
4 | |||
5 | /*- | ||
6 | * Copyright (c) 2011 The NetBSD Foundation, Inc. | ||
7 | * All rights reserved. | ||
8 | * | ||
9 | * This code is derived from software contributed to The NetBSD Foundation | ||
10 | * by Christos Zoulas. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in the | ||
19 | * documentation and/or other materials provided with the distribution. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||
22 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | ||
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
31 | * POSSIBILITY OF SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | /* NETBSD ORIGINAL: external/bsd/file/dist/src/getline.c */ | ||
35 | |||
36 | #include "includes.h" | ||
37 | |||
38 | #if 0 | ||
39 | #include "file.h" | ||
40 | #endif | ||
41 | |||
42 | #if !HAVE_GETLINE | ||
43 | #include <stdlib.h> | ||
44 | #include <stdio.h> | ||
45 | #include <unistd.h> | ||
46 | #include <errno.h> | ||
47 | #include <string.h> | ||
48 | |||
49 | static ssize_t | ||
50 | getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) | ||
51 | { | ||
52 | char *ptr, *eptr; | ||
53 | |||
54 | |||
55 | if (*buf == NULL || *bufsiz == 0) { | ||
56 | *bufsiz = BUFSIZ; | ||
57 | if ((*buf = malloc(*bufsiz)) == NULL) | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | for (ptr = *buf, eptr = *buf + *bufsiz;;) { | ||
62 | int c = fgetc(fp); | ||
63 | if (c == -1) { | ||
64 | if (feof(fp)) { | ||
65 | ssize_t diff = (ssize_t)(ptr - *buf); | ||
66 | if (diff != 0) { | ||
67 | *ptr = '\0'; | ||
68 | return diff; | ||
69 | } | ||
70 | } | ||
71 | return -1; | ||
72 | } | ||
73 | *ptr++ = c; | ||
74 | if (c == delimiter) { | ||
75 | *ptr = '\0'; | ||
76 | return ptr - *buf; | ||
77 | } | ||
78 | if (ptr + 2 >= eptr) { | ||
79 | char *nbuf; | ||
80 | size_t nbufsiz = *bufsiz * 2; | ||
81 | ssize_t d = ptr - *buf; | ||
82 | if ((nbuf = realloc(*buf, nbufsiz)) == NULL) | ||
83 | return -1; | ||
84 | *buf = nbuf; | ||
85 | *bufsiz = nbufsiz; | ||
86 | eptr = nbuf + nbufsiz; | ||
87 | ptr = nbuf + d; | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | ssize_t | ||
93 | getline(char **buf, size_t *bufsiz, FILE *fp) | ||
94 | { | ||
95 | return getdelim(buf, bufsiz, '\n', fp); | ||
96 | } | ||
97 | |||
98 | #endif | ||
99 | |||
100 | #ifdef TEST | ||
101 | int | ||
102 | main(int argc, char *argv[]) | ||
103 | { | ||
104 | char *p = NULL; | ||
105 | ssize_t len; | ||
106 | size_t n = 0; | ||
107 | |||
108 | while ((len = getline(&p, &n, stdin)) != -1) | ||
109 | (void)printf("%" SIZE_T_FORMAT "d %s", len, p); | ||
110 | free(p); | ||
111 | return 0; | ||
112 | } | ||
113 | #endif | ||