2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/* Copyright (c) 1986 AT&T */
2N/A/* All Rights Reserved */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * fputws transforms the process code string pointed to by "ptr"
2N/A * into a byte string, and writes the string to the named
2N/A * output "iop".
2N/A *
2N/A * Use an intermediate buffer to transform a string from wchar_t to
2N/A * multibyte char. In order to not overflow the intermediate buffer,
2N/A * impose a limit on the length of string to output to PC_MAX process
2N/A * codes. If the input string exceeds PC_MAX process codes, process
2N/A * the string in a series of smaller buffers.
2N/A */
2N/A
2N/A#include "lint.h"
2N/A#include "file64.h"
2N/A#include "mse_int.h"
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <limits.h>
2N/A#include <widec.h>
2N/A#include <macros.h>
2N/A#include <errno.h>
2N/A#include "libc.h"
2N/A#include "stdiom.h"
2N/A#include "mse.h"
2N/A
2N/A#define PC_MAX 256
2N/A#define MBBUFLEN (PC_MAX * MB_LEN_MAX)
2N/A
2N/Aint
2N/A__fputws_xpg5(const wchar_t *ptr, FILE *iop)
2N/A{
2N/A int pcsize, ret;
2N/A ssize_t pclen, pccnt;
2N/A int nbytes, i;
2N/A char mbbuf[MBBUFLEN], *mp;
2N/A void *lc;
2N/A int (*fp_wctomb)(void *, char *, wchar_t);
2N/A rmutex_t *lk;
2N/A
2N/A FLOCKFILE(lk, iop);
2N/A
2N/A if (_set_orientation_wide(iop, &lc,
2N/A (void (*(*))(void))&fp_wctomb, FP_WCTOMB) == -1) {
2N/A errno = EBADF;
2N/A FUNLOCKFILE(lk);
2N/A return (EOF);
2N/A }
2N/A
2N/A pclen = pccnt = wcslen(ptr);
2N/A while (pclen > 0) {
2N/A pcsize = (int)min(pclen, PC_MAX - 1);
2N/A nbytes = 0;
2N/A for (i = 0, mp = mbbuf; i < pcsize; i++, mp += ret) {
2N/A if ((ret = fp_wctomb(lc, mp, *ptr++)) == -1) {
2N/A FUNLOCKFILE(lk);
2N/A return (EOF);
2N/A }
2N/A nbytes += ret;
2N/A }
2N/A *mp = '\0';
2N/A /*
2N/A * In terms of locking, since libc is using rmutex_t
2N/A * for locking iop, we can call fputs() with iop that
2N/A * has been already locked.
2N/A * But again,
2N/A * can wide I/O functions call byte I/O functions
2N/A * because a steam bound to WIDE should not be used
2N/A * by byte I/O functions ?
2N/A */
2N/A if (fputs(mbbuf, iop) != nbytes) {
2N/A FUNLOCKFILE(lk);
2N/A return (EOF);
2N/A }
2N/A pclen -= pcsize;
2N/A }
2N/A FUNLOCKFILE(lk);
2N/A if (pccnt <= INT_MAX)
2N/A return ((int)pccnt);
2N/A else
2N/A return (EOF);
2N/A}