1 /* Copyright (C) 2004-2005 Manuel Novoa III <mjn3@codepoet.org> 2 * 3 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. 4 * 5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. 6 */ 7 8 #include <features.h> 9 #include <assert.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <limits.h> 13 #include <signal.h> 14 #include <stdint.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <stdarg.h> 19 #include <unistd.h> 20 #ifdef __UCLIBC_HAS_WCHAR__ 21 #include <wchar.h> 22 #endif 23 24 #include <bits/uClibc_mutex.h> 25 26 #define __STDIO_THREADLOCK_OPENLIST_ADD \ 27 __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_add_lock) 28 29 #define __STDIO_THREADUNLOCK_OPENLIST_ADD \ 30 __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_add_lock) 31 32 #ifdef __STDIO_BUFFERS 33 34 #define __STDIO_THREADLOCK_OPENLIST_DEL \ 35 __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_del_lock) 36 37 #define __STDIO_THREADUNLOCK_OPENLIST_DEL \ 38 __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_del_lock) 39 40 41 #ifdef __UCLIBC_HAS_THREADS__ 42 extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) attribute_hidden; 43 44 extern volatile int _stdio_openlist_use_count attribute_hidden; /* _stdio_openlist_del_lock */ 45 #define __STDIO_OPENLIST_INC_USE \ 46 do { \ 47 __STDIO_THREADLOCK_OPENLIST_DEL; \ 48 ++_stdio_openlist_use_count; \ 49 __STDIO_THREADUNLOCK_OPENLIST_DEL; \ 50 } while (0) 51 52 extern void _stdio_openlist_dec_use(void) attribute_hidden; 53 54 #define __STDIO_OPENLIST_DEC_USE \ 55 _stdio_openlist_dec_use() 56 57 extern int _stdio_openlist_del_count attribute_hidden; /* _stdio_openlist_del_lock */ 58 #define __STDIO_OPENLIST_INC_DEL_CNT \ 59 do { \ 60 __STDIO_THREADLOCK_OPENLIST_DEL; \ 61 ++_stdio_openlist_del_count; \ 62 __STDIO_THREADUNLOCK_OPENLIST_DEL; \ 63 } while (0) 64 65 #define __STDIO_OPENLIST_DEC_DEL_CNT \ 66 do { \ 67 __STDIO_THREADLOCK_OPENLIST_DEL; \ 68 --_stdio_openlist_del_count; \ 69 __STDIO_THREADUNLOCK_OPENLIST_DEL; \ 70 } while (0) 71 72 #endif /* __UCLIBC_HAS_THREADS__ */ 73 #endif /* __STDIO_BUFFERS */ 74 75 #ifndef __STDIO_THREADLOCK_OPENLIST_DEL 76 #define __STDIO_THREADLOCK_OPENLIST_DEL ((void)0) 77 #endif 78 #ifndef __STDIO_THREADUNLOCK_OPENLIST_DEL 79 #define __STDIO_THREADUNLOCK_OPENLIST_DEL ((void)0) 80 #endif 81 #ifndef __STDIO_OPENLIST_INC_USE 82 #define __STDIO_OPENLIST_INC_USE ((void)0) 83 #endif 84 #ifndef __STDIO_OPENLIST_DEC_USE 85 #define __STDIO_OPENLIST_DEC_USE ((void)0) 86 #endif 87 #ifndef __STDIO_OPENLIST_INC_DEL_CNT 88 #define __STDIO_OPENLIST_INC_DEL_CNT ((void)0) 89 #endif 90 #ifndef __STDIO_OPENLIST_DEC_DEL_CNT 91 #define __STDIO_OPENLIST_DEC_DEL_CNT ((void)0) 92 #endif 93 94 #define __UNDEFINED_OR_NONPORTABLE ((void)0) 95 96 /**********************************************************************/ 97 #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ 98 99 extern __ssize_t _cs_read(void *cookie, char *buf, size_t bufsize) attribute_hidden; 100 extern __ssize_t _cs_write(void *cookie, const char *buf, size_t bufsize) attribute_hidden; 101 extern int _cs_seek(void *cookie, __offmax_t *pos, int whence) attribute_hidden; 102 extern int _cs_close(void *cookie) attribute_hidden; 103 104 #define __STDIO_STREAM_RESET_GCS(S) \ 105 (S)->__cookie = &((S)->__filedes); \ 106 (S)->__gcs.read = _cs_read; \ 107 (S)->__gcs.write = _cs_write; \ 108 (S)->__gcs.seek = _cs_seek; \ 109 (S)->__gcs.close = _cs_close 110 111 112 #define __READ(STREAMPTR,BUF,SIZE) \ 113 ((((STREAMPTR)->__gcs.read) == NULL) ? -1 : \ 114 (((STREAMPTR)->__gcs.read)((STREAMPTR)->__cookie,(BUF),(SIZE)))) 115 #define __WRITE(STREAMPTR,BUF,SIZE) \ 116 ((((STREAMPTR)->__gcs.write) == NULL) ? -1 : \ 117 (((STREAMPTR)->__gcs.write)((STREAMPTR)->__cookie,(BUF),(SIZE)))) 118 #define __SEEK(STREAMPTR,PPOS,WHENCE) \ 119 ((((STREAMPTR)->__gcs.seek) == NULL) ? -1 : \ 120 (((STREAMPTR)->__gcs.seek)((STREAMPTR)->__cookie,(PPOS),(WHENCE)))) 121 #define __CLOSE(STREAMPTR) \ 122 ((((STREAMPTR)->__gcs.close) == NULL) ? 0 : \ 123 (((STREAMPTR)->__gcs.close)((STREAMPTR)->__cookie))) 124 125 #else /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ 126 127 extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attribute_hidden; 128 129 #define __STDIO_STREAM_RESET_GCS(S) ((void)0) 130 131 #define __READ(STREAMPTR,BUF,SIZE) \ 132 (read((STREAMPTR)->__filedes,(BUF),(SIZE))) 133 #define __WRITE(STREAMPTR,BUF,SIZE) \ 134 (write((STREAMPTR)->__filedes,(BUF),(SIZE))) 135 #define __SEEK(STREAMPTR,PPOS,WHENCE) \ 136 (__stdio_seek((STREAMPTR),(PPOS),(WHENCE))) 137 #define __CLOSE(STREAMPTR) \ 138 (close((STREAMPTR)->__filedes)) 139 140 #endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ 141 142 /**********************************************************************/ 143 #ifdef __UCLIBC_HAS_WCHAR__ 144 145 #define __STDIO_STREAM_TRANS_TO_WRITE(S,O) __stdio_trans2w_o((S), (O)) 146 #define __STDIO_STREAM_TRANS_TO_READ(S,O) __stdio_trans2r_o((S), (O)) 147 148 #else 149 150 #define __STDIO_STREAM_TRANS_TO_WRITE(S,O) __stdio_trans2w((S)) 151 #define __STDIO_STREAM_TRANS_TO_READ(S,O) __stdio_trans2r((S)) 152 153 #endif 154 /**********************************************************************/ 155 156 #define __STDIO_STREAM_IS_READING(S) ((S)->__modeflags & __MASK_READING) 157 #define __STDIO_STREAM_IS_WRITING(S) ((S)->__modeflags & __FLAG_WRITING) 158 159 #define __STDIO_STREAM_SET_READING(S) ((S)->__modeflags |= __FLAG_READING) 160 #define __STDIO_STREAM_SET_WRITING(S) ((S)->__modeflags |= __FLAG_WRITING) 161 162 #define __STDIO_STREAM_IS_READING_OR_READONLY(S) \ 163 ((S)->__modeflags & (__MASK_READING|__FLAG_READONLY)) 164 165 #define __STDIO_STREAM_IS_WRITING_OR_WRITEONLY(S) \ 166 ((S)->__modeflags & (__FLAG_WRITING|__FLAG_WRITEONLY)) 167 168 #define __STDIO_STREAM_IS_READONLY(S) ((S)->__modeflags & __FLAG_READONLY) 169 #define __STDIO_STREAM_IS_WRITEONLY(S) ((S)->__modeflags & __FLAG_WRITEONLY) 170 171 172 /**********************************************************************/ 173 #ifdef __UCLIBC_HAS_WCHAR__ 174 175 #define __STDIO_STREAM_IS_NARROW_WRITING(S) \ 176 (((S)->__modeflags & (__FLAG_WRITING|__FLAG_NARROW)) \ 177 == (__FLAG_WRITING|__FLAG_NARROW)) 178 179 #define __STDIO_STREAM_IS_WIDE_WRITING(S) \ 180 (((S)->__modeflags & (__FLAG_WRITING|__FLAG_WIDE)) \ 181 == (__FLAG_WRITING|__FLAG_WIDE)) 182 183 #if (__FLAG_NARROW <= __MASK_READING) 184 #error assumption violated regarding __FLAG_NARROW 185 #endif 186 187 #define __STDIO_STREAM_IS_NARROW_READING(S) \ 188 (((S)->__modeflags & (__MASK_READING|__FLAG_NARROW)) > __FLAG_NARROW) 189 190 #define __STDIO_STREAM_IS_WIDE_READING(S) \ 191 (((S)->__modeflags & (__MASK_READING|__FLAG_WIDE)) > __FLAG_WIDE) 192 193 #define __STDIO_STREAM_IS_NARROW(S) ((S)->__modeflags & __FLAG_NARROW) 194 #define __STDIO_STREAM_IS_WIDE(S) ((S)->__modeflags & __FLAG_WIDE) 195 196 #define __STDIO_STREAM_SET_NARROW(S) \ 197 ((void)((S)->__modeflags |= __FLAG_NARROW)) 198 #define __STDIO_STREAM_SET_WIDE(S) \ 199 ((void)((S)->__modeflags |= __FLAG_WIDE)) 200 201 #else 202 203 #define __STDIO_STREAM_IS_NARROW_WRITING(S) __STDIO_STREAM_IS_WRITING(S) 204 205 #define __STDIO_STREAM_IS_NARROW_READING(S) __STDIO_STREAM_IS_READING(S) 206 207 #define __STDIO_STREAM_IS_NARROW(S) (1) 208 #define __STDIO_STREAM_IS_WIDE(S) (0) 209 210 #define __STDIO_STREAM_SET_NARROW(S) ((void)0) 211 #define __STDIO_STREAM_SET_WIDE(S) ((void)0) 212 213 #endif 214 /**********************************************************************/ 215 216 #define __STDIO_STREAM_SET_EOF(S) \ 217 ((void)((S)->__modeflags |= __FLAG_EOF)) 218 #define __STDIO_STREAM_SET_ERROR(S) \ 219 ((void)((S)->__modeflags |= __FLAG_ERROR)) 220 221 #define __STDIO_STREAM_CLEAR_EOF(S) \ 222 ((void)((S)->__modeflags &= ~__FLAG_EOF)) 223 #define __STDIO_STREAM_CLEAR_ERROR(S) \ 224 ((void)((S)->__modeflags &= ~__FLAG_ERROR)) 225 226 #define __STDIO_STREAM_CLEAR_READING_AND_UNGOTS(S) \ 227 ((void)((S)->__modeflags &= ~__MASK_READING)) 228 #define __STDIO_STREAM_CLEAR_WRITING(S) \ 229 ((void)((S)->__modeflags &= ~__FLAG_WRITING)) 230 231 #ifdef __UCLIBC_HAS_STDIO_GETC_MACRO__ 232 # define __STDIO_STREAM_DISABLE_GETC(S) \ 233 ((void)((S)->__bufgetc_u = (S)->__bufstart)) 234 # define __STDIO_STREAM_ENABLE_GETC(S) \ 235 ((void)((S)->__bufgetc_u = (S)->__bufread)) 236 # define __STDIO_STREAM_CAN_USE_BUFFER_GET(S) \ 237 ((S)->__bufpos < (S)->__bufgetc_u) 238 #else 239 # define __STDIO_STREAM_DISABLE_GETC(S) ((void)0) 240 # define __STDIO_STREAM_ENABLE_GETC(S) ((void)0) 241 # define __STDIO_STREAM_CAN_USE_BUFFER_GET(S) (0) 242 #endif 243 244 #ifdef __UCLIBC_HAS_STDIO_PUTC_MACRO__ 245 # define __STDIO_STREAM_DISABLE_PUTC(S) \ 246 ((void)((S)->__bufputc_u = (S)->__bufstart)) 247 # define __STDIO_STREAM_ENABLE_PUTC(S) \ 248 ((void)((S)->__bufputc_u = (S)->__bufend)) 249 # define __STDIO_STREAM_CAN_USE_BUFFER_ADD(S) \ 250 ((S)->__bufpos < (S)->__bufputc_u) 251 #else 252 # define __STDIO_STREAM_DISABLE_PUTC(S) ((void)0) 253 # define __STDIO_STREAM_ENABLE_PUTC(S) ((void)0) 254 # define __STDIO_STREAM_CAN_USE_BUFFER_ADD(S) (0) 255 #endif 256 257 #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ 258 #define __STDIO_STREAM_IS_CUSTOM(S) ((S)->__cookie != &((S)->__filedes)) 259 #else 260 #define __STDIO_STREAM_IS_CUSTOM(S) (0) 261 #endif 262 263 /**********************************************************************/ 264 265 #ifdef __STDIO_BUFFERS 266 #define __STDIO_STREAM_FREE_BUFFER(S) \ 267 do { if ((S)->__modeflags & __FLAG_FREEBUF) \ 268 free((S)->__bufstart); } while (0) 269 #else 270 #define __STDIO_STREAM_FREE_BUFFER(S) ((void)0) 271 #endif 272 273 #define __STDIO_STREAM_FREE_FILE(S) \ 274 do { if ((S)->__modeflags & __FLAG_FREEFILE) \ 275 free((S)); } while (0) 276 277 278 #ifdef __UCLIBC_HAS_LFS__ 279 #define __STDIO_WHEN_LFS(E) E 280 #else 281 #define __STDIO_WHEN_LFS(E) ((void)0) 282 #endif 283 284 /**********************************************************************/ 285 /* The following return 0 on success. */ 286 287 #ifdef __STDIO_BUFFERS 288 /* Assume stream in valid writing state. Do not reset writing flag 289 * or disble putc macro unless error. */ 290 /* Should we assume that buffer is not empty to avoid a check? */ 291 extern size_t __stdio_wcommit(FILE *__restrict stream) attribute_hidden; 292 293 /* Remember to fail if at EOF! */ 294 extern size_t __stdio_rfill(FILE *__restrict stream) attribute_hidden; 295 296 extern size_t __stdio_fwrite(const unsigned char *__restrict buffer, 297 size_t bytes, FILE *__restrict stream) attribute_hidden; 298 #else 299 300 #define __stdio_fwrite(B,N,S) __stdio_WRITE((S),(B),(N)) 301 302 #endif 303 304 extern size_t __stdio_WRITE(FILE *stream, const unsigned char *buf, 305 size_t bufsize) attribute_hidden; 306 extern size_t __stdio_READ(FILE *stream, unsigned char *buf, 307 size_t bufsize) attribute_hidden; 308 309 extern int __stdio_trans2r(FILE *__restrict stream) attribute_hidden; 310 extern int __stdio_trans2w(FILE *__restrict stream) attribute_hidden; 311 312 extern int __stdio_trans2r_o(FILE *__restrict stream, int oflag) attribute_hidden; 313 extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidden; 314 315 extern uintmax_t _load_inttype(int desttype, register const void *src, int uflag) attribute_hidden; 316 extern void _store_inttype(void *dest, int desttype, uintmax_t val) attribute_hidden; 317 318 /**********************************************************************/ 319 #ifdef __STDIO_BUFFERS 320 321 #define __STDIO_STREAM_IS_FBF(S) (!((S)->__modeflags & __MASK_BUFMODE)) 322 #define __STDIO_STREAM_IS_LBF(S) ((S)->__modeflags & __FLAG_LBF) 323 #define __STDIO_STREAM_IS_NBF(S) ((S)->__modeflags & __FLAG_NBF) 324 325 #define __STDIO_STREAM_BUFFER_SIZE(S) ((S)->__bufend - (S)->__bufstart) 326 327 /* Valid when writing... */ 328 #define __STDIO_STREAM_BUFFER_ADD(S,C) (*(S)->__bufpos++ = (C)) 329 #define __STDIO_STREAM_BUFFER_UNADD(S) (--(S)->__bufpos) 330 #define __STDIO_STREAM_BUFFER_WAVAIL(S) ((S)->__bufend - (S)->__bufpos) 331 #define __STDIO_STREAM_BUFFER_WUSED(S) ((S)->__bufpos - (S)->__bufstart) 332 #define __STDIO_COMMIT_WRITE_BUFFER(S) __stdio_wcommit((S)) 333 #ifdef __UCLIBC_HAS_WCHAR__ 334 #define __STDIO_STREAM_IS_NARROW_FBF(S) \ 335 (!((S)->__modeflags & (__MASK_BUFMODE|__FLAG_WIDE))) 336 #else 337 #define __STDIO_STREAM_IS_NARROW_FBF(S) __STDIO_STREAM_IS_FBF((S)) 338 #endif 339 340 /* Valid when reading... */ 341 #define __STDIO_STREAM_BUFFER_RAVAIL(S) ((S)->__bufread - (S)->__bufpos) 342 #define __STDIO_STREAM_BUFFER_GET(S) (*(S)->__bufpos++) 343 #define __STDIO_FILL_READ_BUFFER(S) __stdio_rfill((S)) 344 345 #define __STDIO_STREAM_INIT_BUFREAD_BUFPOS(S) \ 346 (S)->__bufread = (S)->__bufpos = (S)->__bufstart 347 348 349 #define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES (-2) 350 #define __STDIO_STREAM_FAKE_VSSCANF_FILEDES (-2) 351 #define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES (-3) 352 #define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES (-3) 353 354 #define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S) \ 355 ((S)->__filedes == __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES) 356 #define __STDIO_STREAM_IS_FAKE_VSSCANF(S) \ 357 ((S)->__filedes == __STDIO_STREAM_FAKE_VSSCANF_FILEDES) 358 #define __STDIO_STREAM_IS_FAKE_VSWPRINTF(S) \ 359 ((S)->__filedes == __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES) 360 #define __STDIO_STREAM_IS_FAKE_VSWSCANF(S) \ 361 ((S)->__filedes == __STDIO_STREAM_FAKE_VSWSCANF_FILEDES) 362 363 #else /* __STDIO_BUFFERS */ 364 365 #define __STDIO_STREAM_IS_FBF(S) (0) 366 #define __STDIO_STREAM_IS_LBF(S) (0) 367 #define __STDIO_STREAM_IS_NBF(S) (1) 368 369 #define __STDIO_STREAM_BUFFER_SIZE(S) (0) 370 #define __STDIO_STREAM_BUFFER_ADD(S,C) ((void)0) 371 #define __STDIO_STREAM_BUFFER_UNADD(S) ((void)0) 372 #define __STDIO_STREAM_BUFFER_WAVAIL(S) (0) 373 #define __STDIO_STREAM_BUFFER_WUSED(S) (0) 374 #define __STDIO_COMMIT_WRITE_BUFFER(S) (0) 375 #define __STDIO_STREAM_IS_NARROW_FBF(S) (0) 376 377 #define __STDIO_STREAM_BUFFER_RAVAIL(S) (0) 378 #define __STDIO_STREAM_BUFFER_GET(S) (EOF) 379 #define __STDIO_FILL_READ_BUFFER(S) (0) 380 #define __STDIO_STREAM_INIT_BUFREAD_BUFPOS(S) ((void)0) 381 382 #undef __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES 383 #undef __STDIO_STREAM_FAKE_VSSCANF_FILEDES 384 #undef __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES 385 386 #define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S) (0) 387 #define __STDIO_STREAM_IS_FAKE_VSSCANF(S) (0) 388 #undef __STDIO_STREAM_IS_FAKE_VSWPRINTF 389 390 # ifdef __USE_OLD_VFPRINTF__ 391 # define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB (-2) 392 # define __STDIO_STREAM_IS_FAKE_VSNPRINTF_NB(S) \ 393 ((S)->__filedes == __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB) 394 # endif 395 396 # ifndef __UCLIBC_HAS_WCHAR__ 397 # define __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB (-2) 398 # define __STDIO_STREAM_IS_FAKE_VSSCANF_NB(S) \ 399 ((S)->__filedes == __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB) 400 # endif 401 402 #endif /* __STDIO_BUFFERS */ 403 /**********************************************************************/ 404 405 extern int __stdio_adjust_position(FILE *__restrict stream, __offmax_t *pos) attribute_hidden; 406 407 #ifdef __STDIO_HAS_OPENLIST 408 /* Uses an implementation hack!!! */ 409 #define __STDIO_FLUSH_LBF_STREAMS \ 410 fflush_unlocked((FILE *) &_stdio_openlist) 411 #else 412 #define __STDIO_FLUSH_LBF_STREAMS ((void)0) 413 #endif 414 415 #ifdef NDEBUG 416 #define __STDIO_STREAM_VALIDATE(S) ((void)0) 417 #else 418 extern void _stdio_validate_FILE(const FILE *stream) attribute_hidden; 419 #define __STDIO_STREAM_VALIDATE(S) _stdio_validate_FILE((S)) 420 #endif 421 422 #ifdef __STDIO_MBSTATE 423 #define __COPY_MBSTATE(dest,src) \ 424 ((void)((dest)->__mask = (src)->__mask, (dest)->__wc = (src)->__wc)) 425 #define __INIT_MBSTATE(dest) ((void)((dest)->__mask = 0)) 426 #else 427 #define __COPY_MBSTATE(dest,src) ((void)0) 428 #define __INIT_MBSTATE(dest) ((void)0) 429 #endif 430 431 /**********************************************************************/ 432 433 extern FILE *_stdio_fopen(intptr_t fname_or_mode, const char *__restrict mode, 434 FILE *__restrict stream, int filedes) attribute_hidden; 435 436 #ifdef __UCLIBC_HAS_WCHAR__ 437 extern size_t _wstdio_fwrite(const wchar_t *__restrict ws, 438 size_t n, FILE *__restrict stream) attribute_hidden; 439 #endif 440 441 /**********************************************************************/ 442 443 extern int _vfprintf_internal (FILE * __restrict stream, 444 const char * __restrict format, 445 va_list arg) attribute_hidden; 446 447 #ifdef __UCLIBC_HAS_WCHAR__ 448 extern int _vfwprintf_internal (FILE * __restrict stream, 449 const wchar_t * __restrict format, 450 va_list arg) attribute_hidden; 451 #endif 452 453 /**********************************************************************/ 454 /* Only use the macro below if you know fp is a valid FILE for a valid fd. 455 * This is _not_ true for custom streams! */ 456 #define __FILENO_UNLOCKED(fp) ((fp)->__filedes) 457 458 #define __FEOF_OR_FERROR_UNLOCKED(stream) \ 459 ((stream)->__modeflags & (__FLAG_EOF|__FLAG_ERROR)) 460 461 #if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__) 462 #define __STDIO_HAS_VSNPRINTF 1 463 #endif 464