fputwc.c revision 321074
1178476Sjb/*-
2178476Sjb * Copyright (c) 2002-2004 Tim J. Robbins.
3178476Sjb * All rights reserved.
4178476Sjb *
5178476Sjb * Copyright (c) 2011 The FreeBSD Foundation
6178476Sjb * All rights reserved.
7178476Sjb * Portions of this software were developed by David Chisnall
8178476Sjb * under sponsorship from the FreeBSD Foundation.
9178476Sjb *
10178476Sjb * Redistribution and use in source and binary forms, with or without
11178476Sjb * modification, are permitted provided that the following conditions
12178476Sjb * are met:
13178476Sjb * 1. Redistributions of source code must retain the above copyright
14178476Sjb *    notice, this list of conditions and the following disclaimer.
15178476Sjb * 2. Redistributions in binary form must reproduce the above copyright
16178476Sjb *    notice, this list of conditions and the following disclaimer in the
17178476Sjb *    documentation and/or other materials provided with the distribution.
18178476Sjb *
19178476Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20178476Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21178476Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22178476Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23178476Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24178476Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25178476Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26178476Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27178476Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28178476Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29178476Sjb * SUCH DAMAGE.
30178476Sjb */
31178476Sjb
32178476Sjb#include <sys/cdefs.h>
33178476Sjb__FBSDID("$FreeBSD: stable/10/lib/libc/stdio/fputwc.c 321074 2017-07-17 14:09:34Z kib $");
34178476Sjb
35178476Sjb#include "namespace.h"
36178476Sjb#include <errno.h>
37178476Sjb#include <limits.h>
38178476Sjb#include <stdio.h>
39178476Sjb#include <stdlib.h>
40178476Sjb#include <wchar.h>
41178476Sjb#include "un-namespace.h"
42178476Sjb#include "libc_private.h"
43178476Sjb#include "local.h"
44178476Sjb#include "mblocal.h"
45178476Sjb
46178476Sjb/*
47178476Sjb * Non-MT-safe version.
48178476Sjb */
49178476Sjbwint_t
50178476Sjb__fputwc(wchar_t wc, FILE *fp, locale_t locale)
51178476Sjb{
52178476Sjb	char buf[MB_LEN_MAX];
53178476Sjb	size_t i, len;
54178476Sjb	struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
55178476Sjb
56178476Sjb	if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
57178476Sjb		fp->_flags |= __SERR;
58178476Sjb		return (WEOF);
59178476Sjb	}
60178476Sjb
61178476Sjb	for (i = 0; i < len; i++)
62178476Sjb		if (__sputc((unsigned char)buf[i], fp) == EOF)
63178476Sjb			return (WEOF);
64178476Sjb
65178476Sjb	return ((wint_t)wc);
66178476Sjb}
67178476Sjb
68178476Sjb/*
69178476Sjb * MT-safe version.
70178476Sjb */
71178476Sjbwint_t
72178476Sjbfputwc_l(wchar_t wc, FILE *fp, locale_t locale)
73178476Sjb{
74178476Sjb	wint_t r;
75178476Sjb	FIX_LOCALE(locale);
76178476Sjb
77178476Sjb	FLOCKFILE_CANCELSAFE(fp);
78178476Sjb	ORIENT(fp, 1);
79178476Sjb	r = __fputwc(wc, fp, locale);
80178476Sjb	FUNLOCKFILE_CANCELSAFE();
81178476Sjb
82178476Sjb	return (r);
83178476Sjb}
84178476Sjbwint_t
85211545Srpaulofputwc(wchar_t wc, FILE *fp)
86178476Sjb{
87	return fputwc_l(wc, fp, __get_locale());
88}
89