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 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #ifndef _C89_INTMAX32
33 #pragma weak _vscanf = vscanf
34 #pragma weak _vfscanf = vfscanf
35 #pragma weak _vsscanf = vsscanf
36 #endif
37
38 #include "lint.h"
39 #include "file64.h"
40 #include "mtlib.h"
41 #include <stdio.h>
42 #include <stdarg.h>
43 #include <string.h>
44 #include <thread.h>
45 #include <synch.h>
46 #include "libc.h"
47 #include "stdiom.h"
48 #include "mse.h"
49 #include <stdio_ext.h>
50
51
52 /*
53 * 32-bit shadow functions _vscanf_c89(), _vfscanf_c89(), _vsscanf_c89()
54 * are included here.
55 * When using the c89 compiler to build 32-bit applications, the size
56 * of intmax_t is 32-bits, otherwise the size of intmax_t is 64-bits.
57 * The shadow function uses 32-bit size of intmax_t for %j conversion.
58 * The #pragma redefine_extname in <stdio.h> selects the proper routine
59 * at compile time for the user application.
60 * NOTE: the shadow function only exists in the 32-bit library.
61 */
62
63 int
64 #ifdef _C89_INTMAX32 /* _C89_INTMAX32 version in 32-bit libc only */
_vscanf_c89(const char * fmt,va_list ap)65 _vscanf_c89(const char *fmt, va_list ap)
66 #else
67 vscanf(const char *fmt, va_list ap)
68 #endif
69 {
70 rmutex_t *lk;
71 int ret;
72
73 FLOCKFILE(lk, stdin);
74
75 _SET_ORIENTATION_BYTE(stdin);
76
77 #ifdef _C89_INTMAX32
78 ret = __doscan_u(stdin, fmt, ap, _F_INTMAX32);
79 #else
80 ret = __doscan_u(stdin, fmt, ap, 0);
81 #endif
82
83 FUNLOCKFILE(lk);
84 return (ret);
85 }
86
87 int
88 #ifdef _C89_INTMAX32 /* _C89_INTMAX32 version in 32-bit libc only */
_vfscanf_c89(FILE * iop,const char * fmt,va_list ap)89 _vfscanf_c89(FILE *iop, const char *fmt, va_list ap)
90 #else
91 vfscanf(FILE *iop, const char *fmt, va_list ap)
92 #endif
93 {
94 rmutex_t *lk;
95 int ret;
96
97 FLOCKFILE(lk, iop);
98
99 _SET_ORIENTATION_BYTE(iop);
100
101 #ifdef _C89_INTMAX32
102 ret = __doscan_u(iop, fmt, ap, _F_INTMAX32);
103 #else
104 ret = __doscan_u(iop, fmt, ap, 0);
105 #endif
106 FUNLOCKFILE(lk);
107 return (ret);
108 }
109
110 int
111 #ifdef _C89_INTMAX32 /* _C89_INTMAX32 version in 32-bit libc only */
_vsscanf_c89(const char * str,const char * fmt,va_list ap)112 _vsscanf_c89(const char *str, const char *fmt, va_list ap)
113 #else
114 vsscanf(const char *str, const char *fmt, va_list ap)
115 #endif
116 {
117 FILE strbuf;
118
119 /*
120 * The dummy FILE * created for sscanf has the _IOWRT
121 * flag set to distinguish it from scanf and fscanf
122 * invocations.
123 */
124 strbuf._flag = _IOREAD | _IOWRT;
125 strbuf._ptr = strbuf._base = (unsigned char *)str;
126 strbuf._cnt = strlen(str);
127 SET_FILE(&strbuf, _NFILE);
128
129 /*
130 * Mark the stream so that routines called by __doscan_u()
131 * do not do any locking. In particular this avoids a NULL
132 * lock pointer being used by getc() causing a core dump.
133 * See bugid - 1210179 program SEGV's in sscanf if linked with
134 * the libthread.
135 * This also makes sscanf() quicker since it does not need
136 * to do any locking.
137 */
138 if (__fsetlocking(&strbuf, FSETLOCKING_BYCALLER) == -1) {
139 return (-1); /* this should never happen */
140 }
141
142 /* as this stream is local to this function, no locking is be done */
143 #ifdef _C89_INTMAX32
144 return (__doscan_u(&strbuf, fmt, ap, _F_INTMAX32));
145 #else
146 return (__doscan_u(&strbuf, fmt, ap, 0));
147 #endif
148 }
149