/* Print formatted output to the stream FP. Return string length of formatted string. On error, return a negative value. */ int fprintf (FILE *fp, const char *format, ...) { char buf[2000]; char *output; size_t len; size_t lenbuf = sizeof (buf); va_list args; va_start (args, format); output = vasnprintf (buf, &lenbuf, format, args); len = lenbuf; va_end (args); if (!output) { fseterr (fp); return -1; } if (fwrite (output, 1, len, fp) < len) { if (output != buf) { int saved_errno = errno; free (output); errno = saved_errno; } return -1; } if (output != buf) free (output); if (len > INT_MAX) { errno = EOVERFLOW; fseterr (fp); return -1; } return len; }
int rpl_vfprintf( FILE *fp, char *format, va_list args ) { int eax; char buf[2000]; char *output; size_t len; size_t lenbuf = 2000; output = vasnprintf( buf, &lenbuf, format, args ); len = lenbuf; if ( output == 0 ) { fseterr( fp ); return -1; } else { if ( fwrite( output, 1, len, fp ) < len ) { if ( output != buf[0] ) { int saved_errno = *(int*)(__errno_location( )); free( output ); *(int*)(__errno_location( )) = saved_errno; } return -1; } else { if ( (int)len < 0 ) { *(int*)(__errno_location( )) = 75; fseterr( fp ); return -1; } else return (int)len; } } }
int main () { /* All streams are initially created with the error indicator cleared. */ if (ferror (stdout)) abort (); /* Verify that fseterr() works. */ fseterr (stdout); if (!ferror (stdout)) abort (); /* Verify fseterr's effect can be undone by clearerr(). */ clearerr (stdout); if (ferror (stdout)) abort (); return 0; }