1 /* 2 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 #include "lint.h" 27 #include "mse_int.h" 28 #include "file64.h" 29 #include "mtlib.h" 30 #include <errno.h> 31 #include <limits.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <wchar.h> 35 #include "mblocal.h" 36 #include "stdiom.h" 37 38 static int 39 _fputws_impl(const wchar_t *_RESTRICT_KYWD ws, FILE *_RESTRICT_KYWD fp, 40 int orient) 41 { 42 int nchars; 43 int nwritten; 44 char buf[BUFSIZ]; 45 rmutex_t *lk; 46 47 /* 48 * The FreeBSD implementation here was a bit more complex, because 49 * it repeated much of what is in fputs. For simplicity's sake, we 50 * juse wctomb to convert the wide string to a mbs, and then use 51 * fputs to print the mbs. 52 */ 53 54 nchars = wcslen(ws); 55 nwritten = 0; 56 57 FLOCKFILE(lk, fp); 58 if (orient && GET_NO_MODE(fp)) 59 _setorientation(fp, _WC_MODE); 60 61 while (nchars > 0) { 62 int nbytes = 0; 63 char *ptr = buf; 64 while ((nbytes < (BUFSIZ - (MB_LEN_MAX * 2))) && nchars) { 65 int n; 66 if ((n = wctomb(ptr, *ws)) < 0) { 67 FUNLOCKFILE(lk); 68 fp->_flag |= _IOERR; 69 errno = EILSEQ; 70 return (EOF); 71 } 72 ws++; 73 ptr += n; 74 nbytes += n; 75 nchars--; 76 } 77 *ptr = '\0'; 78 if (fputs(buf, fp) < nbytes) { 79 FUNLOCKFILE(lk); 80 return (EOF); 81 } 82 nwritten += nbytes; 83 } 84 FUNLOCKFILE(lk); 85 return (nwritten); 86 } 87 88 int 89 fputws(const wchar_t *_RESTRICT_KYWD ws, FILE *_RESTRICT_KYWD fp) 90 { 91 return (_fputws_impl(ws, fp, 0)); 92 } 93 94 int 95 __fputws_xpg5(const wchar_t *ws, FILE *fp) 96 { 97 return (_fputws_impl(ws, fp, 1)); 98 } 99