diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 14:49:57 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 14:49:57 +0300 |
commit | 6a2caf2157d87b4b582b2494bdd7d6a688dd0b1f (patch) | |
tree | 9a2862cc11be4832f188cfbdce175120ceba5024 /missing_d/snprintf.c.save | |
parent | 315bd501ca696bc3e3c938b4604d8dac7a6f512f (diff) | |
download | egawk-6a2caf2157d87b4b582b2494bdd7d6a688dd0b1f.tar.gz egawk-6a2caf2157d87b4b582b2494bdd7d6a688dd0b1f.tar.bz2 egawk-6a2caf2157d87b4b582b2494bdd7d6a688dd0b1f.zip |
Move to gawk-3.1.6.
Diffstat (limited to 'missing_d/snprintf.c.save')
-rw-r--r-- | missing_d/snprintf.c.save | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/missing_d/snprintf.c.save b/missing_d/snprintf.c.save new file mode 100644 index 00000000..9f59e73e --- /dev/null +++ b/missing_d/snprintf.c.save @@ -0,0 +1,136 @@ +/* + * snprintf.c - Implement snprintf and vsnprintf on platforms that need them. + */ + +/* + * Copyright (C) 2006 the Free Software Foundation, Inc. + * + * This file is part of GAWK, the GNU implementation of the + * AWK Programming Language. + * + * GAWK is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GAWK is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +/* If using in a multi-threaded context, then SNPRINTF_REENTRANT must be + defined. But in that case, performance will be much worse, since a + temporary file is created and closed for each call to snprintf. */ + +#if defined(HAVE_MKSTEMP) +/* If mkstemp is available, use it instead of tmpfile(), since some older + implementations of tmpfile() were not secure. */ + +static FILE * +safe_tmpfile (void) +{ + static const char template[] = "/tmp/snprintfXXXXXX"; + FILE *f; + int fd; + char t[sizeof (template)]; + + strcpy (t, template); + if ((fd = mkstemp (t)) < 0) + return NULL; + unlink (t); + if ((f = fdopen (fd, "w+b")) == NULL) { + close (fd); + return NULL; + } + /* setvbuf(f,NULL,_IOFBF,4*BUFSIZ); */ + return f; +} + +#elif defined(HAVE_TMPFILE) +#define safe_tmpfile tmpfile +#else +#error Neither mkstemp() nor tmpfile() is available on this platform. +#endif + +int +vsnprintf (char *restrict buf, size_t len, + const char *restrict fmt, va_list args) +{ + int actual; + int nread; + size_t cnt = 0; +#ifndef SNPRINTF_REENTRANT + static +#endif + FILE *fp; + + if ((buf == NULL) || (len < 1)) + return -1; + + buf[0] = '\0'; /* in case the caller does not check the return code! */ + +#ifdef SNPRINTF_REENTRANT + if ((fp = safe_tmpfile ()) == NULL) + return -1; +#else + if ((fp == NULL) && ((fp = safe_tmpfile ()) == NULL)) + return -1; + rewind (fp); +#endif + actual = vfprintf (fp, fmt, args); + rewind (fp); + if (actual < 0) { +#ifdef SNPRINTF_REENTRANT + fclose (fp); +#endif + return -1; + } + else if ((size_t) actual < len) + len = actual; + else + --len; + while (cnt < len && (nread = fread (buf + cnt, 1, len - cnt, fp)) > 0) + cnt += nread; + buf[cnt] = '\0'; +#ifdef SNPRINTF_REENTRANT + fclose (fp); +#endif + if (cnt < len) + return -1; + + return actual; +} + +int +#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ +snprintf (char *restrict buf, size_t len, const char *restrict fmt, ...) +#else +snprintf (va_alist) + va_dcl +#endif +{ + int rv; + va_list args; + +#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ + va_start (args, fmt); +#else + char *buf; + size_t len; + char *fmt; + + va_start (args); + buf = va_arg (args, char *); + len = va_arg (args, size_t); + fmt = va_arg (args, char *); +#endif + rv = vsnprintf (buf, len, fmt, args); + va_end (args); + return rv; +} |