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