11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1990, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
5227753Stheraven * Copyright (c) 2011 The FreeBSD Foundation
6227753Stheraven * All rights reserved.
7227753Stheraven * Portions of this software were developed by David Chisnall
8227753Stheraven * under sponsorship from the FreeBSD Foundation.
9227753Stheraven *
101573Srgrimes * This code is derived from software contributed to Berkeley by
111573Srgrimes * Chris Torek.
121573Srgrimes *
131573Srgrimes * Redistribution and use in source and binary forms, with or without
141573Srgrimes * modification, are permitted provided that the following conditions
151573Srgrimes * are met:
161573Srgrimes * 1. Redistributions of source code must retain the above copyright
171573Srgrimes *    notice, this list of conditions and the following disclaimer.
181573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
191573Srgrimes *    notice, this list of conditions and the following disclaimer in the
201573Srgrimes *    documentation and/or other materials provided with the distribution.
21249808Semaste * 3. Neither the name of the University nor the names of its contributors
221573Srgrimes *    may be used to endorse or promote products derived from this software
231573Srgrimes *    without specific prior written permission.
241573Srgrimes *
251573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
261573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
271573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
281573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
291573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
301573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
311573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
321573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
331573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
341573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
351573Srgrimes * SUCH DAMAGE.
361573Srgrimes */
371573Srgrimes
381573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
391573Srgrimesstatic char sccsid[] = "@(#)snprintf.c	8.1 (Berkeley) 6/4/93";
401573Srgrimes#endif /* LIBC_SCCS and not lint */
4192986Sobrien#include <sys/cdefs.h>
4292986Sobrien__FBSDID("$FreeBSD$");
431573Srgrimes
44234531Sdas#include <errno.h>
4532168Sache#include <limits.h>
461573Srgrimes#include <stdio.h>
471573Srgrimes#include <stdarg.h>
48227753Stheraven#include "xlocale_private.h"
491573Srgrimes
5072373Sdeischen#include "local.h"
5172373Sdeischen
5213545Sjulianint
53103012Stjrsnprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
541573Srgrimes{
5532168Sache	size_t on;
561573Srgrimes	int ret;
571573Srgrimes	va_list ap;
58205021Sjhb	FILE f = FAKE_FILE;
591573Srgrimes
6031980Sache	on = n;
6132168Sache	if (n != 0)
6231980Sache		n--;
63234531Sdas	if (n > INT_MAX) {
64234531Sdas		errno = EOVERFLOW;
65234531Sdas		*str = '\0';
66234531Sdas		return (EOF);
67234531Sdas	}
681573Srgrimes	va_start(ap, fmt);
691573Srgrimes	f._flags = __SWR | __SSTR;
701573Srgrimes	f._bf._base = f._p = (unsigned char *)str;
7131966Sache	f._bf._size = f._w = n;
72227753Stheraven	ret = __vfprintf(&f, __get_locale(), fmt, ap);
7331980Sache	if (on > 0)
7431980Sache		*f._p = '\0';
751573Srgrimes	va_end(ap);
7631980Sache	return (ret);
771573Srgrimes}
78227753Stheravenint
79227753Stheravensnprintf_l(char * __restrict str, size_t n, locale_t locale,
80227753Stheraven		char const * __restrict fmt, ...)
81227753Stheraven{
82227753Stheraven	size_t on;
83227753Stheraven	int ret;
84227753Stheraven	va_list ap;
85227753Stheraven	FILE f = FAKE_FILE;
86227753Stheraven	FIX_LOCALE(locale);
87227753Stheraven
88227753Stheraven	on = n;
89227753Stheraven	if (n != 0)
90227753Stheraven		n--;
91234531Sdas	if (n > INT_MAX) {
92234531Sdas		errno = EOVERFLOW;
93234531Sdas		*str = '\0';
94234531Sdas		return (EOF);
95234531Sdas	}
96227753Stheraven	va_start(ap, fmt);
97227753Stheraven	f._flags = __SWR | __SSTR;
98227753Stheraven	f._bf._base = f._p = (unsigned char *)str;
99227753Stheraven	f._bf._size = f._w = n;
100227753Stheraven	ret = __vfprintf(&f, locale, fmt, ap);
101227753Stheraven	if (on > 0)
102227753Stheraven		*f._p = '\0';
103227753Stheraven	va_end(ap);
104227753Stheraven	return (ret);
105227753Stheraven}
106