diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libc/port/stdio/vscanf.c | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libc/port/stdio/vscanf.c')
-rw-r--r-- | usr/src/lib/libc/port/stdio/vscanf.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/usr/src/lib/libc/port/stdio/vscanf.c b/usr/src/lib/libc/port/stdio/vscanf.c new file mode 100644 index 0000000000..986feae37a --- /dev/null +++ b/usr/src/lib/libc/port/stdio/vscanf.c @@ -0,0 +1,149 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* Copyright (c) 1988 AT&T */ +/* All Rights Reserved */ + + +#ifndef _C89_INTMAX32 +#pragma weak vscanf = _vscanf +#pragma weak vfscanf = _vfscanf +#pragma weak vsscanf = _vsscanf +#endif + +#include "synonyms.h" +#include "file64.h" +#include "mtlib.h" +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <thread.h> +#include <synch.h> +#include "libc.h" +#include "stdiom.h" +#include "mse.h" +#include <stdio_ext.h> + + +/* + * 32-bit shadow functions _vscanf_c89(), _vfscanf_c89(), _vsscanf_c89() + * are included here. + * When using the c89 compiler to build 32-bit applications, the size + * of intmax_t is 32-bits, otherwise the size of intmax_t is 64-bits. + * The shadow function uses 32-bit size of intmax_t for %j conversion. + * The #pragma redefine_extname in <stdio.h> selects the proper routine + * at compile time for the user application. + * NOTE: the shadow function only exists in the 32-bit library. + */ + +int +#ifdef _C89_INTMAX32 /* _C89_INTMAX32 version in 32-bit libc only */ +_vscanf_c89(const char *fmt, va_list ap) +#else +vscanf(const char *fmt, va_list ap) +#endif +{ + rmutex_t *lk; + int ret; + + FLOCKFILE(lk, stdin); + + _SET_ORIENTATION_BYTE(stdin); + +#ifdef _C89_INTMAX32 + ret = __doscan_u(stdin, fmt, ap, _F_INTMAX32); +#else + ret = __doscan_u(stdin, fmt, ap, 0); +#endif + + FUNLOCKFILE(lk); + return (ret); +} + +int +#ifdef _C89_INTMAX32 /* _C89_INTMAX32 version in 32-bit libc only */ +_vfscanf_c89(FILE *iop, const char *fmt, va_list ap) +#else +vfscanf(FILE *iop, const char *fmt, va_list ap) +#endif +{ + rmutex_t *lk; + int ret; + + FLOCKFILE(lk, iop); + + _SET_ORIENTATION_BYTE(iop); + +#ifdef _C89_INTMAX32 + ret = __doscan_u(iop, fmt, ap, _F_INTMAX32); +#else + ret = __doscan_u(iop, fmt, ap, 0); +#endif + FUNLOCKFILE(lk); + return (ret); +} + +int +#ifdef _C89_INTMAX32 /* _C89_INTMAX32 version in 32-bit libc only */ +_vsscanf_c89(const char *str, const char *fmt, va_list ap) +#else +vsscanf(const char *str, const char *fmt, va_list ap) +#endif +{ + FILE strbuf; + + /* + * The dummy FILE * created for sscanf has the _IOWRT + * flag set to distinguish it from scanf and fscanf + * invocations. + */ + strbuf._flag = _IOREAD | _IOWRT; + strbuf._ptr = strbuf._base = (unsigned char *)str; + strbuf._cnt = strlen(str); + strbuf._file = _NFILE; + + /* + * Mark the stream so that routines called by __doscan_u() + * do not do any locking. In particular this avoids a NULL + * lock pointer being used by getc() causing a core dump. + * See bugid - 1210179 program SEGV's in sscanf if linked with + * the libthread. + * This also makes sscanf() quicker since it does not need + * to do any locking. + */ + if (__fsetlocking(&strbuf, FSETLOCKING_BYCALLER) == -1) { + return (-1); /* this should never happen */ + } + + /* as this stream is local to this function, no locking is be done */ +#ifdef _C89_INTMAX32 + return (__doscan_u(&strbuf, fmt, ap, _F_INTMAX32)); +#else + return (__doscan_u(&strbuf, fmt, ap, 0)); +#endif +} |