1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include "lint.h"
30 #include "mtlib.h"
31 #include "mbstatet.h"
32 #include "file64.h"
33 #include <sys/types.h>
34 #include <stdio.h>
35 #include <wchar.h>
36 #include <thread.h>
37 #include <synch.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include "libc.h"
41 #include "stdiom.h"
42 #include "mse.h"
43
44 /*
45 * DESCRIPTION:
46 * This function sets the error indicator for the specified stream.
47 * This is a private API for the L10N method functions, especially
48 * for fgetwc().
49 *
50 * The stream needs to have been properly locked. Usually, the wrapper
51 * function of fgetwc() locks the stream.
52 */
53 void
__fseterror_u(FILE * iop)54 __fseterror_u(FILE *iop)
55 {
56 iop->_flag |= _IOERR;
57 }
58
59 /*
60 * DESCRIPTION:
61 * This function/macro gets the orientation bound to the specified iop.
62 *
63 * RETURNS:
64 * _WC_MODE if iop has been bound to Wide orientation
65 * _BYTE_MODE if iop has been bound to Byte orientation
66 * _NO_MODE if iop has been bound to neither Wide nor Byte
67 */
68 _IOP_orientation_t
_getorientation(FILE * iop)69 _getorientation(FILE *iop)
70 {
71 if (GET_BYTE_MODE(iop))
72 return (_BYTE_MODE);
73 else if (GET_WC_MODE(iop))
74 return (_WC_MODE);
75
76 return (_NO_MODE);
77 }
78
79 /*
80 * DESCRIPTION:
81 * This function/macro sets the orientation to the specified iop.
82 *
83 * INPUT:
84 * flag may take one of the following:
85 * _WC_MODE Wide orientation
86 * _BYTE_MODE Byte orientation
87 * _NO_MODE Unoriented
88 */
89 void
_setorientation(FILE * iop,_IOP_orientation_t mode)90 _setorientation(FILE *iop, _IOP_orientation_t mode)
91 {
92 switch (mode) {
93 case _NO_MODE:
94 CLEAR_BYTE_MODE(iop);
95 CLEAR_WC_MODE(iop);
96 break;
97 case _BYTE_MODE:
98 CLEAR_WC_MODE(iop);
99 SET_BYTE_MODE(iop);
100 break;
101 case _WC_MODE:
102 CLEAR_BYTE_MODE(iop);
103 SET_WC_MODE(iop);
104 break;
105 }
106 }
107
108 static mbstate_t **__top_mbstates = NULL;
109 static mutex_t __top_mbstates_lock = DEFAULTMUTEX;
110
111 void
_clear_internal_mbstate(void)112 _clear_internal_mbstate(void)
113 {
114 int i;
115
116 lmutex_lock(&__top_mbstates_lock);
117 if (__top_mbstates) {
118 for (i = 0; i <= _MAX_MB_FUNC; i++) {
119 if (*(__top_mbstates + i)) {
120 lfree(*(__top_mbstates + i),
121 sizeof (mbstate_t));
122 }
123 }
124 lfree(__top_mbstates,
125 (_MAX_MB_FUNC + 1) * sizeof (mbstate_t *));
126 __top_mbstates = NULL;
127 }
128 lmutex_unlock(&__top_mbstates_lock);
129 }
130
131 mbstate_t *
_get_internal_mbstate(int item)132 _get_internal_mbstate(int item)
133 {
134 if (item < 0 || item > _MAX_MB_FUNC)
135 return (NULL);
136
137 lmutex_lock(&__top_mbstates_lock);
138 if (__top_mbstates == NULL) {
139 __top_mbstates =
140 lmalloc((_MAX_MB_FUNC + 1) * sizeof (mbstate_t *));
141 if (__top_mbstates == NULL) {
142 lmutex_unlock(&__top_mbstates_lock);
143 return (NULL);
144 }
145 *(__top_mbstates + item) = lmalloc(sizeof (mbstate_t));
146 if (*(__top_mbstates + item) == NULL) {
147 lmutex_unlock(&__top_mbstates_lock);
148 return (NULL);
149 }
150 lmutex_unlock(&__top_mbstates_lock);
151 return (*(__top_mbstates + item));
152 }
153 if (*(__top_mbstates + item) == NULL) {
154 *(__top_mbstates + item) = lmalloc(sizeof (mbstate_t));
155 if (*(__top_mbstates + item) == NULL) {
156 lmutex_unlock(&__top_mbstates_lock);
157 return (NULL);
158 }
159 }
160 lmutex_unlock(&__top_mbstates_lock);
161 return (*(__top_mbstates + item));
162 }
163
164 /*
165 * From page 32 of XSH5
166 * Once a wide-character I/O function has been applied
167 * to a stream without orientation, the stream becomes
168 * wide-orientated. Similarly, once a byte I/O function
169 * has been applied to a stream without orientation,
170 * the stream becomes byte-orientated. Only a call to
171 * the freopen() function or the fwide() function can
172 * otherwise alter the orientation of a stream.
173 */
174
175 /*
176 * void
177 * _set_orientation_byte(FILE *iop)
178 *
179 * Note: this is now implemented as macro __SET_ORIENTATION_BYTE()
180 * (in libc/inc/mse.h) for performance improvement.
181 */
182
183 /* Returns the value of 'ps->__nconsumed' */
184 char
__mbst_get_nconsumed(const mbstate_t * ps)185 __mbst_get_nconsumed(const mbstate_t *ps)
186 {
187 return (ps->__nconsumed);
188 }
189
190 /* Sets 'n' to 'ps->__nconsumed' */
191 void
__mbst_set_nconsumed(mbstate_t * ps,char n)192 __mbst_set_nconsumed(mbstate_t *ps, char n)
193 {
194 ps->__nconsumed = n;
195 }
196
197 /* Copies 'len' bytes from '&ps->__consumed[index]' to 'str' */
198 int
__mbst_get_consumed_array(const mbstate_t * ps,char * str,size_t index,size_t len)199 __mbst_get_consumed_array(const mbstate_t *ps, char *str,
200 size_t index, size_t len)
201 {
202 if ((index + len) > 8) {
203 /* The max size of __consumed[] is 8 */
204 return (-1);
205 }
206 (void) memcpy((void *)str, (const void *)&ps->__consumed[index], len);
207 return (0);
208 }
209
210 /* Copies 'len' bytes from 'str' to '&ps->__consumed[index]' */
211 int
__mbst_set_consumed_array(mbstate_t * ps,const char * str,size_t index,size_t len)212 __mbst_set_consumed_array(mbstate_t *ps, const char *str,
213 size_t index, size_t len)
214 {
215 if ((index + len) > 8) {
216 /* The max size of __consumed[] is 8 */
217 return (-1);
218 }
219 (void) memcpy((void *)&ps->__consumed[index], (const void *)str, len);
220 return (0);
221 }
222
223 /* Returns 'ps->__lc_locale' */
224 void *
__mbst_get_locale(const mbstate_t * ps)225 __mbst_get_locale(const mbstate_t *ps)
226 {
227 return (ps->__lc_locale);
228 }
229
230 /* Sets 'loc' to 'ps->__lc_locale' */
231 void
__mbst_set_locale(mbstate_t * ps,const void * loc)232 __mbst_set_locale(mbstate_t *ps, const void *loc)
233 {
234 ps->__lc_locale = (void *)loc;
235 }
236