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