1/* Formatted output to a stream.
2   Copyright (C) 2004, 2006-2012 Free Software Foundation, Inc.
3
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 3 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17#if 1
18# include <config.h>
19#endif
20
21/* Specification.  */
22#include <stdio.h>
23
24#include <errno.h>
25#include <limits.h>
26#include <stdarg.h>
27#include <stdlib.h>
28
29#include "fseterr.h"
30#include "vasnprintf.h"
31
32/* Print formatted output to the stream FP.
33   Return string length of formatted string.  On error, return a negative
34   value.  */
35int
36fprintf (FILE *fp, const char *format, ...)
37{
38  char buf[2000];
39  char *output;
40  size_t len;
41  size_t lenbuf = sizeof (buf);
42  va_list args;
43
44  va_start (args, format);
45  output = vasnprintf (buf, &lenbuf, format, args);
46  len = lenbuf;
47  va_end (args);
48
49  if (!output)
50    {
51      fseterr (fp);
52      return -1;
53    }
54
55  if (fwrite (output, 1, len, fp) < len)
56    {
57      if (output != buf)
58        {
59          int saved_errno = errno;
60          free (output);
61          errno = saved_errno;
62        }
63      return -1;
64    }
65
66  if (output != buf)
67    free (output);
68
69  if (len > INT_MAX)
70    {
71      errno = EOVERFLOW;
72      fseterr (fp);
73      return -1;
74    }
75
76  return len;
77}
78