Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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