Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenvsnprintf.c
Go to the documentation of this file.
00001 /* 00002 * Revision 12: http://theos.com/~deraadt/snprintf.c 00003 * 00004 * Copyright (c) 1997 Theo de Raadt 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00017 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00018 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00019 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00020 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00021 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00022 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00024 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00025 */ 00026 00027 #ifndef __VMS 00028 # include <sys/param.h> 00029 #endif 00030 #include <sys/types.h> 00031 #include <sys/mman.h> 00032 #include <signal.h> 00033 #include <stdio.h> 00034 #if __STDC__ 00035 #include <stdarg.h> 00036 #include <stdlib.h> 00037 #else 00038 #include <varargs.h> 00039 #endif 00040 #include <setjmp.h> 00041 #include <unistd.h> 00042 #include <string.h> 00043 00044 #ifndef roundup 00045 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 00046 #endif 00047 00048 #ifdef __sgi 00049 #define size_t ssize_t 00050 #endif 00051 00052 static int pgsize; 00053 static char *curobj; 00054 static int caught; 00055 static sigjmp_buf bail; 00056 00057 #define EXTRABYTES 2 /* XXX: why 2? you don't want to know */ 00058 00059 static char * 00060 msetup(str, n) 00061 char *str; 00062 size_t n; 00063 { 00064 char *e; 00065 00066 if (n == 0) 00067 return NULL; 00068 if (pgsize == 0) 00069 pgsize = getpagesize(); 00070 curobj = (char *)malloc(n + EXTRABYTES + pgsize * 2); 00071 if (curobj == NULL) 00072 return NULL; 00073 e = curobj + n + EXTRABYTES; 00074 e = (char *)roundup((unsigned long)e, pgsize); 00075 if (mprotect(e, pgsize, PROT_NONE) == -1) { 00076 free(curobj); 00077 curobj = NULL; 00078 return NULL; 00079 } 00080 e = e - n - EXTRABYTES; 00081 *e = '\0'; 00082 return (e); 00083 } 00084 00085 static void 00086 mcatch( int a ) 00087 { 00088 siglongjmp(bail, 1); 00089 } 00090 00091 static void 00092 mcleanup(str, n, p) 00093 char *str; 00094 size_t n; 00095 char *p; 00096 { 00097 strncpy(str, p, n-1); 00098 str[n-1] = '\0'; 00099 if (mprotect((caddr_t)(p + n + EXTRABYTES), pgsize, 00100 PROT_READ|PROT_WRITE|PROT_EXEC) == -1) 00101 mprotect((caddr_t)(p + n + EXTRABYTES), pgsize, 00102 PROT_READ|PROT_WRITE); 00103 free(curobj); 00104 } 00105 00106 int 00107 #if __STDC__ 00108 vsnprintf(char *str, size_t n, char const *fmt, va_list ap) 00109 #else 00110 vsnprintf(str, n, fmt, ap) 00111 char *str; 00112 size_t n; 00113 char *fmt; 00114 char *ap; 00115 #endif 00116 { 00117 struct sigaction osa, nsa; 00118 char *p; 00119 int ret = n + 1; /* if we bail, indicated we overflowed */ 00120 00121 memset(&nsa, 0, sizeof nsa); 00122 nsa.sa_handler = mcatch; 00123 sigemptyset(&nsa.sa_mask); 00124 00125 p = msetup(str, n); 00126 if (p == NULL) { 00127 *str = '\0'; 00128 return 0; 00129 } 00130 if (sigsetjmp(bail, 1) == 0) { 00131 if (sigaction(SIGSEGV, &nsa, &osa) == -1) { 00132 mcleanup(str, n, p); 00133 return (0); 00134 } 00135 ret = vsprintf(p, fmt, ap); 00136 } 00137 mcleanup(str, n, p); 00138 (void) sigaction(SIGSEGV, &osa, NULL); 00139 return (ret); 00140 } 00141 00142 int 00143 #if __STDC__ 00144 snprintf(char *str, size_t n, char const *fmt, ...) 00145 #else 00146 snprintf(str, n, fmt, va_alist) 00147 char *str; 00148 size_t n; 00149 char *fmt; 00150 va_dcl 00151 #endif 00152 { 00153 va_list ap; 00154 #if __STDC__ 00155 va_start(ap, fmt); 00156 #else 00157 va_start(ap); 00158 #endif 00159 00160 return (vsnprintf(str, n, fmt, ap)); 00161 va_end(ap); 00162 } 00163 00164 00165 Generated on Sun May 27 2012 04:20:31 for ReactOS by
1.7.6.1
|