Remove __getdelim and just use getdelim. fgetstr now works with strings up to SSIZE_MAX as a result, but may reallocate buffers needlessly just like it used to when the buffer size exceeds INT_MAX. fgetstr converts errno EOVERFLOW to EINVAL on getdelim error.diff -r1.8 -r1.9 src/lib/libc/stdio/fgetstr.c
(roy)
--- src/lib/libc/stdio/fgetstr.c 2009/10/15 00:36:24 1.8
+++ src/lib/libc/stdio/fgetstr.c 2009/12/01 00:03:53 1.9
@@ -1,74 +1,78 @@ | @@ -1,74 +1,78 @@ | |||
1 | /* $NetBSD: fgetstr.c,v 1.8 2009/10/15 00:36:24 roy Exp $ */ | 1 | /* $NetBSD: fgetstr.c,v 1.9 2009/12/01 00:03:53 roy Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2009 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2009 The NetBSD Foundation, Inc. | |
5 | * | 5 | * | |
6 | * This code is derived from software contributed to The NetBSD Foundation | 6 | * This code is derived from software contributed to The NetBSD Foundation | |
7 | * by Roy Marples. | 7 | * by Roy Marples. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. | |
17 | * | 17 | * | |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include <sys/cdefs.h> | 30 | #include <sys/cdefs.h> | |
31 | __RCSID("$NetBSD: fgetstr.c,v 1.8 2009/10/15 00:36:24 roy Exp $"); | 31 | __RCSID("$NetBSD: fgetstr.c,v 1.9 2009/12/01 00:03:53 roy Exp $"); | |
32 | 32 | |||
33 | #include "namespace.h" | 33 | #include "namespace.h" | |
34 | 34 | |||
35 | #include <assert.h> | 35 | #include <assert.h> | |
36 | #include <errno.h> | 36 | #include <errno.h> | |
37 | #include <limits.h> | 37 | #include <limits.h> | |
38 | #include <stdio.h> | 38 | #include <stdio.h> | |
39 | 39 | |||
40 | #include "reentrant.h" | 40 | #include "reentrant.h" | |
41 | #include "local.h" | 41 | #include "local.h" | |
42 | 42 | |||
43 | /* | 43 | /* | |
44 | * Get an input line. | 44 | * Get an input line. | |
45 | * This now uses getdelim(3) for a code reduction. | 45 | * This now uses getdelim(3) for a code reduction. | |
46 | * The upside is that strings are now always NULL terminated, but relying | 46 | * The upside is that strings are now always NULL terminated, but relying | |
47 | * on this is non portable - better to use the POSIX getdelim(3) function. | 47 | * on this is non portable - better to use the POSIX getdelim(3) function. | |
48 | */ | 48 | */ | |
49 | char * | 49 | char * | |
50 | __fgetstr(FILE *__restrict fp, size_t *__restrict lenp, int sep) | 50 | __fgetstr(FILE *__restrict fp, size_t *__restrict lenp, int sep) | |
51 | { | 51 | { | |
52 | char *p; | 52 | char *p; | |
53 | size_t size; | 53 | size_t size; | |
54 | ssize_t n; | |||
54 | 55 | |||
55 | _DIAGASSERT(fp != NULL); | 56 | _DIAGASSERT(fp != NULL); | |
56 | _DIAGASSERT(lenp != NULL); | 57 | _DIAGASSERT(lenp != NULL); | |
57 | 58 | |||
58 | p = (char *)fp->_lb._base; | 59 | p = (char *)fp->_lb._base; | |
59 | size = fp->_lb._size; | 60 | size = fp->_lb._size; | |
60 | *lenp = __getdelim(&p, &size, sep, fp); | 61 | n = getdelim(&p, &size, sep, fp); | |
61 | fp->_lb._base = (unsigned char *)p; | 62 | fp->_lb._base = (unsigned char *)p; | |
62 | /* The struct size variable is only an int ..... */ | 63 | /* The struct size variable is only an int ..... | |
63 | if (size > INT_MAX) { | 64 | * This still works when exceeded, but the buffer could be | |
65 | * realloced needlessly. */ | |||
66 | if (size > INT_MAX) | |||
64 | fp->_lb._size = INT_MAX; | 67 | fp->_lb._size = INT_MAX; | |
65 | errno = EOVERFLOW; | 68 | else | |
66 | goto error; | 69 | fp->_lb._size = (int)size; | |
70 | if (n == -1) { | |||
71 | *lenp = 0; | |||
72 | if (errno == EOVERFLOW) /* fixup errno */ | |||
73 | errno = EINVAL; | |||
74 | return NULL; | |||
67 | } | 75 | } | |
68 | fp->_lb._size = (int)size; | 76 | *lenp = n; | |
69 | if (*lenp != 0 && *lenp < SIZE_MAX - 1) | 77 | return p; | |
70 | return p; | |||
71 | error: | |||
72 | *lenp = 0; | |||
73 | return NULL; | |||
74 | } | 78 | } |
--- src/lib/libc/stdio/getdelim.c 2009/10/25 20:44:13 1.7
+++ src/lib/libc/stdio/getdelim.c 2009/12/01 00:03:53 1.8
@@ -1,156 +1,140 @@ | @@ -1,156 +1,140 @@ | |||
1 | /* $NetBSD: getdelim.c,v 1.7 2009/10/25 20:44:13 christos Exp $ */ | 1 | /* $NetBSD: getdelim.c,v 1.8 2009/12/01 00:03:53 roy Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2009 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2009 The NetBSD Foundation, Inc. | |
5 | * | 5 | * | |
6 | * This code is derived from software contributed to The NetBSD Foundation | 6 | * This code is derived from software contributed to The NetBSD Foundation | |
7 | * by Roy Marples. | 7 | * by Roy Marples. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. | |
17 | * | 17 | * | |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include <sys/cdefs.h> | 30 | #include <sys/cdefs.h> | |
31 | __RCSID("$NetBSD: getdelim.c,v 1.7 2009/10/25 20:44:13 christos Exp $"); | 31 | __RCSID("$NetBSD: getdelim.c,v 1.8 2009/12/01 00:03:53 roy Exp $"); | |
32 | 32 | |||
33 | #include "namespace.h" | 33 | #include "namespace.h" | |
34 | 34 | |||
35 | #include <sys/param.h> | 35 | #include <sys/param.h> | |
36 | 36 | |||
37 | #include <assert.h> | 37 | #include <assert.h> | |
38 | #include <errno.h> | 38 | #include <errno.h> | |
39 | #include <limits.h> | 39 | #include <limits.h> | |
40 | #include <stdio.h> | 40 | #include <stdio.h> | |
41 | #include <stdlib.h> | 41 | #include <stdlib.h> | |
42 | #include <string.h> | 42 | #include <string.h> | |
43 | 43 | |||
44 | #include "reentrant.h" | 44 | #include "reentrant.h" | |
45 | #include "local.h" | 45 | #include "local.h" | |
46 | 46 | |||
47 | /* Minimum buffer size we create. | 47 | /* Minimum buffer size we create. | |
48 | * This should allow config files to fit into our power of 2 buffer growth | 48 | * This should allow config files to fit into our power of 2 buffer growth | |
49 | * without the need for a realloc. */ | 49 | * without the need for a realloc. */ | |
50 | #define MINBUF 128 | 50 | #define MINBUF 128 | |
51 | 51 | |||
52 | /* This private function allows strings of upto SIZE_MAX - 2 | |||
53 | * and returns 0 on EOF, both of which are disallowed by POSIX. | |||
54 | * Maybe this should be named fgetdelim and proposed to the OpenGroup....*/ | |||
55 | ssize_t | 52 | ssize_t | |
56 | __getdelim(char **__restrict buf, size_t *__restrict buflen, | 53 | getdelim(char **__restrict buf, size_t *__restrict buflen, | |
57 | int sep, FILE *__restrict fp) | 54 | int sep, FILE *__restrict fp) | |
58 | { | 55 | { | |
59 | unsigned char *p; | 56 | unsigned char *p; | |
60 | size_t len, newlen, off; | 57 | size_t len, newlen, off; | |
61 | char *newb; | 58 | char *newb; | |
62 | 59 | |||
63 | _DIAGASSERT(fp != NULL); | 60 | _DIAGASSERT(fp != NULL); | |
64 | 61 | |||
65 | if (buf == NULL || buflen == NULL) { | 62 | if (buf == NULL || buflen == NULL) { | |
66 | errno = EINVAL; | 63 | errno = EINVAL; | |
67 | return -1; | 64 | return -1; | |
68 | } | 65 | } | |
69 | 66 | |||
70 | /* If buf is NULL, we have to assume a size of zero */ | 67 | /* If buf is NULL, we have to assume a size of zero */ | |
71 | if (*buf == NULL) | 68 | if (*buf == NULL) | |
72 | *buflen = 0; | 69 | *buflen = 0; | |
73 | 70 | |||
74 | FLOCKFILE(fp); | 71 | FLOCKFILE(fp); | |
75 | _SET_ORIENTATION(fp, -1); | 72 | _SET_ORIENTATION(fp, -1); | |
76 | off = 0; | 73 | off = 0; | |
77 | for (;;) { | 74 | do { | |
78 | /* If the input buffer is empty, refill it */ | 75 | /* If the input buffer is empty, refill it */ | |
79 | if (fp->_r <= 0 && __srefill(fp)) { | 76 | if (fp->_r <= 0 && __srefill(fp)) { | |
80 | if (__sferror(fp)) | 77 | if (__sferror(fp)) | |
81 | goto error; | 78 | goto error; | |
79 | /* No error, so EOF. */ | |||
82 | break; | 80 | break; | |
83 | } | 81 | } | |
84 | 82 | |||
85 | /* Scan through looking for the separator */ | 83 | /* Scan through looking for the separator */ | |
86 | p = memchr(fp->_p, sep, (size_t)fp->_r); | 84 | p = memchr(fp->_p, sep, (size_t)fp->_r); | |
87 | if (p == NULL) | 85 | if (p == NULL) | |
88 | len = fp->_r; | 86 | len = fp->_r; | |
89 | else | 87 | else | |
90 | len = (p - fp->_p) + 1; | 88 | len = (p - fp->_p) + 1; | |
91 | 89 | |||
92 | newlen = off + len + 1; | 90 | newlen = off + len + 1; | |
93 | /* Ensure we can handle it */ | 91 | /* Ensure we can handle it */ | |
94 | if (newlen < off || newlen > SIZE_MAX - 2) { | 92 | if (newlen < off || newlen > (size_t)SSIZE_MAX + 1) { | |
95 | errno = EOVERFLOW; | 93 | errno = EOVERFLOW; | |
96 | goto error; | 94 | goto error; | |
97 | } | 95 | } | |
98 | if (newlen > *buflen) { | 96 | if (newlen > *buflen) { | |
99 | if (newlen < MINBUF) | 97 | if (newlen < MINBUF) | |
100 | newlen = MINBUF; | 98 | newlen = MINBUF; | |
101 | if (!powerof2(newlen)) { | 99 | if (!powerof2(newlen)) { | |
102 | /* Grow the buffer to the next power of 2 */ | 100 | /* Grow the buffer to the next power of 2 */ | |
103 | newlen--; | 101 | newlen--; | |
104 | newlen |= newlen >> 1; | 102 | newlen |= newlen >> 1; | |
105 | newlen |= newlen >> 2; | 103 | newlen |= newlen >> 2; | |
106 | newlen |= newlen >> 4; | 104 | newlen |= newlen >> 4; | |
107 | newlen |= newlen >> 8; | 105 | newlen |= newlen >> 8; | |
108 | newlen |= newlen >> 16; | 106 | newlen |= newlen >> 16; | |
109 | #if SIZE_T_MAX > 0xffffffffU | 107 | #if SIZE_T_MAX > 0xffffffffU | |
110 | newlen |= newlen >> 32; | 108 | newlen |= newlen >> 32; | |
111 | #endif | 109 | #endif | |
112 | newlen++; | 110 | newlen++; | |
113 | } | 111 | } | |
114 | 112 | |||
115 | newb = realloc(*buf, newlen); | 113 | newb = realloc(*buf, newlen); | |
116 | if (newb == NULL) | 114 | if (newb == NULL) | |
117 | goto error; | 115 | goto error; | |
118 | *buf = newb; | 116 | *buf = newb; | |
119 | *buflen = newlen; | 117 | *buflen = newlen; | |
120 | } | 118 | } | |
121 | 119 | |||
122 | (void)memcpy((*buf + off), fp->_p, len); | 120 | (void)memcpy((*buf + off), fp->_p, len); | |
123 | /* Safe, len is never greater than what fp->_r can fit. */ | 121 | /* Safe, len is never greater than what fp->_r can fit. */ | |
124 | fp->_r -= (int)len; | 122 | fp->_r -= (int)len; | |
125 | fp->_p += (int)len; | 123 | fp->_p += (int)len; | |
126 | off += len; | 124 | off += len; | |
127 | if (p != NULL) | 125 | } while (p == NULL); | |
128 | break; | |||
129 | } | |||
130 | FUNLOCKFILE(fp); | 126 | FUNLOCKFILE(fp); | |
127 | ||||
128 | /* POSIX demands we return -1 on EOF. */ | |||
129 | if (off == 0) | |||
130 | return -1; | |||
131 | ||||
131 | if (*buf != NULL) | 132 | if (*buf != NULL) | |
132 | *(*buf + off) = '\0'; | 133 | *(*buf + off) = '\0'; | |
133 | return off; | 134 | return off; | |
134 | 135 | |||
135 | error: | 136 | error: | |
137 | fp->_flags |= __SERR; | |||
136 | FUNLOCKFILE(fp); | 138 | FUNLOCKFILE(fp); | |
137 | return -1; | 139 | return -1; | |
138 | } | 140 | } | |
139 | ||||
140 | ssize_t | |||
141 | getdelim(char **__restrict buf, size_t *__restrict buflen, | |||
142 | int sep, FILE *__restrict fp) | |||
143 | { | |||
144 | ssize_t len; | |||
145 | ||||
146 | len = __getdelim(buf, buflen, sep, fp); | |||
147 | if (len == 0) { | |||
148 | /* POSIX requires that we return -1 on EOF */ | |||
149 | return -1; | |||
150 | } else if (len < -1) { | |||
151 | /* POSIX requires no string larger than SSIZE_MAX */ | |||
152 | errno = EOVERFLOW; | |||
153 | return -1; | |||
154 | } | |||
155 | return len; | |||
156 | } |
--- src/lib/libc/stdio/local.h 2009/09/24 20:38:53 1.21
+++ src/lib/libc/stdio/local.h 2009/12/01 00:03:53 1.22
@@ -1,114 +1,112 @@ | @@ -1,114 +1,112 @@ | |||
1 | /* $NetBSD: local.h,v 1.21 2009/09/24 20:38:53 roy Exp $ */ | 1 | /* $NetBSD: local.h,v 1.22 2009/12/01 00:03:53 roy Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1990, 1993 | 4 | * Copyright (c) 1990, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Chris Torek. | 8 | * Chris Torek. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. Neither the name of the University nor the names of its contributors | 18 | * 3. Neither the name of the University nor the names of its contributors | |
19 | * may be used to endorse or promote products derived from this software | 19 | * may be used to endorse or promote products derived from this software | |
20 | * without specific prior written permission. | 20 | * without specific prior written permission. | |
21 | * | 21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | * | 33 | * | |
34 | * @(#)local.h 8.3 (Berkeley) 7/3/94 | 34 | * @(#)local.h 8.3 (Berkeley) 7/3/94 | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include "wcio.h" | 37 | #include "wcio.h" | |
38 | #include "fileext.h" | 38 | #include "fileext.h" | |
39 | 39 | |||
40 | /* | 40 | /* | |
41 | * Information local to this implementation of stdio, | 41 | * Information local to this implementation of stdio, | |
42 | * in particular, macros and private variables. | 42 | * in particular, macros and private variables. | |
43 | */ | 43 | */ | |
44 | 44 | |||
45 | extern int __sflush __P((FILE *)); | 45 | extern int __sflush __P((FILE *)); | |
46 | extern FILE *__sfp __P((void)); | 46 | extern FILE *__sfp __P((void)); | |
47 | extern int __srefill __P((FILE *)); | 47 | extern int __srefill __P((FILE *)); | |
48 | extern int __sread __P((void *, char *, int)); | 48 | extern int __sread __P((void *, char *, int)); | |
49 | extern int __swrite __P((void *, char const *, int)); | 49 | extern int __swrite __P((void *, char const *, int)); | |
50 | extern fpos_t __sseek __P((void *, fpos_t, int)); | 50 | extern fpos_t __sseek __P((void *, fpos_t, int)); | |
51 | extern int __sclose __P((void *)); | 51 | extern int __sclose __P((void *)); | |
52 | extern void __sinit __P((void)); | 52 | extern void __sinit __P((void)); | |
53 | extern void _cleanup __P((void)); | 53 | extern void _cleanup __P((void)); | |
54 | extern void (*__cleanup) __P((void)); | 54 | extern void (*__cleanup) __P((void)); | |
55 | extern void __smakebuf __P((FILE *)); | 55 | extern void __smakebuf __P((FILE *)); | |
56 | extern int __swhatbuf __P((FILE *, size_t *, int *)); | 56 | extern int __swhatbuf __P((FILE *, size_t *, int *)); | |
57 | extern int _fwalk __P((int (*)(FILE *))); | 57 | extern int _fwalk __P((int (*)(FILE *))); | |
58 | extern char *_mktemp __P((char *)); | 58 | extern char *_mktemp __P((char *)); | |
59 | extern int __swsetup __P((FILE *)); | 59 | extern int __swsetup __P((FILE *)); | |
60 | extern int __sflags __P((const char *, int *)); | 60 | extern int __sflags __P((const char *, int *)); | |
61 | extern int __svfscanf __P((FILE * __restrict, const char * __restrict, | 61 | extern int __svfscanf __P((FILE * __restrict, const char * __restrict, | |
62 | _BSD_VA_LIST_)) | 62 | _BSD_VA_LIST_)) | |
63 | __attribute__((__format__(__scanf__, 2, 0))); | 63 | __attribute__((__format__(__scanf__, 2, 0))); | |
64 | extern int __svfscanf_unlocked __P((FILE * __restrict, const char * __restrict, | 64 | extern int __svfscanf_unlocked __P((FILE * __restrict, const char * __restrict, | |
65 | _BSD_VA_LIST_)) | 65 | _BSD_VA_LIST_)) | |
66 | __attribute__((__format__(__scanf__, 2, 0))); | 66 | __attribute__((__format__(__scanf__, 2, 0))); | |
67 | extern int __vfprintf_unlocked __P((FILE * __restrict, const char * __restrict, | 67 | extern int __vfprintf_unlocked __P((FILE * __restrict, const char * __restrict, | |
68 | _BSD_VA_LIST_)); | 68 | _BSD_VA_LIST_)); | |
69 | 69 | |||
70 | 70 | |||
71 | extern int __sdidinit; | 71 | extern int __sdidinit; | |
72 | 72 | |||
73 | extern int __gettemp __P((char *, int *, int)); | 73 | extern int __gettemp __P((char *, int *, int)); | |
74 | 74 | |||
75 | extern wint_t __fgetwc_unlock __P((FILE *)); | 75 | extern wint_t __fgetwc_unlock __P((FILE *)); | |
76 | extern wint_t __fputwc_unlock __P((wchar_t, FILE *)); | 76 | extern wint_t __fputwc_unlock __P((wchar_t, FILE *)); | |
77 | 77 | |||
78 | extern ssize_t __getdelim __P((char ** __restrict, size_t * __restrict, int, | |||
79 | FILE * __restrict)); | |||
80 | extern char *__fgetstr __P((FILE * __restrict, size_t * __restrict, int)); | 78 | extern char *__fgetstr __P((FILE * __restrict, size_t * __restrict, int)); | |
81 | extern int __vfwprintf_unlocked __P((FILE *, const wchar_t *, | 79 | extern int __vfwprintf_unlocked __P((FILE *, const wchar_t *, | |
82 | _BSD_VA_LIST_)); | 80 | _BSD_VA_LIST_)); | |
83 | extern int __vfwscanf_unlocked __P((FILE * __restrict, | 81 | extern int __vfwscanf_unlocked __P((FILE * __restrict, | |
84 | const wchar_t * __restrict, _BSD_VA_LIST_)); | 82 | const wchar_t * __restrict, _BSD_VA_LIST_)); | |
85 | 83 | |||
86 | /* | 84 | /* | |
87 | * Return true iff the given FILE cannot be written now. | 85 | * Return true iff the given FILE cannot be written now. | |
88 | */ | 86 | */ | |
89 | #define cantwrite(fp) \ | 87 | #define cantwrite(fp) \ | |
90 | ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \ | 88 | ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \ | |
91 | __swsetup(fp)) | 89 | __swsetup(fp)) | |
92 | 90 | |||
93 | /* | 91 | /* | |
94 | * Test whether the given stdio file has an active ungetc buffer; | 92 | * Test whether the given stdio file has an active ungetc buffer; | |
95 | * release such a buffer, without restoring ordinary unread data. | 93 | * release such a buffer, without restoring ordinary unread data. | |
96 | */ | 94 | */ | |
97 | #define HASUB(fp) (_UB(fp)._base != NULL) | 95 | #define HASUB(fp) (_UB(fp)._base != NULL) | |
98 | #define FREEUB(fp) { \ | 96 | #define FREEUB(fp) { \ | |
99 | if (_UB(fp)._base != (fp)->_ubuf) \ | 97 | if (_UB(fp)._base != (fp)->_ubuf) \ | |
100 | free((char *)_UB(fp)._base); \ | 98 | free((char *)_UB(fp)._base); \ | |
101 | _UB(fp)._base = NULL; \ | 99 | _UB(fp)._base = NULL; \ | |
102 | } | 100 | } | |
103 | 101 | |||
104 | /* | 102 | /* | |
105 | * test for an fgetln() buffer. | 103 | * test for an fgetln() buffer. | |
106 | */ | 104 | */ | |
107 | #define HASLB(fp) ((fp)->_lb._base != NULL) | 105 | #define HASLB(fp) ((fp)->_lb._base != NULL) | |
108 | #define FREELB(fp) { \ | 106 | #define FREELB(fp) { \ | |
109 | free((char *)(fp)->_lb._base); \ | 107 | free((char *)(fp)->_lb._base); \ | |
110 | (fp)->_lb._base = NULL; \ | 108 | (fp)->_lb._base = NULL; \ | |
111 | } | 109 | } | |
112 | 110 | |||
113 | extern void __flockfile_internal __P((FILE *, int)); | 111 | extern void __flockfile_internal __P((FILE *, int)); | |
114 | extern void __funlockfile_internal __P((FILE *, int)); | 112 | extern void __funlockfile_internal __P((FILE *, int)); |