/* Formatted output to strings.
- Copyright (C) 2004 Free Software Foundation, Inc.
- Written by Simon Josefsson.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+ Written by Simon Josefsson and Paul Eggert.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
-/* Specification. */
#include "snprintf.h"
-/* Get va_list, va_start, va_end. */
+#include <errno.h>
+#include <limits.h>
#include <stdarg.h>
-/* Get free. */
#include <stdlib.h>
-/* Get memcpy, size_t. */
#include <string.h>
-/* Get vasnprintf. */
#include "vasnprintf.h"
-/* Get MIN. */
-#include "minmax.h"
+/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
+#ifndef EOVERFLOW
+# define EOVERFLOW E2BIG
+#endif
/* Print formatted output to string STR. Similar to sprintf, but
additional length SIZE limit how much is written into STR. Returns
{
char *output;
size_t len;
+ size_t lenbuf = size;
va_list args;
va_start (args, format);
- output = vasnprintf (NULL, &len, format, args);
+ output = vasnprintf (str, &lenbuf, format, args);
+ len = lenbuf;
va_end (args);
if (!output)
return -1;
- if (str)
+ if (output != str)
{
- memcpy (str, output, MIN (len + 1, size));
- str[size - 1] = '\0';
+ if (size)
+ {
+ size_t pruned_len = (len < size ? len : size - 1);
+ memcpy (str, output, pruned_len);
+ str[pruned_len] = '\0';
+ }
+
+ free (output);
}
- free (output);
+ if (INT_MAX < len)
+ {
+ errno = EOVERFLOW;
+ return -1;
+ }
return len;
}