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 2010 Nexenta Systems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 32 #include "lint.h" 33 #include "file64.h" 34 #include <mtlib.h> 35 #include <stdio.h> 36 #include <stdarg.h> 37 #include <errno.h> 38 #include <thread.h> 39 #include <synch.h> 40 #include <values.h> 41 #include <wchar.h> 42 #include "print.h" 43 #include "stdiom.h" 44 #include <sys/types.h> 45 #include "libc.h" 46 #include "mse.h" 47 48 /* 49 * 32-bit shadow functions _wprintf_c89(), _fwprintf_c89(), _swprintf_c89() 50 * are included here. 51 * When using the c89 compiler to build 32-bit applications, the size 52 * of intmax_t is 32-bits, otherwise the size of intmax_t is 64-bits. 53 * The shadow function uses 32-bit size of intmax_t for j conversion. 54 * The #pragma redefine_extname in <stdio.h> selects the proper routine 55 * at compile time for the user application. 56 * NOTE: the shadow functions only exist in the 32-bit library. 57 */ 58 59 int 60 wprintf(const wchar_t *format, ...) 61 { 62 ssize_t count; 63 rmutex_t *lk; 64 va_list ap; 65 66 va_start(ap, format); 67 FLOCKFILE(lk, stdout); 68 69 if (GET_NO_MODE(stdout)) 70 _setorientation(stdout, _WC_MODE); 71 72 if (!(stdout->_flag & _IOWRT)) { 73 /* if no write flag */ 74 if (stdout->_flag & _IORW) { 75 /* if ok, cause read-write */ 76 stdout->_flag |= _IOWRT; 77 } else { 78 /* else error */ 79 errno = EBADF; 80 FUNLOCKFILE(lk); 81 return (EOF); 82 } 83 } 84 85 count = _wndoprnt(format, ap, stdout, 0); 86 va_end(ap); 87 if (FERROR(stdout) || count == EOF) { 88 FUNLOCKFILE(lk); 89 return (EOF); 90 } 91 FUNLOCKFILE(lk); 92 /* check for overflow */ 93 if ((size_t)count > MAXINT) { 94 errno = EOVERFLOW; 95 return (EOF); 96 } else { 97 return ((int)count); 98 } 99 } 100 101 int 102 fwprintf(FILE *iop, const wchar_t *format, ...) 103 { 104 ssize_t count; 105 rmutex_t *lk; 106 va_list ap; 107 108 va_start(ap, format); 109 110 FLOCKFILE(lk, iop); 111 112 if (GET_NO_MODE(iop)) 113 _setorientation(iop, _WC_MODE); 114 115 if (!(iop->_flag & _IOWRT)) { 116 /* if no write flag */ 117 if (iop->_flag & _IORW) { 118 /* if ok, cause read-write */ 119 iop->_flag |= _IOWRT; 120 } else { 121 /* else error */ 122 errno = EBADF; 123 FUNLOCKFILE(lk); 124 return (EOF); 125 } 126 } 127 128 count = _wndoprnt(format, ap, iop, 0); 129 va_end(ap); 130 if (FERROR(iop) || count == EOF) { 131 FUNLOCKFILE(lk); 132 return (EOF); 133 } 134 FUNLOCKFILE(lk); 135 /* check for overflow */ 136 if ((size_t)count > MAXINT) { 137 errno = EOVERFLOW; 138 return (EOF); 139 } else { 140 return ((int)count); 141 } 142 } 143 144 int 145 swprintf(wchar_t *string, size_t n, const wchar_t *format, ...) 146 { 147 ssize_t count; 148 FILE siop; 149 wchar_t *wp; 150 va_list ap; 151 152 if (n == 0) 153 return (EOF); 154 siop._cnt = (ssize_t)n - 1; 155 siop._base = siop._ptr = (unsigned char *)string; 156 siop._flag = _IOREAD; 157 158 va_start(ap, format); 159 count = _wndoprnt(format, ap, &siop, 0); 160 va_end(ap); 161 wp = (wchar_t *)(uintptr_t)siop._ptr; 162 *wp = L'\0'; 163 if (count == EOF) { 164 return (EOF); 165 } 166 /* check for overflow */ 167 if ((size_t)count > MAXINT) { 168 errno = EOVERFLOW; 169 return (EOF); 170 } else { 171 return ((int)count); 172 } 173 } 174 175 #ifndef _LP64 176 177 int 178 _wprintf_c89(const wchar_t *format, ...) 179 { 180 ssize_t count; 181 va_list ap; 182 183 va_start(ap, format); 184 count = _vwprintf_c89(format, ap); 185 va_end(ap); 186 return ((int)count); 187 } 188 189 int 190 _fwprintf_c89(FILE *iop, const wchar_t *format, ...) 191 { 192 ssize_t count; 193 va_list ap; 194 195 va_start(ap, format); 196 count = _vfwprintf_c89(iop, format, ap); 197 va_end(ap); 198 return ((int)count); 199 } 200 201 int 202 _swprintf_c89(wchar_t *string, size_t n, const wchar_t *format, ...) 203 { 204 ssize_t count; 205 va_list ap; 206 207 va_start(ap, format); 208 count = _vswprintf_c89(string, n, format, ap); 209 va_end(ap); 210 return ((int)count); 211 } 212 213 #endif /* _LP64 */ 214