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,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
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 | |
@@ -18,57 +18,61 @@ | @@ -18,57 +18,61 @@ | |||
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,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
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 | |
@@ -18,90 +18,88 @@ | @@ -18,90 +18,88 @@ | |||
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; | |
@@ -114,43 +112,29 @@ __getdelim(char **__restrict buf, size_t | @@ -114,43 +112,29 @@ __getdelim(char **__restrict buf, size_t | |||
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,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
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. | |
@@ -65,28 +65,26 @@ extern int __svfscanf_unlocked __P((FILE | @@ -65,28 +65,26 @@ extern int __svfscanf_unlocked __P((FILE | |||
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 |