From 94f6070cbe78694c6b3f6419f4dd812a45ded3f2 Mon Sep 17 00:00:00 2001 From: Raja R Harinath Date: Wed, 11 Mar 1998 22:30:51 +0000 Subject: Importing as vsnprintf.c. svn path=/branches/SNPRINTF_de_Raadt/; revision=133 --- support/vsnprintf.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 1 deletion(-) diff --git a/support/vsnprintf.c b/support/vsnprintf.c index 6119346..4059113 100644 --- a/support/vsnprintf.c +++ b/support/vsnprintf.c @@ -1 +1,150 @@ -#error "Fill in the code" +/* + * Revision 12: http://theos.com/~deraadt/snprintf.c + * + * Copyright (c) 1997 Theo de Raadt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#if __STDC__ +#include +#include +#else +#include +#endif +#include + +#ifndef roundup +#define roundup (x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +static int pgsize; +static char *curobj; +static int caught; +static sigjmp_buf bail; + +#define EXTRABYTES 2 /* XXX: why 2? you don't want to know */ + +static char * +msetup(str, n) + char *str; + size_t n; +{ + char *e; + + if (n == 0) + return NULL; + if (pgsize == 0) + pgsize = getpagesize(); + curobj = (char *)malloc(n + EXTRABYTES + pgsize * 2); + if (curobj == NULL) + return NULL; + e = curobj + n + EXTRABYTES; + e = (char *)roundup((unsigned long)e, pgsize); + if (mprotect(e, pgsize, PROT_NONE) == -1) { + free(curobj); + curobj = NULL; + return NULL; + } + e = e - n - EXTRABYTES; + *e = '\0'; + return (e); +} + +static void +mcatch() +{ + siglongjmp(bail, 1); +} + +static void +mcleanup(str, n, p) + char *str; + size_t n; + char *p; +{ + strncpy(str, p, n-1); + str[n-1] = '\0'; + if (mprotect((caddr_t)(p + n + EXTRABYTES), pgsize, + PROT_READ|PROT_WRITE|PROT_EXEC) == -1) + mprotect((caddr_t)(p + n + EXTRABYTES), pgsize, + PROT_READ|PROT_WRITE); + free(curobj); +} + +int +#if __STDC__ +snprintf(char *str, size_t n, char const *fmt, ...) +#else +snprintf(str, n, fmt, va_alist) + char *str; + size_t n; + char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + + return (vsnprintf(str, n, fmt, ap)); + va_end(ap); +} + +int +vsnprintf(str, n, fmt, ap) + char *str; + size_t n; + char *fmt; + char *ap; +{ + struct sigaction osa, nsa; + char *p; + int ret = n + 1; /* if we bail, indicated we overflowed */ + + memset(&nsa, 0, sizeof nsa); + nsa.sa_handler = mcatch; + sigemptyset(&nsa.sa_mask); + + p = msetup(str, n); + if (p == NULL) { + *str = '\0'; + return 0; + } + if (sigsetjmp(bail, 1) == 0) { + if (sigaction(SIGSEGV, &nsa, &osa) == -1) { + mcleanup(str, n, p); + return (0); + } + ret = vsprintf(p, fmt, ap); + } + mcleanup(str, n, p); + (void) sigaction(SIGSEGV, &osa, NULL); + return (ret); +} -- cgit v1.2.1