Home | History | Annotate | Download | only in include
      1 /*	$OpenBSD: stdio.h,v 1.35 2006/01/13 18:10:09 miod Exp $	*/
      2 /*	$NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $	*/
      3 
      4 /*-
      5  * Copyright (c) 1990 The Regents of the University of California.
      6  * All rights reserved.
      7  *
      8  * This code is derived from software contributed to Berkeley by
      9  * Chris Torek.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  *
     35  *	@(#)stdio.h	5.17 (Berkeley) 6/3/91
     36  */
     37 
     38 #ifndef	_STDIO_H_
     39 #define	_STDIO_H_
     40 
     41 #include <sys/cdefs.h>
     42 #include <sys/types.h>
     43 
     44 #include <stdarg.h>
     45 #include <stddef.h>
     46 
     47 #define __need_NULL
     48 #include <stddef.h>
     49 
     50 #include <bits/seek_constants.h>
     51 
     52 #if __ANDROID_API__ < __ANDROID_API_N__
     53 #include <bits/struct_file.h>
     54 #endif
     55 
     56 __BEGIN_DECLS
     57 
     58 #if defined(__clang__)
     59 #pragma clang diagnostic push
     60 #pragma clang diagnostic ignored "-Wnullability-completeness"
     61 #endif
     62 
     63 typedef off_t fpos_t;
     64 typedef off64_t fpos64_t;
     65 
     66 struct __sFILE;
     67 typedef struct __sFILE FILE;
     68 
     69 #if __ANDROID_API__ >= __ANDROID_API_M__
     70 extern FILE* stdin __INTRODUCED_IN(23);
     71 extern FILE* stdout __INTRODUCED_IN(23);
     72 extern FILE* stderr __INTRODUCED_IN(23);
     73 
     74 /* C99 and earlier plus current C++ standards say these must be macros. */
     75 #define stdin stdin
     76 #define stdout stdout
     77 #define stderr stderr
     78 #else
     79 /* Before M the actual symbols for stdin and friends had different names. */
     80 extern FILE __sF[] __REMOVED_IN(23);
     81 
     82 #define stdin (&__sF[0])
     83 #define stdout (&__sF[1])
     84 #define stderr (&__sF[2])
     85 #endif
     86 
     87 /*
     88  * The following three definitions are for ANSI C, which took them
     89  * from System V, which brilliantly took internal interface macros and
     90  * made them official arguments to setvbuf(), without renaming them.
     91  * Hence, these ugly _IOxxx names are *supposed* to appear in user code.
     92  *
     93  * Although numbered as their counterparts above, the implementation
     94  * does not rely on this.
     95  */
     96 #define	_IOFBF	0		/* setvbuf should set fully buffered */
     97 #define	_IOLBF	1		/* setvbuf should set line buffered */
     98 #define	_IONBF	2		/* setvbuf should set unbuffered */
     99 
    100 #define	BUFSIZ	1024		/* size of buffer used by setbuf */
    101 #define	EOF	(-1)
    102 
    103 /*
    104  * FOPEN_MAX is a minimum maximum, and is the number of streams that
    105  * stdio can provide without attempting to allocate further resources
    106  * (which could fail).  Do not use this for anything.
    107  */
    108 
    109 #define	FOPEN_MAX	20	/* must be <= OPEN_MAX <sys/syslimits.h> */
    110 #define	FILENAME_MAX	1024	/* must be <= PATH_MAX <sys/syslimits.h> */
    111 
    112 #define	L_tmpnam	1024	/* XXX must be == PATH_MAX */
    113 #define	TMP_MAX		308915776
    114 
    115 /*
    116  * Functions defined in ANSI C standard.
    117  */
    118 void	 clearerr(FILE *);
    119 int	 fclose(FILE *);
    120 int	 feof(FILE *);
    121 int	 ferror(FILE *);
    122 int	 fflush(FILE *);
    123 int	 fgetc(FILE *);
    124 char	*fgets(char * __restrict, int, FILE * __restrict) __overloadable
    125   __RENAME_CLANG(fgets);
    126 int	 fprintf(FILE * __restrict , const char * __restrict _Nonnull, ...) __printflike(2, 3);
    127 int	 fputc(int, FILE *);
    128 int	 fputs(const char * __restrict, FILE * __restrict);
    129 size_t	 fread(void * __restrict, size_t, size_t, FILE * __restrict)
    130       __overloadable __RENAME_CLANG(fread);
    131 int	 fscanf(FILE * __restrict, const char * __restrict _Nonnull, ...) __scanflike(2, 3);
    132 size_t	 fwrite(const void * __restrict, size_t, size_t, FILE * __restrict)
    133     __overloadable __RENAME_CLANG(fwrite);
    134 int	 getc(FILE *);
    135 int	 getchar(void);
    136 ssize_t getdelim(char** __restrict, size_t* __restrict, int, FILE* __restrict) __INTRODUCED_IN(18);
    137 ssize_t getline(char** __restrict, size_t* __restrict, FILE* __restrict) __INTRODUCED_IN(18);
    138 
    139 void	 perror(const char *);
    140 int	 printf(const char * __restrict _Nonnull, ...) __printflike(1, 2);
    141 int	 putc(int, FILE *);
    142 int	 putchar(int);
    143 int	 puts(const char *);
    144 int	 remove(const char *);
    145 void	 rewind(FILE *);
    146 int	 scanf(const char * __restrict _Nonnull, ...) __scanflike(1, 2);
    147 void	 setbuf(FILE * __restrict, char * __restrict);
    148 int	 setvbuf(FILE * __restrict, char * __restrict, int, size_t);
    149 int	 sscanf(const char * __restrict, const char * __restrict _Nonnull, ...) __scanflike(2, 3);
    150 int	 ungetc(int, FILE *);
    151 int	 vfprintf(FILE * __restrict, const char * __restrict _Nonnull, __va_list) __printflike(2, 0);
    152 int	 vprintf(const char * __restrict _Nonnull, __va_list) __printflike(1, 0);
    153 
    154 int dprintf(int, const char* __restrict _Nonnull, ...) __printflike(2, 3) __INTRODUCED_IN(21);
    155 int vdprintf(int, const char* __restrict _Nonnull, __va_list) __printflike(2, 0) __INTRODUCED_IN(21);
    156 
    157 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 201112L) || \
    158     (defined(__cplusplus) && __cplusplus <= 201103L)
    159 char* gets(char*) __attribute__((deprecated("gets is unsafe, use fgets instead")));
    160 #endif
    161 int sprintf(char* __restrict, const char* __restrict _Nonnull, ...)
    162     __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf")
    163     __overloadable __RENAME_CLANG(sprintf);
    164 int vsprintf(char* __restrict, const char* __restrict _Nonnull, __va_list)
    165     __overloadable __printflike(2, 0) __RENAME_CLANG(vsprintf)
    166     __warnattr_strict("vsprintf is often misused; please use vsnprintf");
    167 char* tmpnam(char*)
    168     __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
    169 #define P_tmpdir "/tmp/" /* deprecated */
    170 char* tempnam(const char*, const char*)
    171     __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
    172 
    173 int rename(const char*, const char*);
    174 int renameat(int, const char*, int, const char*);
    175 
    176 int fseek(FILE*, long, int);
    177 long ftell(FILE*);
    178 
    179 #if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_N__
    180 int fgetpos(FILE*, fpos_t*) __RENAME(fgetpos64);
    181 int fsetpos(FILE*, const fpos_t*) __RENAME(fsetpos64);
    182 int fseeko(FILE*, off_t, int) __RENAME(fseeko64);
    183 off_t ftello(FILE*) __RENAME(ftello64);
    184 #  if defined(__USE_BSD)
    185 FILE* funopen(const void*,
    186               int (*)(void*, char*, int),
    187               int (*)(void*, const char*, int),
    188               fpos_t (*)(void*, fpos_t, int),
    189               int (*)(void*)) __RENAME(funopen64);
    190 #  endif
    191 #else
    192 int fgetpos(FILE*, fpos_t*);
    193 int fsetpos(FILE*, const fpos_t*);
    194 int fseeko(FILE*, off_t, int);
    195 off_t ftello(FILE*);
    196 #  if defined(__USE_BSD)
    197 FILE* funopen(const void*,
    198               int (*)(void*, char*, int),
    199               int (*)(void*, const char*, int),
    200               fpos_t (*)(void*, fpos_t, int),
    201               int (*)(void*));
    202 #  endif
    203 #endif
    204 int fgetpos64(FILE*, fpos64_t*) __INTRODUCED_IN(24);
    205 int fsetpos64(FILE*, const fpos64_t*) __INTRODUCED_IN(24);
    206 int fseeko64(FILE*, off64_t, int) __INTRODUCED_IN(24);
    207 off64_t ftello64(FILE*) __INTRODUCED_IN(24);
    208 #if defined(__USE_BSD)
    209 FILE* funopen64(const void*, int (*)(void*, char*, int), int (*)(void*, const char*, int),
    210                 fpos64_t (*)(void*, fpos64_t, int), int (*)(void*)) __INTRODUCED_IN(24);
    211 #endif
    212 
    213 FILE* fopen(const char* __restrict, const char* __restrict);
    214 FILE* fopen64(const char* __restrict, const char* __restrict) __INTRODUCED_IN(24);
    215 FILE* freopen(const char* __restrict, const char* __restrict, FILE* __restrict);
    216 FILE* freopen64(const char* __restrict, const char* __restrict, FILE* __restrict)
    217   __INTRODUCED_IN(24);
    218 FILE* tmpfile(void);
    219 FILE* tmpfile64(void) __INTRODUCED_IN(24);
    220 
    221 int snprintf(char* __restrict, size_t, const char* __restrict _Nonnull, ...)
    222     __printflike(3, 4) __overloadable __RENAME_CLANG(snprintf);
    223 int vfscanf(FILE* __restrict, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0);
    224 int vscanf(const char* _Nonnull , __va_list) __scanflike(1, 0);
    225 int vsnprintf(char* __restrict, size_t, const char* __restrict _Nonnull, __va_list)
    226     __printflike(3, 0) __overloadable __RENAME_CLANG(vsnprintf);
    227 int vsscanf(const char* __restrict _Nonnull, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0);
    228 
    229 #define L_ctermid 1024 /* size for ctermid() */
    230 char* ctermid(char*) __INTRODUCED_IN(26);
    231 
    232 FILE* fdopen(int, const char*);
    233 int fileno(FILE*);
    234 int pclose(FILE*);
    235 FILE* popen(const char*, const char*);
    236 void flockfile(FILE*);
    237 int ftrylockfile(FILE*);
    238 void funlockfile(FILE*);
    239 int getc_unlocked(FILE*);
    240 int getchar_unlocked(void);
    241 int putc_unlocked(int, FILE*);
    242 int putchar_unlocked(int);
    243 
    244 FILE* fmemopen(void*, size_t, const char*) __INTRODUCED_IN(23);
    245 FILE* open_memstream(char**, size_t*) __INTRODUCED_IN(23);
    246 
    247 #if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
    248 int  asprintf(char** __restrict, const char* __restrict _Nonnull, ...) __printflike(2, 3);
    249 char* fgetln(FILE* __restrict, size_t* __restrict);
    250 int fpurge(FILE*);
    251 void setbuffer(FILE*, char*, int);
    252 int setlinebuf(FILE*);
    253 int vasprintf(char** __restrict, const char* __restrict _Nonnull, __va_list) __printflike(2, 0);
    254 void clearerr_unlocked(FILE*) __INTRODUCED_IN(23);
    255 int feof_unlocked(FILE*) __INTRODUCED_IN(23);
    256 int ferror_unlocked(FILE*) __INTRODUCED_IN(23);
    257 int fileno_unlocked(FILE*) __INTRODUCED_IN(24);
    258 #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
    259 #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
    260 #endif /* __USE_BSD */
    261 
    262 char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
    263 size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t)
    264     __INTRODUCED_IN(24);
    265 size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
    266     __INTRODUCED_IN(24);
    267 
    268 #if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
    269 
    270 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
    271 __BIONIC_FORTIFY_INLINE __printflike(3, 0)
    272 int vsnprintf(char *const __pass_object_size dest, size_t size,
    273               const char *_Nonnull format, __va_list ap) __overloadable {
    274     return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
    275 }
    276 
    277 __BIONIC_FORTIFY_INLINE __printflike(2, 0)
    278 int vsprintf(char *const __pass_object_size dest, const char *_Nonnull format,
    279              __va_list ap) __overloadable {
    280     return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
    281 }
    282 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
    283 
    284 #if defined(__clang__)
    285 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
    286 /*
    287  * Simple case: `format` can't have format specifiers, so we can just compare
    288  * its length to the length of `dest`
    289  */
    290 __BIONIC_ERROR_FUNCTION_VISIBILITY
    291 int snprintf(char *__restrict dest, size_t size, const char *__restrict format)
    292     __overloadable
    293     __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
    294                 __bos(dest) < __builtin_strlen(format),
    295                 "format string will always overflow destination buffer")
    296     __errorattr("format string will always overflow destination buffer");
    297 
    298 __BIONIC_FORTIFY_INLINE
    299 __printflike(3, 4)
    300 int snprintf(char *__restrict const __pass_object_size dest,
    301              size_t size, const char *__restrict format, ...) __overloadable {
    302     va_list va;
    303     va_start(va, format);
    304     int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
    305     va_end(va);
    306     return result;
    307 }
    308 
    309 __BIONIC_ERROR_FUNCTION_VISIBILITY
    310 int sprintf(char *__restrict dest, const char *__restrict format) __overloadable
    311     __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
    312                 __bos(dest) < __builtin_strlen(format),
    313                 "format string will always overflow destination buffer")
    314     __errorattr("format string will always overflow destination buffer");
    315 
    316 __BIONIC_FORTIFY_INLINE
    317 __printflike(2, 3)
    318 int sprintf(char *__restrict const __pass_object_size dest,
    319         const char *__restrict format, ...) __overloadable {
    320     va_list va;
    321     va_start(va, format);
    322     int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
    323     va_end(va);
    324     return result;
    325 }
    326 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
    327 
    328 #if __ANDROID_API__ >= __ANDROID_API_N__
    329 __BIONIC_FORTIFY_INLINE
    330 size_t fread(void *__restrict buf, size_t size, size_t count,
    331              FILE *__restrict stream) __overloadable
    332         __enable_if(__unsafe_check_mul_overflow(size, count), "size * count overflows")
    333         __errorattr("size * count overflows");
    334 
    335 __BIONIC_FORTIFY_INLINE
    336 size_t fread(void *__restrict buf, size_t size, size_t count,
    337              FILE *__restrict stream) __overloadable
    338     __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
    339     __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
    340                 size * count > __bos(buf), "size * count is too large")
    341     __errorattr("size * count is too large");
    342 
    343 __BIONIC_FORTIFY_INLINE
    344 size_t fread(void *__restrict const __pass_object_size0 buf, size_t size,
    345              size_t count, FILE *__restrict stream) __overloadable {
    346     size_t bos = __bos0(buf);
    347 
    348     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    349         return __call_bypassing_fortify(fread)(buf, size, count, stream);
    350     }
    351 
    352     return __fread_chk(buf, size, count, stream, bos);
    353 }
    354 
    355 size_t fwrite(const void * __restrict buf, size_t size,
    356               size_t count, FILE * __restrict stream) __overloadable
    357     __enable_if(__unsafe_check_mul_overflow(size, count),
    358                 "size * count overflows")
    359     __errorattr("size * count overflows");
    360 
    361 size_t fwrite(const void * __restrict buf, size_t size,
    362               size_t count, FILE * __restrict stream) __overloadable
    363     __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
    364     __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
    365                 size * count > __bos(buf), "size * count is too large")
    366     __errorattr("size * count is too large");
    367 
    368 __BIONIC_FORTIFY_INLINE
    369 size_t fwrite(const void * __restrict const __pass_object_size0 buf,
    370               size_t size, size_t count, FILE * __restrict stream)
    371         __overloadable {
    372     size_t bos = __bos0(buf);
    373 
    374     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    375         return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
    376     }
    377 
    378     return __fwrite_chk(buf, size, count, stream, bos);
    379 }
    380 #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
    381 
    382 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
    383 __BIONIC_ERROR_FUNCTION_VISIBILITY
    384 char *fgets(char* __restrict dest, int size, FILE* stream) __overloadable
    385     __enable_if(size < 0, "size is negative")
    386     __errorattr("size is negative");
    387 
    388 __BIONIC_ERROR_FUNCTION_VISIBILITY
    389 char *fgets(char* dest, int size, FILE* stream) __overloadable
    390     __enable_if(size >= 0 && size > __bos(dest),
    391                 "size is larger than the destination buffer")
    392     __errorattr("size is larger than the destination buffer");
    393 
    394 __BIONIC_FORTIFY_INLINE
    395 char *fgets(char* __restrict const __pass_object_size dest,
    396         int size, FILE* stream) __overloadable {
    397     size_t bos = __bos(dest);
    398 
    399     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    400         return __call_bypassing_fortify(fgets)(dest, size, stream);
    401     }
    402 
    403     return __fgets_chk(dest, size, stream, bos);
    404 }
    405 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
    406 
    407 #else /* defined(__clang__) */
    408 
    409 size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);
    410 __errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
    411 __errordecl(__fread_overflow, "fread called with overflowing size * count");
    412 
    413 char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
    414 __errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
    415 __errordecl(__fgets_too_small_error, "fgets called with size less than zero");
    416 
    417 size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);
    418 __errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
    419 __errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
    420 
    421 
    422 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
    423 __BIONIC_FORTIFY_INLINE __printflike(3, 4)
    424 int snprintf(char *__restrict dest, size_t size, const char* _Nonnull format, ...)
    425 {
    426     return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format,
    427                                     __builtin_va_arg_pack());
    428 }
    429 
    430 __BIONIC_FORTIFY_INLINE __printflike(2, 3)
    431 int sprintf(char *__restrict dest, const char* _Nonnull format, ...) {
    432     return __builtin___sprintf_chk(dest, 0, __bos(dest), format,
    433                                    __builtin_va_arg_pack());
    434 }
    435 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
    436 
    437 #if __ANDROID_API__ >= __ANDROID_API_N__
    438 __BIONIC_FORTIFY_INLINE
    439 size_t fread(void *__restrict buf, size_t size, size_t count, FILE * __restrict stream) {
    440     size_t bos = __bos0(buf);
    441 
    442     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    443         return __fread_real(buf, size, count, stream);
    444     }
    445 
    446     if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
    447         size_t total;
    448         if (__size_mul_overflow(size, count, &total)) {
    449             __fread_overflow();
    450         }
    451 
    452         if (total > bos) {
    453             __fread_too_big_error();
    454         }
    455 
    456         return __fread_real(buf, size, count, stream);
    457     }
    458 
    459     return __fread_chk(buf, size, count, stream, bos);
    460 }
    461 
    462 __BIONIC_FORTIFY_INLINE
    463 size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
    464     size_t bos = __bos0(buf);
    465 
    466     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    467         return __fwrite_real(buf, size, count, stream);
    468     }
    469 
    470     if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
    471         size_t total;
    472         if (__size_mul_overflow(size, count, &total)) {
    473             __fwrite_overflow();
    474         }
    475 
    476         if (total > bos) {
    477             __fwrite_too_big_error();
    478         }
    479 
    480         return __fwrite_real(buf, size, count, stream);
    481     }
    482 
    483     return __fwrite_chk(buf, size, count, stream, bos);
    484 }
    485 #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
    486 
    487 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
    488 __BIONIC_FORTIFY_INLINE
    489 char *fgets(char* dest, int size, FILE* stream) {
    490     size_t bos = __bos(dest);
    491 
    492     // Compiler can prove, at compile time, that the passed in size
    493     // is always negative. Force a compiler error.
    494     if (__builtin_constant_p(size) && (size < 0)) {
    495         __fgets_too_small_error();
    496     }
    497 
    498     // Compiler doesn't know destination size. Don't call __fgets_chk
    499     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    500         return __fgets_real(dest, size, stream);
    501     }
    502 
    503     // Compiler can prove, at compile time, that the passed in size
    504     // is always <= the actual object size. Don't call __fgets_chk
    505     if (__builtin_constant_p(size) && (size <= (int) bos)) {
    506         return __fgets_real(dest, size, stream);
    507     }
    508 
    509     // Compiler can prove, at compile time, that the passed in size
    510     // is always > the actual object size. Force a compiler error.
    511     if (__builtin_constant_p(size) && (size > (int) bos)) {
    512         __fgets_too_big_error();
    513     }
    514 
    515     return __fgets_chk(dest, size, stream, bos);
    516 }
    517 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
    518 
    519 #endif /* defined(__clang__) */
    520 #endif /* defined(__BIONIC_FORTIFY) */
    521 
    522 #if defined(__clang__)
    523 #pragma clang diagnostic pop
    524 #endif
    525 
    526 __END_DECLS
    527 
    528 #endif /* _STDIO_H_ */
    529