xref: /onnv-gate/usr/src/lib/libc/port/stdio/mse.c (revision 6812:febeba71273d)
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