#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: vsnprintf.c,v 1.29 2017/01/12 18:16:52 christos Exp $");
#endif
#endif
#include "namespace.h"
#include <assert.h>
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include "reentrant.h"
#include "setlocale_local.h"
#include "local.h"
#if __SSP_FORTIFY_LEVEL != 0
# undef vsnprintf
# define vsnprintf _vsnprintf
# undef snprintf
# define snprintf _snprintf
int snprintf(char * __restrict, size_t, const char * __restrict, ...)
__printflike(3, 4);
int vsnprintf(char * __restrict, size_t, const char * __restrict,
__va_list) __printflike(3, 0);
#endif
#ifdef __weak_alias
__weak_alias(vsnprintf,_vsnprintf)
__weak_alias(vsnprintf_l,_vsnprintf_l)
__weak_alias(snprintf,_snprintf)
__weak_alias(snprintf_l,_snprintf_l)
#endif
int
vsnprintf_l(char *str, size_t n, locale_t loc, const char *fmt, va_list ap)
{
int ret;
FILE f;
struct __sfileext fext;
unsigned char dummy[1];
_DIAGASSERT(n == 0 || str != NULL);
_DIAGASSERT(fmt != NULL);
if (n > INT_MAX) {
errno = EOVERFLOW;
return -1;
}
_FILEEXT_SETUP(&f, &fext);
f._file = -1;
f._flags = __SWR | __SSTR;
if (n == 0) {
f._bf._base = f._p = dummy;
f._bf._size = f._w = 0;
} else {
f._bf._base = f._p = (unsigned char *)str;
_DIAGASSERT(__type_fit(int, n - 1));
f._bf._size = f._w = (int)(n - 1);
}
ret = __vfprintf_unlocked_l(&f, loc, fmt, ap);
*f._p = 0;
return ret;
}
int
vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
{
return vsnprintf_l(str, n, _current_locale(), fmt, ap);
}
int
snprintf(char *str, size_t n, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = vsnprintf(str, n, fmt, ap);
va_end(ap);
return ret;
}
int
snprintf_l(char *str, size_t n, locale_t loc, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = vsnprintf_l(str, n, loc, fmt, ap);
va_end(ap);
return ret;
}