1 /* Checking macros for stdio functions. 2 Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 02111-1307 USA. */ 19 20 #ifndef _STDIO_H 21 # error "Never include <bits/stdio2.h> directly; use <stdio.h> instead." 22 #endif 23 24 extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen, 25 __const char *__restrict __format, ...) __THROW; 26 extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen, 27 __const char *__restrict __format, 28 _G_va_list __ap) __THROW; 29 30 #ifdef __va_arg_pack 31 __extern_always_inline int 32 __NTH (sprintf (char *__restrict __s, __const char *__restrict __fmt, ...)) 33 { 34 return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, 35 __bos (__s), __fmt, __va_arg_pack ()); 36 } 37 #elif !defined __cplusplus 38 # define sprintf(str, ...) \ 39 __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \ 40 __VA_ARGS__) 41 #endif 42 43 __extern_always_inline int 44 __NTH (vsprintf (char *__restrict __s, __const char *__restrict __fmt, 45 _G_va_list __ap)) 46 { 47 return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, 48 __bos (__s), __fmt, __ap); 49 } 50 51 #if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98 52 53 extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag, 54 size_t __slen, __const char *__restrict __format, 55 ...) __THROW; 56 extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, 57 size_t __slen, __const char *__restrict __format, 58 _G_va_list __ap) __THROW; 59 60 # ifdef __va_arg_pack 61 __extern_always_inline int 62 __NTH (snprintf (char *__restrict __s, size_t __n, 63 __const char *__restrict __fmt, ...)) 64 { 65 return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, 66 __bos (__s), __fmt, __va_arg_pack ()); 67 } 68 # elif !defined __cplusplus 69 # define snprintf(str, len, ...) \ 70 __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \ 71 __VA_ARGS__) 72 # endif 73 74 __extern_always_inline int 75 __NTH (vsnprintf (char *__restrict __s, size_t __n, 76 __const char *__restrict __fmt, _G_va_list __ap)) 77 { 78 return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, 79 __bos (__s), __fmt, __ap); 80 } 81 82 #endif 83 84 #if __USE_FORTIFY_LEVEL > 1 85 86 extern int __fprintf_chk (FILE *__restrict __stream, int __flag, 87 __const char *__restrict __format, ...); 88 extern int __printf_chk (int __flag, __const char *__restrict __format, ...); 89 extern int __vfprintf_chk (FILE *__restrict __stream, int __flag, 90 __const char *__restrict __format, _G_va_list __ap); 91 extern int __vprintf_chk (int __flag, __const char *__restrict __format, 92 _G_va_list __ap); 93 94 # ifdef __va_arg_pack 95 __extern_always_inline int 96 fprintf (FILE *__restrict __stream, __const char *__restrict __fmt, ...) 97 { 98 return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, 99 __va_arg_pack ()); 100 } 101 102 __extern_always_inline int 103 printf (__const char *__restrict __fmt, ...) 104 { 105 return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ()); 106 } 107 # elif !defined __cplusplus 108 # define printf(...) \ 109 __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__) 110 # define fprintf(stream, ...) \ 111 __fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) 112 # endif 113 114 __extern_always_inline int 115 vprintf (__const char *__restrict __fmt, _G_va_list __ap) 116 { 117 #ifdef __USE_EXTERN_INLINES 118 return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); 119 #else 120 return __vprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap); 121 #endif 122 } 123 124 __extern_always_inline int 125 vfprintf (FILE *__restrict __stream, 126 __const char *__restrict __fmt, _G_va_list __ap) 127 { 128 return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); 129 } 130 131 #endif 132 133 extern char *__gets_chk (char *__str, size_t) __wur; 134 extern char *__REDIRECT (__gets_warn, (char *__str), gets) 135 __wur __warnattr ("please use fgets or getline instead, gets can't " 136 "specify buffer size"); 137 138 __extern_always_inline __wur char * 139 gets (char *__str) 140 { 141 if (__bos (__str) != (size_t) -1) 142 return __gets_chk (__str, __bos (__str)); 143 return __gets_warn (__str); 144 } 145 146 extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n, 147 FILE *__restrict __stream) __wur; 148 extern char *__REDIRECT (__fgets_alias, 149 (char *__restrict __s, int __n, 150 FILE *__restrict __stream), fgets) __wur; 151 extern char *__REDIRECT (__fgets_chk_warn, 152 (char *__restrict __s, size_t __size, int __n, 153 FILE *__restrict __stream), __fgets_chk) 154 __wur __warnattr ("fgets called with bigger size than length " 155 "of destination buffer"); 156 157 __extern_always_inline __wur char * 158 fgets (char *__restrict __s, int __n, FILE *__restrict __stream) 159 { 160 if (__bos (__s) != (size_t) -1) 161 { 162 if (!__builtin_constant_p (__n) || __n <= 0) 163 return __fgets_chk (__s, __bos (__s), __n, __stream); 164 165 if ((size_t) __n > __bos (__s)) 166 return __fgets_chk_warn (__s, __bos (__s), __n, __stream); 167 } 168 return __fgets_alias (__s, __n, __stream); 169 } 170 171 extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, 172 size_t __size, size_t __n, 173 FILE *__restrict __stream) __wur; 174 extern size_t __REDIRECT (__fread_alias, 175 (void *__restrict __ptr, size_t __size, 176 size_t __n, FILE *__restrict __stream), 177 fread) __wur; 178 extern size_t __REDIRECT (__fread_chk_warn, 179 (void *__restrict __ptr, size_t __ptrlen, 180 size_t __size, size_t __n, 181 FILE *__restrict __stream), 182 __fread_chk) 183 __wur __warnattr ("fread called with bigger size * nmemb than length " 184 "of destination buffer"); 185 186 __extern_always_inline __wur size_t 187 fread (void *__restrict __ptr, size_t __size, size_t __n, 188 FILE *__restrict __stream) 189 { 190 if (__bos0 (__ptr) != (size_t) -1) 191 { 192 if (!__builtin_constant_p (__size) 193 || !__builtin_constant_p (__n) 194 || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) 195 return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream); 196 197 if (__size * __n > __bos0 (__ptr)) 198 return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream); 199 } 200 return __fread_alias (__ptr, __size, __n, __stream); 201 } 202 203 #ifdef __USE_GNU 204 extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size, 205 int __n, FILE *__restrict __stream) __wur; 206 extern char *__REDIRECT (__fgets_unlocked_alias, 207 (char *__restrict __s, int __n, 208 FILE *__restrict __stream), fgets_unlocked) __wur; 209 extern char *__REDIRECT (__fgets_unlocked_chk_warn, 210 (char *__restrict __s, size_t __size, int __n, 211 FILE *__restrict __stream), __fgets_unlocked_chk) 212 __wur __warnattr ("fgets_unlocked called with bigger size than length " 213 "of destination buffer"); 214 215 __extern_always_inline __wur char * 216 fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) 217 { 218 if (__bos (__s) != (size_t) -1) 219 { 220 if (!__builtin_constant_p (__n) || __n <= 0) 221 return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream); 222 223 if ((size_t) __n > __bos (__s)) 224 return __fgets_unlocked_chk_warn (__s, __bos (__s), __n, __stream); 225 } 226 return __fgets_unlocked_alias (__s, __n, __stream); 227 } 228 #endif 229 230 #ifdef __USE_MISC 231 # undef fread_unlocked 232 extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen, 233 size_t __size, size_t __n, 234 FILE *__restrict __stream) __wur; 235 extern size_t __REDIRECT (__fread_unlocked_alias, 236 (void *__restrict __ptr, size_t __size, 237 size_t __n, FILE *__restrict __stream), 238 fread_unlocked) __wur; 239 extern size_t __REDIRECT (__fread_unlocked_chk_warn, 240 (void *__restrict __ptr, size_t __ptrlen, 241 size_t __size, size_t __n, 242 FILE *__restrict __stream), 243 __fread_unlocked_chk) 244 __wur __warnattr ("fread_unlocked called with bigger size * nmemb than " 245 "length of destination buffer"); 246 247 __extern_always_inline __wur size_t 248 fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, 249 FILE *__restrict __stream) 250 { 251 if (__bos0 (__ptr) != (size_t) -1) 252 { 253 if (!__builtin_constant_p (__size) 254 || !__builtin_constant_p (__n) 255 || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) 256 return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n, 257 __stream); 258 259 if (__size * __n > __bos0 (__ptr)) 260 return __fread_unlocked_chk_warn (__ptr, __bos0 (__ptr), __size, __n, 261 __stream); 262 } 263 264 # ifdef __USE_EXTERN_INLINES 265 if (__builtin_constant_p (__size) 266 && __builtin_constant_p (__n) 267 && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) 268 && __size * __n <= 8) 269 { 270 size_t __cnt = __size * __n; 271 char *__cptr = (char *) __ptr; 272 if (__cnt == 0) 273 return 0; 274 275 for (; __cnt > 0; --__cnt) 276 { 277 int __c = _IO_getc_unlocked (__stream); 278 if (__c == EOF) 279 break; 280 *__cptr++ = __c; 281 } 282 return (__cptr - (char *) __ptr) / __size; 283 } 284 # endif 285 return __fread_unlocked_alias (__ptr, __size, __n, __stream); 286 } 287 #endif 288