10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*6812Sraf * Common Development and Distribution License (the "License").
6*6812Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*6812Sraf
220Sstevel@tonic-gate /*
23*6812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
29*6812Sraf #include "lint.h"
300Sstevel@tonic-gate #include "mtlib.h"
310Sstevel@tonic-gate #include "mbstatet.h"
320Sstevel@tonic-gate #include "file64.h"
330Sstevel@tonic-gate #include <sys/types.h>
340Sstevel@tonic-gate #include <stdio.h>
350Sstevel@tonic-gate #include <wchar.h>
360Sstevel@tonic-gate #include <thread.h>
370Sstevel@tonic-gate #include <synch.h>
380Sstevel@tonic-gate #include <stdlib.h>
390Sstevel@tonic-gate #include <string.h>
400Sstevel@tonic-gate #include "libc.h"
410Sstevel@tonic-gate #include "stdiom.h"
420Sstevel@tonic-gate #include "mse.h"
430Sstevel@tonic-gate
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate * DESCRIPTION:
460Sstevel@tonic-gate * This function sets the error indicator for the specified stream.
470Sstevel@tonic-gate * This is a private API for the L10N method functions, especially
480Sstevel@tonic-gate * for fgetwc().
490Sstevel@tonic-gate *
500Sstevel@tonic-gate * The stream needs to have been properly locked. Usually, the wrapper
510Sstevel@tonic-gate * function of fgetwc() locks the stream.
520Sstevel@tonic-gate */
530Sstevel@tonic-gate void
__fseterror_u(FILE * iop)540Sstevel@tonic-gate __fseterror_u(FILE *iop)
550Sstevel@tonic-gate {
560Sstevel@tonic-gate iop->_flag |= _IOERR;
570Sstevel@tonic-gate }
580Sstevel@tonic-gate
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate * DESCRIPTION:
610Sstevel@tonic-gate * This function/macro gets the orientation bound to the specified iop.
620Sstevel@tonic-gate *
630Sstevel@tonic-gate * RETURNS:
640Sstevel@tonic-gate * _WC_MODE if iop has been bound to Wide orientation
650Sstevel@tonic-gate * _BYTE_MODE if iop has been bound to Byte orientation
660Sstevel@tonic-gate * _NO_MODE if iop has been bound to neither Wide nor Byte
670Sstevel@tonic-gate */
680Sstevel@tonic-gate _IOP_orientation_t
_getorientation(FILE * iop)690Sstevel@tonic-gate _getorientation(FILE *iop)
700Sstevel@tonic-gate {
710Sstevel@tonic-gate if (GET_BYTE_MODE(iop))
720Sstevel@tonic-gate return (_BYTE_MODE);
730Sstevel@tonic-gate else if (GET_WC_MODE(iop))
740Sstevel@tonic-gate return (_WC_MODE);
750Sstevel@tonic-gate
760Sstevel@tonic-gate return (_NO_MODE);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate
790Sstevel@tonic-gate /*
800Sstevel@tonic-gate * DESCRIPTION:
810Sstevel@tonic-gate * This function/macro sets the orientation to the specified iop.
820Sstevel@tonic-gate *
830Sstevel@tonic-gate * INPUT:
840Sstevel@tonic-gate * flag may take one of the following:
850Sstevel@tonic-gate * _WC_MODE Wide orientation
860Sstevel@tonic-gate * _BYTE_MODE Byte orientation
870Sstevel@tonic-gate * _NO_MODE Unoriented
880Sstevel@tonic-gate */
890Sstevel@tonic-gate void
_setorientation(FILE * iop,_IOP_orientation_t mode)900Sstevel@tonic-gate _setorientation(FILE *iop, _IOP_orientation_t mode)
910Sstevel@tonic-gate {
920Sstevel@tonic-gate switch (mode) {
930Sstevel@tonic-gate case _NO_MODE:
940Sstevel@tonic-gate CLEAR_BYTE_MODE(iop);
950Sstevel@tonic-gate CLEAR_WC_MODE(iop);
960Sstevel@tonic-gate break;
970Sstevel@tonic-gate case _BYTE_MODE:
980Sstevel@tonic-gate CLEAR_WC_MODE(iop);
990Sstevel@tonic-gate SET_BYTE_MODE(iop);
1000Sstevel@tonic-gate break;
1010Sstevel@tonic-gate case _WC_MODE:
1020Sstevel@tonic-gate CLEAR_BYTE_MODE(iop);
1030Sstevel@tonic-gate SET_WC_MODE(iop);
1040Sstevel@tonic-gate break;
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate static mbstate_t **__top_mbstates = NULL;
1090Sstevel@tonic-gate static mutex_t __top_mbstates_lock = DEFAULTMUTEX;
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate void
_clear_internal_mbstate(void)1120Sstevel@tonic-gate _clear_internal_mbstate(void)
1130Sstevel@tonic-gate {
1140Sstevel@tonic-gate int i;
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate lmutex_lock(&__top_mbstates_lock);
1170Sstevel@tonic-gate if (__top_mbstates) {
1180Sstevel@tonic-gate for (i = 0; i <= _MAX_MB_FUNC; i++) {
1190Sstevel@tonic-gate if (*(__top_mbstates + i)) {
1200Sstevel@tonic-gate lfree(*(__top_mbstates + i),
1210Sstevel@tonic-gate sizeof (mbstate_t));
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate lfree(__top_mbstates,
1250Sstevel@tonic-gate (_MAX_MB_FUNC + 1) * sizeof (mbstate_t *));
1260Sstevel@tonic-gate __top_mbstates = NULL;
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate lmutex_unlock(&__top_mbstates_lock);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate mbstate_t *
_get_internal_mbstate(int item)1320Sstevel@tonic-gate _get_internal_mbstate(int item)
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate if (item < 0 || item > _MAX_MB_FUNC)
1350Sstevel@tonic-gate return (NULL);
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate lmutex_lock(&__top_mbstates_lock);
1380Sstevel@tonic-gate if (__top_mbstates == NULL) {
1390Sstevel@tonic-gate __top_mbstates =
140*6812Sraf lmalloc((_MAX_MB_FUNC + 1) * sizeof (mbstate_t *));
1410Sstevel@tonic-gate if (__top_mbstates == NULL) {
1420Sstevel@tonic-gate lmutex_unlock(&__top_mbstates_lock);
1430Sstevel@tonic-gate return (NULL);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate *(__top_mbstates + item) = lmalloc(sizeof (mbstate_t));
1460Sstevel@tonic-gate if (*(__top_mbstates + item) == NULL) {
1470Sstevel@tonic-gate lmutex_unlock(&__top_mbstates_lock);
1480Sstevel@tonic-gate return (NULL);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate lmutex_unlock(&__top_mbstates_lock);
1510Sstevel@tonic-gate return (*(__top_mbstates + item));
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate if (*(__top_mbstates + item) == NULL) {
1540Sstevel@tonic-gate *(__top_mbstates + item) = lmalloc(sizeof (mbstate_t));
1550Sstevel@tonic-gate if (*(__top_mbstates + item) == NULL) {
1560Sstevel@tonic-gate lmutex_unlock(&__top_mbstates_lock);
1570Sstevel@tonic-gate return (NULL);
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate lmutex_unlock(&__top_mbstates_lock);
1610Sstevel@tonic-gate return (*(__top_mbstates + item));
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate /*
1650Sstevel@tonic-gate * From page 32 of XSH5
1660Sstevel@tonic-gate * Once a wide-character I/O function has been applied
1670Sstevel@tonic-gate * to a stream without orientation, the stream becomes
1680Sstevel@tonic-gate * wide-orientated. Similarly, once a byte I/O function
1690Sstevel@tonic-gate * has been applied to a stream without orientation,
1700Sstevel@tonic-gate * the stream becomes byte-orientated. Only a call to
1710Sstevel@tonic-gate * the freopen() function or the fwide() function can
1720Sstevel@tonic-gate * otherwise alter the orientation of a stream.
1730Sstevel@tonic-gate */
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate /*
1760Sstevel@tonic-gate * void
1770Sstevel@tonic-gate * _set_orientation_byte(FILE *iop)
1780Sstevel@tonic-gate *
1790Sstevel@tonic-gate * Note: this is now implemented as macro __SET_ORIENTATION_BYTE()
1800Sstevel@tonic-gate * (in libc/inc/mse.h) for performance improvement.
1810Sstevel@tonic-gate */
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate /* Returns the value of 'ps->__nconsumed' */
1840Sstevel@tonic-gate char
__mbst_get_nconsumed(const mbstate_t * ps)1850Sstevel@tonic-gate __mbst_get_nconsumed(const mbstate_t *ps)
1860Sstevel@tonic-gate {
1870Sstevel@tonic-gate return (ps->__nconsumed);
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate /* Sets 'n' to 'ps->__nconsumed' */
1910Sstevel@tonic-gate void
__mbst_set_nconsumed(mbstate_t * ps,char n)1920Sstevel@tonic-gate __mbst_set_nconsumed(mbstate_t *ps, char n)
1930Sstevel@tonic-gate {
1940Sstevel@tonic-gate ps->__nconsumed = n;
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate /* Copies 'len' bytes from '&ps->__consumed[index]' to 'str' */
1980Sstevel@tonic-gate int
__mbst_get_consumed_array(const mbstate_t * ps,char * str,size_t index,size_t len)1990Sstevel@tonic-gate __mbst_get_consumed_array(const mbstate_t *ps, char *str,
2000Sstevel@tonic-gate size_t index, size_t len)
2010Sstevel@tonic-gate {
2020Sstevel@tonic-gate if ((index + len) > 8) {
2030Sstevel@tonic-gate /* The max size of __consumed[] is 8 */
2040Sstevel@tonic-gate return (-1);
2050Sstevel@tonic-gate }
206*6812Sraf (void) memcpy((void *)str, (const void *)&ps->__consumed[index], len);
2070Sstevel@tonic-gate return (0);
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate /* Copies 'len' bytes from 'str' to '&ps->__consumed[index]' */
2110Sstevel@tonic-gate int
__mbst_set_consumed_array(mbstate_t * ps,const char * str,size_t index,size_t len)2120Sstevel@tonic-gate __mbst_set_consumed_array(mbstate_t *ps, const char *str,
2130Sstevel@tonic-gate size_t index, size_t len)
2140Sstevel@tonic-gate {
2150Sstevel@tonic-gate if ((index + len) > 8) {
2160Sstevel@tonic-gate /* The max size of __consumed[] is 8 */
2170Sstevel@tonic-gate return (-1);
2180Sstevel@tonic-gate }
219*6812Sraf (void) memcpy((void *)&ps->__consumed[index], (const void *)str, len);
2200Sstevel@tonic-gate return (0);
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate /* Returns 'ps->__lc_locale' */
2240Sstevel@tonic-gate void *
__mbst_get_locale(const mbstate_t * ps)2250Sstevel@tonic-gate __mbst_get_locale(const mbstate_t *ps)
2260Sstevel@tonic-gate {
2270Sstevel@tonic-gate return (ps->__lc_locale);
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate /* Sets 'loc' to 'ps->__lc_locale' */
2310Sstevel@tonic-gate void
__mbst_set_locale(mbstate_t * ps,const void * loc)2320Sstevel@tonic-gate __mbst_set_locale(mbstate_t *ps, const void *loc)
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate ps->__lc_locale = (void *)loc;
2350Sstevel@tonic-gate }
236