snprintf.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:4k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* $Id: snprintf.c,v 1.4 1999/05/13 16:35:58 karls Exp $ */
  2. #ifdef HAVE_CONFIG_H
  3. #include "autoconf.h"
  4. #endif  /* HAVE_CONFIG_H */
  5. #include "common.h"
  6. #if !HAVE_SNPRINTF
  7. /*
  8.  * Revision 12: http://theos.com/~deraadt/snprintf.c
  9.  *
  10.  * Copyright (c) 1997 Theo de Raadt
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, are permitted provided that the following conditions
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  25.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  30.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31.  */
  32. #if 0
  33. #ifndef _COMMON_H_
  34. #include <sys/types.h>
  35. #endif  /* !_COMMON_H_ */
  36. #include <sys/mman.h>
  37. #include <signal.h>
  38. #include <stdio.h>
  39. #if STDC_HEADERS
  40. #include <stdarg.h>
  41. #include <stdlib.h>
  42. #else
  43. #include <varargs.h>
  44. #endif  /* STDC_HEADERS */
  45. #include <setjmp.h>
  46. #if HAVE_UNISTD_H
  47. #include <unistd.h>
  48. #endif  /* HAVE_UNISTD_H */
  49. #endif
  50. #ifndef roundup
  51. #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
  52. #endif
  53. static int pgsize;
  54. static char *curobj;
  55. /*static int caught;*/
  56. static sigjmp_buf bail;
  57. static char *msetup __P((char *, size_t));
  58. static void mcatch __P((void));
  59. static void mcleanup __P((char *, size_t, char *));
  60. #define EXTRABYTES      2       /* XXX: why 2? you don't want to know */
  61. static char *
  62. msetup(str, n)
  63. char *str;
  64. size_t n;
  65. {
  66. char *e;
  67. if (n == 0)
  68. return NULL;
  69. if (pgsize == 0)
  70. pgsize = getpagesize();
  71. curobj = (char *)malloc(n + EXTRABYTES + pgsize * 2);
  72. if (curobj == NULL)
  73. return NULL;
  74. e = curobj + n + EXTRABYTES;
  75. e = (char *)roundup((unsigned long)e, pgsize);
  76. if (mprotect(e, pgsize, PROT_NONE) == -1) {
  77. free(curobj);
  78. curobj = NULL;
  79. return NULL;
  80. }
  81. e = e - n - EXTRABYTES;
  82. *e = '';
  83. return (e);
  84. }
  85. static void
  86. mcatch()
  87. {
  88. siglongjmp(bail, 1);
  89. }
  90. static void
  91. mcleanup(str, n, p)
  92. char *str;
  93. size_t n;
  94. char *p;
  95. {
  96. strncpy(str, p, n-1);
  97. str[n-1] = '';
  98. if (mprotect((caddr_t)(p + n + EXTRABYTES), pgsize,
  99. PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
  100. mprotect((caddr_t)(p + n + EXTRABYTES), pgsize,
  101. PROT_READ|PROT_WRITE);
  102. free(curobj);
  103. }
  104. int
  105. #ifdef STDC_HEADERS
  106. snprintf(char *str, size_t n, char const *fmt, ...)
  107. #else
  108. snprintf(str, n, fmt, va_alist)
  109. char *str;
  110. size_t n;
  111. char *fmt;
  112. va_dcl
  113. #endif  /* STDC_HEADERS */
  114. {
  115. va_list ap;
  116. #ifdef STDC_HEADERS
  117. va_start(ap, fmt);
  118. #else
  119. va_start(ap);
  120. #endif  /* STDC_HEADERS */
  121. return (vsnprintf(str, n, fmt, ap));
  122. va_end(ap);
  123. }
  124. int
  125. vsnprintf(str, n, fmt, ap)
  126. char *str;
  127. size_t n;
  128. const char *fmt;
  129. va_list ap;
  130. {
  131. struct sigaction osa, nsa;
  132. char *p;
  133. int ret = n + 1;        /* if we bail, indicated we overflowed */
  134. memset(&nsa, 0, sizeof nsa);
  135. nsa.sa_handler = mcatch;
  136. sigemptyset(&nsa.sa_mask);
  137. p = msetup(str, n);
  138. if (p == NULL) {
  139. *str = '';
  140. return 0;
  141. }
  142. if (sigsetjmp(bail, 1) == 0) {
  143. if (sigaction(SIGSEGV, &nsa, &osa) == -1) {
  144. mcleanup(str, n, p);
  145. return (0);
  146. }
  147. ret = vsprintf(p, fmt, ap);
  148. #if HAVE_BROKEN_VSPRINTF
  149. ret = strlen(p);
  150. #endif  /* HAVE_BROKEN_VSPRINTF */
  151. }
  152. mcleanup(str, n, p);
  153. (void) sigaction(SIGSEGV, &osa, NULL);
  154. return (ret);
  155. }
  156. #else
  157. static void avoid_error __P((void));
  158. static void avoid_error()
  159. {
  160. avoid_error();
  161. }
  162. #endif  /* !HAVE_SNPRINTF */