ungetwc.c revision 227753
1240116Smarcel/*-
2240116Smarcel * Copyright (c) 2002-2004 Tim J. Robbins.
3240116Smarcel * All rights reserved.
4240116Smarcel *
5240116Smarcel * Copyright (c) 2011 The FreeBSD Foundation
6240116Smarcel * All rights reserved.
7240116Smarcel * Portions of this software were developed by David Chisnall
8240116Smarcel * under sponsorship from the FreeBSD Foundation.
9240116Smarcel *
10240116Smarcel * Redistribution and use in source and binary forms, with or without
11240116Smarcel * modification, are permitted provided that the following conditions
12240116Smarcel * are met:
13240116Smarcel * 1. Redistributions of source code must retain the above copyright
14240116Smarcel *    notice, this list of conditions and the following disclaimer.
15240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
16240116Smarcel *    notice, this list of conditions and the following disclaimer in the
17240116Smarcel *    documentation and/or other materials provided with the distribution.
18240116Smarcel *
19240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20240116Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21240116Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22240116Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23240116Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25240116Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26240116Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27240116Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28240116Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29240116Smarcel * SUCH DAMAGE.
30240116Smarcel */
31240116Smarcel
32240116Smarcel#include <sys/cdefs.h>
33240116Smarcel__FBSDID("$FreeBSD: head/lib/libc/stdio/ungetwc.c 227753 2011-11-20 14:45:42Z theraven $");
34240116Smarcel
35240116Smarcel#include "namespace.h"
36240116Smarcel#include <errno.h>
37240116Smarcel#include <limits.h>
38240116Smarcel#include <stdio.h>
39240116Smarcel#include <stdlib.h>
40240116Smarcel#include <wchar.h>
41240116Smarcel#include "un-namespace.h"
42240116Smarcel#include "libc_private.h"
43240116Smarcel#include "local.h"
44240116Smarcel#include "mblocal.h"
45240116Smarcel#include "xlocale_private.h"
46240116Smarcel
47240116Smarcel/*
48240116Smarcel * Non-MT-safe version.
49240116Smarcel */
50240116Smarcelwint_t
51240116Smarcel__ungetwc(wint_t wc, FILE *fp, locale_t locale)
52240116Smarcel{
53240116Smarcel	char buf[MB_LEN_MAX];
54240116Smarcel	size_t len;
55240116Smarcel	struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
56240116Smarcel
57240116Smarcel	if (wc == WEOF)
58240116Smarcel		return (WEOF);
59240116Smarcel	if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
60240116Smarcel		fp->_flags |= __SERR;
61240116Smarcel		return (WEOF);
62240116Smarcel	}
63240116Smarcel	while (len-- != 0)
64240116Smarcel		if (__ungetc((unsigned char)buf[len], fp) == EOF)
65240116Smarcel			return (WEOF);
66240116Smarcel
67240116Smarcel	return (wc);
68240116Smarcel}
69240116Smarcel
70240116Smarcel/*
71240116Smarcel * MT-safe version.
72240116Smarcel */
73240116Smarcelwint_t
74240116Smarcelungetwc_l(wint_t wc, FILE *fp, locale_t locale)
75240116Smarcel{
76240116Smarcel	wint_t r;
77240116Smarcel	FIX_LOCALE(locale);
78240116Smarcel
79240116Smarcel	FLOCKFILE(fp);
80240116Smarcel	ORIENT(fp, 1);
81240116Smarcel	r = __ungetwc(wc, fp, locale);
82240116Smarcel	FUNLOCKFILE(fp);
83240116Smarcel
84240116Smarcel	return (r);
85240116Smarcel}
86240116Smarcelwint_t
87240116Smarcelungetwc(wint_t wc, FILE *fp)
88240116Smarcel{
89240116Smarcel	return ungetwc_l(wc, fp, __get_locale());
90240116Smarcel}
91240116Smarcel