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 * Copyright 2025 Hans Rosenfeld 32 */ 33 34 #include "lint.h" 35 #include "file64.h" 36 #include <mtlib.h> 37 #include <stdio.h> 38 #include <stdarg.h> 39 #include <errno.h> 40 #include <thread.h> 41 #include <synch.h> 42 #include <values.h> 43 #include <wchar.h> 44 #include "print.h" 45 #include "stdiom.h" 46 #include <sys/types.h> 47 #include "libc.h" 48 #include "mse.h" 49 #include <stdio_ext.h> 50 #include <upanic.h> 51 52 #ifdef _C89_INTMAX32 53 #pragma redefine_extname vfwprintf _vfwprintf_c89 54 #pragma redefine_extname vswprintf _vswprintf_c89 55 #pragma redefine_extname vwprintf _vwprintf_c89 56 #pragma redefine_extname fwprintf _fwprintf_c89 57 #pragma redefine_extname swprintf _swprintf_c89 58 #pragma redefine_extname wprintf _wprintf_c89 59 #endif 60 61 /* 62 * 32-bit shadow functions _vwprintf_c89(), _vfwprintf_c89(), _vswprintf_c89(), 63 * _wprintf_c89(), _fwprintf_c89(), and _swprintf_c89() are included here. 64 * When using the c89 compiler to build 32-bit applications, the size 65 * of intmax_t is 32-bits, otherwise the size of intmax_t is 64-bits. 66 * The shadow function uses 32-bit size of intmax_t for j conversion. 67 * The #pragma redefine_extname in <wchar.h> selects the proper routine 68 * at compile time for the user application. 69 * NOTE: shadow functions only exist in the 32-bit library. 70 */ 71 72 int 73 vfwprintf(FILE *iop, const wchar_t *format, va_list ap) 74 { 75 ssize_t count; 76 rmutex_t *lk; 77 78 FLOCKFILE(lk, iop); 79 80 if (GET_NO_MODE(iop)) 81 _setorientation(iop, _WC_MODE); 82 83 if (!(iop->_flag & _IOWRT)) { 84 /* if no write flag */ 85 if (iop->_flag & _IORW) { 86 /* if ok, cause read-write */ 87 iop->_flag |= _IOWRT; 88 } else { 89 /* else error */ 90 errno = EBADF; 91 FUNLOCKFILE(lk); 92 return (EOF); 93 } 94 } 95 #ifdef _C89_INTMAX32 96 count = _ndoprnt(format, ap, iop, _F_INTMAX32); 97 #else 98 count = _ndoprnt(format, ap, iop, 0); 99 #endif 100 if (FERROR(iop) || count == EOF) { 101 FUNLOCKFILE(lk); 102 return (EOF); 103 } 104 FUNLOCKFILE(lk); 105 /* check for overflow */ 106 if ((size_t)count > MAXINT) { 107 errno = EOVERFLOW; 108 return (EOF); 109 } 110 111 return ((int)count); 112 } 113 114 int 115 fwprintf(FILE *iop, const wchar_t *format, ...) 116 { 117 int count; 118 va_list ap; 119 120 va_start(ap, format); 121 count = vfwprintf(iop, format, ap); 122 va_end(ap); 123 124 return (count); 125 } 126 127 int 128 vwprintf(const wchar_t *format, va_list ap) 129 { 130 int count; 131 132 count = vfwprintf(stdout, format, ap); 133 134 return (count); 135 } 136 137 int 138 wprintf(const wchar_t *format, ...) 139 { 140 int count; 141 va_list ap; 142 143 va_start(ap, format); 144 count = vfwprintf(stdout, format, ap); 145 va_end(ap); 146 147 return (count); 148 } 149 150 int 151 vswprintf(wchar_t *string, size_t n, const wchar_t *format, va_list ap) 152 { 153 int count; 154 FILE siop; 155 wchar_t *wp; 156 157 if (n == 0) 158 return (EOF); 159 160 /* 161 * The dummy FILE * created for vswprintf has the _IOREAD 162 * flag set to distinguish it from wprintf and wfprintf 163 * invocations. It also has the _IOWRT flag set to indicate 164 * it is writable, which is checked later by vfwprintf(). 165 */ 166 siop._flag = _IOWRT | _IOREAD; 167 siop._cnt = (ssize_t)n - 1; 168 siop._base = siop._ptr = (unsigned char *)string; 169 170 /* 171 * Mark the dummy FILE so that no locking is ever done. 172 */ 173 if (__fsetlocking(&siop, FSETLOCKING_BYCALLER) == -1) 174 upanic(NULL, 0); /* this should never happen */ 175 176 count = vfwprintf(&siop, format, ap); 177 178 wp = (wchar_t *)(uintptr_t)siop._ptr; 179 *wp = L'\0'; 180 181 return (count); 182 } 183 184 int 185 swprintf(wchar_t *string, size_t n, const wchar_t *format, ...) 186 { 187 int count; 188 va_list ap; 189 190 va_start(ap, format); 191 count = vswprintf(string, n, format, ap); 192 va_end(ap); 193 194 return (count); 195 } 196