00001 /*! 00002 * @file stdio.c 00003 * 00004 * @brief Standard Output and Standard Error print functions that are 00005 * isolated from certain compile requirements of the other code. 00006 * 00007 * USE THESE FUNCTIONS IN PLACE OF fprintf() AND sprintf() IN ALL 00008 * CODE DUE TO STRUCTURE PACKING OPTIONS CAUSING @b SIGSEGV IN 00009 * SOME ARCHITECTURES (specifically Solaris 32-bit) WITH 'GCC' 00010 * 00011 * THIS FILE MUST BE COMPILED WITH STRUCTURE PACKING OFF 00012 * (at least for the default GCC stdio library) OR IN THE 00013 * SAME MANNER IN WHICH YOUR COMPILER'S RUNTIME LIBRARY 00014 * HAS IT COMPILED. (You may get unexplainable @b SIGSEGV 00015 * errors otherwise.) 00016 * 00017 * 00018 * @section Control 00019 * 00020 * \$URL: https://svn.apache.org/path/name/stdio.c $ \$Id: stdio.c 0 09/28/2005 dlydick $ 00021 * 00022 * Copyright 2005 The Apache Software Foundation 00023 * or its licensors, as applicable. 00024 * 00025 * Licensed under the Apache License, Version 2.0 ("the License"); 00026 * you may not use this file except in compliance with the License. 00027 * You may obtain a copy of the License at 00028 * 00029 * http://www.apache.org/licenses/LICENSE-2.0 00030 * 00031 * Unless required by applicable law or agreed to in writing, 00032 * software distributed under the License is distributed on an 00033 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 00034 * either express or implied. 00035 * 00036 * See the License for the specific language governing permissions 00037 * and limitations under the License. 00038 * 00039 * @version \$LastChangedRevision: 0 $ 00040 * 00041 * @date \$LastChangedDate: 09/28/2005 $ 00042 * 00043 * @author \$LastChangedBy: dlydick $ 00044 * Original code contributed by Daniel Lydick on 09/28/2005. 00045 * 00046 * @section Reference 00047 * 00048 */ 00049 00050 #include "arch.h" 00051 ARCH_COPYRIGHT_APACHE(stdio, c, "$URL: https://svn.apache.org/path/name/stdio.c $ $Id: stdio.c 0 09/28/2005 dlydick $"); 00052 00053 00054 #include <stdio.h> 00055 #include <stdarg.h> 00056 00057 #define SUPPRESS_STDIO_REDIRECTION /* All other files redirect here */ 00058 #include "jvmcfg.h" 00059 00060 /* Defeat compiler complaints about @c @b extern */ 00061 #define I_AM_STDIO_C 00062 00063 #include "util.h" 00064 00065 /*! 00066 * @name printf() style printing to standard error and 00067 * buffer formatting. 00068 * 00069 * There are three versions of this routine. One conditionally 00070 * prints a message to stderr based on a debug level. 00071 * The others perform unconditional actions. 00072 * 00073 * Create a variable-argument message to standard error or a buffer 00074 * in a fashion with a tag string on the front telling what type 00075 * of error it is. 00076 * 00077 * 00078 * @param dml Debug msg level @link #DML0 DML0@endlink through 00079 * @link #DML10 DML10@endlink 00080 * 00081 * @param bfr Buffer to format 00082 * 00083 * @param fn Function name of caller or other unique "string" 00084 * 00085 * @param fmt printf() style format string 00086 * 00087 * _param ... printf() style argument list, zero or more 00088 * 00089 * 00090 * @returns number of characters emitted or formatted 00091 * 00092 */ 00093 00094 /*@{ */ /* Begin grouped definitions */ 00095 00096 int sysDbgMsg(rint dml, rchar *fn, rchar *fmt, ...) 00097 { 00098 /* Display @e nothing if debug messages are disabled */ 00099 if (rfalse == JVMCFG_DEBUG_MESSAGE_ENABLE) 00100 { 00101 return(0); 00102 } 00103 00104 if (jvmutil_get_dml() < dml) 00105 { 00106 return(0); 00107 } 00108 00109 /* If debug levels are satisfied, proceed to print message */ 00110 00111 rchar extfmt[JVMCFG_STDIO_BFR]; /* WARNING! On the stack! */ 00112 00113 /* Load up format string w/ user specification */ 00114 00115 va_list ap; 00116 va_start(ap, fmt); 00117 00118 sprintf(extfmt, "%s: %s\n", fn, fmt); 00119 int rc = vfprintf(stderr, extfmt, ap); 00120 00121 va_end(ap); 00122 00123 fflush(stderr); 00124 JVMCFG_DEBUG_ECLIPSE_FLUSH_STDIO_BETTER; 00125 return(rc); 00126 00127 } /* END of sysDbgMsg() */ 00128 00129 00130 int sysErrMsg(rchar *fn, rchar *fmt, ...) 00131 { 00132 rchar extfmt[JVMCFG_STDIO_BFR]; /* WARNING! On the stack! */ 00133 00134 /* Load up format string w/ user specification */ 00135 00136 va_list ap; 00137 va_start(ap, fmt); 00138 00139 sprintf(extfmt, "%s: %s\n", fn, fmt); 00140 int rc = vfprintf(stderr, extfmt, ap); 00141 00142 va_end(ap); 00143 00144 fflush(stderr); 00145 JVMCFG_DEBUG_ECLIPSE_FLUSH_STDIO_BETTER; 00146 return(rc); 00147 00148 } /* END of sysErrMsg() */ 00149 00150 00151 int sysErrMsgBfrFormat(rchar *bfr, rchar *fn, rchar *fmt, ...) 00152 { 00153 rchar extfmt[JVMCFG_STDIO_BFR]; /* WARNING! On the stack! */ 00154 00155 /* Load up format string w/ user specification */ 00156 00157 va_list ap; 00158 va_start(ap, fmt); 00159 00160 sprintf(extfmt, "%s: %s\n", fn, fmt); 00161 int rc = vsprintf(bfr, extfmt, ap); 00162 00163 va_end(ap); 00164 00165 return(rc); 00166 00167 } /* END of sysErrMsgBfrFormat() */ 00168 00169 /*@} */ /* End of grouped definitions */ 00170 00171 00172 /*! 00173 * @name Macro support for local standard output utilities 00174 * 00175 */ 00176 00177 /*@{ */ /* Begin grouped definitions */ 00178 00179 #define LOCAL_FPRINTF(FP) \ 00180 va_list ap; \ 00181 va_start(ap, fmt); \ 00182 \ 00183 int rc = vfprintf(FP, fmt, ap); \ 00184 \ 00185 va_end(ap); \ 00186 fflush(FP); \ 00187 JVMCFG_DEBUG_ECLIPSE_FLUSH_STDIO_BETTER; \ 00188 return(rc) 00189 00190 #define LOCAL_SPRINTF \ 00191 va_list ap; \ 00192 va_start(ap, fmt); \ 00193 \ 00194 int rc = vsprintf(bfr, fmt, ap); \ 00195 \ 00196 va_end(ap); \ 00197 return(rc) 00198 00199 /*@} */ /* End of grouped definitions */ 00200 00201 /*! 00202 * @name Local version of standard output routines. 00203 * 00204 * Local implementations of @c @b sprintf(3) and @c @b fprintf(3) 00205 * are provided for both stdout and stderr. These functions are 00206 * intended to bypass the structure packing mismatch between the 00207 * requirements of parts of this application and the manner in 00208 * which any compiler's runtime library was compiled. 00209 * 00210 * In the same manner as the printf() style printing functions 00211 * above, there are three versions of this routine. In this 00212 * case, one writes to standard output, another to standard error, 00213 * and the third formats a buffer. 00214 * 00215 * @param fmt printf() style format string 00216 * 00217 * _param ... printf() style argument list, zero or more 00218 * 00219 * 00220 * @returns number of characters emitted or formatted 00221 * 00222 */ 00223 00224 /*@{ */ /* Begin grouped definitions */ 00225 00226 int fprintfLocalStdout(rchar *fmt, ...) 00227 { 00228 LOCAL_FPRINTF(stdout); 00229 00230 } /* END of fprintfLocalStdout() */ 00231 00232 00233 int fprintfLocalStderr(rchar *fmt, ...) 00234 { 00235 LOCAL_FPRINTF(stderr); 00236 00237 } /* END of fprintfLocalStderr() */ 00238 00239 int sprintfLocal(rchar *bfr, rchar *fmt, ...) 00240 { 00241 LOCAL_SPRINTF; 00242 00243 } /* END of sprintfLocal() */ 00244 00245 /*@} */ /* End of grouped definitions */ 00246 00247 00248 /*! 00249 * @name Magic redirection of selected standard I/O functions. 00250 * 00251 * In @link jvm/src/jvmcfg.h jvmcfg.h@endlink, there are 00252 * several @c @b \#define statements that redirect @c @b printf() 00253 * and @c @b fprintf() and @c @b sprintf() from the 00254 * @c @b <stdio.h> linkages to local linkages. 00255 * 00256 * This magic redirection used the compile-time definition 00257 * @c @b SUPPRESS_STDIO_REDIRECTION to co-opt these standard I/O 00258 * calls and redirect them to local version so as to avoid @b SIGSEGV 00259 * problems with certain configurations. * These routines are meant 00260 * to encourage use of proper functions above. 00261 * 00262 * @param fp @c @b FILE handle to standard I/O file handle. 00263 * 00264 * @param bfr Buffer to format 00265 * 00266 * @param fmt printf() style format string 00267 * 00268 * _param ... printf() style argument list, zero or more 00269 * 00270 * 00271 * @returns number of characters emitted or formatted 00272 */ 00273 00274 /*@{ */ /* Begin grouped definitions */ 00275 00276 int _printfLocal(const rchar *fmt, ...) 00277 { 00278 return(sysErrMsg("_printfLocal", 00279 "Please use 'printfLocal' function instead")); 00280 00281 } /* END of _printfLocal() */ 00282 00283 int _fprintfLocal(FILE *fp, const rchar *fmt, ...) 00284 { 00285 return(sysErrMsg("_fprintfLocal", 00286 "Please use 'fprintfLocal' function instead")); 00287 00288 } /* END of _fprintfLocal() */ 00289 00290 int _sprintfLocal(rchar *bfr, const rchar *fmt, ...) 00291 { 00292 return(sysErrMsg("_sprintfLocal", 00293 "Please use 'sprintfLocal' function instead")); 00294 00295 } /* END of _sprintfLocal() */ 00296 00297 /*@} */ /* End of grouped definitions */ 00298 00299 00300 /* EOF */ 00301