X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fsnprintf.c;h=db1ca9af1e7c2ab4e9f0a55073f5345dfe76084a;hb=74fcb0575a5b053a1b1078a5595c1795790c63cb;hp=6cc44aa91a9b6424ccb1d057f912b3eee2da843a;hpb=d6fa94ab159dbceb9291e431271f6733bbd586ce;p=gnulib.git diff --git a/lib/snprintf.c b/lib/snprintf.c index 6cc44aa91..db1ca9af1 100644 --- a/lib/snprintf.c +++ b/lib/snprintf.c @@ -1,6 +1,6 @@ /* 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 @@ -14,20 +14,24 @@ 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 -#endif +#include -/* Get specification. */ #include "snprintf.h" -/* Get vasnprintf. */ +#include +#include +#include +#include +#include + #include "vasnprintf.h" -/* Get MIN. */ -#include +/* 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 @@ -37,19 +41,36 @@ int snprintf (char *str, size_t size, const char *format, ...) { + char *output; size_t len; - char *out = vasnprintf (NULL, &len, format, args); + size_t lenbuf = size; + va_list args; + + va_start (args, format); + output = vasnprintf (str, &lenbuf, format, args); + len = lenbuf; + va_end (args); - if (!out) + if (!output) return -1; - if (str) + if (output != str) { - memcpy (str, out, 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 (out); + if (INT_MAX < len) + { + errno = EOVERFLOW; + return -1; + } return len; }