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